From 8b453f012862ae00612ce590e54b6f4c6f7e6a5d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 5 Aug 2008 15:46:16 +0000 Subject: [PATCH] added im_guess_libdir, meta set/get for C++/Python --- ChangeLog | 3 ++ TODO | 6 ++-- configure.in | 19 +++++++++++ doc/src/packages.tex | 1 + include/vips/VImage.h | 9 +++++ include/vips/proto.h | 1 + libsrc/iofuncs/im_guess_prefix.c | 30 +++++++++++++++++ libsrc/iofuncs/im_init_world.c | 11 +++++-- libsrc/iofuncs/package.c | 48 ++++++++++++++++++++++++--- libsrcCC/VImage.cc | 56 ++++++++++++++++++++++++++++++++ man/Makefile.am | 1 + man/im_guess_libdir.3 | 1 + man/im_guess_prefix.3 | 11 ++++++- man/im_init_world.3 | 4 +-- man/im_meta.3 | 2 ++ 15 files changed, 188 insertions(+), 15 deletions(-) create mode 100644 man/im_guess_libdir.3 diff --git a/ChangeLog b/ChangeLog index ea7331e8..6a0725d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,9 @@ - better jpeg-in-tiff YCbCr read (thanks Ole) - oops, invalidatefns were not being freed on im__close() - 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 25/1/08 started 7.14.0 - bump all version numbers for new stable diff --git a/TODO b/TODO index e938fedb..a0d474fb 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,3 @@ -- we need im_guess_eprefix(), use it to find plugins - - look for plugins in eprefix/lib/vips-7.15 - - note new VMask constructor in docs test new VMask constructor from python @@ -10,6 +6,8 @@ need fred.get_int ("poop"); I think + add notes to docs on this + - try libsrc/convolution$ grep -l offsets *.c diff --git a/configure.in b/configure.in index dab9fd4f..5db83d78 100644 --- a/configure.in +++ b/configure.in @@ -96,10 +96,29 @@ AC_PROG_LN_S AC_PROG_CXX AM_WITH_DMALLOC +# we need a fully expanded version of $libdir +# without this we get something like +# define IM_LIBDIR ${exec_prefix}/lib +# argh +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# set $expanded_value to the full-expanded value of the argument +expand () { + eval expanded_value=$1 + + if test x"$expanded_value" != x"$1"; then + expand "$expanded_value" + fi +} + +expand $libdir +my_libdir=$expanded_value + # vips.c/im_guess_prefix.c need to know the exe suffix and (as a fallback) # the configure-time install prefix AC_DEFINE_UNQUOTED(IM_EXEEXT,"$EXEEXT",[extension for executable files]) AC_DEFINE_UNQUOTED(IM_PREFIX,"$prefix",[configure-time install prefix]) +AC_DEFINE_UNQUOTED(IM_LIBDIR,"$my_libdir",[configure-time library directory]) # i18n GETTEXT_PACKAGE=vips7 diff --git a/doc/src/packages.tex b/doc/src/packages.tex index af466e84..72206e63 100644 --- a/doc/src/packages.tex +++ b/doc/src/packages.tex @@ -841,6 +841,7 @@ example% vips --list iofuncs im_binfile - open a headerless binary file im_cache - cache results of an operation im_guess_prefix - guess install area +im_guess_libdir - guess library area im_header_get_type - return field type im_header_int - extract int fields from header im_header_double - extract double fields from header diff --git a/include/vips/VImage.h b/include/vips/VImage.h index 345d9eb3..b6fd6778 100644 --- a/include/vips/VImage.h +++ b/include/vips/VImage.h @@ -243,6 +243,15 @@ public: const char *filename(); const char *Hist(); + // metadata + 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_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 ); + // 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/proto.h b/include/vips/proto.h index 175bd8cd..fcaf40cf 100644 --- a/include/vips/proto.h +++ b/include/vips/proto.h @@ -92,6 +92,7 @@ void *im_header_map( IMAGE *im, im_header_map_fn fn, void *a ); const char *im_version_string( void ); int im_version( int flag ); const char *im_guess_prefix( const char *, const char * ); +const char *im_guess_libdir( const char *, const char * ); IMAGE *im_init( const char * ); IMAGE *im_openout( const char * ); int im_openin( IMAGE *image ); diff --git a/libsrc/iofuncs/im_guess_prefix.c b/libsrc/iofuncs/im_guess_prefix.c index 0281e6c5..d4fb970a 100644 --- a/libsrc/iofuncs/im_guess_prefix.c +++ b/libsrc/iofuncs/im_guess_prefix.c @@ -39,6 +39,8 @@ * 21/7/07 * - fall back to configure-time prefix rather than returning an error * (thanks Jay) + * 5/8/08 + * - added im_guess_libdir() */ /* @@ -396,3 +398,31 @@ im_guess_prefix( const char *argv0, const char *env_name ) return( prefix ); } + +const char * +im_guess_libdir( const char *argv0, const char *env_name ) +{ + const char *prefix = im_guess_prefix( argv0, env_name ); + static char *libdir = NULL; + + if( libdir ) + return( libdir ); + + /* Have we been moved since configure? If not, use the configure-time + * libdir. + */ + if( strcmp( prefix, IM_PREFIX ) == 0 ) + libdir = IM_LIBDIR; + else + libdir = g_strdup_printf( "%s/lib", prefix ); + +#ifdef DEBUG + printf( "im_guess_libdir: IM_PREFIX = %s\n", IM_PREFIX ); + printf( "im_guess_libdir: IM_LIBDIR = %s\n", IM_LIBDIR ); + printf( "im_guess_libdir: prefix = %s\n", prefix ); + printf( "im_guess_libdir: libdir = %s\n", libdir ); +#endif /*DEBUG*/ + + return( libdir ); +} + diff --git a/libsrc/iofuncs/im_init_world.c b/libsrc/iofuncs/im_init_world.c index fc2a8401..3b2186e8 100644 --- a/libsrc/iofuncs/im_init_world.c +++ b/libsrc/iofuncs/im_init_world.c @@ -17,6 +17,8 @@ * VIPS refuse to start because of a dodgy plugin * 7/11/07 * - progress feedback option + * 5/8/08 + * - load plugins from libdir/vips-x.x */ /* @@ -78,6 +80,7 @@ im_init_world( const char *argv0 ) static gboolean done = FALSE; char *prgname; const char *prefix; + const char *libdir; char name[256]; /* Two stage done handling: 'done' means we've completed, 'started' @@ -113,7 +116,8 @@ im_init_world( const char *argv0 ) /* Try to discover our prefix. */ - if( !(prefix = im_guess_prefix( argv0, "VIPSHOME" )) ) + if( !(prefix = im_guess_prefix( argv0, "VIPSHOME" )) || + !(libdir = im_guess_libdir( argv0, "VIPSHOME" )) ) return( -1 ); /* Get i18n .mo files from $VIPSHOME/share/locale/. @@ -131,11 +135,12 @@ im_init_world( const char *argv0 ) */ im__meta_init_types(); - /* Load up any plugins in $VIPSHOME/lib. We don't error on failure, + /* Load up any plugins in the vips libdir. We don't error on failure, * it's too annoying to have VIPS refuse to start because of a broken * plugin. */ - if( im_load_plugins( "%s/lib", prefix ) ) { + if( im_load_plugins( "%s/vips-%d.%d", + libdir, IM_MAJOR_VERSION, IM_MINOR_VERSION ) ) { im_warn( "im_init_world", "%s", im_errorstring() ); im_error_clear(); } diff --git a/libsrc/iofuncs/package.c b/libsrc/iofuncs/package.c index 9e86645c..9f19571b 100644 --- a/libsrc/iofuncs/package.c +++ b/libsrc/iofuncs/package.c @@ -8,6 +8,8 @@ * - uses glib dir scanning stuff instead of dirent.h * 20/5/08 * - note_dependencies() does IMAGEVEC as well as IMAGE + * 5/8/08 + * - silent success in loading plugins if the dir isn't there */ /* @@ -107,6 +109,42 @@ static im_function guess_prefix_desc = { guess_prefix_args /* Arg list */ }; +/* im_guess_libdir() args. + */ +static im_arg_desc guess_libdir_args[] = { + IM_INPUT_STRING( "argv0" ), + IM_INPUT_STRING( "env_name" ), + IM_OUTPUT_STRING( "LIBDIR" ) +}; + +/* Call im_guess_libdir() via arg vector. + */ +static int +guess_libdir_vec( im_object *argv ) +{ + const char *libdir = im_guess_libdir( argv[0], argv[1] ); + + if( !libdir ) { + argv[2] = NULL; + return( -1 ); + } + + argv[2] = im_strdup( NULL, libdir ); + + return( 0 ); +} + +/* Description of im_guess_libdir. + */ +static im_function guess_libdir_desc = { + "im_guess_libdir", /* Name */ + "guess library area", /* Description */ + 0, /* Flags */ + guess_libdir_vec, /* Dispatch function */ + IM_NUMBER( guess_libdir_args ), /* Size of arg list */ + guess_libdir_args /* Arg list */ +}; + /* im_header_int() args. */ static im_arg_desc header_int_args[] = { @@ -378,6 +416,7 @@ static im_function *iofuncs_list[] = { &binfile_desc, &cache_desc, &guess_prefix_desc, + &guess_libdir_desc, &header_get_type_desc, &header_int_desc, &header_double_desc, @@ -549,11 +588,10 @@ im_load_plugins( const char *fmt, ... ) (void) im_vsnprintf( dir_name, PATH_MAX - 1, fmt, ap ); va_end( ap ); - if( !(dir = g_dir_open( dir_name, 0, NULL )) ) { - im_error( "plugin", - "unable to open directory \"%s\"", dir_name ); - return( -1 ); - } + if( !(dir = g_dir_open( dir_name, 0, NULL )) ) + /* Silent success for dir not there. + */ + return( 0 ); result = 0; while( (name = g_dir_read_name( dir )) ) diff --git a/libsrcCC/VImage.cc b/libsrcCC/VImage.cc index 51195620..4186d6c6 100644 --- a/libsrcCC/VImage.cc +++ b/libsrcCC/VImage.cc @@ -314,6 +314,62 @@ int VImage::Yoffset() { return( _ref->im->Yoffset ); } const char *VImage::filename() { return( _ref->im->filename ); } const char *VImage::Hist() { return( im_history_get( _ref->im ) ); } +// metadata + +int VImage::meta_get_int( const char *field ) + throw( VError ) +{ + int result; + + if( im_meta_get_int( _ref->im, field, &result ) ) + verror(); + + return( result ); +} + +double VImage::meta_get_double( const char *field ) + throw( VError ) +{ + double result; + + if( im_meta_get_double( _ref->im, field, &result ) ) + verror(); + + return( result ); +} + +const char *VImage::meta_get_string( const char *field ) + throw( VError ) +{ + char *result; + + if( im_meta_get_string( _ref->im, field, &result ) ) + verror(); + + return( result ); +} + +void VImage::meta_set( const char *field, int value ) + throw( VError ) +{ + if( im_meta_set_int( _ref->im, field, value ) ) + verror(); +} + +void VImage::meta_set( const char *field, double value ) + throw( VError ) +{ + if( im_meta_set_double( _ref->im, field, value ) ) + verror(); +} + +void VImage::meta_set( const char *field, const char *value ) + throw( VError ) +{ + if( im_meta_set_string( _ref->im, field, value ) ) + 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/Makefile.am b/man/Makefile.am index 79729971..fecdd2d1 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -214,6 +214,7 @@ man_MANS = \ im_grey.3 \ im_grid.3 \ im_guess_prefix.3 \ + im_guess_libdir.3 \ im_header.3 \ im_header_double.3 \ im_header_get.3 \ diff --git a/man/im_guess_libdir.3 b/man/im_guess_libdir.3 new file mode 100644 index 00000000..cc35252a --- /dev/null +++ b/man/im_guess_libdir.3 @@ -0,0 +1 @@ +.so man3/im_guess_prefix.3 diff --git a/man/im_guess_prefix.3 b/man/im_guess_prefix.3 index 785d56b6..bdc334f3 100644 --- a/man/im_guess_prefix.3 +++ b/man/im_guess_prefix.3 @@ -1,12 +1,15 @@ .TH IM_VIPSHOME 3 "8 March 2001" .SH NAME -im_guess_prefix \- try to guess install directory +im_guess_prefix, im_guess_libdir \- try to guess install directory .SH SYNOPSIS .B #include .B const char *im_guess_prefix( const char *argv0, .B const char *env_name ) +.B const char *im_guess_libdir( const char *argv0, +.B const char *env_name ) + .SH DESCRIPTION .B im_guess_prefix(3) tries to guess the install directory. You should pass in the value of @@ -25,5 +28,11 @@ able to find data files. Don't free the return string! +.B im_guess_libdir(3) +works exactly as +.B im_guess_prefix(3) +but, if vips has not been moved since configure, returns the libdir configure +setting. If vips has been moved, it returns prefix/lib. + .SH RETURN VALUE The function returns NULL on failure. diff --git a/man/im_init_world.3 b/man/im_init_world.3 index 4374f029..2b266a28 100644 --- a/man/im_init_world.3 +++ b/man/im_init_world.3 @@ -14,7 +14,7 @@ starts up the VIPS library. It: - initialises any libraries that VIPS is using, including GObject - starts up the threading system - guesses where the VIPS data files are and sets up i18n - - loads any plugins + - loads any plugins from libdir/vips-x.x The .B argv0 @@ -42,6 +42,6 @@ containing various VIPS command-line options. It can be used with GOption to help parse argc/argv. .SH SEE ALSO -im_guess_prefix(3), GOption(3) +im_guess_prefix(3), im_guess_libdir(3), GOption(3) .SH COPYRIGHT Birkbeck College and the National Gallery (c) 1994 diff --git a/man/im_meta.3 b/man/im_meta.3 index 5a3d9892..f11283f5 100644 --- a/man/im_meta.3 +++ b/man/im_meta.3 @@ -32,6 +32,8 @@ int im_meta_set_blob( IMAGE *im, const char *field, int im_meta_get_blob( IMAGE *im, const char *field, void **blob, int *blob_length ); +typedef int (*im_callback_fn)( void *, void * ); + int im_meta_set( IMAGE *im, const char *field, GValue *value ); .br int im_meta_get( IMAGE *im, const char *field, GValue *value_copy );