func vipsSave(image *C.VipsImage, o vipsSaveOptions) ([]byte, error) { defer C.g_object_unref(C.gpointer(image)) tmpImage, err := vipsPreSave(image, &o) if err != nil { return nil, err } // When an image has an unsupported color space, vipsPreSave // returns the pointer of the image passed to it unmodified. // When this occurs, we must take care to not dereference the // original image a second time; we may otherwise erroneously // free the object twice. if tmpImage != image { defer C.g_object_unref(C.gpointer(tmpImage)) } length := C.size_t(0) saveErr := C.int(0) interlace := C.int(boolToInt(o.Interlace)) quality := C.int(o.Quality) var ptr unsafe.Pointer switch o.Type { case WEBP: saveErr = C.vips_webpsave_bridge(tmpImage, &ptr, &length, 1, quality) break case PNG: saveErr = C.vips_pngsave_bridge(tmpImage, &ptr, &length, 1, C.int(o.Compression), quality, interlace) break case GIF: return nil, errors.New("VIPS cannot save to GIF") case PDF: return nil, errors.New("VIPS cannot save to PDF") case SVG: return nil, errors.New("VIPS cannot save to SVG") default: saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, 1, quality, interlace) break } if int(saveErr) != 0 { return nil, catchVipsError() } buf := C.GoBytes(ptr, C.int(length)) // Clean up C.g_free(C.gpointer(ptr)) C.vips_error_clear() return buf, nil }
func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) { // Remove ICC profile metadata if o.NoProfile { C.remove_profile(image) } // Use a default interpretation and cast it to C type if o.Interpretation == 0 { o.Interpretation = INTERPRETATION_sRGB } interpretation := C.VipsInterpretation(o.Interpretation) // Apply the proper colour space var outImage *C.VipsImage if vipsColourspaceIsSupported(image) { err := int(C.vips_colourspace_bridge(image, &outImage, interpretation)) if err != 0 { return nil, catchVipsError() } C.g_object_unref(C.gpointer(image)) image = outImage } return image, nil }
func affineImage(image *C.struct__VipsImage, o Options, residual float64) (*C.struct__VipsImage, error) { newImage, err := vipsAffine(image, residual, o.Interpolator) if err != nil { C.g_object_unref(C.gpointer(image)) return nil, err } if o.Enlarge || (o.Width > int(newImage.Xsize) && o.Height > int(newImage.Ysize)) { C.g_object_unref(C.gpointer(image)) image = newImage } else { C.g_object_unref(C.gpointer(newImage)) } return image, nil }
func vipsAffine(input *C.VipsImage, residualx, residualy float64, i Interpolator) (*C.VipsImage, error) { var image *C.VipsImage cstring := C.CString(i.String()) interpolator := C.vips_interpolate_new(cstring) defer C.free(unsafe.Pointer(cstring)) defer C.g_object_unref(C.gpointer(input)) defer C.g_object_unref(C.gpointer(interpolator)) err := C.vips_affine_interpolator(input, &image, C.double(residualx), 0, 0, C.double(residualy), interpolator) if err != 0 { return nil, catchVipsError() } return image, nil }
func (t *PDFStreamTextObject) WriteAt(text string, props TypesettingProps, x float64, y float64) error { var layout *C.PangoLayout var font_description *C.PangoFontDescription font_description = C.pango_font_description_new() cfontname := C.CString(props.Fontname) defer C.free(unsafe.Pointer(cfontname)) C.pango_font_description_set_family(font_description, cfontname) C.pango_font_description_set_weight(font_description, C.PANGO_WEIGHT_NORMAL) C.pango_font_description_set_absolute_size(font_description, C.double(props.Fontsize)*C.PANGO_SCALE) layout = C.pango_cairo_create_layout(t.context) C.pango_layout_set_font_description(layout, font_description) width := props.PageWidth - props.LeftMargin - props.RightMargin fmt.Printf("width is %f\n", width) C.pango_layout_set_width(layout, C.int(width*C.PANGO_SCALE)) C.pango_layout_set_justify(layout, C.TRUE) ctext := C.CString(text) defer C.free(unsafe.Pointer(ctext)) C.pango_layout_set_text(layout, ctext, -1) C.cairo_set_source_rgb(t.context, 0.0, 0.0, 0.0) C.cairo_move_to(t.context, C.double(x), C.double(y)) skip := props.Baselineskip nlines := int(C.pango_layout_get_line_count(layout)) for i := 0; i < nlines; i++ { C.cairo_move_to(t.context, C.double(x), C.double(y+float64(i)*skip)) C.pango_cairo_show_layout_line(t.context, C.pango_layout_get_line(layout, C.int(i))) } C.g_object_unref(C.gpointer(layout)) C.pango_font_description_free(font_description) return nil }
//-------------------------------------------------------------- // Object //-------------------------------------------------------------- func objectFinalizer(obj *Object) { if FQueue.Push(unsafe.Pointer(obj), objectFinalizer2) { return } C.g_object_set_qdata((*C.GObject)(obj.C), C.GQuark(go_repr), nil) C.g_object_unref(C.gpointer(obj.C)) }
// Metadata returns the image metadata (size, type, alpha channel, profile, EXIF orientation...). func Metadata(buf []byte) (ImageMetadata, error) { defer C.vips_thread_shutdown() image, imageType, err := vipsRead(buf) if err != nil { return ImageMetadata{}, err } defer C.g_object_unref(C.gpointer(image)) size := ImageSize{ Width: int(image.Xsize), Height: int(image.Ysize), } metadata := ImageMetadata{ Size: size, Channels: int(image.Bands), Orientation: vipsExifOrientation(image), Alpha: vipsHasAlpha(image), Profile: vipsHasProfile(image), Space: vipsSpace(image), Type: ImageTypeName(imageType), } return metadata, nil }
// imageError adapts image modification semantics from being the VIPS-style // chain of immutable objects that we need to individually free to a single // stateful Go object that can be closed once, greatly simplifying error // handling. func (in *Image) imageError(out *C.struct__VipsImage, e C.int) error { if in.vi == nil { panic("Input image is nil") } if err := vipsError(e); err != nil { if out != nil { C.g_object_unref(C.gpointer(out)) } return err } C.g_object_unref(C.gpointer(in.vi)) in.vi = out return nil }
func vipsColourspaceIsSupportedBuffer(buf []byte) (bool, error) { image, _, err := vipsRead(buf) if err != nil { return false, err } C.g_object_unref(C.gpointer(image)) return vipsColourspaceIsSupported(image), nil }
func vipsInterpretationBuffer(buf []byte) (Interpretation, error) { image, _, err := vipsRead(buf) if err != nil { return INTERPRETATION_ERROR, err } C.g_object_unref(C.gpointer(image)) return vipsInterpretation(image), nil }
func vipsGaussianBlur(image *C.VipsImage, o GaussianBlur) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) err := C.vips_gaussblur_bridge(image, &out, C.double(o.Sigma), C.double(o.MinAmpl)) if err != 0 { return nil, catchVipsError() } return out, nil }
func vipsSharpen(image *C.VipsImage, o Sharpen) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) err := C.vips_sharpen_bridge(image, &out, C.int(o.Radius), C.double(o.X1), C.double(o.Y2), C.double(o.Y3), C.double(o.M1), C.double(o.M2)) if err != 0 { return nil, catchVipsError() } return out, nil }
func vipsSave(image *C.struct__VipsImage, o vipsSaveOptions) ([]byte, error) { length := C.size_t(0) err := C.int(0) interlace := C.int(boolToInt(o.Interlace)) // Remove ICC profile metadata if o.NoProfile { C.remove_profile(image) } // Force RGB color space var outImage *C.struct__VipsImage C.vips_colourspace_bridge(image, &outImage) defer C.g_object_unref(C.gpointer(image)) defer C.g_object_unref(C.gpointer(outImage)) var ptr unsafe.Pointer switch o.Type { case PNG: err = C.vips_pngsave_bridge(outImage, &ptr, &length, 1, C.int(o.Compression), C.int(o.Quality), interlace) break case WEBP: err = C.vips_webpsave_bridge(outImage, &ptr, &length, 1, C.int(o.Quality)) break default: err = C.vips_jpegsave_bridge(outImage, &ptr, &length, 1, C.int(o.Quality), interlace) break } if int(err) != 0 { return nil, catchVipsError() } buf := C.GoBytes(ptr, C.int(length)) // Clean up C.g_free(C.gpointer(ptr)) C.vips_error_clear() return buf, nil }
func NewParamSpecFromCPointer(p unsafe.Pointer) *ParamSpec { ret := &ParamSpec{ NewTraitParamSpec(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *ParamSpec) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewObjectFromCPointer(p unsafe.Pointer) *Object { ret := &Object{ NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *Object) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewAppLaunchContextFromCPointer(p unsafe.Pointer) *AppLaunchContext { ret := &AppLaunchContext{ NewTraitAppLaunchContext(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *AppLaunchContext) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func (d *dialog) cleanup(box *C.GtkWidget) { // have to explicitly close the dialog box, otherwise wacky things will happen C.gtk_widget_destroy(box) if d.parent != dialogWindow { C.gtk_window_group_remove_window(d.newgroup, d.pwin) C.g_object_unref(C.gpointer(unsafe.Pointer(d.newgroup))) // free the group if d.prevgroup != nil { C.gtk_window_group_add_window(d.prevgroup, d.pwin) } // otherwise it'll go back into the default group on its own } }
func vipsEmbed(input *C.VipsImage, left, top, width, height, extend int) (*C.VipsImage, error) { var image *C.VipsImage defer C.g_object_unref(C.gpointer(input)) err := C.vips_embed_bridge(input, &image, C.int(left), C.int(top), C.int(width), C.int(height), C.int(extend)) if err != 0 { return nil, catchVipsError() } return image, nil }
func vipsZoom(image *C.VipsImage, zoom int) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) err := C.vips_zoom_bridge(image, &out, C.int(zoom), C.int(zoom)) if err != 0 { return nil, catchVipsError() } return out, nil }
func vipsShrink(input *C.VipsImage, shrink int) (*C.VipsImage, error) { var image *C.VipsImage defer C.g_object_unref(C.gpointer(input)) err := C.vips_shrink_bridge(input, &image, C.double(float64(shrink)), C.double(float64(shrink))) if err != 0 { return nil, catchVipsError() } return image, nil }
func vipsFlip(image *C.VipsImage, direction Direction) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) err := C.vips_flip_bridge(image, &out, C.int(direction)) if err != 0 { return nil, catchVipsError() } return out, nil }
func vipsRotate(image *C.VipsImage, angle Angle) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) err := C.vips_rotate(image, &out, C.int(angle)) if err != 0 { return nil, catchVipsError() } return out, nil }
func vipsShrinkJpeg(buf []byte, input *C.VipsImage, shrink int) (*C.VipsImage, error) { var image *C.VipsImage defer C.g_object_unref(C.gpointer(input)) err := C.vips_jpegload_buffer_shrink(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), &image, C.int(shrink)) if err != 0 { return nil, catchVipsError() } return image, nil }
func NewApplicationCommandLineFromCPointer(p unsafe.Pointer) *ApplicationCommandLine { ret := &ApplicationCommandLine{ NewTraitApplicationCommandLine(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *ApplicationCommandLine) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewDBusServerFromCPointer(p unsafe.Pointer) *DBusServer { ret := &DBusServer{ NewTraitDBusServer(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *DBusServer) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewDesktopAppInfoFromCPointer(p unsafe.Pointer) *DesktopAppInfo { ret := &DesktopAppInfo{ NewTraitDesktopAppInfo(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *DesktopAppInfo) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewEmblemedIconFromCPointer(p unsafe.Pointer) *EmblemedIcon { ret := &EmblemedIcon{ NewTraitEmblemedIcon(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *EmblemedIcon) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewFilenameCompleterFromCPointer(p unsafe.Pointer) *FilenameCompleter { ret := &FilenameCompleter{ NewTraitFilenameCompleter(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *FilenameCompleter) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewInetAddressMaskFromCPointer(p unsafe.Pointer) *InetAddressMask { ret := &InetAddressMask{ NewTraitInetAddressMask(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *InetAddressMask) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }
func NewInputStreamFromCPointer(p unsafe.Pointer) *InputStream { ret := &InputStream{ NewTraitInputStream(p), gobject.NewTraitObject(p), p, } C.g_object_ref_sink(C.gpointer(p)) runtime.SetFinalizer(ret, func(p *InputStream) { C.g_object_unref(C.gpointer(unsafe.Pointer(p.CPointer))) }) return ret }