diff --git a/ChangeLog b/ChangeLog index 541a8c3d..096b329c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ 12/8/14 started 7.40.6 - more doc fixes - fix similarity rotate+scale, thanks Topochicho +- fix 16-bit PNG save, thanks John 25/7/14 started 7.40.5 - fix a race in im_maxpos_avg() diff --git a/TODO b/TODO index 33ed4863..dcc74eb6 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,5 @@ - can we pick the vipsthumbnail int shrink factor more intelligently? -- did we include the exif patch in the latest windows build? check on laptop - - we don't seem to have this fix in the repository! - - vips_object_unref_outputs() needs docs ... bindings will need it - rewrite im_conv() etc. as vips_conv() diff --git a/libvips/deprecated/package.c b/libvips/deprecated/package.c index 29332809..0548d734 100644 --- a/libvips/deprecated/package.c +++ b/libvips/deprecated/package.c @@ -1198,45 +1198,3 @@ im_run_command( char *name, int argc, char **argv ) return( 0 ); } - -/** - * im_version_string: - * - * Get the VIPS version as a static string, including a build date and time. - * Do not free. - * - * Returns: a static version string - */ -const char * -im_version_string( void ) -{ - return( IM_VERSION_STRING ); -} - -/** - * im_version: - * @flag: which field of the version to get - * - * Get the major, minor or micro library version, with @flag values 0, 1 and - * 2. - * - * Returns: library version number - */ -int -im_version( int flag ) -{ - switch( flag ) { - case 0: - return( IM_MAJOR_VERSION ); - - case 1: - return( IM_MINOR_VERSION ); - - case 2: - return( IM_MICRO_VERSION ); - - default: - vips_error( "im_version", "%s", _( "flag not 0, 1, 2" ) ); - return( -1 ); - } -} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 5090548c..5890b2a8 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -242,12 +242,7 @@ im_open( const char *filename, const char *mode ) { VipsImage *image; - /* Pass in a nonsense name for argv0 ... this init path is only here - * for old programs which are missing an vips_init() call. We need - * i18n set up before we can translate. - */ - if( vips_init( "giant_banana" ) ) - vips_error_clear(); + vips_check_init(); /* We have to go via the old VipsFormat system so we can support the * "filename:option" syntax. @@ -427,7 +422,7 @@ im_init( const char *filename ) int im_init_world( const char *argv0 ) { - return( vips_init( argv0 ) ); + return( vips__init( argv0 ) ); } /* Prettyprint various header fields. Just for vips7 compat, use diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index b39f611e..3e4f3a22 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -8,6 +8,8 @@ * - auto rshift down to 8 bits during save * 19/1/14 * - pack and unpack rad to scrgb + * 18/8/14 + * - fix conversion to 16-bit RGB, thanks John */ /* @@ -1228,14 +1230,27 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) in = out; } } - else if( in->Bands == 3 && - vips_colourspace_issupported( in ) ) { - /* Interpret the Type field for colorimetric images. + else if( in->Bands >= 3 && + vips_colourspace_issupported( in ) && + (class->saveable == VIPS_SAVEABLE_RGB || + class->saveable == VIPS_SAVEABLE_RGBA || + class->saveable == VIPS_SAVEABLE_RGB_CMYK) ) { + /* Use vips_colourspace() to make an RGB image from LAB or + * whatever this thing is. */ VipsImage *out; + VipsInterpretation interpretation; - if( vips_colourspace( in, &out, - VIPS_INTERPRETATION_sRGB, NULL ) ) { + /* Do we make RGB or RGB16? We don't want to squash a 16-bit + * RGB down to 8 bits if the saver supports 16. + */ + if( vips_band_format_is8bit( + class->format_table[in->BandFmt] ) ) + interpretation = VIPS_INTERPRETATION_sRGB; + else + interpretation = VIPS_INTERPRETATION_RGB16; + + if( vips_colourspace( in, &out, interpretation, NULL ) ) { g_object_unref( in ); return( -1 ); } diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 23451125..5ec1a5b1 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -52,6 +52,8 @@ typedef struct _VipsMeta { GValue value; /* copy of value */ } VipsMeta; +void vips_check_init( void ); + void vips__meta_init_types( void ); void vips__meta_destroy( VipsImage *im ); int vips__meta_cp( VipsImage *, const VipsImage * ); diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index 79a51f74..d61cdce3 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -164,7 +164,7 @@ extern "C" { /* We can't use _ here since this will be compiled by our clients and they may * not have _(). */ -#define vips_init( ARGV0 ) \ +#define VIPS_INIT( ARGV0 ) \ (sizeof( VipsObject ) != vips__get_sizeof_vipsobject() ? ( \ vips_info( "vips_init", "ABI mismatch" ), \ vips_info( "vips_init", \ @@ -178,7 +178,6 @@ extern "C" { vips__init( ARGV0 )) const char *vips_get_argv0( void ); -void vips_check_init( void ); void vips_shutdown( void ); void vips_thread_shutdown( void ); GOptionGroup *vips_get_option_group( void ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index cc275eb4..23ee74d1 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -266,6 +266,10 @@ vips_image_new_mode( const char *filename, const char *mode ); int im_init_world( const char *argv0 ); +/* We used to have this in lowercase. + */ +#define vips_init(X) VIPS_INIT(X) + VipsImage *im_open( const char *filename, const char *mode ); VipsImage *im_open_local( VipsImage *parent, diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index a8b7e6ab..4ce62305 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1061,12 +1061,9 @@ vips_image_class_init( VipsImageClass *class ) VIPS_DEBUG_MSG( "vips_image_class_init:\n" ); - /* Pass in a nonsense name for argv0 ... this init world is only here - * for old programs which are missing a vips_init() call. We must - * have threads set up before we can process. + /* We must have threads set up before we can process. */ - if( vips_init( "vips" ) ) - vips_error_clear(); + vips_check_init(); gobject_class->finalize = vips_image_finalize; gobject_class->dispose = vips_image_dispose; diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 9c10910a..c2419795 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -117,52 +117,41 @@ vips_get_argv0( void ) } /** - * vips_init: + * VIPS_INIT: * @argv0: name of application * - * vips_init() starts up the world of VIPS. You should call this on + * VIPS_INIT() starts up the world of VIPS. You should call this on * program startup before using any other VIPS operations. If you do not call - * vips_init(), VIPS will call it for you when you use your first VIPS - * operation, but - * it may not be able to get hold of @argv0 and VIPS may therefore be unable - * to find its data files. It is much better to call this function yourself. + * VIPS_INIT(), VIPS will call it for you when you use your first VIPS + * operation, but it may not be able to get hold of @argv0 and VIPS may + * therefore be unable to find its data files. It is much better to call + * this macro yourself. * - * vips_init() is a macro, since it tries to check binary compatibility + * VIPS_INIT() is a macro, since it tries to check binary compatibility * between the caller and the library. * - * vips_init() does approximately the following: + * VIPS_INIT() does approximately the following: * - * - * - * checks that the libvips your program is expecting is - * binary-compatible with the vips library you're running against - * - * - * initialises any libraries that VIPS is using, including GObject - * and the threading system, if neccessary - * - * - * guesses where the VIPS data files are and sets up - * internationalisation --- see vips_guess_prefix() - * - * - * - * creates the main vips types, including VipsImage and friends - * - * - * - * loads any plugins from $libdir/vips-x.y/, where x and y are the - * major and minor version numbers for this VIPS. - * - * - * + * + checks that the libvips your program is expecting is + * binary-compatible with the vips library you're running against + * + * + initialises any libraries that VIPS is using, including GObject + * and the threading system, if neccessary + * + * + guesses where the VIPS data files are and sets up + * internationalisation --- see vips_guess_prefix() + * + * + creates the main vips types, including #VipsImage and friends + * + * + loads any plugins from $libdir/vips-x.y/, where x and y are the + * major and minor version numbers for this VIPS. * * Example: * * |[ * int main (int argc, char **argv) * { - * if (vips_init (argv[0])) + * if (VIPS_INIT (argv[0])) * vips_error_exit ("unable to start VIPS"); * * vips_shutdown (); @@ -360,7 +349,7 @@ vips_check_init( void ) * for old programs which are missing an vips_init() call. We need * i18n set up before we can translate. */ - if( vips_init( "giant_banana" ) ) + if( vips__init( "vips" ) ) vips_error_clear(); } @@ -404,9 +393,11 @@ vips_leak( void ) * by vips_g_thread_new(). * * You will need to call it from threads created in - * other ways. If you do not call it, vips will generate an error message. + * other ways or there will be memory leaks. If you do not call it, vips + * will generate a warning message. * - * May be called many times. + * It may be called many times, and you can continue using vips after + * calling it. Calling it too often will reduce performance. */ void vips_thread_shutdown( void ) @@ -572,14 +563,14 @@ static GOptionEntry option_entries[] = { /** * vips_get_option_group: (skip) * - * vips_get_option_group() returns a GOptionGroup containing various VIPS - * command-line options. It can be used with GOption to help + * vips_get_option_group() returns a %GOptionGroup containing various VIPS + * command-line options. It can be used with %GOption to help * parse argc/argv. * * See also: vips_version(), vips_guess_prefix(), * vips_guess_libdir(), vips_init(). * - * Returns: a GOptionGroup for VIPS, see GOption + * Returns: a %GOptionGroup for VIPS, see %GOption */ GOptionGroup * vips_get_option_group( void ) @@ -913,3 +904,45 @@ vips_guess_libdir( const char *argv0, const char *env_name ) return( libdir ); } + +/** + * vips_version_string: + * + * Get the VIPS version as a static string, including a build date and time. + * Do not free. + * + * Returns: (transfer none): a static version string + */ +const char * +vips_version_string( void ) +{ + return( VIPS_VERSION_STRING ); +} + +/** + * vips_version: + * @flag: which field of the version to get + * + * Get the major, minor or micro library version, with @flag values 0, 1 and + * 2. + * + * Returns: library version number + */ +int +vips_version( int flag ) +{ + switch( flag ) { + case 0: + return( VIPS_MAJOR_VERSION ); + + case 1: + return( VIPS_MINOR_VERSION ); + + case 2: + return( VIPS_MICRO_VERSION ); + + default: + vips_error( "vips_version", "%s", _( "flag not 0, 1, 2" ) ); + return( -1 ); + } +} diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 3f124396..a540c7df 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -43,6 +43,7 @@ #include #include +#include #include #include diff --git a/libvipsCC/VImage.cc b/libvipsCC/VImage.cc index 15369e96..5709762d 100644 --- a/libvipsCC/VImage.cc +++ b/libvipsCC/VImage.cc @@ -56,7 +56,7 @@ VIPS_NAMESPACE_START */ bool init( const char *argv0 ) { - return( vips_init( argv0 ) == 0 ); + return( vips__init( argv0 ) == 0 ); } void shutdown() diff --git a/tools/vipsheader.c b/tools/vipsheader.c index ad2eeafc..7cc94711 100644 --- a/tools/vipsheader.c +++ b/tools/vipsheader.c @@ -183,7 +183,7 @@ main( int argc, char *argv[] ) int i; int result; - if( vips_init( argv[0] ) ) + if( vips__init( argv[0] ) ) vips_error_exit( "unable to start VIPS" ); textdomain( GETTEXT_PACKAGE ); setlocale( LC_ALL, "" ); diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index a9bd0d90..d4a66e3f 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -718,7 +718,7 @@ main( int argc, char **argv ) GError *error = NULL; int i; - if( vips_init( argv[0] ) ) + if( vips__init( argv[0] ) ) vips_error_exit( "unable to start VIPS" ); textdomain( GETTEXT_PACKAGE ); setlocale( LC_ALL, "" );