From 69aaca13ae0949acf12056e390cbd1009a8487b2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 13 Jul 2015 12:54:06 +0300 Subject: [PATCH] Handle interlaced PNG images --- source/graphics/png/pngloader.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/source/graphics/png/pngloader.cpp b/source/graphics/png/pngloader.cpp index ede91b0..c2691bd 100644 --- a/source/graphics/png/pngloader.cpp +++ b/source/graphics/png/pngloader.cpp @@ -56,15 +56,21 @@ bool PngLoader::detect(const std::string &sig) void PngLoader::load(Image::Data &data) { + png_byte **rows = 0; + if(setjmp(png_jmpbuf(priv->png))) + { + delete[] rows; throw bad_image_data(priv->message); + } png_read_info(priv->png, priv->info); png_uint_32 width; png_uint_32 height; int depth; int color; - png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, 0, 0, 0); + int interlace; + png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, &interlace, 0, 0); unsigned nchans = png_get_channels(priv->png, priv->info); if(depth!=8) @@ -85,8 +91,26 @@ void PngLoader::load(Image::Data &data) } data.data = new char[data.stride*data.height]; - for(unsigned y=0; ypng, reinterpret_cast(data.data+data.stride*(data.height-1-y)), 0); + + if(interlace==PNG_INTERLACE_ADAM7) + { + // ADAM7 requires all rows to be loaded at once + unsigned n_passes = png_set_interlace_handling(priv->png); + rows = new png_byte *[data.height]; + for(unsigned y=0; y(data.data+data.stride*(data.height-1-y)); + + for(unsigned i=0; ipng, rows, 0, data.height); + + delete[] rows; + rows = 0; + } + else + { + for(unsigned y=0; ypng, reinterpret_cast(data.data+data.stride*(data.height-1-y)), 0); + } png_read_end(priv->png, 0); } -- 2.45.2