# libpng playing up...

## Recommended Posts

iNsAn1tY    476
I'm writing a PNG loader using libpng, and I've run up against a strange problem. I've written the code correctly, so far as I can see from the example file and the tutorial provided, and it compiles fine, but it crashes when I call png_read_info(png_ptr, info_ptr); The error occurs in the file _file.c, and has something to do with locking the file, as far as I can see. The exact message is:
Unhandled exception at 0x7c918fea in ImageTest.exe: 0xC0000005: Access violation writing location 0x00000010.

My code:
FILE *fpPNG = NULL;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_byte sig[8];
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;

fpPNG = fopen(sFilename.c_str(), "rb");

if(!fpPNG) throw Exception("The Portable Network Graphics file \"" + sFilename + "\" could not be opened.", __FUNCTION__, __FILE__, __LINE__);

try
{

// Read 8 bytes of the file, and check them...
if(!png_check_sig(sig, 8)) throw Exception("The Portable Network Graphics file \"" + sFilename + "\" is not valid.", __FUNCTION__, __FILE__, __LINE_);

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
if(png_ptr == NULL) throw Exception("An error has occurred reading the Portable Network Graphics file \"" + sFilename + "\".", __FUNCTION__, __FILE__, __LINE__);

info_ptr = png_create_info_struct(png_ptr);
if(info_ptr == NULL) throw Exception("An error has occurred reading the Portable Network Graphics file \"" + sFilename + "\".", __FUNCTION__, __FILE__, __LINE__);

png_init_io(png_ptr, fpPNG);
png_set_sig_bytes(png_ptr, 8);

png_read_info(png_ptr, info_ptr); // <- This is the problem...

png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);

png_bytep *row_pointers = new png_bytep[height];

for(png_uint_32 row = 0; row < height; row++)
{

row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));

}

}
catch(Exception e)
{

fclose(fpPNG);
fpPNG = NULL;

throw e;

}

fclose(fpPNG);
fpPNG = NULL;


Anyone got any suggestions? I've tried both the debug and release builds of the libpng/zlib DLL, and tested them with the pngtest program. They both work, apparently.

##### Share on other sites
onnel    124
Hi Insanty,

I'm having exactly the same problem. My work around has been to use tiffs since libtif seems to have no problem, but that is *far* from ideal.

I have tried compiling different versions of libpng with different options, but this problem persists. Hope someone has a suggestion!

Onnel

##### Share on other sites
Syranide    375
Are you passing the correct arguments?
From what it looks like it crashes because of something that (however, could be an internal problem too).

##### Share on other sites
iNsAn1tY    476
Yeah, the arguments are correct. There are two ways of reading a file using libpng, a high-level way, and a low-level way. The code above uses the low-level method, but I've tried both, and neither work. They both fail at exactly the same place. Now I know someone else is having problems, I think I'll email the libpng guys and see if there's a problem with this build of the library...

##### Share on other sites
Dave Hunt    4872
According to the docs:
Quote:
 If you are intending to keep the file pointer open for use in libpng,you must ensure you don't read more than 8 bytes from the beginningof the file, and you also have to make a call to png_set_sig_bytes_read()with the number of bytes you read from the beginning. Libpng willthen only check the bytes (if any) that your program didn't read.

I don't see a call to png_set_sig_bytes_read() in your posted code. Perhaps that is causing the problem? Not sure it matters, but it might be worth a try.

##### Share on other sites
abdulla    164
I think png_set_sig_bytes needs to be called before png_create_info_struct. Other than that, it looks alright, but I use custom IO in my code and png_get_image_width/png_get_image_height rather than png_get_IHDR.

##### Share on other sites
iNsAn1tY    476
Quote:
Original post by Dave Hunt
According to the docs:
Quote:
 If you are intending to keep the file pointer open for use in libpng,you must ensure you don't read more than 8 bytes from the beginningof the file, and you also have to make a call to png_set_sig_bytes_read()with the number of bytes you read from the beginning. Libpng willthen only check the bytes (if any) that your program didn't read.

I don't see a call to png_set_sig_bytes_read() in your posted code. Perhaps that is causing the problem? Not sure it matters, but it might be worth a try.

