forked from Leak_Technologies/VideoTools
Vendor gotk3 library to ensure consistent GTK3 bindings across environments and simplify dependency management. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
669 lines
18 KiB
Go
669 lines
18 KiB
Go
// Same copyright and license as the rest of the files in this project
|
|
|
|
package gdk
|
|
|
|
// #cgo pkg-config: gdk-3.0 glib-2.0 gobject-2.0
|
|
// #include <gdk/gdk.h>
|
|
// #include "gdk.go.h"
|
|
// #include "pixbuf.go.h"
|
|
import "C"
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"runtime"
|
|
"strconv"
|
|
"unsafe"
|
|
|
|
"github.com/gotk3/gotk3/glib"
|
|
)
|
|
|
|
func init() {
|
|
tm := []glib.TypeMarshaler{
|
|
// Enums
|
|
{glib.Type(C.gdk_pixbuf_alpha_mode_get_type()), marshalPixbufAlphaMode},
|
|
|
|
// Objects/Interfaces
|
|
{glib.Type(C.gdk_pixbuf_get_type()), marshalPixbuf},
|
|
{glib.Type(C.gdk_pixbuf_animation_get_type()), marshalPixbufAnimation},
|
|
{glib.Type(C.gdk_pixbuf_loader_get_type()), marshalPixbufLoader},
|
|
}
|
|
glib.RegisterGValueMarshalers(tm)
|
|
}
|
|
|
|
/*
|
|
* Constants
|
|
*/
|
|
|
|
// TODO:
|
|
// GdkPixbufError
|
|
|
|
// PixbufRotation is a representation of GDK's GdkPixbufRotation.
|
|
type PixbufRotation int
|
|
|
|
const (
|
|
PIXBUF_ROTATE_NONE PixbufRotation = C.GDK_PIXBUF_ROTATE_NONE
|
|
PIXBUF_ROTATE_COUNTERCLOCKWISE PixbufRotation = C.GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE
|
|
PIXBUF_ROTATE_UPSIDEDOWN PixbufRotation = C.GDK_PIXBUF_ROTATE_UPSIDEDOWN
|
|
PIXBUF_ROTATE_CLOCKWISE PixbufRotation = C.GDK_PIXBUF_ROTATE_CLOCKWISE
|
|
)
|
|
|
|
// PixbufAlphaMode is a representation of GDK's GdkPixbufAlphaMode.
|
|
type PixbufAlphaMode int
|
|
|
|
const (
|
|
GDK_PIXBUF_ALPHA_BILEVEL PixbufAlphaMode = C.GDK_PIXBUF_ALPHA_BILEVEL
|
|
GDK_PIXBUF_ALPHA_FULL PixbufAlphaMode = C.GDK_PIXBUF_ALPHA_FULL
|
|
)
|
|
|
|
func marshalPixbufAlphaMode(p uintptr) (interface{}, error) {
|
|
c := C.g_value_get_enum((*C.GValue)(unsafe.Pointer(p)))
|
|
return PixbufAlphaMode(c), nil
|
|
}
|
|
|
|
/*
|
|
* GdkPixbuf
|
|
*/
|
|
|
|
// PixbufGetType is a wrapper around gdk_pixbuf_get_type().
|
|
func PixbufGetType() glib.Type {
|
|
return glib.Type(C.gdk_pixbuf_get_type())
|
|
}
|
|
|
|
// Pixbuf is a representation of GDK's GdkPixbuf.
|
|
type Pixbuf struct {
|
|
*glib.Object
|
|
}
|
|
|
|
// native returns a pointer to the underlying GdkPixbuf.
|
|
func (v *Pixbuf) native() *C.GdkPixbuf {
|
|
if v == nil || v.GObject == nil {
|
|
return nil
|
|
}
|
|
p := unsafe.Pointer(v.GObject)
|
|
return C.toGdkPixbuf(p)
|
|
}
|
|
|
|
// Native returns a pointer to the underlying GdkPixbuf.
|
|
func (v *Pixbuf) Native() uintptr {
|
|
return uintptr(unsafe.Pointer(v.native()))
|
|
}
|
|
|
|
func (v *Pixbuf) NativePrivate() *C.GdkPixbuf {
|
|
if v == nil || v.GObject == nil {
|
|
return nil
|
|
}
|
|
p := unsafe.Pointer(v.GObject)
|
|
return C.toGdkPixbuf(p)
|
|
}
|
|
|
|
func marshalPixbuf(p uintptr) (interface{}, error) {
|
|
c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
return &Pixbuf{obj}, nil
|
|
}
|
|
|
|
// PixbufNew is a wrapper around gdk_pixbuf_new().
|
|
func PixbufNew(colorspace Colorspace, hasAlpha bool, bitsPerSample, width, height int) (*Pixbuf, error) {
|
|
c := C.gdk_pixbuf_new(C.GdkColorspace(colorspace), gbool(hasAlpha),
|
|
C.int(bitsPerSample), C.int(width), C.int(height))
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
//obj.Ref()
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
return p, nil
|
|
}
|
|
|
|
// File Loading
|
|
|
|
// PixbufNewFromFile is a wrapper around gdk_pixbuf_new_from_file().
|
|
func PixbufNewFromFile(filename string) (*Pixbuf, error) {
|
|
cstr := C.CString(filename)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
var err *C.GError
|
|
c := C.gdk_pixbuf_new_from_file((*C.char)(cstr), &err)
|
|
if c == nil {
|
|
defer C.g_error_free(err)
|
|
return nil, errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
//obj.Ref()
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
return p, nil
|
|
}
|
|
|
|
// Image Data in Memory
|
|
|
|
// PixbufNewFromData is a wrapper around gdk_pixbuf_new_from_data().
|
|
func PixbufNewFromData(pixbufData []byte, cs Colorspace, hasAlpha bool, bitsPerSample, width, height, rowStride int) (*Pixbuf, error) {
|
|
arrayPtr := (*C.guchar)(unsafe.Pointer(&pixbufData[0]))
|
|
|
|
c := C.gdk_pixbuf_new_from_data(
|
|
arrayPtr,
|
|
C.GdkColorspace(cs),
|
|
gbool(hasAlpha),
|
|
C.int(bitsPerSample),
|
|
C.int(width),
|
|
C.int(height),
|
|
C.int(rowStride),
|
|
nil, // TODO: missing support for GdkPixbufDestroyNotify
|
|
nil,
|
|
)
|
|
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
//obj.Ref()
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
|
|
return p, nil
|
|
}
|
|
|
|
// PixbufNewFromDataOnly is a convenient alternative to PixbufNewFromData() and also a wrapper around gdk_pixbuf_new_from_data().
|
|
func PixbufNewFromDataOnly(pixbufData []byte) (*Pixbuf, error) {
|
|
pixbufLoader, err := PixbufLoaderNew()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return pixbufLoader.WriteAndReturnPixbuf(pixbufData)
|
|
}
|
|
|
|
// PixbufNewFromResource is a wrapper around gdk_pixbuf_new_from_resource()
|
|
func PixbufNewFromResource(resourcePath string) (*Pixbuf, error) {
|
|
var gerr *C.GError
|
|
|
|
cstr := C.CString(resourcePath)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
c := C.gdk_pixbuf_new_from_resource((*C.gchar)(cstr), &gerr)
|
|
|
|
if gerr != nil {
|
|
defer C.g_error_free(gerr)
|
|
return nil, errors.New(C.GoString(gerr.message))
|
|
}
|
|
|
|
obj := glib.Take(unsafe.Pointer(c))
|
|
return &Pixbuf{obj}, nil
|
|
}
|
|
|
|
// PixbufNewFromResourceAtScale is a wrapper around gdk_pixbuf_new_from_resource_at_scale()
|
|
func PixbufNewFromResourceAtScale(resourcePath string, width, height int, preserveAspectRatio bool) (*Pixbuf, error) {
|
|
var gerr *C.GError
|
|
|
|
cstr := C.CString(resourcePath)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
cPreserveAspectRatio := gbool(preserveAspectRatio)
|
|
|
|
c := C.gdk_pixbuf_new_from_resource_at_scale(
|
|
(*C.gchar)(cstr),
|
|
C.gint(width),
|
|
C.gint(height),
|
|
C.gboolean(cPreserveAspectRatio),
|
|
&gerr,
|
|
)
|
|
|
|
if gerr != nil {
|
|
defer C.g_error_free(gerr)
|
|
return nil, errors.New(C.GoString(gerr.message))
|
|
}
|
|
|
|
obj := glib.Take(unsafe.Pointer(c))
|
|
return &Pixbuf{obj}, nil
|
|
}
|
|
|
|
// TODO:
|
|
// gdk_pixbuf_new_from_xpm_data().
|
|
// gdk_pixbuf_new_subpixbuf()
|
|
|
|
// PixbufCopy is a wrapper around gdk_pixbuf_copy().
|
|
func PixbufCopy(v *Pixbuf) (*Pixbuf, error) {
|
|
c := C.gdk_pixbuf_copy(v.native())
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
//obj.Ref()
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
return p, nil
|
|
}
|
|
|
|
// The GdkPixbuf Structure
|
|
|
|
// GetColorspace is a wrapper around gdk_pixbuf_get_colorspace().
|
|
func (v *Pixbuf) GetColorspace() Colorspace {
|
|
c := C.gdk_pixbuf_get_colorspace(v.native())
|
|
return Colorspace(c)
|
|
}
|
|
|
|
// GetNChannels is a wrapper around gdk_pixbuf_get_n_channels().
|
|
func (v *Pixbuf) GetNChannels() int {
|
|
c := C.gdk_pixbuf_get_n_channels(v.native())
|
|
return int(c)
|
|
}
|
|
|
|
// GetHasAlpha is a wrapper around gdk_pixbuf_get_has_alpha().
|
|
func (v *Pixbuf) GetHasAlpha() bool {
|
|
c := C.gdk_pixbuf_get_has_alpha(v.native())
|
|
return gobool(c)
|
|
}
|
|
|
|
// GetBitsPerSample is a wrapper around gdk_pixbuf_get_bits_per_sample().
|
|
func (v *Pixbuf) GetBitsPerSample() int {
|
|
c := C.gdk_pixbuf_get_bits_per_sample(v.native())
|
|
return int(c)
|
|
}
|
|
|
|
// GetPixels is a wrapper around gdk_pixbuf_get_pixels_with_length().
|
|
// A Go slice is used to represent the underlying Pixbuf data array, one
|
|
// byte per channel.
|
|
func (v *Pixbuf) GetPixels() (channels []byte) {
|
|
var length C.guint
|
|
c := C.gdk_pixbuf_get_pixels_with_length(v.native(), &length)
|
|
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&channels))
|
|
sliceHeader.Data = uintptr(unsafe.Pointer(c))
|
|
sliceHeader.Len = int(length)
|
|
sliceHeader.Cap = int(length)
|
|
|
|
// To make sure the slice doesn't outlive the Pixbuf, add a reference
|
|
v.Ref()
|
|
runtime.SetFinalizer(&channels, func(_ *[]byte) {
|
|
glib.FinalizerStrategy(v.Unref)
|
|
})
|
|
return
|
|
}
|
|
|
|
// GetWidth is a wrapper around gdk_pixbuf_get_width().
|
|
func (v *Pixbuf) GetWidth() int {
|
|
c := C.gdk_pixbuf_get_width(v.native())
|
|
return int(c)
|
|
}
|
|
|
|
// GetHeight is a wrapper around gdk_pixbuf_get_height().
|
|
func (v *Pixbuf) GetHeight() int {
|
|
c := C.gdk_pixbuf_get_height(v.native())
|
|
return int(c)
|
|
}
|
|
|
|
// GetRowstride is a wrapper around gdk_pixbuf_get_rowstride().
|
|
func (v *Pixbuf) GetRowstride() int {
|
|
c := C.gdk_pixbuf_get_rowstride(v.native())
|
|
return int(c)
|
|
}
|
|
|
|
// GetOption is a wrapper around gdk_pixbuf_get_option(). ok is true if
|
|
// the key has an associated value.
|
|
func (v *Pixbuf) GetOption(key string) (value string, ok bool) {
|
|
cstr := C.CString(key)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
c := C.gdk_pixbuf_get_option(v.native(), (*C.gchar)(cstr))
|
|
if c == nil {
|
|
return "", false
|
|
}
|
|
return C.GoString((*C.char)(c)), true
|
|
}
|
|
|
|
// Scaling
|
|
|
|
// ScaleSimple is a wrapper around gdk_pixbuf_scale_simple().
|
|
func (v *Pixbuf) ScaleSimple(destWidth, destHeight int, interpType InterpType) (*Pixbuf, error) {
|
|
c := C.gdk_pixbuf_scale_simple(v.native(), C.int(destWidth),
|
|
C.int(destHeight), C.GdkInterpType(interpType))
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
//obj.Ref()
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
return p, nil
|
|
}
|
|
|
|
// Scale is a wrapper around gdk_pixbuf_scale().
|
|
func (v *Pixbuf) Scale(dest *Pixbuf, destX, destY, destWidth, destHeight int, offsetX, offsetY, scaleX, scaleY float64, interpType InterpType) {
|
|
C.gdk_pixbuf_scale(
|
|
v.native(),
|
|
dest.native(),
|
|
C.int(destX),
|
|
C.int(destY),
|
|
C.int(destWidth),
|
|
C.int(destHeight),
|
|
C.double(offsetX),
|
|
C.double(offsetY),
|
|
C.double(scaleX),
|
|
C.double(scaleY),
|
|
C.GdkInterpType(interpType),
|
|
)
|
|
}
|
|
|
|
// Composite is a wrapper around gdk_pixbuf_composite().
|
|
func (v *Pixbuf) Composite(dest *Pixbuf, destX, destY, destWidth, destHeight int, offsetX, offsetY, scaleX, scaleY float64, interpType InterpType, overallAlpha int) {
|
|
C.gdk_pixbuf_composite(
|
|
v.native(),
|
|
dest.native(),
|
|
C.int(destX),
|
|
C.int(destY),
|
|
C.int(destWidth),
|
|
C.int(destHeight),
|
|
C.double(offsetX),
|
|
C.double(offsetY),
|
|
C.double(scaleX),
|
|
C.double(scaleY),
|
|
C.GdkInterpType(interpType),
|
|
C.int(overallAlpha),
|
|
)
|
|
}
|
|
|
|
// TODO:
|
|
// gdk_pixbuf_composite_color_simple().
|
|
// gdk_pixbuf_composite_color().
|
|
|
|
// Utilities
|
|
|
|
// TODO:
|
|
// gdk_pixbuf_copy_area().
|
|
// gdk_pixbuf_saturate_and_pixelate().
|
|
|
|
// Fill is a wrapper around gdk_pixbuf_fill(). The given pixel is an RGBA value.
|
|
func (v *Pixbuf) Fill(pixel uint32) {
|
|
C.gdk_pixbuf_fill(v.native(), C.guint32(pixel))
|
|
}
|
|
|
|
// AddAlpha is a wrapper around gdk_pixbuf_add_alpha(). If substituteColor is
|
|
// true, then the color specified by r, g and b will be assigned zero opacity.
|
|
func (v *Pixbuf) AddAlpha(substituteColor bool, r, g, b uint8) *Pixbuf {
|
|
c := C.gdk_pixbuf_add_alpha(v.native(), gbool(substituteColor), C.guchar(r), C.guchar(g), C.guchar(b))
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
|
|
return p
|
|
}
|
|
|
|
// File saving
|
|
|
|
// TODO:
|
|
// gdk_pixbuf_savev().
|
|
// gdk_pixbuf_save().
|
|
|
|
// SaveJPEG is a convenience wrapper around gdk_pixbuf_save() for saving image as jpeg file.
|
|
// Quality is a number between 0...100
|
|
func (v *Pixbuf) SaveJPEG(path string, quality int) error {
|
|
cpath := C.CString(path)
|
|
cquality := C.CString(strconv.Itoa(quality))
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
defer C.free(unsafe.Pointer(cquality))
|
|
|
|
var err *C.GError
|
|
c := C._gdk_pixbuf_save_jpeg(v.native(), cpath, &err, cquality)
|
|
if !gobool(c) {
|
|
defer C.g_error_free(err)
|
|
return errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SavePNG is a convenience wrapper around gdk_pixbuf_save() for saving image as png file.
|
|
// Compression is a number between 0...9
|
|
func (v *Pixbuf) SavePNG(path string, compression int) error {
|
|
cpath := C.CString(path)
|
|
ccompression := C.CString(strconv.Itoa(compression))
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
defer C.free(unsafe.Pointer(ccompression))
|
|
|
|
var err *C.GError
|
|
c := C._gdk_pixbuf_save_png(v.native(), cpath, &err, ccompression)
|
|
if !gobool(c) {
|
|
defer C.g_error_free(err)
|
|
return errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
* PixbufFormat
|
|
*/
|
|
|
|
type PixbufFormat struct {
|
|
format *C.GdkPixbufFormat
|
|
}
|
|
|
|
// native returns a pointer to the underlying GdkPixbuf.
|
|
func (v *PixbufFormat) native() *C.GdkPixbufFormat {
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
|
|
return v.format
|
|
}
|
|
|
|
func wrapPixbufFormat(obj *C.GdkPixbufFormat) *PixbufFormat {
|
|
return &PixbufFormat{obj}
|
|
}
|
|
|
|
// Native returns a pointer to the underlying GdkPixbuf.
|
|
func (v *PixbufFormat) Native() uintptr {
|
|
return uintptr(unsafe.Pointer(v.native()))
|
|
}
|
|
|
|
/*
|
|
* GdkPixbufAnimation
|
|
*/
|
|
|
|
// PixbufAnimation is a representation of GDK's GdkPixbufAnimation.
|
|
type PixbufAnimation struct {
|
|
*glib.Object
|
|
}
|
|
|
|
// native returns a pointer to the underlying GdkPixbufAnimation.
|
|
func (v *PixbufAnimation) native() *C.GdkPixbufAnimation {
|
|
if v == nil || v.GObject == nil {
|
|
return nil
|
|
}
|
|
p := unsafe.Pointer(v.GObject)
|
|
return C.toGdkPixbufAnimation(p)
|
|
}
|
|
|
|
func (v *PixbufAnimation) NativePrivate() *C.GdkPixbufAnimation {
|
|
if v == nil || v.GObject == nil {
|
|
return nil
|
|
}
|
|
p := unsafe.Pointer(v.GObject)
|
|
return C.toGdkPixbufAnimation(p)
|
|
}
|
|
|
|
func (v *PixbufAnimation) GetStaticImage() *Pixbuf {
|
|
c := C.gdk_pixbuf_animation_get_static_image(v.native())
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &Pixbuf{obj}
|
|
|
|
// Add a reference so the pixbuf doesn't outlive the parent pixbuf
|
|
// animation.
|
|
v.Ref()
|
|
runtime.SetFinalizer(p, func(*Pixbuf) { glib.FinalizerStrategy(v.Unref) })
|
|
|
|
return p
|
|
}
|
|
|
|
func marshalPixbufAnimation(p uintptr) (interface{}, error) {
|
|
c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
return &PixbufAnimation{obj}, nil
|
|
}
|
|
|
|
// PixbufAnimationNewFromFile is a wrapper around gdk_pixbuf_animation_new_from_file().
|
|
func PixbufAnimationNewFromFile(filename string) (*PixbufAnimation, error) {
|
|
cstr := C.CString(filename)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
var err *C.GError
|
|
c := C.gdk_pixbuf_animation_new_from_file((*C.char)(cstr), &err)
|
|
if c == nil {
|
|
defer C.g_error_free(err)
|
|
return nil, errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
p := &PixbufAnimation{obj}
|
|
runtime.SetFinalizer(p, func(_ interface{}) { glib.FinalizerStrategy(obj.Unref) })
|
|
return p, nil
|
|
}
|
|
|
|
// TODO:
|
|
// gdk_pixbuf_animation_new_from_resource().
|
|
|
|
/*
|
|
* GdkPixbufLoader
|
|
*/
|
|
|
|
// PixbufLoader is a representation of GDK's GdkPixbufLoader.
|
|
// Users of PixbufLoader are expected to call Close() when they are finished.
|
|
type PixbufLoader struct {
|
|
*glib.Object
|
|
}
|
|
|
|
// native() returns a pointer to the underlying GdkPixbufLoader.
|
|
func (v *PixbufLoader) native() *C.GdkPixbufLoader {
|
|
if v == nil || v.GObject == nil {
|
|
return nil
|
|
}
|
|
p := unsafe.Pointer(v.GObject)
|
|
return C.toGdkPixbufLoader(p)
|
|
}
|
|
|
|
func marshalPixbufLoader(p uintptr) (interface{}, error) {
|
|
c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
|
|
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
|
|
return &PixbufLoader{obj}, nil
|
|
}
|
|
|
|
// PixbufLoaderNew() is a wrapper around gdk_pixbuf_loader_new().
|
|
func PixbufLoaderNew() (*PixbufLoader, error) {
|
|
c := C.gdk_pixbuf_loader_new()
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
return &PixbufLoader{glib.AssumeOwnership(unsafe.Pointer(c))}, nil
|
|
}
|
|
|
|
// PixbufLoaderNewWithType() is a wrapper around gdk_pixbuf_loader_new_with_type().
|
|
func PixbufLoaderNewWithType(t string) (*PixbufLoader, error) {
|
|
var err *C.GError
|
|
|
|
cstr := C.CString(t)
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
c := C.gdk_pixbuf_loader_new_with_type((*C.char)(cstr), &err)
|
|
if err != nil {
|
|
defer C.g_error_free(err)
|
|
return nil, errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
return &PixbufLoader{glib.AssumeOwnership(unsafe.Pointer(c))}, nil
|
|
}
|
|
|
|
// Write() is a wrapper around gdk_pixbuf_loader_write(). The
|
|
// function signature differs from the C equivalent to satisify the
|
|
// io.Writer interface.
|
|
func (v *PixbufLoader) Write(data []byte) (int, error) {
|
|
// n is set to 0 on error, and set to len(data) otherwise.
|
|
// This is a tiny hacky to satisfy io.Writer and io.WriteCloser,
|
|
// which would allow access to all io and ioutil goodies,
|
|
// and play along nice with go environment.
|
|
|
|
if len(data) == 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
var err *C.GError
|
|
c := C.gdk_pixbuf_loader_write(v.native(),
|
|
(*C.guchar)(unsafe.Pointer(&data[0])), C.gsize(len(data)),
|
|
&err)
|
|
|
|
if !gobool(c) {
|
|
defer C.g_error_free(err)
|
|
return 0, errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
|
|
return len(data), nil
|
|
}
|
|
|
|
// Convenient function like above for Pixbuf. Write data, close loader and return Pixbuf.
|
|
func (v *PixbufLoader) WriteAndReturnPixbuf(data []byte) (*Pixbuf, error) {
|
|
_, err := v.Write(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := v.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return v.GetPixbuf()
|
|
}
|
|
|
|
// Close is a wrapper around gdk_pixbuf_loader_close(). An error is
|
|
// returned instead of a bool like the native C function to support the
|
|
// io.Closer interface.
|
|
func (v *PixbufLoader) Close() error {
|
|
var err *C.GError
|
|
|
|
if ok := gobool(C.gdk_pixbuf_loader_close(v.native(), &err)); !ok {
|
|
defer C.g_error_free(err)
|
|
return errors.New(C.GoString((*C.char)(err.message)))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetPixbuf is a wrapper around gdk_pixbuf_loader_get_pixbuf().
|
|
func (v *PixbufLoader) GetPixbuf() (*Pixbuf, error) {
|
|
c := C.gdk_pixbuf_loader_get_pixbuf(v.native())
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
return &Pixbuf{glib.Take(unsafe.Pointer(c))}, nil
|
|
}
|
|
|
|
// GetAnimation is a wrapper around gdk_pixbuf_loader_get_animation().
|
|
func (v *PixbufLoader) GetAnimation() (*PixbufAnimation, error) {
|
|
c := C.gdk_pixbuf_loader_get_animation(v.native())
|
|
if c == nil {
|
|
return nil, nilPtrErr
|
|
}
|
|
|
|
return &PixbufAnimation{glib.Take(unsafe.Pointer(c))}, nil
|
|
}
|
|
|
|
// Convenient function like above for Pixbuf. Write data, close loader and return PixbufAnimation.
|
|
func (v *PixbufLoader) WriteAndReturnPixbufAnimation(data []byte) (*PixbufAnimation, error) {
|
|
_, err := v.Write(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := v.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return v.GetAnimation()
|
|
}
|