3
* Unlike GArray, this has fixed length, tracks a GType for emements, and has
4
* a per-element free function.
12
This file is part of VIPS.
14
VIPS is free software; you can redistribute it and/or modify
15
it under the terms of the GNU Lesser General Public License as published by
16
the Free Software Foundation; either version 2 of the License, or
17
(at your option) any later version.
19
This program is distributed in the hope that it will be useful,
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
GNU Lesser General Public License for more details.
24
You should have received a copy of the GNU Lesser General Public License
25
along with this program; if not, write to the Free Software
26
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
43
#endif /*HAVE_CONFIG_H*/
44
#include <vips/intl.h>
50
#include <vips/vips.h>
51
#include <vips/internal.h>
52
#include <vips/debug.h>
54
/* A very simple boxed type for testing. Just an int.
61
* Returns: (transfer full): a new #VipsThing.
64
vips_thing_new( int i )
68
thing = g_new( VipsThing, 1 );
71
printf( "vips_thing_new: %d %p\n", i, thing );
77
vips_thing_copy( VipsThing *thing )
81
thing2 = vips_thing_new( thing->i );
83
printf( "vips_thing_copy: %d %p = %p\n", thing->i, thing2, thing );
89
vips_thing_free( VipsThing *thing )
91
printf( "vips_thing_free: %d %p\n", thing->i, thing );
97
vips_thing_get_i( VipsThing *thing )
99
printf( "vips_thing_get_i: %d %p\n", thing->i, thing );
104
G_DEFINE_BOXED_TYPE( VipsThing, vips_thing,
105
(GBoxedCopyFunc) vips_thing_copy,
106
(GBoxedFreeFunc) vips_thing_free );
110
* @short_description: an area of memory
112
* @see_also: <link linkend="libvips-meta">header</link>,
113
* @include: vips/vips.h
115
* A VipsArea wraps a chunk of memory. It adds reference counting and a free
116
* function. It also keeps a count and a GType, so the area can be an array.
118
* This type is used for things like passing an array of double or an array of
119
* VipsObject pointers to operations, and for reference-countred immutable
124
static int vips_area_number = 0;
128
vips_area_copy( VipsArea *area )
130
g_assert( area->count >= 0 );
135
printf( "vips_area_copy: %p count = %d\n", area, area->count );
142
vips_area_unref( VipsArea *area )
144
g_assert( area->count > 0 );
149
printf( "vips_area_unref: %p count = %d\n", area, area->count );
152
if( area->count == 0 ) {
153
if( area->free_fn && area->data ) {
154
area->free_fn( area->data, area );
156
area->free_fn = NULL;
162
vips_area_number -= 1;
163
printf( "vips_area_unref: free .. total = %d\n",
171
* @free_fn: (scope async): @data will be freed with this function
172
* @data: data will be freed with this function
174
* An area of memory with a free function. (eg. \0-terminated string, or a
175
* struct). Inital count == 1, so _unref() after attaching somewhere.
177
* See also: vips_area_unref().
179
* Returns: (transfer full): the new #VipsArea.
182
vips_area_new( VipsCallbackFn free_fn, void *data )
186
area = g_new( VipsArea, 1 );
190
area->free_fn = free_fn;
192
area->sizeof_type = 0;
195
vips_area_number += 1;
196
printf( "vips_area_new: %p count = %d (%d in total)\n",
197
area, area->count, vips_area_number );
204
* vips_area_new_blob:
205
* @free_fn: (scope async): @data will be freed with this function
206
* @data: data will be freed with this function
207
* @length: number of bytes in @data
209
* Like vips_area_new(), but track a length as well.
211
* An area of mem with a free func and a length (some sort of binary object,
212
* like an ICC profile).
214
* See also: vips_area_unref().
216
* Returns: (transfer full): the new #VipsArea.
219
vips_area_new_blob( VipsCallbackFn free_fn, void *data, size_t length )
223
area = vips_area_new( free_fn, data );
224
area->length = length;
230
* vips_area_new_array:
231
* @type: %GType of elements to store
232
* @sizeof_type: sizeof() an element in the array
233
* @n: number of elements in the array
235
* An area which holds an array of elements of some GType. To set values for
236
* the elements, get the pointer and write.
238
* See also: vips_area_unref().
240
* Returns: (transfer full): the new #VipsArea.
243
vips_area_new_array( GType type, size_t sizeof_type, int n )
248
array = g_malloc( n * sizeof_type );
249
area = vips_area_new( (VipsCallbackFn) g_free, array );
251
area->length = n * sizeof_type;
253
area->sizeof_type = sizeof_type;
259
vips_area_free_array_object( GObject **array, VipsArea *area )
263
for( i = 0; i < area->n; i++ )
264
VIPS_FREEF( g_object_unref, array[i] );
270
* vips_area_new_array_object:
271
* @n: number of elements in the array
273
* An area which holds an array of GObjects. See vips_area_new_array(). When
274
* the area is freed, each %GObject will be unreffed.
276
* See also: vips_area_unref().
278
* Returns: (transfer full): the new #VipsArea.
281
vips_area_new_array_object( int n )
286
array = g_new0( GObject *, n );
287
area = vips_area_new( (VipsCallbackFn) vips_area_free_array_object,
290
area->length = n * sizeof( GObject * );
291
area->type = G_TYPE_OBJECT;
292
area->sizeof_type = sizeof( GObject * );
298
* vips_area_get_data:
299
* @area: #VipsArea to fetch from
300
* @length: (allow-none): optionally return length in bytes here
301
* @n: (allow-none): optionally return number of elements here
302
* @type: (allow-none): optionally return element type here
303
* @sizeof_type: (allow-none): optionally return sizeof() element type here
305
* Return the data pointer plus optionally the length in bytes of an area,
306
* the number of elements, the %GType of each element and the sizeof() each
309
* Returns: (transfer none): The pointer held by @area.
312
vips_area_get_data( VipsArea *area,
313
size_t *length, int *n, GType *type, size_t *sizeof_type )
316
*length = area->length;
322
*sizeof_type = area->sizeof_type;
324
return( area->data );
327
/* Transform an area to a G_TYPE_STRING.
330
transform_area_g_string( const GValue *src_value, GValue *dest_value )
335
area = g_value_get_boxed( src_value );
336
vips_snprintf( buf, 256, "VIPS_TYPE_AREA, count = %d, data = %p",
337
area->count, area->data );
338
g_value_set_string( dest_value, buf );
342
vips_area_get_type( void )
344
static GType type = 0;
347
type = g_boxed_type_register_static( "VipsArea",
348
(GBoxedCopyFunc) vips_area_copy,
349
(GBoxedFreeFunc) vips_area_unref );
350
g_value_register_transform_func( type, G_TYPE_STRING,
351
transform_area_g_string );
357
/* Transform funcs for builtin types to SAVE_STRING.
360
transform_int_save_string( const GValue *src_value, GValue *dest_value )
362
vips_value_set_save_stringf( dest_value,
363
"%d", g_value_get_int( src_value ) );
367
transform_save_string_int( const GValue *src_value, GValue *dest_value )
369
g_value_set_int( dest_value,
370
atoi( vips_value_get_save_string( src_value ) ) );
374
transform_double_save_string( const GValue *src_value, GValue *dest_value )
376
char buf[G_ASCII_DTOSTR_BUF_SIZE];
378
/* Need to be locale independent.
380
g_ascii_dtostr( buf, G_ASCII_DTOSTR_BUF_SIZE,
381
g_value_get_double( src_value ) );
382
vips_value_set_save_string( dest_value, buf );
386
transform_save_string_double( const GValue *src_value, GValue *dest_value )
388
g_value_set_double( dest_value,
389
g_ascii_strtod( vips_value_get_save_string( src_value ),
393
/* Save meta fields to the header. We have a new string type for header fields
394
* to save to XML and define transform functions to go from our meta types to
398
vips_save_string_get_type( void )
400
static GType type = 0;
403
type = g_boxed_type_register_static( "VipsSaveString",
404
(GBoxedCopyFunc) g_strdup,
405
(GBoxedFreeFunc) g_free );
411
/* Transform a refstring to a G_TYPE_STRING and back.
414
transform_ref_string_g_string( const GValue *src_value, GValue *dest_value )
416
g_value_set_string( dest_value,
417
vips_value_get_ref_string( src_value, NULL ) );
421
transform_g_string_ref_string( const GValue *src_value, GValue *dest_value )
423
vips_value_set_ref_string( dest_value,
424
g_value_get_string( src_value ) );
430
transform_ref_string_save_string( const GValue *src_value, GValue *dest_value )
432
vips_value_set_save_stringf( dest_value,
433
"%s", vips_value_get_ref_string( src_value, NULL ) );
437
transform_save_string_ref_string( const GValue *src_value, GValue *dest_value )
439
vips_value_set_ref_string( dest_value,
440
vips_value_get_save_string( src_value ) );
444
vips_ref_string_get_type( void )
446
static GType type = 0;
449
type = g_boxed_type_register_static( "VipsRefString",
450
(GBoxedCopyFunc) vips_area_copy,
451
(GBoxedFreeFunc) vips_area_unref );
452
g_value_register_transform_func( type, G_TYPE_STRING,
453
transform_ref_string_g_string );
454
g_value_register_transform_func( G_TYPE_STRING, type,
455
transform_g_string_ref_string );
456
g_value_register_transform_func( type, VIPS_TYPE_SAVE_STRING,
457
transform_ref_string_save_string );
458
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, type,
459
transform_save_string_ref_string );
465
/* Transform a blob to a G_TYPE_STRING.
468
transform_blob_g_string( const GValue *src_value, GValue *dest_value )
474
blob = vips_value_get_blob( src_value, &blob_length );
475
vips_snprintf( buf, 256, "VIPS_TYPE_BLOB, data = %p, length = %zd",
477
g_value_set_string( dest_value, buf );
480
/* Transform a blob to a save string and back.
483
transform_blob_save_string( const GValue *src_value, GValue *dest_value )
489
blob = vips_value_get_blob( src_value, &blob_length );
490
if( (b64 = vips__b64_encode( blob, blob_length )) ) {
491
vips_value_set_save_string( dest_value, b64 );
497
transform_save_string_blob( const GValue *src_value, GValue *dest_value )
503
b64 = vips_value_get_save_string( src_value );
504
if( (blob = vips__b64_decode( b64, &blob_length )) )
505
vips_value_set_blob( dest_value,
506
(VipsCallbackFn) vips_free, blob, blob_length );
510
vips_blob_get_type( void )
512
static GType type = 0;
515
type = g_boxed_type_register_static( "VipsBlob",
516
(GBoxedCopyFunc) vips_area_copy,
517
(GBoxedFreeFunc) vips_area_unref );
518
g_value_register_transform_func( type, G_TYPE_STRING,
519
transform_blob_g_string );
520
g_value_register_transform_func( type, VIPS_TYPE_SAVE_STRING,
521
transform_blob_save_string );
522
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, type,
523
transform_save_string_blob );
530
transform_array_double_g_string( const GValue *src_value, GValue *dest_value )
533
double *array = vips_value_get_array_double( src_value, &n );
536
VipsBuf buf = VIPS_BUF_STATIC( txt );
539
for( i = 0; i < n; i++ )
540
/* Use space as a separator since ',' may be a decimal point
543
vips_buf_appendf( &buf, "%g ", array[i] );
545
g_value_set_string( dest_value, vips_buf_all( &buf ) );
548
/* It'd be great to be able to write a generic string->array function, but
549
* it doesn't seem possible.
552
transform_g_string_array_double( const GValue *src_value, GValue *dest_value )
560
/* Walk the string to get the number of elements.
561
* We need a copy of the string, since we insert \0 during
564
* We can't allow ',' as a separator, since some locales use it as a
567
str = g_value_dup_string( src_value );
569
for( p = str; (q = vips_break_token( p, "\t; " )); p = q )
573
vips_value_set_array( dest_value, n, G_TYPE_DOUBLE, sizeof( double ) );
574
array = (double *) vips_value_get_array( dest_value, NULL, NULL, NULL );
576
str = g_value_dup_string( src_value );
578
for( p = str; (q = vips_break_token( p, "\t; " )); p = q )
579
array[i++] = atof( p );
584
vips_array_double_get_type( void )
586
static GType type = 0;
589
type = g_boxed_type_register_static( "VipsArrayDouble",
590
(GBoxedCopyFunc) vips_area_copy,
591
(GBoxedFreeFunc) vips_area_unref );
592
g_value_register_transform_func( type, G_TYPE_STRING,
593
transform_array_double_g_string );
594
g_value_register_transform_func( G_TYPE_STRING, type,
595
transform_g_string_array_double );
602
transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
610
/* We need a copy of the string, since we insert \0 during
613
str = g_value_dup_string( src_value );
615
for( p = str; (q = vips_break_token( p, " " )); p = q )
619
vips_value_set_array_object( dest_value, n );
620
array = vips_value_get_array_object( dest_value, NULL );
622
str = g_value_dup_string( src_value );
623
for( i = 0, p = str; (q = vips_break_token( p, " " )); i++, p = q )
624
if( !(array[i] = G_OBJECT( vips_image_new_from_file( p ) )) ) {
625
/* Set the dest to length zero to indicate error.
627
vips_value_set_array_object( dest_value, 0 );
635
vips_array_image_get_type( void )
637
static GType type = 0;
640
type = g_boxed_type_register_static( "VipsArrayImage",
641
(GBoxedCopyFunc) vips_area_copy,
642
(GBoxedFreeFunc) vips_area_unref );
643
g_value_register_transform_func( G_TYPE_STRING, type,
644
transform_g_string_array_image );
651
* vips_value_set_area:
652
* @value: (out): set this value
653
* @free_fn: (scope async): data will be freed with this function
654
* @data: set @value to track this pointer
656
* Set value to be a ref-counted area of memory with a free function.
659
vips_value_set_area( GValue *value, VipsCallbackFn free_fn, void *data )
663
area = vips_area_new( free_fn, data );
664
g_value_init( value, VIPS_TYPE_AREA );
665
g_value_set_boxed( value, area );
666
vips_area_unref( area );
670
* vips_value_get_area:
671
* @value: get from this value
672
* @length: (allow-none): optionally return length here
674
* Get the pointer from an area. Don't touch count (area is static).
676
* Returns: (transfer none): The pointer held by @value.
679
vips_value_get_area( const GValue *value, size_t *length )
683
area = g_value_get_boxed( value );
685
return( vips_area_get_data( area, length, NULL, NULL, NULL ) );
689
* vips_value_get_save_string:
690
* @value: GValue to get from
692
* Get the C string held internally by the GValue.
694
* Returns: (transfer none): The C string held by @value.
697
vips_value_get_save_string( const GValue *value )
699
return( (char *) g_value_get_boxed( value ) );
703
* vips_value_set_save_string:
704
* @value: (out): GValue to set
705
* @str: C string to copy into the GValue
707
* Copies the C string into @value.
710
vips_value_set_save_string( GValue *value, const char *str )
712
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
714
g_value_set_boxed( value, str );
718
* vips_value_set_save_stringf:
719
* @value: (out): GValue to set
720
* @fmt: printf()-style format string
721
* @Varargs: arguments to printf()-formatted @fmt
723
* Generates a string and copies it into @value.
726
vips_value_set_save_stringf( GValue *value, const char *fmt, ... )
731
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_SAVE_STRING );
734
str = g_strdup_vprintf( fmt, ap );
736
vips_value_set_save_string( value, str );
741
* vips_value_get_ref_string:
742
* @value: %GValue to get from
743
* @length: (allow-none): return length here, optionally
745
* Get the C string held internally by the GValue.
747
* Returns: (transfer none): The C string held by @value.
750
vips_value_get_ref_string( const GValue *value, size_t *length )
752
return( vips_value_get_area( value, length ) );
756
* vips_value_set_ref_string:
757
* @value: (out): GValue to set
758
* @str: C string to copy into the GValue
760
* Copies the C string @str into @value.
762
* vips_ref_string are immutable C strings that are copied between images by
763
* copying reference-counted pointers, making the much more efficient than
764
* regular GValue strings.
766
* Returns: 0 on success, -1 otherwise.
769
vips_value_set_ref_string( GValue *value, const char *str )
774
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
776
str_copy = g_strdup( str );
777
area = vips_area_new( (VipsCallbackFn) vips_free, str_copy );
779
/* Handy place to cache this.
781
area->length = strlen( str );
783
g_value_set_boxed( value, area );
784
vips_area_unref( area );
790
* vips_value_set_blob:
791
* @value: (out): GValue to set
792
* @free_fn: (scope async): free function for @data
793
* @data: pointer to area of memory
794
* @length: length of memory area
796
* Sets @value to hold a @data. When @value is freed, @data will be
797
* freed with @free_fn. @value also holds a note of the length of the memory
800
* blobs are things like ICC profiles or EXIF data. They are relocatable, and
801
* are saved to VIPS files for you coded as base64 inside the XML. They are
802
* copied by copying reference-counted pointers.
804
* See also: vips_value_get_blob()
807
vips_value_set_blob( GValue *value,
808
VipsCallbackFn free_fn, void *data, size_t length )
812
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_BLOB );
814
area = vips_area_new_blob( free_fn, data, length );
815
g_value_set_boxed( value, area );
816
vips_area_unref( area );
820
* vips_value_get_blob:
821
* @value: GValue to set
822
* @length: (allow-none): optionally return length of memory area
824
* Returns the data pointer from a blob. Optionally returns the length too.
826
* blobs are things like ICC profiles or EXIF data. They are relocatable, and
827
* are saved to VIPS files for you coded as base64 inside the XML. They are
828
* copied by copying reference-counted pointers.
830
* See also: vips_value_set_blob()
832
* Returns: (transfer none): The pointer held by @value.
835
vips_value_get_blob( const GValue *value, size_t *length )
837
return( vips_value_get_area( value, length ) );
841
* vips_value_set_array:
842
* @value: (out): %GValue to set
843
* @n: number of elements
844
* @type: the type of each element
845
* @sizeof_type: the sizeof each element
847
* Set @value to be an array of things.
849
* This allocates memory but does not
850
* initialise the contents: get the pointer and write instead.
853
vips_value_set_array( GValue *value, int n, GType type, size_t sizeof_type )
857
area = vips_area_new_array( type, sizeof_type, n );
858
g_value_set_boxed( value, area );
859
vips_area_unref( area );
863
* vips_value_get_array:
864
* @value: %GValue to get from
865
* @n: (allow-none): return the number of elements here, optionally
866
* @type: (allow-none): return the type of each element here, optionally
867
* @sizeof_type: (allow-none): return the sizeof each element here, optionally
869
* Return the pointer to the array held by @value.
870
* Optionally return the other properties of the array in @n, @type,
873
* See also: vips_value_set_array().
875
* Returns: (transfer none): The array address.
878
vips_value_get_array( const GValue *value,
879
int *n, GType *type, size_t *sizeof_type )
883
/* Can't check value type, because we may get called from
887
area = g_value_get_boxed( value );
893
*sizeof_type = area->sizeof_type;
895
return( area->data );
899
* vips_array_double_new:
900
* @array: (array length=n): array of double
901
* @n: number of doubles
903
* Allocate a new array of doubles and copy @array into it. Free with
906
* See also: #VipsArea.
908
* Returns: (transfer full): A new #VipsArrayDouble.
911
vips_array_double_new( const double *array, int n )
916
printf( "hello, world!\n" );
918
area = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), n );
919
array_copy = vips_area_get_data( area, NULL, NULL, NULL, NULL );
920
memcpy( array_copy, array, n * sizeof( double ) );
926
* vips_value_get_array_double:
927
* @value: %GValue to get from
928
* @n: (allow-none): return the number of elements here, optionally
930
* Return the start of the array of doubles held by @value.
931
* optionally return the number of elements in @n.
933
* See also: vips_array_double_set().
935
* Returns: (transfer none): The array address.
938
vips_value_get_array_double( const GValue *value, int *n )
940
return( vips_value_get_array( value, n, NULL, NULL ) );
944
* vips_value_set_array_double:
945
* @value: (out): %GValue to get from
946
* @array: (array length=n): array of doubles
947
* @n: the number of elements
949
* Set @value to hold a copy of @array. Pass in the array length in @n.
951
* See also: vips_array_double_get().
953
* Returns: 0 on success, -1 otherwise.
956
vips_value_set_array_double( GValue *value, const double *array, int n )
960
g_value_init( value, VIPS_TYPE_ARRAY_DOUBLE );
961
vips_value_set_array( value, n, G_TYPE_DOUBLE, sizeof( double ) );
962
array_copy = vips_value_get_array_double( value, NULL );
963
memcpy( array_copy, array, n * sizeof( double ) );
969
* vips_value_get_array_object: (skip)
970
* @value: %GValue to get from
971
* @n: (allow-none): return the number of elements here, optionally
973
* Return the start of the array of %GObject held by @value.
974
* optionally return the number of elements in @n.
976
* See also: vips_array_object_set().
978
* Returns: (transfer none): The array address.
981
vips_value_get_array_object( const GValue *value, int *n )
983
return( vips_value_get_array( value, n, NULL, NULL ) );
987
* vips_array_object_set:
988
* @value: (out): %GValue to set
989
* @n: the number of elements
991
* Set @value to hold an array of GObject. Pass in the array length in @n.
993
* See also: vips_array_object_get().
995
* Returns: 0 on success, -1 otherwise.
998
vips_value_set_array_object( GValue *value, int n )
1002
if( !(area = vips_area_new_array_object( n )) )
1004
g_value_set_boxed( value, area );
1005
vips_area_unref( area );
1010
/* Make the types we need for basic functioning. Called from init_world().
1013
vips__meta_init_types( void )
1015
(void) vips_thing_get_type();
1016
(void) vips_save_string_get_type();
1017
(void) vips_area_get_type();
1018
(void) vips_ref_string_get_type();
1019
(void) vips_blob_get_type();
1020
(void) vips_array_double_get_type();
1021
(void) vips_array_image_get_type();
1023
/* Register transform functions to go from built-in saveable types to
1024
* a save string. Transform functions for our own types are set
1025
* during type creation.
1027
g_value_register_transform_func( G_TYPE_INT, VIPS_TYPE_SAVE_STRING,
1028
transform_int_save_string );
1029
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_INT,
1030
transform_save_string_int );
1031
g_value_register_transform_func( G_TYPE_DOUBLE, VIPS_TYPE_SAVE_STRING,
1032
transform_double_save_string );
1033
g_value_register_transform_func( VIPS_TYPE_SAVE_STRING, G_TYPE_DOUBLE,
1034
transform_save_string_double );