Re: writing 48/64 bit PNGs?

Marcus Johnson <[email protected]> Fri, 27 Mar 2020 01:28:57 -0400
Newsgroups gmane.comp.graphics.png.devel
Message-ID <[email protected]>
Sounds like a byte order issue

> On Mar 26, 2020, at 11:11 PM, Andrew Randrianasulu <[email protected]> wrote:
> 
> 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
> 
> 
> 
> 
> _______________________________________________
> png-mng-implement mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/png-mng-implement


_______________________________________________
png-mng-implement mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/png-mng-implement