Merge pull request #1678 from randy408/spng-fix

Revise spngloader
This commit is contained in:
John Cupitt 2020-06-11 11:38:26 +01:00 committed by GitHub
commit 49b35f708f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 60 additions and 46 deletions

View File

@ -315,50 +315,23 @@ vips_foreign_load_png_header( VipsForeignLoad *load )
png->ihdr.interlace_method ); png->ihdr.interlace_method );
*/ */
/* Just convert to host-endian if nothing else applies.
*/
png->fmt = SPNG_FMT_PNG;
switch( png->ihdr.color_type ) { switch( png->ihdr.color_type ) {
case SPNG_COLOR_TYPE_GRAYSCALE: case SPNG_COLOR_TYPE_INDEXED:
case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: bands = 3;
png->bands = 1;
png->interpretation = VIPS_INTERPRETATION_B_W;
png->fmt = SPNG_FMT_PNG;
if( !spng_get_trns( png->ctx, &trns ) ) {
png->bands += 1;
/* Expand 1/2/4 bit images to 8 bit.
*/
if( png->ihdr.bit_depth < 8 )
png->fmt = SPNG_FMT_GA8;
}
else {
if( png->ihdr.bit_depth < 8 )
png->fmt = SPNG_FMT_G8;
}
break; break;
case SPNG_COLOR_TYPE_TRUECOLOR: case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA: case SPNG_COLOR_TYPE_GRAYSCALE:
png->bands = 3; bands = 1;
png->interpretation = VIPS_INTERPRETATION_sRGB;
png->fmt = SPNG_FMT_PNG;
if( !spng_get_trns( png->ctx, &trns ) )
png->bands += 1;
break; break;
case SPNG_COLOR_TYPE_INDEXED: case SPNG_COLOR_TYPE_RGB:
png->bands = 3; case SPNG_COLOR_TYPE_RGB_ALPHA:
png->interpretation = VIPS_INTERPRETATION_sRGB; bands = 3;
/* Expand indexed images to RGB8.
*/
if( !spng_get_trns( png->ctx, &trns ) ) {
png->bands += 1;
png->fmt = SPNG_FMT_RGBA8;
}
else
png->fmt = SPNG_FMT_RGB8;
break; break;
default: default:
@ -366,15 +339,56 @@ vips_foreign_load_png_header( VipsForeignLoad *load )
return( -1 ); return( -1 );
} }
if( png->ihdr.bit_depth == 16 ) { if( bit_depth > 8 ) {
png->format = VIPS_FORMAT_USHORT; if( bands < 3 )
if( png->interpretation == VIPS_INTERPRETATION_B_W ) interpretation = VIPS_INTERPRETATION_GREY16;
png->interpretation = VIPS_INTERPRETATION_GREY16; else
if( png->interpretation == VIPS_INTERPRETATION_sRGB ) interpretation = VIPS_INTERPRETATION_RGB16;
png->interpretation = VIPS_INTERPRETATION_RGB16; }
else {
if( bands < 3 )
interpretation = VIPS_INTERPRETATION_B_W;
else
interpretation = VIPS_INTERPRETATION_sRGB;
}
/* Expand palette images.
*/
if( png->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED )
png->fmt = SPNG_FMT_RGB8;
/* Expand <8 bit images to full bytes.
*/
if( png->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE &&
png->ihdr.bit_depth < 8 )
png->fmt = SPNG_FMT_G8;
/* Expand transparency.
*/
if( !spng_get_trns( png->ctx, &trns ) ) {
bands += 1;
if( png->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR ) {
if( png->ihdr.bit_depth == 16 )
png->fmt = SPNG_FMT_RGBA16;
else
png->fmt = SPNG_FMT_RGBA8;
}
else if( png->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED )
png->fmt = SPNG_FMT_RGBA8;
else if( png->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE ) {
if( png->ihdr.bit_depth == 16 )
png->fmt = SPNG_FMT_GA16;
else
png->fmt = SPNG_FMT_GA8;
}
}
else if( png->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ||
png->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA ) {
/* Some images have their own alpha channel,
* not just a transparent color.
*/
bands += 1;
} }
else
png->format = VIPS_FORMAT_UCHAR;
vips_source_minimise( png->source ); vips_source_minimise( png->source );