Report bugs of libpng-1.6.37, about function png_image_write_to_file()
失散糖 <sugar013-Mj/[email protected]> Fri, 21 Feb 2020 18:46:05 +0800 (CST)
| Newsgroups | gmane.comp.graphics.png.devel |
|---|---|
| Message-ID | <[email protected]> |
hello:
I test a image with format PNG_FORMAT_LINEAR_RGB_ALPHA, and find 2 bugs.
Bug 1: The function png_image_write_to_file() has param row_stride, whick can be zero, positive or negative, and a negative stride indicates that the bottom-most row is first in the buffer. But when I test a negative stride, "Segmentation fault (core dumped)".
Bug 2: libpng is completely lossless compression, but I write a test image with function png_image_write_to_file(), and read back it with function png_image_begin_read_from_file() and png_image_finish_read(), image changes.
test.cc:
#include <stdint.h>
#include <stdlib.h>
#include "png.h"
int main()
{
const int X_WIDTH = 3;
const int Y_HEIGHT = 2;
const int Z_CHANNELS = 4;
png_image w_image = { 0 };
w_image.version = PNG_IMAGE_VERSION;
w_image.width = X_WIDTH;
w_image.height = Y_HEIGHT;
w_image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
const char *tm_filename = "tm.png";
uint16_t w_buffer[Y_HEIGHT][X_WIDTH][Z_CHANNELS] =
{
{
{ 0x5FFF, 0x6000, 0x6001, 0xFFFB },
{ 0x9FFF, 0xA000, 0xA001, 0xFFFB },
{ 0xDFFF, 0xE000, 0xE001, 0xFFFB },
},
{
{ 0xAFFF, 0xB000, 0xB001, 0xFFFC },
{ 0xBFFF, 0xC000, 0xC001, 0xFFFD },
{ 0xCFFF, 0xD000, 0xD001, 0xFFFE },
},
};
// A positive stride indicates that the top-most row is first in the buffer
int w_result = png_image_write_to_file (
&w_image, tm_filename, 0, w_buffer, X_WIDTH * Z_CHANNELS, NULL);
if (w_result == 0)
{
printf ("write top-most fail!\n");
exit (-1);
}
printf ("write top-most ok\n");
png_image r_image = { 0 };
r_image.version = PNG_IMAGE_VERSION;
int r_result = png_image_begin_read_from_file (
&r_image, tm_filename);
r_image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
uint16_t r_buffer[Y_HEIGHT][X_WIDTH][Z_CHANNELS] = { 0 };
r_result = png_image_finish_read (
&r_image, 0, r_buffer, X_WIDTH * Z_CHANNELS, 0);
if (r_result == 0)
{
printf ("read top-most fail!\n");
exit (-1);
}
printf ("read top-most ok\n");
printf ("compare:\n"); // test bug 1
for (int y = 0; y < Y_HEIGHT; ++y)
{
for (int x = 0; x < X_WIDTH; ++x)
{
for (int z = 0; z < Z_CHANNELS; ++z)
{
char same = ' ';
if (r_buffer[y][x][z] != w_buffer[y][x][z])
{
same = '!';
}
printf ("0x%04X%c ", r_buffer[y][x][z], same);
}
printf ("\n");
}
printf ("\n");
}
// A negative stride indicates that the bottom-most row is first in the buffer
const char *bm_filename = "bm.png";
w_result = png_image_write_to_file (
&w_image, bm_filename, 0, w_buffer, -X_WIDTH * Z_CHANNELS, NULL); // test bug 2
if (w_result == 0)
{
printf ("write bottom-most fail!\n");
exit (-1);
}
printf ("write bottom-most ok\n");
return 0;
}
// end of file
output:
write top-most ok
read top-most ok
compare:
0x5FFE! 0x6000 0x6001 0xFFFB
0x9FFE! 0xA000 0xA001 0xFFFB
0xDFFE! 0xE000 0xE001 0xFFFB
0xB000! 0xB001! 0xB002! 0xFFFC
0xBFFE! 0xC000 0xC001 0xFFFD
0xD000! 0xD001! 0xD002! 0xFFFE
Segmentation fault (core dumped)
I fount from manual, "It is important to note that when an image with an alpha channel is scaled, linear encoded, pre-multiplied component values must be used!"
So, the function png_image_write_to_file() will divide red, green, blue channels by alpha channels, and the function png_image_finish_read()will multiply this channels by alpha channels, and the compression will be not lossless.
Is there any flag for struct png_image , whicn let function png_image_write_to_file()and png_image_finish_read()not to scale component values?
_______________________________________________
png-mng-implement mailing list
png-mng-implement-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/png-mng-implement