From cb2b217434a1c80946ab62631cdc0649023f8f2e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 18 Aug 2014 13:54:06 +0100 Subject: [PATCH] fix 16-bit PNG save see https://github.com/jcupitt/libvips/issues/156 --- ChangeLog | 1 + TODO | 4 ---- libvips/foreign/foreign.c | 25 ++++++++++++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f58d25df..4d06c83d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,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 4d015a25..7a36e5b4 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 - vips_init() has a deprecation warning, bizarre 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 ); }