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