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, "" );