fix low bitdepth PNG save of high bitdepth images
SOme combinations of high bitdepth images with low bitdepth PNG save could produce incorrect images, for example saving a 16-bit fourier image as 1-bit.
This commit is contained in:
parent
94d3f93a46
commit
1989203985
@ -5,6 +5,7 @@
|
||||
- add "unlimited" to jpegload
|
||||
- better 0 detection in unpremultiply
|
||||
- fix low bitdepth spng save [jeffska]
|
||||
- fix PNG low bitdepth save of high bitdepth images
|
||||
|
||||
21/11/21 started 8.13
|
||||
- configure fails for requested but unmet dependencies [remicollet]
|
||||
|
@ -112,12 +112,22 @@ vips_foreign_save_png_build( VipsObject *object )
|
||||
in = save->ready;
|
||||
g_object_ref( in );
|
||||
|
||||
/* save->ready will have been converted to uint16 for high-bitdepth
|
||||
* formats (eg. float) ... we need to check Type to see if we want
|
||||
* to save as 8 or 16-bits. Eg. imagine a float image tagged as sRGB.
|
||||
/* If no output bitdepth has been specified, use input Type to pick.
|
||||
*/
|
||||
if( in->Type == VIPS_INTERPRETATION_sRGB ||
|
||||
in->Type == VIPS_INTERPRETATION_B_W ) {
|
||||
if( !vips_object_argument_isset( object, "bitdepth" ) )
|
||||
png->bitdepth =
|
||||
in->Type == VIPS_INTERPRETATION_RGB16 ||
|
||||
in->Type == VIPS_INTERPRETATION_GREY16 ? 16 : 8;
|
||||
|
||||
/* Deprecated "colours" arg just sets bitdepth large enough to hold
|
||||
* that many colours.
|
||||
*/
|
||||
if( vips_object_argument_isset( object, "colours" ) )
|
||||
png->bitdepth = ceil( log2( png->colours ) );
|
||||
|
||||
/* Cast in down to 8 bit if we can.
|
||||
*/
|
||||
if( png->bitdepth <= 8 ) {
|
||||
VipsImage *x;
|
||||
|
||||
if( vips_cast( in, &x, VIPS_FORMAT_UCHAR, NULL ) ) {
|
||||
@ -128,15 +138,6 @@ vips_foreign_save_png_build( VipsObject *object )
|
||||
in = x;
|
||||
}
|
||||
|
||||
/* Deprecated "colours" arg just sets bitdepth large enough to hold
|
||||
* that many colours.
|
||||
*/
|
||||
if( vips_object_argument_isset( object, "colours" ) )
|
||||
png->bitdepth = ceil( log2( png->colours ) );
|
||||
|
||||
if( !vips_object_argument_isset( object, "bitdepth" ) )
|
||||
png->bitdepth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16;
|
||||
|
||||
/* If this is a RGB or RGBA image and a low bit depth has been
|
||||
* requested, enable palettization.
|
||||
*/
|
||||
@ -144,6 +145,11 @@ vips_foreign_save_png_build( VipsObject *object )
|
||||
png->bitdepth < 8 )
|
||||
png->palette = TRUE;
|
||||
|
||||
/* Disable palettization for >8 bit save.
|
||||
*/
|
||||
if( png->bitdepth >= 8 )
|
||||
png->palette = FALSE;
|
||||
|
||||
if( vips__png_write_target( in, png->target,
|
||||
png->compression, png->interlace, png->profile, png->filter,
|
||||
save->strip, png->palette, png->Q, png->dither,
|
||||
|
@ -42,9 +42,9 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
#define DEBUG_VERBOSE
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@ -485,7 +485,7 @@ vips_foreign_save_spng_write( VipsForeignSaveSpng *spng, VipsImage *in )
|
||||
spng_set_option( spng->ctx,
|
||||
SPNG_FILTER_CHOICE, spng->filter );
|
||||
|
||||
/* Set resolution. libpng uses pixels per meter.
|
||||
/* Set resolution. png uses pixels per meter.
|
||||
*/
|
||||
phys.unit_specifier = 1;
|
||||
phys.ppu_x = VIPS_RINT( in->Xres * 1000.0 );
|
||||
@ -580,12 +580,22 @@ vips_foreign_save_spng_build( VipsObject *object )
|
||||
in = save->ready;
|
||||
g_object_ref( in );
|
||||
|
||||
/* in will have been converted to uint16 for high-bitdepth
|
||||
* formats (eg. float) ... we need to check Type to see if we want
|
||||
* to save as 8 or 16-bits. Eg. imagine a float image tagged as sRGB.
|
||||
/* If no output bitdepth has been specified, use input Type to pick.
|
||||
*/
|
||||
if( in->Type == VIPS_INTERPRETATION_sRGB ||
|
||||
in->Type == VIPS_INTERPRETATION_B_W ) {
|
||||
if( !vips_object_argument_isset( object, "bitdepth" ) )
|
||||
spng->bitdepth =
|
||||
in->Type == VIPS_INTERPRETATION_RGB16 ||
|
||||
in->Type == VIPS_INTERPRETATION_GREY16 ? 16 : 8;
|
||||
|
||||
/* Deprecated "colours" arg just sets bitdepth large enough to hold
|
||||
* that many colours.
|
||||
*/
|
||||
if( vips_object_argument_isset( object, "colours" ) )
|
||||
spng->bitdepth = ceil( log2( spng->colours ) );
|
||||
|
||||
/* Cast in down to 8 bit if we can.
|
||||
*/
|
||||
if( spng->bitdepth <= 8 ) {
|
||||
VipsImage *x;
|
||||
|
||||
if( vips_cast( in, &x, VIPS_FORMAT_UCHAR, NULL ) ) {
|
||||
@ -596,19 +606,6 @@ vips_foreign_save_spng_build( VipsObject *object )
|
||||
in = x;
|
||||
}
|
||||
|
||||
/* If no output bitdepth has been specified, use input Type to pick.
|
||||
* We only go for 16 bits for the types where we know there's a
|
||||
* 0-65535 range.
|
||||
*/
|
||||
if( !vips_object_argument_isset( object, "bitdepth" ) )
|
||||
spng->bitdepth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16;
|
||||
|
||||
/* Deprecated "colours" arg just sets bitdepth large enough to hold
|
||||
* that many colours.
|
||||
*/
|
||||
if( vips_object_argument_isset( object, "colours" ) )
|
||||
spng->bitdepth = ceil( log2( spng->colours ) );
|
||||
|
||||
/* If this is a RGB or RGBA image and a low bit depth has been
|
||||
* requested, enable palettisation.
|
||||
*/
|
||||
@ -616,6 +613,11 @@ vips_foreign_save_spng_build( VipsObject *object )
|
||||
spng->bitdepth < 8 )
|
||||
spng->palette = TRUE;
|
||||
|
||||
/* Disable palettization for >8 bit save.
|
||||
*/
|
||||
if( spng->bitdepth >= 8 )
|
||||
spng->palette = FALSE;
|
||||
|
||||
if( vips_foreign_save_spng_write( spng, in ) ) {
|
||||
g_object_unref( in );
|
||||
return( -1 );
|
||||
|
Loading…
Reference in New Issue
Block a user