writing 48/64 bit PNGs?
Andrew Randrianasulu <[email protected]> Fri, 27 Mar 2020 05:58:29 +0300
| Newsgroups | gmane.comp.graphics.png.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello!
I'm trying to implement 16 bits per channel PNG writing.
I use this software (video editor/compositor)
https://git.cinelerra-gg.org/git/?p=goodguy/cinelerra.git;a=blob;f=cinelerra-5.1/cinelerra/filepng.C;h=3b28e0eac5fa145ee8c99b7adc21cf4c9b688d6f;hb=HEAD
well, actually in this form 64 bit PNGs are broken.
If I add small patch adding png_set_swap - it works!
Still, there is something strange:
depend on OS I tested my changes with, place where I must put this call
for fixing broken PNG was different!
On 64-bit Ubuntu 18.04.4:
diff --git a/cinelerra-5.1/cinelerra/filepng.C b/cinelerra-5.1/cinelerra/filepng.C
index 3b28e0ea..2d1f3fbd 100644
--- a/cinelerra-5.1/cinelerra/filepng.C
+++ b/cinelerra-5.1/cinelerra/filepng.C
@@ -228,6 +228,8 @@ int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
png_set_IHDR(png_ptr, info_ptr, asset->width, asset->height, asset->png_depth,
asset->png_use_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ if( asset->png_depth == 16 && BC_Resources::little_endian )
+ png_set_swap(png_ptr);
png_write_info(png_ptr, info_ptr);
png_write_image(png_ptr, output_frame->get_rows());
png_write_end(png_ptr, info_ptr);
in other words png_set_swap BEFORE png_write_info/png_write_image
On my 32-bit Slackware system I must place this call AFTER png_write_info:
diff --git a/cinelerra-5.1/cinelerra/filepng.C b/cinelerra-5.1/cinelerra/filepng.C
index 3b28e0ea..1e380e61 100644
--- a/cinelerra-5.1/cinelerra/filepng.C
+++ b/cinelerra-5.1/cinelerra/filepng.C
@@ -228,7 +228,11 @@ int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
png_set_IHDR(png_ptr, info_ptr, asset->width, asset->height, asset->png_depth,
asset->png_use_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ if( asset->png_depth == 16 && BC_Resources::little_endian )
+ png_set_swap(png_ptr);
png_write_info(png_ptr, info_ptr);
+ if( asset->png_depth == 16 && BC_Resources::little_endian )
+ png_set_swap(png_ptr);
png_write_image(png_ptr, output_frame->get_rows());
png_write_end(png_ptr, info_ptr);
result = 0;
I found this ..strange. On Slackware I have libpng 1.6.37. (but also 1.4.15)
On Ubuntu ....
1.6.34
Ubuntu version I tested, under qemu:
http://mirror.yandex.ru/ubuntu-cdimage/xubuntu/releases/18.04/release/
xubuntu-18.04.4-desktop-amd64.iso
As far as I can see this call is required, yet depend on system/libpng version exact
place to put it may wary, or this is a bug?
I used GIMP source as my reference:
https://github.com/GNOME/gimp/blob/mainline/plug-ins/common/file-png.c