break out libvip gtypes
all libvips gtype definitions broken out and renamed for consistency
This commit is contained in:
parent
7dcda5c0c9
commit
c1f1957e88
|
@ -337,7 +337,7 @@ vips_bandjoin( VipsImage **in, VipsImage **out, int n, ... )
|
|||
int i;
|
||||
int result;
|
||||
|
||||
area = vips_array_object_new( n );
|
||||
area = vips_area_new_array_object( n );
|
||||
array = (VipsImage **) area->data;
|
||||
for( i = 0; i < n; i++ ) {
|
||||
array[i] = in[i];
|
||||
|
|
|
@ -1283,3 +1283,12 @@ im_clip2fmt( IMAGE *in, IMAGE *out, VipsBandFmt fmt )
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
size_t
|
||||
im_ref_string_get_length( const GValue *value )
|
||||
{
|
||||
size_t length;
|
||||
|
||||
(void) vips_value_get_ref_string( value, &length );
|
||||
|
||||
return( length );
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ update_orientation_cb( VipsImage *in, const char *name, GValue *value, void *a )
|
|||
if( vips_isprefix( "exif-Orientation", name ) ) {
|
||||
const char *string;
|
||||
|
||||
if( !(string = vips_ref_string_get( value )) ) {
|
||||
if( !(string = vips_value_get_ref_string( value, NULL )) ) {
|
||||
vips_warn( "im_jpeg2vips",
|
||||
"%s", _( "exif-Orientation is not a string" ) );
|
||||
return( NULL );
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pkginclude_HEADERS = \
|
||||
type.h \
|
||||
almostdeprecated.h \
|
||||
deprecated.h \
|
||||
arithmetic.h \
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/* area.h
|
||||
*
|
||||
* 27/10/11
|
||||
* - from header.h
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifndef VIPS_AREA_H
|
||||
#define VIPS_AREA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* Also used for eg. vips_local() and friends.
|
||||
*/
|
||||
typedef int (*VipsCallbackFn)( void *a, void *b );
|
||||
|
||||
/* A ref-counted area of memory. Can hold arrays of things as well.
|
||||
*/
|
||||
typedef struct _VipsArea {
|
||||
void *data;
|
||||
size_t length; /* 0 if not known */
|
||||
|
||||
/* If this area represents an array, the number of elements in the
|
||||
* array. Equal to length / sizeof(element).
|
||||
*/
|
||||
int n;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* Reference count.
|
||||
*/
|
||||
int count;
|
||||
|
||||
/* Things like ICC profiles need their own free functions.
|
||||
*/
|
||||
VipsCallbackFn free_fn;
|
||||
|
||||
/* If we are holding an array (for exmaple, an array of double), the
|
||||
* GType of the elements and their size. 0 for not known.
|
||||
*
|
||||
* n is always length / sizeof_type, we keep it as a member for
|
||||
* convenience.
|
||||
*/
|
||||
GType type;
|
||||
size_t sizeof_type;
|
||||
} VipsArea;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#endif /*VIPS_AREA_H*/
|
|
@ -113,75 +113,6 @@ typedef void *(*VipsImageMapFn)( VipsImage *image,
|
|||
const char *field, GValue *value, void *a );
|
||||
void *vips_image_map( VipsImage *im, VipsImageMapFn fn, void *a );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_SAVE_STRING:
|
||||
*
|
||||
* The #GType for a "vips_save_string".
|
||||
*/
|
||||
#define VIPS_TYPE_SAVE_STRING (vips_save_string_get_type())
|
||||
GType vips_save_string_get_type( void );
|
||||
const char *vips_save_string_get( const GValue *value );
|
||||
void vips_save_string_set( GValue *value, const char *str );
|
||||
void vips_save_string_setf( GValue *value, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_AREA:
|
||||
*
|
||||
* The #GType for a #vips_area.
|
||||
*/
|
||||
#define VIPS_TYPE_AREA (vips_area_get_type())
|
||||
GType vips_area_get_type( void );
|
||||
VipsArea *vips_area_new_array( GType type, size_t sizeof_type, int n );
|
||||
void vips_area_unref( VipsArea *area );
|
||||
VipsArea *vips_area_copy( VipsArea *area );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_REF_STRING:
|
||||
*
|
||||
* The #GType for a #vips_refstring.
|
||||
*/
|
||||
#define VIPS_TYPE_REF_STRING (vips_ref_string_get_type())
|
||||
GType vips_ref_string_get_type( void );
|
||||
int vips_ref_string_set( GValue *value, const char *str );
|
||||
const char *vips_ref_string_get( const GValue *value );
|
||||
size_t vips_ref_string_get_length( const GValue *value );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_BLOB:
|
||||
*
|
||||
* The #GType for a #vips_blob.
|
||||
*/
|
||||
|
||||
#define VIPS_TYPE_BLOB (vips_blob_get_type())
|
||||
GType vips_blob_get_type( void );
|
||||
void *vips_blob_get( const GValue *value, size_t *length );
|
||||
int vips_blob_set( GValue *value, VipsCallbackFn free_fn,
|
||||
void *data, size_t length );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_ARRAY_DOUBLE:
|
||||
*
|
||||
* The #GType for a #vips_array_double.
|
||||
*/
|
||||
|
||||
#define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type())
|
||||
GType vips_array_double_get_type( void );
|
||||
double *vips_array_double_get( const GValue *value, int *n );
|
||||
int vips_array_double_set( GValue *value, const double *array, int n );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_ARRAY_IMAGE:
|
||||
*
|
||||
* The #GType for a #vips_array_image.
|
||||
*/
|
||||
|
||||
#define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type())
|
||||
GType vips_array_image_get_type( void );
|
||||
GObject **vips_array_object_get( const GValue *value, int *n );
|
||||
int vips_array_object_set( GValue *value, int n );
|
||||
VipsArea *vips_array_object_new( int n );
|
||||
|
||||
void vips_image_set_area( VipsImage *image,
|
||||
const char *field, VipsCallbackFn free_fn, void *data );
|
||||
int vips_image_get_area( VipsImage *image, const char *field, void **data );
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* VIPS argument types
|
||||
/* area.h
|
||||
*
|
||||
* 27/10/11
|
||||
* - from header.h
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -27,122 +30,129 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef IM_TYPE_H
|
||||
#define IM_TYPE_H
|
||||
#ifndef VIPS_AREA_H
|
||||
#define VIPS_AREA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* Type names. Old code might use "doublevec" etc. from before we had the
|
||||
* "array" type.
|
||||
/* Also used for eg. vips_local() and friends.
|
||||
*/
|
||||
#define IM_TYPE_NAME_DOUBLE "double" /* im_value_t is ptr to double */
|
||||
#define IM_TYPE_NAME_INT "integer" /* 32-bit integer */
|
||||
#define IM_TYPE_NAME_COMPLEX "complex" /* Pair of doubles */
|
||||
#define IM_TYPE_NAME_STRING "string" /* Zero-terminated char array */
|
||||
#define IM_TYPE_NAME_IMASK "intmask" /* Integer mask type */
|
||||
#define IM_TYPE_NAME_DMASK "doublemask" /* Double mask type */
|
||||
#define IM_TYPE_NAME_IMAGE "image" /* IMAGE descriptor */
|
||||
#define IM_TYPE_NAME_DISPLAY "display" /* Display descriptor */
|
||||
#define IM_TYPE_NAME_GVALUE "gvalue" /* GValue wrapper */
|
||||
#define IM_TYPE_NAME_ARRAY "array" /* Array of other values of some type */
|
||||
typedef int (*VipsCallbackFn)( void *a, void *b );
|
||||
|
||||
/* Handy type lookups.
|
||||
/* A ref-counted area of memory. Can hold arrays of things as well.
|
||||
*/
|
||||
#define IM_TYPE_IM (im_type_lookup( IM_TYPE_NAME_IMAGE, NULL ))
|
||||
#define IM_TYPE_AR( OF ) (im_type_lookup( IM_TYPE_NAME_ARRAY, OF ))
|
||||
typedef struct _VipsArea {
|
||||
void *data;
|
||||
size_t length; /* 0 if not known */
|
||||
|
||||
/* A VIPS type.
|
||||
/* If this area represents an array, the number of elements in the
|
||||
* array. Equal to length / sizeof(element).
|
||||
*/
|
||||
int n;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* Reference count.
|
||||
*/
|
||||
int count;
|
||||
|
||||
/* Things like ICC profiles need their own free functions.
|
||||
*/
|
||||
VipsCallbackFn free_fn;
|
||||
|
||||
/* If we are holding an array (for exmaple, an array of double), the
|
||||
* GType of the elements and their size. 0 for not known.
|
||||
*
|
||||
* n is always length / sizeof_type, we keep it as a member for
|
||||
* convenience.
|
||||
*/
|
||||
GType type;
|
||||
size_t sizeof_type;
|
||||
} VipsArea;
|
||||
|
||||
VipsArea *vips_area_copy( VipsArea *area );
|
||||
void vips_area_unref( VipsArea *area );
|
||||
|
||||
VipsArea *vips_area_new( VipsCallbackFn free_fn, void *data );
|
||||
VipsArea *vips_area_new_blob( VipsCallbackFn free_fn,
|
||||
void *blob, size_t blob_length );
|
||||
VipsArea *vips_area_new_array( GType type, size_t sizeof_type, int n );
|
||||
VipsArea *vips_area_new_array_object( int n );
|
||||
|
||||
/**
|
||||
* VIPS_TYPE_AREA:
|
||||
*
|
||||
* The #GType for a #vips_area.
|
||||
*/
|
||||
typedef struct im__type_t {
|
||||
const char *name; /* Name of type, eg. "double" */
|
||||
struct im__type_t *type_param; /* What this is an array of */
|
||||
size_t size; /* sizeof( im_value_t ) repres. ) */
|
||||
} im_type_t;
|
||||
#define VIPS_TYPE_AREA (vips_area_get_type())
|
||||
int vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data );
|
||||
void *vips_value_get_area( const GValue *value, size_t *length );
|
||||
GType vips_area_get_type( void );
|
||||
|
||||
/* Pass (array of pointers to im_value_t) to operations as the argument list.
|
||||
* Cast to the appropriate type for this argument, eg. (int *) or (IMAGE *).
|
||||
/**
|
||||
* VIPS_TYPE_SAVE_STRING:
|
||||
*
|
||||
* The #GType for a "vips_save_string".
|
||||
*/
|
||||
typedef void im_value_t;
|
||||
#define VIPS_TYPE_SAVE_STRING (vips_save_string_get_type())
|
||||
const char *vips_value_get_save_string( const GValue *value );
|
||||
void vips_value_set_save_string( GValue *value, const char *str );
|
||||
void vips_value_set_save_stringf( GValue *value, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
GType vips_save_string_get_type( void );
|
||||
|
||||
/* Various im_value_t values.
|
||||
/**
|
||||
* VIPS_TYPE_REF_STRING:
|
||||
*
|
||||
* The #GType for a #vips_refstring.
|
||||
*/
|
||||
typedef struct {
|
||||
char *name; /* Command-line name in */
|
||||
void *mask; /* Mask --- DOUBLE or INT */
|
||||
} im_value_mask_t;
|
||||
#define VIPS_TYPE_REF_STRING (vips_ref_string_get_type())
|
||||
const char *vips_value_get_ref_string( const GValue *value, size_t *length );
|
||||
int vips_value_set_ref_string( GValue *value, const char *str );
|
||||
GType vips_ref_string_get_type( void );
|
||||
|
||||
typedef struct {
|
||||
int n; /* Array length */
|
||||
im_value_t **array; /* Array */
|
||||
} im_value_array_t;
|
||||
|
||||
/* Flags for arguments.
|
||||
* operation,
|
||||
/**
|
||||
* VIPS_TYPE_BLOB:
|
||||
*
|
||||
* The #GType for a #vips_blob.
|
||||
*/
|
||||
typedef enum {
|
||||
IM_ARGUMENT_NONE = 0, /* No flags set */
|
||||
IM_ARGUMENT_OUTPUT = 0x1 /* Is an output arg */
|
||||
} im_argument_flags;
|
||||
#define VIPS_TYPE_BLOB (vips_blob_get_type())
|
||||
void *vips_value_get_blob( const GValue *value, size_t *length );
|
||||
int vips_value_set_blob( GValue *value,
|
||||
VipsCallbackFn free_fn, void *data, size_t length );
|
||||
GType vips_blob_get_type( void );
|
||||
|
||||
/* An argument to a VIPS operation.
|
||||
*/
|
||||
typedef struct im__argument_t {
|
||||
const char *name; /* Eg. "in2" */
|
||||
im_type_t *type; /* Argument type */
|
||||
im_argument_flags flags; /* Output/input etc. */
|
||||
} im_argument_t;
|
||||
int vips_value_set_array( GValue *value,
|
||||
GType type, size_t sizeof_type, int n );
|
||||
void *vips_value_get_array( const GValue *value,
|
||||
int *n, GType *type, size_t *sizeof_type );
|
||||
|
||||
/* Flags for operations. Various hints for UIs about the behaviour of the
|
||||
* operation,
|
||||
/**
|
||||
* VIPS_TYPE_ARRAY_DOUBLE:
|
||||
*
|
||||
* The #GType for a #vips_array_double.
|
||||
*/
|
||||
typedef enum {
|
||||
IM_OPERATION_NONE = 0, /* No flags set */
|
||||
IM_OPERATION_PIO = 0x1, /* Is a partial function */
|
||||
IM_OPERATION_TRANSFORM = 0x2, /* Performs coord transformations */
|
||||
IM_OPERATION_PTOP = 0x4, /* Point-to-point ... can be LUTted */
|
||||
IM_OPERATION_NOCACHE = 0x8 /* Result should not be cached */
|
||||
} im_operation_flags;
|
||||
#define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type())
|
||||
double *vips_value_get_array_double( const GValue *value, int *n );
|
||||
int vips_value_set_array_double( GValue *value, const double *array, int n );
|
||||
GType vips_array_double_get_type( void );
|
||||
|
||||
/* Type of a VIPS dispatch funtion.
|
||||
/**
|
||||
* VIPS_TYPE_ARRAY_IMAGE:
|
||||
*
|
||||
* The #GType for a #vips_array_image.
|
||||
*/
|
||||
typedef int (*im_operation_dispatch_fn)( im_value_t **argv );
|
||||
#define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type())
|
||||
GObject **vips_value_get_array_object( const GValue *value, int *n );
|
||||
int vips_value_set_array_object( GValue *value, int n );
|
||||
GType vips_array_image_get_type( void );
|
||||
|
||||
/* A VIPS operation.
|
||||
*/
|
||||
typedef struct im__operation_t {
|
||||
const char *name; /* eg "im_invert" */
|
||||
const char *desc; /* One line description */
|
||||
im_operation_flags flags; /* Flags for this function */
|
||||
im_operation_dispatch_fn disp; /* Dispatch */
|
||||
int argc; /* Number of args */
|
||||
im_argument_t **argv; /* Arg list */
|
||||
} im_operation_t;
|
||||
|
||||
/* Register/iterate over types.
|
||||
*/
|
||||
im_type_t *im_type_register( const char *name,
|
||||
im_type_t *type_param, size_t size );
|
||||
void *im_type_map( VSListMap2Fn fn, void *a, void *b );
|
||||
im_type_t *im_type_lookup( const char *name, im_type_t *type_param );
|
||||
|
||||
/* Register/iterate/lookup operations.
|
||||
*/
|
||||
im_operation_t *im_operation_register( const char *name, const char *desc,
|
||||
im_operation_flags flags, im_operation_dispatch_fn disp, int argc );
|
||||
im_operation_t *im_operation_registerv( const char *name, const char *desc,
|
||||
im_operation_flags flags, im_operation_dispatch_fn disp, ... );
|
||||
void *im_operation_map( VSListMap2Fn fn, void *a, void *b );
|
||||
im_operation_t *im_operation_lookup( const char *name );
|
||||
|
||||
/* Create arguments.
|
||||
*/
|
||||
im_argument_t *im_argument_new( const char *name,
|
||||
im_type_t *type, im_argument_flags flags );
|
||||
void vips__meta_init_types( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#endif /*IM_TYPE_H*/
|
||||
#endif /*VIPS_AREA_H*/
|
||||
|
|
|
@ -97,7 +97,7 @@ extern "C" {
|
|||
#include <vips/buf.h>
|
||||
#include <vips/util.h>
|
||||
#include <vips/object.h>
|
||||
#include <vips/area.h>
|
||||
#include <vips/type.h>
|
||||
#include <vips/pool.h>
|
||||
|
||||
#include <vips/version.h>
|
||||
|
|
|
@ -410,16 +410,16 @@ int im_wrapmany( VipsImage **in, VipsImage *out,
|
|||
#define im_updatehist vips_image_history_args
|
||||
#define im_history_get vips_image_get_history
|
||||
|
||||
#define im_save_string_get vips_save_string_get
|
||||
#define im_save_string_set vips_save_string_set
|
||||
#define im_save_string_setf vips_save_string_setf
|
||||
#define im_save_string_get vips_value_get_save_string
|
||||
#define im_save_string_set vips_value_set_save_string
|
||||
#define im_save_string_setf vips_value_set_save_stringf
|
||||
|
||||
#define im_ref_string_set vips_ref_string_set
|
||||
#define im_ref_string_get vips_ref_string_get
|
||||
#define im_ref_string_get_length vips_ref_string_get_length
|
||||
#define im_ref_string_set vips_value_set_ref_string
|
||||
#define im_ref_string_get( V ) vips_value_get_ref_string( V, NULL )
|
||||
size_t im_ref_string_get_length( const GValue *value );
|
||||
|
||||
#define im_blob_get vips_blob_get
|
||||
#define im_blob_set vips_blob_set
|
||||
#define im_blob_get vips_value_get_blob
|
||||
#define im_blob_set vips_value_set_blob
|
||||
|
||||
#define im_meta_set( A, B, C ) (vips_image_set( A, B, C ), 0)
|
||||
#define im_meta_remove vips_image_remove
|
||||
|
@ -560,6 +560,7 @@ int im_replicate( VipsImage *in, VipsImage *out, int across, int down );
|
|||
|
||||
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );
|
||||
|
||||
|
||||
/* ruby-vips uses this
|
||||
*/
|
||||
#define vips_class_map_concrete_all vips_class_map_all
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
noinst_LTLIBRARIES = libiofuncs.la
|
||||
|
||||
libiofuncs_la_SOURCES = \
|
||||
type.c \
|
||||
enumtypes.c \
|
||||
object.c \
|
||||
pool.c \
|
||||
|
|
|
@ -911,336 +911,61 @@ vips_image_map( VipsImage *image, VipsImageMapFn fn, void *a )
|
|||
return( NULL );
|
||||
}
|
||||
|
||||
/* Save meta fields to the header. We have a new string type for header fields
|
||||
* to save to XML and define transform functions to go from our meta types to
|
||||
* this string type.
|
||||
*/
|
||||
GType
|
||||
vips_save_string_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_save_string",
|
||||
(GBoxedCopyFunc) g_strdup,
|
||||
(GBoxedFreeFunc) g_free );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_save_string_get:
|
||||
* @value: GValue to get from
|
||||
*
|
||||
* Get the C string held internally by the GValue.
|
||||
*
|
||||
* Returns: The C string held by @value. This must not be freed.
|
||||
*/
|
||||
const char *
|
||||
vips_save_string_get( const GValue *value )
|
||||
{
|
||||
return( (char *) g_value_get_boxed( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_save_string_set:
|
||||
* @value: GValue to set
|
||||
* @str: C string to copy into the GValue
|
||||
*
|
||||
* Copies the C string into @value.
|
||||
*/
|
||||
void
|
||||
vips_save_string_set( GValue *value, const char *str )
|
||||
{
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
|
||||
|
||||
g_value_set_boxed( value, str );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_save_string_setf:
|
||||
* @value: GValue to set
|
||||
* @fmt: printf()-style format string
|
||||
* @Varargs: arguments to printf()-formatted @fmt
|
||||
*
|
||||
* Generates a string and copies it into @value.
|
||||
*/
|
||||
void
|
||||
vips_save_string_setf( GValue *value, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
char *str;
|
||||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
|
||||
|
||||
va_start( ap, fmt );
|
||||
str = g_strdup_vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
vips_save_string_set( value, str );
|
||||
g_free( str );
|
||||
}
|
||||
|
||||
/* Transform funcs for builtin types to SAVE_STRING.
|
||||
*/
|
||||
static void
|
||||
transform_int_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
vips_save_string_setf( dest_value, "%d", g_value_get_int( src_value ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_int( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_int( dest_value,
|
||||
atoi( vips_save_string_get( src_value ) ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_double_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
/* Need to be locale independent.
|
||||
*/
|
||||
g_ascii_dtostr( buf, G_ASCII_DTOSTR_BUF_SIZE,
|
||||
g_value_get_double( src_value ) );
|
||||
vips_save_string_set( dest_value, buf );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_double( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_double( dest_value,
|
||||
g_ascii_strtod( vips_save_string_get( src_value ), NULL ) );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static int area_number = 0;
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* An area of mem with a free func. (eg. \0-terminated string, or a struct).
|
||||
* Inital count == 1, so _unref() after attaching somewhere.
|
||||
*/
|
||||
static VipsArea *
|
||||
area_new( VipsCallbackFn free_fn, void *data )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = VIPS_NEW( NULL, VipsArea )) )
|
||||
return( NULL );
|
||||
area->count = 1;
|
||||
area->length = 0;
|
||||
area->data = data;
|
||||
area->free_fn = free_fn;
|
||||
area->type = 0;
|
||||
area->sizeof_type = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
area_number += 1;
|
||||
printf( "area_new: %p count = %d (%d in total)\n",
|
||||
area, area->count, area_number );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
return( area );
|
||||
}
|
||||
|
||||
/* An area of mem with a free func and a length (some sort of binary object,
|
||||
* like an ICC profile).
|
||||
*/
|
||||
static VipsArea *
|
||||
area_new_blob( VipsCallbackFn free_fn, void *blob, size_t blob_length )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = area_new( free_fn, blob )) )
|
||||
return( NULL );
|
||||
area->length = blob_length;
|
||||
|
||||
return( area );
|
||||
}
|
||||
|
||||
/* An area which holds a copy of an array of elements of some GType.
|
||||
*/
|
||||
VipsArea *
|
||||
vips_area_new_array( GType type, size_t sizeof_type, int n )
|
||||
{
|
||||
VipsArea *area;
|
||||
void *array;
|
||||
|
||||
array = g_malloc( n * sizeof_type );
|
||||
if( !(area = area_new( (VipsCallbackFn) g_free, array )) )
|
||||
return( NULL );
|
||||
area->n = n;
|
||||
area->length = n * sizeof_type;
|
||||
area->type = G_TYPE_DOUBLE;
|
||||
area->sizeof_type = sizeof_type;
|
||||
|
||||
return( area );
|
||||
}
|
||||
|
||||
VipsArea *
|
||||
vips_area_copy( VipsArea *area )
|
||||
{
|
||||
g_assert( area->count >= 0 );
|
||||
|
||||
area->count += 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_area_copy: %p count = %d\n", area, area->count );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
return( area );
|
||||
}
|
||||
|
||||
void
|
||||
vips_area_unref( VipsArea *area )
|
||||
{
|
||||
g_assert( area->count > 0 );
|
||||
|
||||
area->count -= 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_area_unref: %p count = %d\n", area, area->count );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( area->count == 0 && area->free_fn ) {
|
||||
(void) area->free_fn( area->data, NULL );
|
||||
area->free_fn = NULL;
|
||||
vips_free( area );
|
||||
|
||||
#ifdef DEBUG
|
||||
area_number -= 1;
|
||||
printf( "vips_area_unref: free .. total = %d\n", area_number );
|
||||
#endif /*DEBUG*/
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform an area to a G_TYPE_STRING.
|
||||
*/
|
||||
static void
|
||||
transform_area_g_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
VipsArea *area;
|
||||
char buf[256];
|
||||
|
||||
area = g_value_get_boxed( src_value );
|
||||
vips_snprintf( buf, 256, "VIPS_TYPE_AREA, count = %d, data = %p",
|
||||
area->count, area->data );
|
||||
g_value_set_string( dest_value, buf );
|
||||
}
|
||||
|
||||
GType
|
||||
vips_area_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_area",
|
||||
(GBoxedCopyFunc) vips_area_copy,
|
||||
(GBoxedFreeFunc) vips_area_unref );
|
||||
g_value_register_transform_func(
|
||||
type,
|
||||
G_TYPE_STRING,
|
||||
transform_area_g_string );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/* Set value to be a ref-counted area of memory with a free function.
|
||||
*/
|
||||
static int
|
||||
value_set_area( VipsCallbackFn free_fn, void *data, GValue *value )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = area_new( free_fn, data )) )
|
||||
return( -1 );
|
||||
|
||||
g_value_init( value, VIPS_TYPE_AREA );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Don't touch count (area is static).
|
||||
*/
|
||||
static void *
|
||||
value_get_area_data( const GValue *value )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
area = g_value_get_boxed( value );
|
||||
|
||||
return( area->data );
|
||||
}
|
||||
|
||||
static size_t
|
||||
value_get_area_length( const GValue *value )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
area = g_value_get_boxed( value );
|
||||
|
||||
return( area->length );
|
||||
}
|
||||
|
||||
static int
|
||||
meta_get_value( VipsImage *image,
|
||||
const char *field, GType type, GValue *value_copy )
|
||||
{
|
||||
if( vips_image_get( image, field, value_copy ) )
|
||||
return( -1 );
|
||||
if( G_VALUE_TYPE( value_copy ) != type ) {
|
||||
vips_error( "VipsImage",
|
||||
_( "field \"%s\" is of type %s, not %s" ),
|
||||
field,
|
||||
g_type_name( G_VALUE_TYPE( value_copy ) ),
|
||||
g_type_name( type ) );
|
||||
g_value_unset( value_copy );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* vips_image_set_area:
|
||||
* @image: image to attach the metadata to
|
||||
* @field: metadata name
|
||||
* @free_fn: free function for @data
|
||||
* @data: pointer to area of memory
|
||||
*
|
||||
* Attaches @data as a metadata item on @image under the name @field. When VIPS
|
||||
* no longer needs the metadata, it will be freed with @free_fn.
|
||||
* Attaches @data as a metadata item on @image under the name @field. When
|
||||
* VIPS no longer needs the metadata, it will be freed with @free_fn.
|
||||
*
|
||||
* See also: vips_image_get_double(), vips_image_set()
|
||||
*/
|
||||
void
|
||||
vips_image_set_area( VipsImage *image, const char *field,
|
||||
VipsCallbackFn free_fn, void *data )
|
||||
vips_image_set_area( VipsImage *image, const char *field,
|
||||
VipsCallbackFn free_fn, void *data )
|
||||
{
|
||||
GValue value = { 0 };
|
||||
|
||||
value_set_area( free_fn, data, &value );
|
||||
vips_value_set_area( &value, free_fn, data );
|
||||
vips_image_set( image, field, &value );
|
||||
g_value_unset( &value );
|
||||
}
|
||||
|
||||
/**
|
||||
static int
|
||||
meta_get_value( VipsImage *image,
|
||||
const char *field, GType type, GValue *value_copy )
|
||||
{
|
||||
if( vips_image_get( image, field, value_copy ) )
|
||||
return( -1 );
|
||||
if( G_VALUE_TYPE( value_copy ) != type ) {
|
||||
vips_error( "VipsImage",
|
||||
_( "field \"%s\" is of type %s, not %s" ),
|
||||
field,
|
||||
g_type_name( G_VALUE_TYPE( value_copy ) ),
|
||||
g_type_name( type ) );
|
||||
g_value_unset( value_copy );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_get_area:
|
||||
* @image: image to get the metadata from
|
||||
* @field: metadata name
|
||||
* @data: return metadata value
|
||||
*
|
||||
* Gets @data from @image under the name @field. A convenience
|
||||
* function over vips_image_get(). Use vips_image_get_typeof() to test for the
|
||||
* existance
|
||||
* of a piece of metadata.
|
||||
* function over vips_image_get(). Use vips_image_get_typeof() to test for
|
||||
* the existance of a piece of metadata.
|
||||
*
|
||||
* See also: vips_image_set_area(), vips_image_get(), vips_image_get_typeof()
|
||||
* See also: vips_image_set_area(), vips_image_get(),
|
||||
* vips_image_get_typeof()
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
|
@ -1250,7 +975,7 @@ vips_image_get_area( VipsImage *image, const char *field, void **data )
|
|||
GValue value_copy = { 0 };
|
||||
|
||||
if( !meta_get_value( image, field, VIPS_TYPE_AREA, &value_copy ) ) {
|
||||
*data = value_get_area_data( &value_copy );
|
||||
*data = vips_value_get_area( &value_copy, NULL );
|
||||
g_value_unset( &value_copy );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -1258,537 +983,6 @@ vips_image_get_area( VipsImage *image, const char *field, void **data )
|
|||
return( -1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_ref_string_get:
|
||||
* @value: GValue to get from
|
||||
*
|
||||
* Get the C string held internally by the GValue.
|
||||
*
|
||||
* Returns: The C string held by @value. This must not be freed.
|
||||
*/
|
||||
const char *
|
||||
vips_ref_string_get( const GValue *value )
|
||||
{
|
||||
return( value_get_area_data( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_ref_string_get_length:
|
||||
* @value: GValue to get from
|
||||
*
|
||||
* Gets the cached string length held internally by the refstring.
|
||||
*
|
||||
* Returns: The length of the string.
|
||||
*/
|
||||
size_t
|
||||
vips_ref_string_get_length( const GValue *value )
|
||||
{
|
||||
return( value_get_area_length( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_ref_string_set:
|
||||
* @value: GValue to set
|
||||
* @str: C string to copy into the GValue
|
||||
*
|
||||
* Copies the C string @str into @value.
|
||||
*
|
||||
* vips_ref_string are immutable C strings that are copied between images by
|
||||
* copying reference-counted pointers, making the much more efficient than
|
||||
* regular GValue strings.
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
vips_ref_string_set( GValue *value, const char *str )
|
||||
{
|
||||
VipsArea *area;
|
||||
char *str_copy;
|
||||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
|
||||
|
||||
str_copy = g_strdup( str );
|
||||
if( !(area = area_new( (VipsCallbackFn) vips_free, str_copy )) ) {
|
||||
g_free( str_copy );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Handy place to cache this.
|
||||
*/
|
||||
area->length = strlen( str );
|
||||
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Transform a refstring to a G_TYPE_STRING and back.
|
||||
*/
|
||||
static void
|
||||
transform_ref_string_g_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_string( dest_value, vips_ref_string_get( src_value ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_g_string_ref_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
vips_ref_string_set( dest_value, g_value_get_string( src_value ) );
|
||||
}
|
||||
|
||||
/* To a save string.
|
||||
*/
|
||||
static void
|
||||
transform_ref_string_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
vips_save_string_setf( dest_value,
|
||||
"%s", vips_ref_string_get( src_value ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_ref_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
vips_ref_string_set( dest_value, vips_save_string_get( src_value ) );
|
||||
}
|
||||
|
||||
GType
|
||||
vips_ref_string_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_ref_string",
|
||||
(GBoxedCopyFunc) vips_area_copy,
|
||||
(GBoxedFreeFunc) vips_area_unref );
|
||||
g_value_register_transform_func( type, G_TYPE_STRING,
|
||||
transform_ref_string_g_string );
|
||||
g_value_register_transform_func( G_TYPE_STRING, type,
|
||||
transform_g_string_ref_string );
|
||||
g_value_register_transform_func( type, VIPS_TYPE_SAVE_STRING,
|
||||
transform_ref_string_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, type,
|
||||
transform_save_string_ref_string );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_blob_get:
|
||||
* @value: GValue to get from
|
||||
* @length: return the blob length here, optionally
|
||||
*
|
||||
* Get the address of the blob (binary large object) being held in @value and
|
||||
* optionally return its length in @length.
|
||||
*
|
||||
* See also: vips_blob_set().
|
||||
*
|
||||
* Returns: The blob address.
|
||||
*/
|
||||
void *
|
||||
vips_blob_get( const GValue *value, size_t *length )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
/* Can't check value type, because we may get called from
|
||||
* vips_blob_get_type().
|
||||
*/
|
||||
|
||||
area = g_value_get_boxed( value );
|
||||
if( length )
|
||||
*length = area->length;
|
||||
|
||||
return( area->data );
|
||||
}
|
||||
|
||||
/* Transform a blob to a G_TYPE_STRING.
|
||||
*/
|
||||
static void
|
||||
transform_blob_g_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
void *blob;
|
||||
size_t blob_length;
|
||||
char buf[256];
|
||||
|
||||
blob = vips_blob_get( src_value, &blob_length );
|
||||
vips_snprintf( buf, 256, "VIPS_TYPE_BLOB, data = %p, length = %zd",
|
||||
blob, blob_length );
|
||||
g_value_set_string( dest_value, buf );
|
||||
}
|
||||
|
||||
/* Transform a blob to a save string and back.
|
||||
*/
|
||||
static void
|
||||
transform_blob_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
void *blob;
|
||||
size_t blob_length;
|
||||
char *b64;
|
||||
|
||||
blob = vips_blob_get( src_value, &blob_length );
|
||||
if( (b64 = vips__b64_encode( blob, blob_length )) ) {
|
||||
vips_save_string_set( dest_value, b64 );
|
||||
vips_free( b64 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_blob( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
const char *b64;
|
||||
void *blob;
|
||||
size_t blob_length;
|
||||
|
||||
b64 = vips_save_string_get( src_value );
|
||||
if( (blob = vips__b64_decode( b64, &blob_length )) )
|
||||
vips_blob_set( dest_value,
|
||||
(VipsCallbackFn) vips_free, blob, blob_length );
|
||||
}
|
||||
|
||||
GType
|
||||
vips_blob_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_blob",
|
||||
(GBoxedCopyFunc) vips_area_copy,
|
||||
(GBoxedFreeFunc) vips_area_unref );
|
||||
g_value_register_transform_func( type, G_TYPE_STRING,
|
||||
transform_blob_g_string );
|
||||
g_value_register_transform_func( type, VIPS_TYPE_SAVE_STRING,
|
||||
transform_blob_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, type,
|
||||
transform_save_string_blob );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_blob_set:
|
||||
* @value: GValue to set
|
||||
* @free_fn: free function for @data
|
||||
* @data: pointer to area of memory
|
||||
* @length: length of memory area
|
||||
*
|
||||
* Sets @value to hold a pointer to @blob. When @value is freed, @blob will be
|
||||
* freed with @free_fn. @value also holds a note of the length of the memory
|
||||
* area.
|
||||
*
|
||||
* blobs are things like ICC profiles or EXIF data. They are relocatable, and
|
||||
* are saved to VIPS files for you coded as base64 inside the XML. They are
|
||||
* copied by copying reference-counted pointers.
|
||||
*
|
||||
* See also: vips_blob_get()
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
vips_blob_set( GValue *value,
|
||||
VipsCallbackFn free_fn, void *data, size_t length )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_BLOB );
|
||||
|
||||
if( !(area = area_new_blob( free_fn, data, length )) )
|
||||
return( -1 );
|
||||
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Set value to be an array of things. Don't initialise the contents: get the
|
||||
* pointer and write instead.
|
||||
*/
|
||||
static int
|
||||
vips_array_set( GValue *value, GType type, size_t sizeof_type, int n )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = vips_area_new_array( type, sizeof_type, n )) )
|
||||
return( -1 );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void *
|
||||
vips_array_get( const GValue *value,
|
||||
int *n, GType *type, size_t *sizeof_type )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
/* Can't check value type, because we may get called from
|
||||
* vips_*_get_type().
|
||||
*/
|
||||
|
||||
area = g_value_get_boxed( value );
|
||||
if( n )
|
||||
*n = area->n;
|
||||
if( type )
|
||||
*type = area->type;
|
||||
if( sizeof_type )
|
||||
*sizeof_type = area->sizeof_type;
|
||||
|
||||
return( area->data );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_array_g_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
char *array;
|
||||
int n;
|
||||
GType type;
|
||||
size_t sizeof_type;
|
||||
char txt[1024];
|
||||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||
int i;
|
||||
|
||||
array = (char *) vips_array_get( src_value,
|
||||
&n, &type, &sizeof_type );
|
||||
|
||||
for( i = 0; i < n; i++ ) {
|
||||
GValue value = { 0, };
|
||||
char *str;
|
||||
|
||||
if( i > 0 )
|
||||
vips_buf_appends( &buf, ", " );
|
||||
|
||||
g_value_init( &value, type );
|
||||
g_value_set_instance( &value, array );
|
||||
|
||||
str = g_strdup_value_contents( &value );
|
||||
vips_buf_appends( &buf, str );
|
||||
g_free( str );
|
||||
|
||||
g_value_unset( &value );
|
||||
|
||||
array += sizeof_type;
|
||||
}
|
||||
|
||||
g_value_set_string( dest_value, vips_buf_all( &buf ) );
|
||||
}
|
||||
|
||||
/* It'd be great to be able to write a generic string->array function, but
|
||||
* it doesn't seem possible.
|
||||
*/
|
||||
static void
|
||||
transform_g_string_array_double( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
const char *str = g_value_get_string( src_value );
|
||||
|
||||
int n;
|
||||
const char *p;
|
||||
int i;
|
||||
double *array;
|
||||
|
||||
/* Walk the string to get the number of elements. Empty string is zero
|
||||
* elements.
|
||||
*/
|
||||
for( n = 0, p = str; p && *p; n += 1 ) {
|
||||
p = strchr( p, ',' );
|
||||
if( p )
|
||||
p += 1;
|
||||
}
|
||||
|
||||
vips_array_set( dest_value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array = (double *) vips_array_get( dest_value, NULL, NULL, NULL );
|
||||
|
||||
p = str;
|
||||
for( i = 0; i < n; i++ ) {
|
||||
array[i] = atof( p );
|
||||
p = strchr( p, ',' );
|
||||
if( p )
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
vips_array_double_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_array_double",
|
||||
(GBoxedCopyFunc) vips_area_copy,
|
||||
(GBoxedFreeFunc) vips_area_unref );
|
||||
g_value_register_transform_func( type, G_TYPE_STRING,
|
||||
transform_array_g_string );
|
||||
g_value_register_transform_func( G_TYPE_STRING, type,
|
||||
transform_g_string_array_double );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_array_double_get:
|
||||
* @value: #GValue to get from
|
||||
* @n: return the number of elements here, optionally
|
||||
*
|
||||
* Return the start of the array of doubles held by @value.
|
||||
* optionally return the number of elements in @n.
|
||||
*
|
||||
* See also: vips_array_double_set().
|
||||
*
|
||||
* Returns: The array address.
|
||||
*/
|
||||
double *
|
||||
vips_array_double_get( const GValue *value, int *n )
|
||||
{
|
||||
return( vips_array_get( value, n, NULL, NULL ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_array_double_set:
|
||||
* @value: #GValue to get from
|
||||
* @array: array of doubles
|
||||
* @n: the number of elements
|
||||
*
|
||||
* Set @value to hold a copy of @array. Pass in the array length in @n.
|
||||
*
|
||||
* See also: vips_array_double_get().
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
vips_array_double_set( GValue *value, const double *array, int n )
|
||||
{
|
||||
double *array_copy;
|
||||
|
||||
g_value_init( value, VIPS_TYPE_ARRAY_DOUBLE );
|
||||
vips_array_set( value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array_copy = vips_array_double_get( value, NULL );
|
||||
memcpy( array_copy, array, n * sizeof( double ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_array_object_free( VipsArea *area )
|
||||
{
|
||||
GObject **array = (GObject **) area->data;
|
||||
|
||||
int i;
|
||||
|
||||
for( i = 0; i < area->n; i++ )
|
||||
VIPS_FREEF( g_object_unref, array[i] );
|
||||
|
||||
g_free( area );
|
||||
}
|
||||
|
||||
/* An area which holds an array of GObjects.
|
||||
*/
|
||||
VipsArea *
|
||||
vips_array_object_new( int n )
|
||||
{
|
||||
GObject **array;
|
||||
VipsArea *area;
|
||||
|
||||
array = g_new0( GObject *, n );
|
||||
if( !(area = area_new(
|
||||
(VipsCallbackFn) vips_array_object_free, array )) )
|
||||
return( NULL );
|
||||
area->n = n;
|
||||
area->length = n * sizeof( GObject * );
|
||||
area->type = G_TYPE_OBJECT;
|
||||
area->sizeof_type = sizeof( GObject * );
|
||||
|
||||
return( area );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_array_object_get:
|
||||
* @value: #GValue to get from
|
||||
* @n: return the number of elements here, optionally
|
||||
*
|
||||
* Return the start of the array of #GObject held by @value.
|
||||
* optionally return the number of elements in @n.
|
||||
*
|
||||
* See also: vips_array_object_set().
|
||||
*
|
||||
* Returns: The array address.
|
||||
*/
|
||||
GObject **
|
||||
vips_array_object_get( const GValue *value, int *n )
|
||||
{
|
||||
return( vips_array_get( value, n, NULL, NULL ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_array_object_set:
|
||||
* @value: #GValue to set
|
||||
* @n: the number of elements
|
||||
*
|
||||
* Set @value to hold an array of GObject. Pass in the array length in @n.
|
||||
*
|
||||
* See also: vips_array_object_get().
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
vips_array_object_set( GValue *value, int n )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = vips_array_object_new( n )) )
|
||||
return( -1 );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
char *str;
|
||||
int n;
|
||||
char *p, *q;
|
||||
int i;
|
||||
GObject **array;
|
||||
|
||||
/* We need a copy of the string, since we insert \0 during
|
||||
* scan.
|
||||
*/
|
||||
str = g_strdup_value_contents( src_value );
|
||||
for( n = 0; (q = vips_break_token( p, " " )); n++, p = q )
|
||||
;
|
||||
g_free( str );
|
||||
|
||||
vips_array_object_set( dest_value, n );
|
||||
array = vips_array_object_get( dest_value, NULL );
|
||||
|
||||
str = g_strdup_value_contents( src_value );
|
||||
for( i = 0; (q = vips_break_token( p, " " )); i++, p = q )
|
||||
/* Sadly there's no error return possible here.
|
||||
*/
|
||||
array[i] = G_OBJECT( vips_image_new_from_file( p ) );
|
||||
g_free( str );
|
||||
}
|
||||
|
||||
GType
|
||||
vips_array_image_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_array_image",
|
||||
(GBoxedCopyFunc) vips_area_copy,
|
||||
(GBoxedFreeFunc) vips_area_unref );
|
||||
g_value_register_transform_func( G_TYPE_STRING, type,
|
||||
transform_g_string_array_image );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_set_blob:
|
||||
* @image: image to attach the metadata to
|
||||
|
@ -1810,7 +1004,7 @@ vips_image_set_blob( VipsImage *image, const char *field,
|
|||
GValue value = { 0 };
|
||||
|
||||
g_value_init( &value, VIPS_TYPE_BLOB );
|
||||
vips_blob_set( &value, free_fn, data, length );
|
||||
vips_value_set_blob( &value, free_fn, data, length );
|
||||
vips_image_set( image, field, &value );
|
||||
g_value_unset( &value );
|
||||
}
|
||||
|
@ -1839,7 +1033,7 @@ vips_image_get_blob( VipsImage *image, const char *field,
|
|||
GValue value_copy = { 0 };
|
||||
|
||||
if( !meta_get_value( image, field, VIPS_TYPE_BLOB, &value_copy ) ) {
|
||||
*data = vips_blob_get( &value_copy, length );
|
||||
*data = vips_value_get_blob( &value_copy, length );
|
||||
g_value_unset( &value_copy );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -2038,7 +1232,7 @@ vips_image_set_string( VipsImage *image, const char *field, const char *str )
|
|||
GValue value = { 0 };
|
||||
|
||||
g_value_init( &value, VIPS_TYPE_REF_STRING );
|
||||
vips_ref_string_set( &value, str );
|
||||
vips_value_set_ref_string( &value, str );
|
||||
vips_image_set( image, field, &value );
|
||||
g_value_unset( &value );
|
||||
}
|
||||
|
@ -2076,7 +1270,7 @@ vips_image_get_as_string( VipsImage *image, const char *field, char **out )
|
|||
g_value_init( &save_value, VIPS_TYPE_SAVE_STRING );
|
||||
if( !g_value_transform( &value, &save_value ) )
|
||||
return( -1 );
|
||||
*out = g_strdup( vips_save_string_get( &save_value ) );
|
||||
*out = g_strdup( vips_value_get_save_string( &save_value ) );
|
||||
g_value_unset( &save_value );
|
||||
}
|
||||
else
|
||||
|
@ -2209,27 +1403,3 @@ vips_image_get_history( VipsImage *image )
|
|||
|
||||
return( image->Hist ? image->Hist : "" );
|
||||
}
|
||||
|
||||
/* Make the types we need for basic functioning. Called from init_world().
|
||||
*/
|
||||
void
|
||||
vips__meta_init_types( void )
|
||||
{
|
||||
(void) vips_save_string_get_type();
|
||||
(void) vips_area_get_type();
|
||||
(void) vips_ref_string_get_type();
|
||||
(void) vips_blob_get_type();
|
||||
|
||||
/* Register transform functions to go from built-in saveable types to
|
||||
* a save string. Transform functions for our own types are set
|
||||
* during type creation.
|
||||
*/
|
||||
g_value_register_transform_func( G_TYPE_INT, VIPS_TYPE_SAVE_STRING,
|
||||
transform_int_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_INT,
|
||||
transform_save_string_int );
|
||||
g_value_register_transform_func( G_TYPE_DOUBLE, VIPS_TYPE_SAVE_STRING,
|
||||
transform_double_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_DOUBLE,
|
||||
transform_save_string_double );
|
||||
}
|
||||
|
|
|
@ -95,11 +95,13 @@ vips_area_unref( VipsArea *area )
|
|||
printf( "vips_area_unref: %p count = %d\n", area, area->count );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( area->count == 0 )
|
||||
if( area->free_fn )
|
||||
VIPS_FREEF( area->free_fn, area->data );
|
||||
if( area->count == 0 ) {
|
||||
if( area->free_fn && area->data ) {
|
||||
area->free_fn( area->data, NULL );
|
||||
area->data = NULL;
|
||||
area->free_fn = NULL;
|
||||
}
|
||||
|
||||
area->free_fn = NULL;
|
||||
g_free( area );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -128,7 +130,7 @@ vips_area_new( VipsCallbackFn free_fn, void *data )
|
|||
|
||||
#ifdef DEBUG
|
||||
vips_area_number += 1;
|
||||
printf( "area_new: %p count = %d (%d in total)\n",
|
||||
printf( "vips_area_new: %p count = %d (%d in total)\n",
|
||||
area, area->count, vips_area_number );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
|
@ -143,7 +145,7 @@ vips_area_new_blob( VipsCallbackFn free_fn, void *blob, size_t blob_length )
|
|||
{
|
||||
VipsArea *area;
|
||||
|
||||
area = area_new( free_fn, blob );
|
||||
area = vips_area_new( free_fn, blob );
|
||||
area->length = blob_length;
|
||||
|
||||
return( area );
|
||||
|
@ -159,7 +161,7 @@ vips_area_new_array( GType type, size_t sizeof_type, int n )
|
|||
void *array;
|
||||
|
||||
array = g_malloc( n * sizeof_type );
|
||||
area = area_new( (VipsCallbackFn) g_free, array );
|
||||
area = vips_area_new( (VipsCallbackFn) g_free, array );
|
||||
area->n = n;
|
||||
area->length = n * sizeof_type;
|
||||
area->type = type;
|
||||
|
@ -190,7 +192,8 @@ vips_area_new_array_object( int n )
|
|||
VipsArea *area;
|
||||
|
||||
array = g_new0( GObject *, n );
|
||||
area = area_new( (VipsCallbackFn) vips_array_object_free, array );
|
||||
area = vips_area_new( (VipsCallbackFn) vips_area_free_array_object,
|
||||
array );
|
||||
area->n = n;
|
||||
area->length = n * sizeof( GObject * );
|
||||
area->type = G_TYPE_OBJECT;
|
||||
|
@ -206,7 +209,7 @@ vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data )
|
|||
{
|
||||
VipsArea *area;
|
||||
|
||||
area = area_new( free_fn, data );
|
||||
area = vips_area_new( free_fn, data );
|
||||
g_value_init( value, VIPS_TYPE_AREA );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
@ -259,7 +262,7 @@ vips_area_get_type( void )
|
|||
}
|
||||
|
||||
/**
|
||||
* vips_value_get_ref_string:
|
||||
* vips_value_get_save_string:
|
||||
* @value: GValue to get from
|
||||
*
|
||||
* Get the C string held internally by the GValue.
|
||||
|
@ -267,6 +270,113 @@ vips_area_get_type( void )
|
|||
* Returns: The C string held by @value. This must not be freed.
|
||||
*/
|
||||
const char *
|
||||
vips_value_get_save_string( const GValue *value )
|
||||
{
|
||||
return( (char *) g_value_get_boxed( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_value_set_save_string:
|
||||
* @value: GValue to set
|
||||
* @str: C string to copy into the GValue
|
||||
*
|
||||
* Copies the C string into @value.
|
||||
*/
|
||||
void
|
||||
vips_value_set_save_string( GValue *value, const char *str )
|
||||
{
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
|
||||
|
||||
g_value_set_boxed( value, str );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_value_set_save_stringf:
|
||||
* @value: GValue to set
|
||||
* @fmt: printf()-style format string
|
||||
* @Varargs: arguments to printf()-formatted @fmt
|
||||
*
|
||||
* Generates a string and copies it into @value.
|
||||
*/
|
||||
void
|
||||
vips_value_set_save_stringf( GValue *value, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
char *str;
|
||||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
|
||||
|
||||
va_start( ap, fmt );
|
||||
str = g_strdup_vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
vips_value_set_save_string( value, str );
|
||||
g_free( str );
|
||||
}
|
||||
|
||||
/* Transform funcs for builtin types to SAVE_STRING.
|
||||
*/
|
||||
static void
|
||||
transform_int_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
vips_value_set_save_stringf( dest_value,
|
||||
"%d", g_value_get_int( src_value ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_int( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_int( dest_value,
|
||||
atoi( vips_value_get_save_string( src_value ) ) );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_double_save_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
/* Need to be locale independent.
|
||||
*/
|
||||
g_ascii_dtostr( buf, G_ASCII_DTOSTR_BUF_SIZE,
|
||||
g_value_get_double( src_value ) );
|
||||
vips_value_set_save_string( dest_value, buf );
|
||||
}
|
||||
|
||||
static void
|
||||
transform_save_string_double( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_double( dest_value,
|
||||
g_ascii_strtod( vips_value_get_save_string( src_value ),
|
||||
NULL ) );
|
||||
}
|
||||
|
||||
/* Save meta fields to the header. We have a new string type for header fields
|
||||
* to save to XML and define transform functions to go from our meta types to
|
||||
* this string type.
|
||||
*/
|
||||
GType
|
||||
vips_save_string_get_type( void )
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( !type ) {
|
||||
type = g_boxed_type_register_static( "vips_save_string",
|
||||
(GBoxedCopyFunc) g_strdup,
|
||||
(GBoxedFreeFunc) g_free );
|
||||
}
|
||||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_value_get_ref_string:
|
||||
* @value: #GValue to get from
|
||||
* @length: return length here, optionally
|
||||
*
|
||||
* Get the C string held internally by the GValue.
|
||||
*
|
||||
* Returns: The C string held by @value. This must not be freed.
|
||||
*/
|
||||
const char *
|
||||
vips_value_get_ref_string( const GValue *value, size_t *length )
|
||||
{
|
||||
return( vips_value_get_area( value, length ) );
|
||||
|
@ -294,7 +404,7 @@ vips_value_set_ref_string( GValue *value, const char *str )
|
|||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
|
||||
|
||||
str_copy = g_strdup( str );
|
||||
area = area_new( (VipsCallbackFn) vips_free, str_copy );
|
||||
area = vips_area_new( (VipsCallbackFn) vips_free, str_copy );
|
||||
|
||||
/* Handy place to cache this.
|
||||
*/
|
||||
|
@ -312,7 +422,7 @@ static void
|
|||
transform_ref_string_g_string( const GValue *src_value, GValue *dest_value )
|
||||
{
|
||||
g_value_set_string( dest_value,
|
||||
vips_value_get_ref_string( src_value ) );
|
||||
vips_value_get_ref_string( src_value, NULL ) );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -361,13 +471,13 @@ vips_ref_string_get_type( void )
|
|||
}
|
||||
|
||||
/**
|
||||
* vips_blob_set:
|
||||
* vips_value_set_blob:
|
||||
* @value: GValue to set
|
||||
* @free_fn: free function for @data
|
||||
* @data: pointer to area of memory
|
||||
* @length: length of memory area
|
||||
*
|
||||
* Sets @value to hold a pointer to @blob. When @value is freed, @blob will be
|
||||
* Sets @value to hold a @data. When @value is freed, @data will be
|
||||
* freed with @free_fn. @value also holds a note of the length of the memory
|
||||
* area.
|
||||
*
|
||||
|
@ -375,7 +485,7 @@ vips_ref_string_get_type( void )
|
|||
* are saved to VIPS files for you coded as base64 inside the XML. They are
|
||||
* copied by copying reference-counted pointers.
|
||||
*
|
||||
* See also: vips_value_get_area()
|
||||
* See also: vips_value_get_blob()
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
|
@ -387,13 +497,34 @@ vips_value_set_blob( GValue *value,
|
|||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_BLOB );
|
||||
|
||||
area = area_new_blob( free_fn, data, length );
|
||||
area = vips_area_new_blob( free_fn, data, length );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_value_get_blob:
|
||||
* @value: GValue to set
|
||||
* @length: optionally return length of memory area
|
||||
*
|
||||
* Returns the data pointer from a blob. Optionally returns the length too.
|
||||
*
|
||||
* blobs are things like ICC profiles or EXIF data. They are relocatable, and
|
||||
* are saved to VIPS files for you coded as base64 inside the XML. They are
|
||||
* copied by copying reference-counted pointers.
|
||||
*
|
||||
* See also: vips_value_set_blob()
|
||||
*
|
||||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
void *
|
||||
vips_value_get_blob( const GValue *value, size_t *length )
|
||||
{
|
||||
return( vips_value_get_area( value, length ) );
|
||||
}
|
||||
|
||||
/* Transform a blob to a G_TYPE_STRING.
|
||||
*/
|
||||
static void
|
||||
|
@ -403,11 +534,11 @@ transform_blob_g_string( const GValue *src_value, GValue *dest_value )
|
|||
size_t blob_length;
|
||||
char buf[256];
|
||||
|
||||
blob = vips_blob_get( src_value, &blob_length );
|
||||
blob = vips_value_get_blob( src_value, &blob_length );
|
||||
vips_snprintf( buf, 256, "VIPS_TYPE_BLOB, data = %p, length = %zd",
|
||||
blob, blob_length );
|
||||
g_value_set_string( dest_value, buf );
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform a blob to a save string and back.
|
||||
*/
|
||||
|
@ -418,9 +549,9 @@ transform_blob_save_string( const GValue *src_value, GValue *dest_value )
|
|||
size_t blob_length;
|
||||
char *b64;
|
||||
|
||||
blob = vips_value_get_area( src_value, &blob_length );
|
||||
blob = vips_value_get_blob( src_value, &blob_length );
|
||||
if( (b64 = vips__b64_encode( blob, blob_length )) ) {
|
||||
vips_save_string_set( dest_value, b64 );
|
||||
vips_value_set_save_string( dest_value, b64 );
|
||||
vips_free( b64 );
|
||||
}
|
||||
}
|
||||
|
@ -432,9 +563,9 @@ transform_save_string_blob( const GValue *src_value, GValue *dest_value )
|
|||
void *blob;
|
||||
size_t blob_length;
|
||||
|
||||
b64 = vips_save_string_get( src_value );
|
||||
b64 = vips_value_get_save_string( src_value );
|
||||
if( (blob = vips__b64_decode( b64, &blob_length )) )
|
||||
vips_blob_set( dest_value,
|
||||
vips_value_set_blob( dest_value,
|
||||
(VipsCallbackFn) vips_free, blob, blob_length );
|
||||
}
|
||||
|
||||
|
@ -509,7 +640,7 @@ vips_value_get_array( const GValue *value,
|
|||
double *
|
||||
vips_value_get_array_double( const GValue *value, int *n )
|
||||
{
|
||||
return( vips_array_get( value, n, NULL, NULL ) );
|
||||
return( vips_value_get_array( value, n, NULL, NULL ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -530,8 +661,8 @@ vips_value_set_array_double( GValue *value, const double *array, int n )
|
|||
double *array_copy;
|
||||
|
||||
g_value_init( value, VIPS_TYPE_ARRAY_DOUBLE );
|
||||
vips_array_set( value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array_copy = vips_array_double_get( value, NULL );
|
||||
vips_value_set_array( value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array_copy = vips_value_get_array_double( value, NULL );
|
||||
memcpy( array_copy, array, n * sizeof( double ) );
|
||||
|
||||
return( 0 );
|
||||
|
@ -548,7 +679,7 @@ transform_array_g_string( const GValue *src_value, GValue *dest_value )
|
|||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||
int i;
|
||||
|
||||
array = (char *) vips_array_get( src_value,
|
||||
array = (char *) vips_value_get_array( src_value,
|
||||
&n, &type, &sizeof_type );
|
||||
|
||||
for( i = 0; i < n; i++ ) {
|
||||
|
@ -595,8 +726,8 @@ transform_g_string_array_double( const GValue *src_value, GValue *dest_value )
|
|||
p += 1;
|
||||
}
|
||||
|
||||
vips_array_set( dest_value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array = (double *) vips_array_get( dest_value, NULL, NULL, NULL );
|
||||
vips_value_set_array( dest_value, G_TYPE_DOUBLE, sizeof( double ), n );
|
||||
array = (double *) vips_value_get_array( dest_value, NULL, NULL, NULL );
|
||||
|
||||
p = str;
|
||||
for( i = 0; i < n; i++ ) {
|
||||
|
@ -638,9 +769,9 @@ vips_array_double_get_type( void )
|
|||
* Returns: The array address.
|
||||
*/
|
||||
GObject **
|
||||
vips_array_object_get( const GValue *value, int *n )
|
||||
vips_value_get_array_object( const GValue *value, int *n )
|
||||
{
|
||||
return( vips_array_get( value, n, NULL, NULL ) );
|
||||
return( vips_value_get_array( value, n, NULL, NULL ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -655,11 +786,11 @@ vips_array_object_get( const GValue *value, int *n )
|
|||
* Returns: 0 on success, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
vips_array_object_set( GValue *value, int n )
|
||||
vips_value_set_array_object( GValue *value, int n )
|
||||
{
|
||||
VipsArea *area;
|
||||
|
||||
if( !(area = vips_array_object_new( n )) )
|
||||
if( !(area = vips_area_new_array_object( n )) )
|
||||
return( -1 );
|
||||
g_value_set_boxed( value, area );
|
||||
vips_area_unref( area );
|
||||
|
@ -684,8 +815,8 @@ transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
|
|||
;
|
||||
g_free( str );
|
||||
|
||||
vips_array_object_set( dest_value, n );
|
||||
array = vips_array_object_get( dest_value, NULL );
|
||||
vips_value_set_array_object( dest_value, n );
|
||||
array = vips_value_get_array_object( dest_value, NULL );
|
||||
|
||||
str = g_strdup_value_contents( src_value );
|
||||
for( i = 0; (q = vips_break_token( p, " " )); i++, p = q )
|
||||
|
@ -710,3 +841,27 @@ vips_array_image_get_type( void )
|
|||
|
||||
return( type );
|
||||
}
|
||||
|
||||
/* Make the types we need for basic functioning. Called from init_world().
|
||||
*/
|
||||
void
|
||||
vips__meta_init_types( void )
|
||||
{
|
||||
(void) vips_save_string_get_type();
|
||||
(void) vips_area_get_type();
|
||||
(void) vips_ref_string_get_type();
|
||||
(void) vips_blob_get_type();
|
||||
|
||||
/* Register transform functions to go from built-in saveable types to
|
||||
* a save string. Transform functions for our own types are set
|
||||
* during type creation.
|
||||
*/
|
||||
g_value_register_transform_func( G_TYPE_INT, VIPS_TYPE_SAVE_STRING,
|
||||
transform_int_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_INT,
|
||||
transform_save_string_int );
|
||||
g_value_register_transform_func( G_TYPE_DOUBLE, VIPS_TYPE_SAVE_STRING,
|
||||
transform_double_save_string );
|
||||
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_DOUBLE,
|
||||
transform_save_string_double );
|
||||
}
|
|
@ -926,7 +926,7 @@ vips__gvalue_ref_string_new( const char *text )
|
|||
GValue *value;
|
||||
|
||||
value = vips__gvalue_new( VIPS_TYPE_REF_STRING );
|
||||
vips_ref_string_set( value, text );
|
||||
vips_value_set_ref_string( value, text );
|
||||
|
||||
return( value );
|
||||
}
|
||||
|
@ -985,8 +985,8 @@ vips__gslist_gvalue_merge( GSList *a, const GSList *b )
|
|||
/* Just do a pointer compare ... good enough 99.9% of
|
||||
* the time.
|
||||
*/
|
||||
if( vips_ref_string_get( value ) ==
|
||||
vips_ref_string_get( value2 ) )
|
||||
if( vips_value_get_ref_string( value, NULL ) ==
|
||||
vips_value_get_ref_string( value2, NULL ) )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1016,12 +1016,14 @@ vips__gslist_gvalue_get( const GSList *list )
|
|||
length = 0;
|
||||
for( p = list; p; p = p->next ) {
|
||||
GValue *value = (GValue *) p->data;
|
||||
size_t l2;
|
||||
|
||||
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
|
||||
|
||||
/* +1 for the newline we will add for each item.
|
||||
*/
|
||||
length += vips_ref_string_get_length( value ) + 1;
|
||||
(void) vips_value_get_ref_string( value, &l2 );
|
||||
length += l2 + 1;
|
||||
}
|
||||
|
||||
if( length == 0 )
|
||||
|
@ -1039,9 +1041,10 @@ vips__gslist_gvalue_get( const GSList *list )
|
|||
q = all;
|
||||
for( p = list; p; p = p->next ) {
|
||||
GValue *value = (GValue *) p->data;
|
||||
size_t l2;
|
||||
|
||||
strcpy( q, vips_ref_string_get( value ) );
|
||||
q += vips_ref_string_get_length( value );
|
||||
strcpy( q, vips_value_get_ref_string( value, &l2 ) );
|
||||
q += l2;
|
||||
strcpy( q, "\n" );
|
||||
q += 1;
|
||||
}
|
||||
|
|
|
@ -522,7 +522,7 @@ rebuild_header_meta( VipsImage *im, xmlNode *i )
|
|||
|
||||
content = (char *) xmlNodeGetContent( i );
|
||||
g_value_init( &save_value, VIPS_TYPE_SAVE_STRING );
|
||||
vips_save_string_set( &save_value, content );
|
||||
vips_value_set_save_string( &save_value, content );
|
||||
xmlFree( content );
|
||||
|
||||
g_value_init( &value, gtype );
|
||||
|
@ -682,7 +682,7 @@ save_fields_meta( VipsMeta *meta, xmlNode *node )
|
|||
return( node );
|
||||
}
|
||||
if( set_field( node, meta->field, g_type_name( type ),
|
||||
vips_save_string_get( &save_value ) ) ) {
|
||||
vips_value_get_save_string( &save_value ) ) ) {
|
||||
g_value_unset( &save_value );
|
||||
return( node );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue