From 0ff30f972d736645f459d6a774f9f9c545f1b761 Mon Sep 17 00:00:00 2001 From: Randy Date: Tue, 9 Jun 2020 19:56:23 +0200 Subject: [PATCH 1/2] revise spngload --- libvips/foreign/spngload.c | 106 +++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/libvips/foreign/spngload.c b/libvips/foreign/spngload.c index 2af0229a..37ecbee8 100644 --- a/libvips/foreign/spngload.c +++ b/libvips/foreign/spngload.c @@ -315,50 +315,23 @@ vips_foreign_load_png_header( VipsForeignLoad *load ) png->ihdr.interlace_method ); */ + /* Just convert to host-endian if nothing else applies. + */ + png->fmt = SPNG_FMT_PNG; switch( png->ihdr.color_type ) { - case SPNG_COLOR_TYPE_GRAYSCALE: - case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: - 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; - } + case SPNG_COLOR_TYPE_INDEXED: + bands = 3; break; - case SPNG_COLOR_TYPE_TRUECOLOR: - case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA: - png->bands = 3; - png->interpretation = VIPS_INTERPRETATION_sRGB; - png->fmt = SPNG_FMT_PNG; - - if( !spng_get_trns( png->ctx, &trns ) ) - png->bands += 1; + case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: + case SPNG_COLOR_TYPE_GRAYSCALE: + bands = 1; break; - case SPNG_COLOR_TYPE_INDEXED: - png->bands = 3; - png->interpretation = VIPS_INTERPRETATION_sRGB; - - /* 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; + case SPNG_COLOR_TYPE_RGB: + case SPNG_COLOR_TYPE_RGB_ALPHA: + bands = 3; break; default: @@ -366,15 +339,56 @@ vips_foreign_load_png_header( VipsForeignLoad *load ) return( -1 ); } - if( png->ihdr.bit_depth == 16 ) { - png->format = VIPS_FORMAT_USHORT; - if( png->interpretation == VIPS_INTERPRETATION_B_W ) - png->interpretation = VIPS_INTERPRETATION_GREY16; - if( png->interpretation == VIPS_INTERPRETATION_sRGB ) - png->interpretation = VIPS_INTERPRETATION_RGB16; + if( bit_depth > 8 ) { + if( bands < 3 ) + interpretation = VIPS_INTERPRETATION_GREY16; + else + 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 == PNG_COLOR_TYPE_GRAY_ALPHA || + png->ihdr.color_type == PNG_COLOR_TYPE_RGB_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 ); From 2457e6768a51655853377411f05c3bd5c0b2eebd Mon Sep 17 00:00:00 2001 From: Randy Date: Tue, 9 Jun 2020 20:04:03 +0200 Subject: [PATCH 2/2] fix enums --- libvips/foreign/spngload.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/foreign/spngload.c b/libvips/foreign/spngload.c index 37ecbee8..74545756 100644 --- a/libvips/foreign/spngload.c +++ b/libvips/foreign/spngload.c @@ -382,8 +382,8 @@ vips_foreign_load_png_header( VipsForeignLoad *load ) png->fmt = SPNG_FMT_GA8; } } - else if( png->ihdr.color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - png->ihdr.color_type == PNG_COLOR_TYPE_RGB_ALPHA ) { + 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. */