I am trying to use the progressive read feature of libpng 1.6.39 (with zlib 1.2.13, GCC/C++ 12, on Linux). However, it seems to not matter what image I try to read, I always end up with the warning
Truncated compressed data in IDAT
and no image data whatsoever.
My code is as follows:
#include "png.h"
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <cstring>
void errorFn(png_structp png_ptr, png_const_charp error_msg) {
std::cout << "user_error_fn(): " << error_msg << std::endl;
_exit(1);
}
void warningFn(png_structp png_ptr, png_const_charp warning_msg) {
std::cout << "user_warning_fn(): " << warning_msg << std::endl;
}
void infoCallback(png_structp png_ptr, png_infop info) {
std::cout << "infoCallback()" << std::endl;
}
void rowCallback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) {
std::cout << "rowCallback(): row_num=" << std::dec << row_num << " pass=" << std::dec << pass << std::endl;
}
void endCallback(png_structp png_ptr, png_infop info) {
std::cout << "endCallback(): " << std::endl;
}
int main(int argc, char const *argv[]) {
FILE *fp(fopen("./libpng/1.6.39/contrib/testpngs/rgb-8.png", "rb"));
std::cout << "fp=" << static_cast<void const *>(fp) << std::endl;
std::cout << "fseek: " << fseek(fp, 0, SEEK_END) << std::endl;
size_t const size(ftell(fp));
std::cout << "ftell: " << size << std::endl;
fseek(fp, 0, SEEK_SET);
png_bytep buf(new png_byte[size]);
memset(buf, 0, size);
std::cout << "fread: " << fread(buf, 1, size, fp) << std::endl;
fclose(fp);
png_structp png_ptr(png_create_read_struct(PNG_LIBPNG_VER_STRING, buf, errorFn, warningFn));
png_infop info_ptr(png_create_info_struct(png_ptr));
png_set_progressive_read_fn(png_ptr, buf, infoCallback, rowCallback, endCallback);
png_process_data(png_ptr, info_ptr, buf, size);
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
delete[] buf;
return 0;
}
The file ./libpng/1.6.39/contrib/testpngs/rgb-8.png
being read is one of the samples that ships with libpng but I got the same error with every other PNG image I've tried so far and there were quite a few.
I would typically get as output something like this:
fp=0x47eeb0
fseek: 0
ftell: 759
fread: 759
infoCallback()
user_warning_fn(): Truncated compressed data in IDAT
endCallback():
I would have expected a number of calls to my rowCallback()
function, and, of course, not getting any warnings (or errors).
Does anybody have any idea what I am doing wrong?
You need to call png_start_read_image()
in your infoCallback()
.