Platform=Win10x64 Compiler=GCC Lang=C Lib=libpng16.dll
I'm trying to use the libpng library, but printf outputs nothing after this line:
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
Full code:
#include <stdio.h>
#include <png.h>
int main(int argc, char* argv[])
{
printf("starting...\n");
FILE *fp = fopen("test.png", "rb");
if (!fp) {
printf("error #%d\n", 1);
}
// Read the PNG header
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
printf("error #%d\n", 2);
}
// create stuct for png info/meta data
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
printf("error #%d\n", 3);
}
if (setjmp(png_jmpbuf(png_ptr))) {
printf("error #%d\n", 4);
}
png_init_io(png_ptr, fp);
// Read the PNG image data
printf("before printf dies\n");
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
printf("this will not print after png_read_png is ran\n");
fflush(stdout);
/* it won't print regardless if the below cleanup code is commented out or not */
// Get the image dimensions and bit depth
png_uint_32 width, height;
int bit_depth, color_type;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
// Allocate memory for the image data
png_bytep *row_pointers = png_malloc(png_ptr, height * sizeof(png_bytep));
for (png_uint_32 i = 0; i < height; i )
{
row_pointers[i] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
}
// Read the image data into memory
png_read_image(png_ptr, row_pointers);
// Clean up
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
// Free the memory allocated for the image data
for (png_uint_32 i = 0; i < height; i )
{
png_free(png_ptr, row_pointers[i]);
}
png_free(png_ptr, row_pointers);
/**/
fclose(fp);
return 0;
}
It will output this:
starting...
before printf dies
Sorry for the newb question. But I can't find any information on this. Just a bunch of posts saying to end printf with a newline, but I am doing that. Thank you in advance for any help!
CodePudding user response:
The explanation for why your code appears to lock up and not progress is because you are misunderstanding what setjmp() returns. You seem to think it returns 0 for success, and !0 for an "error".
This not correct. It returns 0 for when you actually call setjmp(), and !0 for when some other code calls longjmp() and returns you to there.
png_read_image() seems to be (for some reason) calling jongjmp() to signal an error. So your code enters an infinite loop.
All of your tests for errors should not just log the error then continue with the program. They should exit() or return.
There is obviously some other problem (why png_read_image() is failing), but this is the explanation for your current problem (code locks up).
CodePudding user response:
After much investigation, it appears that png_read_png was encountering an error that it could not report (even with setjmp and custom error trapping). The reason for this appears to be an incompatibility between the source code and the binary that was packaged with the source. So, there is currently no way to program with libpng with C on Windows 10 without compiling the libpng from src and creating your own binary, unless you can find a 3rd party who offers a Windows x64 binary with compatible source code.
To recap on why printf is not printing:
- png_read_png encounters an unexpected situation due to unknown src/binary mismatch
- png_read_png is unable to call a custom error handler and jumps to the setjpm point before png_read_png is called
- png_read_png is called again and the cycle continues
- Windows must somehow detect an endless loop and the program quietly exits, looking as if it finished without printing, but never actually reaching the lower printf statements
- ???
- Profit