У меня есть этот код:
void PngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
std::vector<uint8_t> *p = (std::vector<uint8_t>*)png_get_io_ptr(png_ptr);
if (p->capacity() <= p->size() + length + 1)
{
p->resize(p->size() + length + 1);
}
p->insert(p->end(), data, data + length);
}
и основная часть метода записи
png_set_IHDR(png_ptr,
info_ptr,
w,
h,
8,
PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_byte ** row_pointers = (png_byte **)png_malloc(png_ptr, h * sizeof(png_byte *));
for (size_t y = 0; y < h; y++)
{
row_pointers[y] = (png_byte *)(data + w * y);
}
png_set_rows(png_ptr, info_ptr, row_pointers);
std::vector<uint8_t> out;
out.reserve(w * h * 4);
png_set_write_fn(png_ptr, &out, PngWriteCallback, NULL);
png_set_compression_strategy(png_ptr, Z_HUFFMAN_ONLY);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
std::vector<uint8_t> out1 = std::move(out);
out.clear();
out.reserve(w * h * 4);
png_set_compression_strategy(png_ptr, Z_FILTERED);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
if (out.size() < out1.size())
{
printf("Huffman %d vs %d\n", out.size(), out1.size());
fwrite(out.data(), sizeof(uint8_t), out.size(), fp);
}
else
{
printf("Z_FILTER %d vs %d\n", out1.size(), out.size());
fwrite(out1.data(), sizeof(uint8_t), out1.size(), fp);
}
//==============================================================
png_free(png_ptr, row_pointers);
Однако программа вылетает с:
libpng warning: zstream not in use (internal error)
libpng error: stream error
на второй звонок png_write_png
.
Как я могу записать файл дважды с разными настройками? Если я опущу второй png_write_png
, все работает правильно.