[source lang="cpp"]bool base::Image::load_png (IODevice &in)
{
png_byte signature [PNG_SIG_SIZE] = {0};
PNGReader png;
PixelFormat format;
boost::scoped_array<png_bytep> rows;
try
{
// Check signature
in.read(signature, PNG_SIG_SIZE);
if (png_sig_cmp(signature, 0, PNG_SIG_SIZE) != 0)
{
throw std::logic_error("Stream is not a PNG image");
}
// Setup input
png_set_read_fn(png.readp, &in, &on_png_read);
png_set_sig_bytes(png.readp, PNG_SIG_SIZE);
// Get info and allocate image
png_read_info(png.readp, png.infop);
switch (png_get_color_type(png.readp, png.infop))
{
case PNG_COLOR_TYPE_GRAY:
format = LUM_8;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
format = LUM_ALPHA_8;
break;
case PNG_COLOR_TYPE_PALETTE:
case PNG_COLOR_TYPE_RGB:
format = RGB_8;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
format = RGB_ALPHA_8;
break;
default:
throw std::invalid_argument("Invalid PNG color type");
}
reset(Vec2u(png_get_image_width(png.readp, png.infop), png_get_image_height(png.readp, png.infop)), format, NULL, 0);
// Setup transformations
png_set_expand(png.readp);
png_set_strip_16(png.readp);
png_set_packing(png.readp);
// Read data
rows.reset(new png_bytep [size.y]);
for (unsigned int y = 0; y < size.y; y++)
{
rows[y] = &data.get()[y * pitch];
}
png_read_image(png.readp, rows.get());
// Finish
return true;
}
catch (const std::exception &e)
{
destroy();
error_string = e.what();
return false;
}
}[/source]
PNGReader is just a basic structure that creates and destroys the PNG structs in a way that takes advantage of RAII.
[source lang="cpp"]struct PNGReader
{
png_structp readp;
png_infop infop;
// Constructor
PNGReader ()
: readp(NULL), infop(NULL)
{
readp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, &on_png_error, &on_png_warning);
if (!readp)
{
throw std::runtime_error("png_create_read_struct failed");
}
infop = png_create_info_struct(readp);
if (!infop)
{
throw std::runtime_error("png_create_info_struct failed");
}
}
// Destructor
~PNGReader ()
{
if (infop)
{
png_destroy_read_struct(&readp, &infop, NULL);
}
else if (readp)
{
png_destroy_read_struct(&readp, NULL, NULL);
}
}
};[/source]
I can't find any problems in my code that would cause zlib to crash. I even replaced the PNGReader struct with manual calls and got the same results. Here's the stack trace:
#0 0x00007ffff6676975 in raise () from /lib/libc.so.6
#1 0x00007ffff6677deb in abort () from /lib/libc.so.6
#2 0x00007ffff66b36ae in __libc_message () from /lib/libc.so.6
#3 0x00007ffff66b9326 in malloc_printerr () from /lib/libc.so.6
#4 0x00007ffff4b8fb5a in inflateEnd () from /usr/lib/libz.so.1
#5 0x00007ffff7749707 in ?? () from /usr/lib/libpng15.so.15
#6 0x00007ffff774997a in png_destroy_read_struct () from /usr/lib/libpng15.so.15
#7 0x000000000040e8c7 in PNGReader::~PNGReader (this=0x7fffffffe410, __in_chrg=<optimized out="">) at src/base/image_png.cpp:78
#8 0x000000000040e507 in base::Image::load_png (this=0x7fffffffe4f0, in=...) at src/base/image_png.cpp:166
#9 0x0000000000406244 in get_texture (path=...) at src/resource.cpp:94
#10 0x000000000040b307 in vd_main (args=...) at src/main.cpp:36
#11 0x000000000040b523 in main (argc=1, argv=0x7fffffffe7f8) at src/main.cpp:75
Has anyone had a similar error when using libpng or zlib? Any help is appreciated.</optimized></png_bytep>