Sign in to follow this  
iNsAn1tY

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


Link to post
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 this post


Link to post
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 this post


Link to post
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 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
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 this post


Link to post
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 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
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 this post


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

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

Share this post


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

VS.NET 2002.

Share this post


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


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


Link to post
Share on other sites
miye    101

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

PngReadStruct png;
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_info(png_ptr,info_ptr);will crash too.
    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 this post


Link to post
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this