diff --git a/ChangeLog b/ChangeLog index 67527867..f1abc4b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,8 +37,9 @@ - VMask() can init from std::vector, so Python can init from [] - added IM_LIBDIR, im_guess_libdir() - load plugins from libdir/vips-x.x on startup -- added meta get/set int/double/string to C++ API +- added meta get/set int/double/string/area/blob/GValue to C++ API - include time_t in vips.h, thanks nicola +- lock global image list (thanks lee) 25/1/08 started 7.14.0 - bump all version numbers for new stable diff --git a/TODO b/TODO index f43b4b79..50f1cc83 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,12 @@ -- docs for im_guess_eprefix(), IM_EPREFIX - -- merge loadable format stuff, postpone new object parameter API to next - version - -- note new VMask constructor in docs - - test new VMask constructor from python - - wrap meta() stuff in C++, we need it in py as well need fred.get_int ("poop"); I think add notes to docs on this +- merge loadable format stuff, postpone new object parameter API to next + version + - try libsrc/convolution$ grep -l offsets *.c diff --git a/include/vips/VImage.h b/include/vips/VImage.h index b6fd6778..21e61b24 100644 --- a/include/vips/VImage.h +++ b/include/vips/VImage.h @@ -59,6 +59,10 @@ extern "C" { VIPS_NAMESPACE_START +/* A VIPS callback, our name for im_callback_fn. + */ +typedef int (*VCallback)( void *, void * ); + /* VIPS image class. * * Slightly tricky: we have two sorts of sharing. Several VImage can share one @@ -244,14 +248,36 @@ public: const char *Hist(); // metadata +#ifndef SWIG + // base functionality + // we don't wrap GValue, so we can't wrap these for now + void meta_set( const char *field, GValue *value ) throw( VError ); + void meta_get( const char *field, GValue *value_copy ) throw( VError ); + GType meta_get_type( const char *field ) throw( VError ); +#endif /*SWIG*/ + + // convenience functions int meta_get_int( const char *field ) throw( VError ); double meta_get_double( const char *field ) throw( VError ); const char *meta_get_string( const char *field ) throw( VError ); + void *meta_get_area( const char *field ) throw( VError ); + void *meta_get_blob( const char *field, size_t *length ) + throw( VError ); void meta_set( const char *field, int value ) throw( VError ); void meta_set( const char *field, double value ) throw( VError ); void meta_set( const char *field, const char *value ) throw( VError ); +#ifndef SWIG + // we don't wrap callbacks yet, so we can't wrap these for now + void meta_set( const char *field, + VCallback free_fn, void *value ) + throw( VError ); + void meta_set( const char *field, + VCallback free_fn, void *value, size_t length ) + throw( VError ); +#endif /*SWIG*/ + // Set header fields void initdesc( int, int, int, TBandFmt, TCoding, TType, float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError ); diff --git a/include/vips/vips b/include/vips/vips index 06490d14..da9c4100 100644 --- a/include/vips/vips +++ b/include/vips/vips @@ -31,6 +31,9 @@ #include +// VImage.h uses GValue for metadata +#include + // If we have already #included the C vips headers, we have to undef a load of // stuff to stop vips's stupid macros messing up our enums #ifdef IM_VIPS_H diff --git a/libsrc/iofuncs/im_close.c b/libsrc/iofuncs/im_close.c index f6030899..70dd3d45 100644 --- a/libsrc/iofuncs/im_close.c +++ b/libsrc/iofuncs/im_close.c @@ -56,6 +56,8 @@ * - added preclose, removed evalend triggers * 23/7/08 * - im__close() will no longer free regions + * 9/8/08 + * - lock global image list (thanks lee) */ /* @@ -297,7 +299,9 @@ im_close( IMAGE *im ) IM_FREE( im->Hist ); IM_FREEF( im__gslist_gvalue_free, im->history_list ); im__meta_destroy( im ); + g_mutex_lock( im__global_lock ); im__open_images = g_slist_remove( im__open_images, im ); + g_mutex_unlock( im__global_lock ); im__time_destroy( im ); IM_FREE( im ); } diff --git a/libsrc/iofuncs/im_init.c b/libsrc/iofuncs/im_init.c index c2135569..d41fddab 100644 --- a/libsrc/iofuncs/im_init.c +++ b/libsrc/iofuncs/im_init.c @@ -29,6 +29,8 @@ * - init history_list * 7/11/07 * - added preclose and evalstart + * 9/8/08 + * - lock global image list (thanks lee) */ /* @@ -73,6 +75,7 @@ #include #include #include +#include #ifdef WITH_DMALLOC #include @@ -170,7 +173,9 @@ im_init( const char *filename ) return( NULL ); } + g_mutex_lock( im__global_lock ); im__open_images = g_slist_prepend( im__open_images, im ); + g_mutex_unlock( im__global_lock ); return( im ); } diff --git a/libsrc/iofuncs/im_open.c b/libsrc/iofuncs/im_open.c index 7f8e8892..946c0032 100644 --- a/libsrc/iofuncs/im_open.c +++ b/libsrc/iofuncs/im_open.c @@ -90,6 +90,8 @@ Modified: * 7/11/07 * - use preclose, not evalend, for delayed save * - add simple cmd-line progress feedback + * 9/8/08 + * - lock global image list (thanks lee) */ /* @@ -134,6 +136,7 @@ Modified: #include #include +#include #ifdef WITH_DMALLOC #include @@ -643,8 +646,13 @@ image_sanity( IMAGE *im ) return( "NULL descriptor" ); if( !im->filename ) return( "NULL filename" ); - if( !g_slist_find( im__open_images, im ) ) + + g_mutex_lock( im__global_lock ); + if( !g_slist_find( im__open_images, im ) ) { + g_mutex_unlock( im__global_lock ); return( "not on open image list" ); + } + g_mutex_unlock( im__global_lock ); if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) return( "bad dimensions" ); diff --git a/libsrcCC/VImage.cc b/libsrcCC/VImage.cc index 4186d6c6..ec7d233f 100644 --- a/libsrcCC/VImage.cc +++ b/libsrcCC/VImage.cc @@ -316,6 +316,25 @@ const char *VImage::Hist() { return( im_history_get( _ref->im ) ); } // metadata +// base functionality +void VImage::meta_set( const char *field, GValue *value ) throw( VError ) +{ + if( im_meta_set( _ref->im, field, value ) ) + verror(); +} + +void VImage::meta_get( const char *field, GValue *value_copy ) throw( VError ) +{ + if( im_meta_get( _ref->im, field, value_copy ) ) + verror(); +} + +GType VImage::meta_get_type( const char *field ) throw( VError ) +{ + return( im_meta_get_type( _ref->im, field ) ); +} + +// convenience functions int VImage::meta_get_int( const char *field ) throw( VError ) { @@ -349,6 +368,26 @@ const char *VImage::meta_get_string( const char *field ) return( result ); } +void *VImage::meta_get_area( const char *field ) throw( VError ) +{ + void *result; + + if( im_meta_get_area( _ref->im, field, &result ) ) + verror(); + + return( result ); +} + +void *VImage::meta_get_blob( const char *field, size_t *length ) throw( VError ) +{ + void *result; + + if( im_meta_get_blob( _ref->im, field, &result, length ) ) + verror(); + + return( result ); +} + void VImage::meta_set( const char *field, int value ) throw( VError ) { @@ -370,6 +409,22 @@ void VImage::meta_set( const char *field, const char *value ) verror(); } +void VImage::meta_set( const char *field, + VCallback free_fn, void *value ) + throw( VError ) +{ + if( im_meta_set_area( _ref->im, field, free_fn, value ) ) + verror(); +} + +void VImage::meta_set( const char *field, + VCallback free_fn, void *value, size_t length ) + throw( VError ) +{ + if( im_meta_set_blob( _ref->im, field, free_fn, value, length ) ) + verror(); +} + // Set header fields and setbuf() in one go. void VImage::initdesc( int x, int y, int b, TBandFmt f, TCoding c, TType t, float xr, float yr, int xo, int yo ) diff --git a/man/im_meta.3 b/man/im_meta.3 index f11283f5..19eede86 100644 --- a/man/im_meta.3 +++ b/man/im_meta.3 @@ -27,10 +27,10 @@ int im_meta_set_string( IMAGE *im, const char *field, int im_meta_get_string( IMAGE *im, const char *field, char **str ); .br int im_meta_set_blob( IMAGE *im, const char *field, - im_callback_fn free_fn, void *blob, int blob_length ); + im_callback_fn free_fn, void *blob, size_t blob_length ); .br int im_meta_get_blob( IMAGE *im, const char *field, - void **blob, int *blob_length ); + void **blob, size_t *blob_length ); typedef int (*im_callback_fn)( void *, void * );