The function is called png_set_sig_bytes, and it is called in my code, just after png_init_io. png_set_sig_bytes_read might be from an earlier version of libpng, but it definitely isn't in the one I'm using (which is the most recent).

Quote:
 Original post by abdullaI think png_set_sig_bytes needs to be called before png_create_info_struct. Other than that, it looks alright, but I use custom IO in my code and png_get_image_width/png_get_image_height rather than png_get_IHDR.

I gave it a try, but got the same error.

##### Share on other sites
mattd    1078
Looks like it might be a specific problem with libpng. Here's the relevant code I use (libpng 1.2.8), and it works fine:

    // [...]    // Check the validity of the file    unsigned char header[8];    fread(header, 1, 8, file);    if(!png_check_sig(header, 8))        // Not a valid PNG        return PNGREADNOTAPNG;    // Prepare PNG structs    if(!CreatePNGStructs(true)) // Note: Does the same as your code, creating m_png and m_pngInfo        return PNGREADFAIL;    // Set error handling    if(setjmp(png_jmpbuf(m_png)))    {        // An error occurred        png_destroy_read_struct(&m_png, &m_pngInfo, 0);        return PNGREADFAIL;    }    // Set file for reading    png_init_io(m_png, file);    png_set_sig_bytes(m_png, 8);    // Read image info    png_read_info(m_png, m_pngInfo);    // [...]

##### Share on other sites
iNsAn1tY    476
Quote:
 Original post by mattdLooks like it might be a specific problem with libpng. Here's the relevant code I use (libpng 1.2.8), and it works fine:*** Source Snippet Removed ***

Ah, you're running the latest version, and it seems to be working OK? Which compiler are you using? I'm on Visual Studio.NET 2003.

##### Share on other sites
Dave Hunt    4872
Quote:
 Original post by iNsAn1tYThe function is called png_set_sig_bytes, and it is called in my code, just after png_init_io. png_set_sig_bytes_read might be from an earlier version of libpng, but it definitely isn't in the one I'm using (which is the most recent).

Interesting. The quote I provided was from the 1.2.8 version of the docs. I guess they forgot to update it.

##### Share on other sites
iNsAn1tY    476
Quote:
Original post by Dave Hunt
Quote:
 Original post by iNsAn1tYThe function is called png_set_sig_bytes, and it is called in my code, just after png_init_io. png_set_sig_bytes_read might be from an earlier version of libpng, but it definitely isn't in the one I'm using (which is the most recent).

Interesting. The quote I provided was from the 1.2.8 version of the docs. I guess they forgot to update it.

Heh, I'll put that in my email to the libpng guys too :)

##### Share on other sites
mattd    1078
Quote:
Original post by iNsAn1tY
Quote:
 Original post by mattdLooks like it might be a specific problem with libpng. Here's the relevant code I use (libpng 1.2.8), and it works fine:*** Source Snippet Removed ***

Ah, you're running the latest version, and it seems to be working OK? Which compiler are you using? I'm on Visual Studio.NET 2003.

VS.NET 2002.

##### Share on other sites
Guest Anonymous Poster
could there be something wrong with the file you are trying to load? (different colour depth, to small/large, file not found etc).

##### Share on other sites
I don't know if this is what you're looking for, but you might just be able to use FreeImage(http://freeimage.sourceforge.net/) to load your png's. Their public license doesn't require you to release your source, as long as you acknowledge that you used it in one of the ways they specify. Also, the library relies on the png library, it might be useful to see how their code does it.

##### Share on other sites
miye    101

Have you solved the problem? I met the same problem with you.

png_structp png_ptr = png.GetPng();
png_infop info_ptr = png.GetInfo();

png_init_io( png_ptr, file.Get() );
png_set_sig_bytes( png_ptr, 8 );
png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 ); //>>problem
Unhandled exception at 0x7c939af2 in squishTest.exe: 0xC0000005: Access violation writing location 0x00000010.
Can you help me? Thanks.

##### Share on other sites
Cornstalks    7030

This is an old thread. Did you read the other results from googling "png_read_info crash" (and the like)?

Here and here it says that libpng and your program need to both link to the same version of the same runtime library. Make sure you're doing that. Otherwise libpng will be using one runtime and your program another runtime, and mixing the two is just asking for trouble.

Edited by Cornstalks