update for SPNG_FMT_PNG

We can now decode PNG to g8/g16/ga8/ga16/rgb8/rgb16 etc.
This commit is contained in:
John Cupitt 2020-05-13 15:25:01 +01:00
parent df4f03863e
commit d78480c846

View File

@ -37,10 +37,10 @@
* no interlace == 0. * no interlace == 0.
* an equivalent of png_sig_cmp() from libpng (is_a_png on a memory area) * an equivalent of png_sig_cmp() from libpng (is_a_png on a memory area)
* *
* This always reads RGBA8 or RGBA16. Other formst G8/G16/GA8 etc. etc. are * test indexed decode
* in the roadmap.
* *
* Most metadata support (eg. XMP, ICC, etc. etc.) is missing. * Most metadata support (eg. XMP, ICC, etc. etc.) is missing. We will need
* to set a chunk size limit with spng_set_chunks_limits().
* *
* Load only, there's no save support for now. * Load only, there's no save support for now.
*/ */
@ -211,6 +211,14 @@ vips_foreign_load_png_header( VipsForeignLoad *load )
*/ */
spng_set_crc_action( png->ctx, SPNG_CRC_USE, SPNG_CRC_USE ); spng_set_crc_action( png->ctx, SPNG_CRC_USE, SPNG_CRC_USE );
/* Set limits to avoid decompression bombs. We should set
* spng_set_chunks_limits() as well, once that API goes in.
*
* No need to test the decoded image size -- the user can do that if
* they wish.
*/
spng_set_image_limits( png->ctx, VIPS_MAX_COORD, VIPS_MAX_COORD );
if( vips_source_rewind( png->source ) ) if( vips_source_rewind( png->source ) )
return( -1 ); return( -1 );
spng_set_png_stream( png->ctx, spng_set_png_stream( png->ctx,
@ -230,23 +238,55 @@ vips_foreign_load_png_header( VipsForeignLoad *load )
png->ihdr.interlace_method ); png->ihdr.interlace_method );
*/ */
/* For now, libspng always outputs RGBA.
*/ switch( png->ihdr.color_type ) {
png->interpretation = VIPS_INTERPRETATION_sRGB; case SPNG_COLOR_TYPE_GRAYSCALE:
png->bands = 4; png->bands = 1;
png->interpretation = VIPS_INTERPRETATION_B_W;
png->fmt = SPNG_FMT_PNG;
break;
case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
png->bands = 2;
png->interpretation = VIPS_INTERPRETATION_B_W;
png->fmt = SPNG_FMT_PNG;
break;
case SPNG_COLOR_TYPE_TRUECOLOR:
png->bands = 3;
png->interpretation = VIPS_INTERPRETATION_sRGB;
png->fmt = SPNG_FMT_PNG;
break;
case SPNG_COLOR_TYPE_INDEXED:
png->bands = 3;
png->interpretation = VIPS_INTERPRETATION_sRGB;
/* Expand indexed images to RGB8.
*/
png->fmt = SPNG_FMT_RGB8;
break;
case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
png->bands = 4;
png->interpretation = VIPS_INTERPRETATION_sRGB;
png->fmt = SPNG_FMT_PNG;
break;
default:
vips_error( class->nickname, "%s", _( "unknown color type" ) );
return( -1 );
}
if( png->ihdr.bit_depth == 16 ) { if( png->ihdr.bit_depth == 16 ) {
png->fmt = SPNG_FMT_RGBA16;
png->format = VIPS_FORMAT_USHORT; png->format = VIPS_FORMAT_USHORT;
if( png->interpretation == VIPS_INTERPRETATION_B_W ) if( png->interpretation == VIPS_INTERPRETATION_B_W )
png->interpretation = VIPS_INTERPRETATION_GREY16; png->interpretation = VIPS_INTERPRETATION_GREY16;
if( png->interpretation == VIPS_INTERPRETATION_sRGB ) if( png->interpretation == VIPS_INTERPRETATION_sRGB )
png->interpretation = VIPS_INTERPRETATION_RGB16; png->interpretation = VIPS_INTERPRETATION_RGB16;
} }
else { else
png->fmt = SPNG_FMT_RGBA8;
png->format = VIPS_FORMAT_UCHAR; png->format = VIPS_FORMAT_UCHAR;
}
/* FIXME ... get resolution, profile, exif, xmp, etc. etc. /* FIXME ... get resolution, profile, exif, xmp, etc. etc.
*/ */