• Advertisement
Sign in to follow this  

libpng playing up...

This topic is 1696 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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...
	fread(sig, 1, sizeof(png_byte [8]), fpPNG);
	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));
		
	}
	
	png_read_image(png_ptr, row_pointers);
	
	png_read_end(png_ptr, info_ptr);
	
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
	
}
catch(Exception e)
{
	
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
	
	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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 beginning
of 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 will
then 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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 beginning
of 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 will
then 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 abdulla
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.

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

Share this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
Quote:
Original post by mattd
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:

*** 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 this post


Link to post
Share on other sites
Quote:
Original post by iNsAn1tY
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).


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement