Libpng: writing PNG files...
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.
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.
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.
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.
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;}
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,
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.
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.
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
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.
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...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement