[Cin] Writing 16-bit per component png?
Andrew Randrianasulu
randrianasulu at gmail.com
Mon Mar 16 18:52:27 CET 2020
Probably stupid misuse of libpng api on my side ...
I tried to add support for writing 16 bit per component PNGs into Cin.
int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
{
PNGUnit *png_unit = (PNGUnit*)unit;
png_structp png_ptr = 0;
png_infop info_ptr = 0;
VFrame *output_frame;
int result = 1;
int is_float = (frame->get_color_model() == BC_RGBA_FLOAT || frame->get_color_model() == BC_RGB_FLOAT);
==== here I try to get idea if project's colormodel actually *-FLOAT or not ====
data->set_compressed_size(0);
//printf("FilePNG::write_frame 1\n");
native_cmodel = asset->png_use_alpha ? BC_RGBA8888 : BC_RGB888;
if (is_float)
native_cmodel = asset->png_use_alpha ? BC_RGBA16161616 : BC_RGB161616;
=== here I try to set native_colormodel to wide-channel integer format, if input was FP ====
if(frame->get_color_model() != native_cmodel)
{
if(!png_unit->temp_frame) png_unit->temp_frame =
new VFrame(asset->width, asset->height, native_cmodel, 0);
png_unit->temp_frame->transfer_from(frame);
output_frame = png_unit->temp_frame;
}
else
output_frame = frame;
//printf("FilePNG::write_frame 1\n");
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if( png_ptr ) {
if( !setjmp(png_jmpbuf(png_ptr)) ) {
info_ptr = png_create_info_struct(png_ptr);
png_set_write_fn(png_ptr, data,
(png_rw_ptr)write_function, (png_flush_ptr)flush_function);
png_set_compression_level(png_ptr, asset->png_compression);
png_set_IHDR(png_ptr, info_ptr, asset->width, asset->height, is_float ? 16 : 8,
asset->png_use_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
==== here I try to call libpng with different bit depth depending on is_float ======
png_write_info(png_ptr, info_ptr);
png_write_image(png_ptr, output_frame->get_rows());
png_write_end(png_ptr, info_ptr);
result = 0;
}
png_destroy_write_struct(&png_ptr, &info_ptr);
}
if( result ) {
char error[256]; png_error(png_ptr, error);
fprintf(stderr, "FilePNG::write_frame failed: %s\n", error);
}
//printf("FilePNG::write_frame 3 %d\n", data->get_compressed_size());
return result;
}
I also modified
int FilePNG::get_best_colormodel(Asset *asset, int driver)
{
if(asset->png_use_alpha)
//return BC_RGBA8888;
return BC_RGBA16161616;
else
//return BC_RGB888;
return BC_RGB161616;
}
but probably those changes alone not enough, I get wrong colors or
completely transparent picture in resulted png ?
More information about the Cin
mailing list