LibPng - напишите изображение дважды с разными настройками - PullRequest
0 голосов
/ 22 июня 2019

У меня есть этот код:

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, все работает правильно.

...