Advertisement

Libpng: writing PNG files...

Started by July 10, 2004 06:17 PM
10 comments, last by Max_Payne 20 years, 3 months ago
So I decided to look into libpng... It seems like the manual on libpng.org does not have any actual function references... And for some unknown reason, the setjmp() function you have to call, returns a nonzero value... And I don't know why. I am also wondering if there are some official versions of libpng and zlib as static libraries... All help is appreciated.

Looking for a serious game project?
www.xgameproject.com
Any special reason you are not using a third party read/write library such as corona? Here is an example of the syntax:

corona::Image* image = corona::OpenImage( "c:/filename.ext", corona::PF_R8G8B8A8 );
corona::SaveImage( "c:/filename.ext", PF_R8G8B8A8, image );
delete image;


It supports writing to .PNG files. It is also licensed under the ZLib license which means you can do literally anything with the code except to try to claim you wrote the 'original' version of it.
Advertisement
I'm interested in using libpng at the moment...

Looking for a serious game project?
www.xgameproject.com
check out http://www.libpng.org/pub/png/libpng.html, it has links to everything you'll need: Source, binaries and the documentation.

Here is a clicky for the documentation (called the manual) http://www.libpng.org/pub/png/libpng-1.2.5-manual.html

About setjmp(): If I understand correctly, setjmp is some kind of C exception handling system. After you call setjmp(), if an exception happens, the library will call longjump() which will cause the point of execution back to where you called setjmp(), and make it return non-zero. So, the reason you are getting a non-zero return is because you've caused an exception.
Quote: Original post by Melekor
About setjmp(): If I understand correctly, setjmp is some kind of C exception handling system. After you call setjmp(), if an exception happens, the library will call longjump() which will cause the point of execution back to where you called setjmp(), and make it return non-zero. So, the reason you are getting a non-zero return is because you've caused an exception.


Thats the manual I have been reading... But setjmp() seems rather annoying... As it doesnt explain what went wrong. I don't know which calls are a requirement to write a PNG file. I will show the source code of my function. Hopefully, someone can point out whats wrong:

/******************************************************** Function: CImage::SavePNG()* Purpose : Save image data to a PNG file* Initial : Max Payne on July 10, 2004********************************************************Revisions and bug fixes:*/bool CImage::SavePNG(const char* FilePath){	// Make sure there is image data	if (!m_pImageData)		return false;	// Attempt to open the file in binary mode for writing	FILE* pImageFile = fopen(FilePath, "wb");	// Make sure the file was opened properly	if (!pImageFile)		return false;	// Attempt to allocate the PNG write struct	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);    	// If the PNG write struct failed to be created	if (!png_ptr)	{		// Close the file and return an error		fclose(pImageFile);		return false;	}	// Attempt to allocate the PNG info struct    png_infop info_ptr = png_create_info_struct(png_ptr);    	// If the PNG info struct failed to be created	if (!info_ptr)    {		// Close the file and return an error		fclose(pImageFile);		return false;    }	// Set the longjump options    if (setjmp(png_jmpbuf(png_ptr)))    {		// Close the file and return an error		fclose(pImageFile);		png_destroy_write_struct(&png_ptr, &info_ptr);		return false;    }	// Init the PNG I/O    png_init_io(png_ptr, pImageFile);	// Set the parameters for the PNG compression	png_set_IHDR(		png_ptr, 		info_ptr, 		m_Width, 		m_Height,		8, 		PNG_COLOR_TYPE_RGB, 		PNG_INTERLACE_NONE,		PNG_COMPRESSION_TYPE_DEFAULT, 		PNG_FILTER_TYPE_DEFAULT	);	// For each row of the image	for (unsigned int Y = 0; Y < m_Height; ++Y)	{		// Get a pointer to this row		unsigned char* pRow = (unsigned char*)&m_pImageData[Y * m_Width];		// Write this row		png_write_row(png_ptr, pRow);	}	// End the PNG writing process    png_write_end(png_ptr, info_ptr);	// Destroy the PNG info and write structs    png_destroy_write_struct(&png_ptr, &info_ptr);	// Close the image file	fclose(pImageFile);	// Nothing went wrong	return true;}

Looking for a serious game project?
www.xgameproject.com
png_write_info(png_ptr, info_ptr);
Must be called before you start writing the rows. After you add that it should work fine.

Also, make sure you are cleaning up your resources properly. For instance,
if (!info_ptr){	// Close the file and return an error	fclose(pImageFile);	return;}


will return without destroying png_ptr with png_destroy_write_struct. Instead of writing the cleanup code over and over again, you could just write a label at the end and say goto label after every error, it saves a lot of code duplication. It also ensures that everything is cleaned up, as you don't have to check every code path for which resources must be freed there.
Advertisement
Quote: you could just write a label at the end and say goto label after every error


Welll..... No. But thanks for the help :D

Looking for a serious game project?
www.xgameproject.com
This is great. I added the call to png_write_info() before the loop that writes the rows... And now I get an exception, which seems to come directly from that call.

Looking for a serious game project?
www.xgameproject.com
It kind of defies me to think that the API for a 2D image format should make it this complicated just to load and write files. Makes you wonder how insanely difficult this format would be to load manually. [wow]
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
Quote: Original post by Thunder_Hawk
It kind of defies me to think that the API for a 2D image format should make it this complicated just to load and write files. Makes you wonder how insanely difficult this format would be to load manually. [wow]


Probably not so hard, at least with zlib... Its true that libpng could have been done alot better... I don't see why they aren't using error codes, seriously...

Looking for a serious game project?
www.xgameproject.com

This topic is closed to new replies.

Advertisement