C语言 Libpng库-索引图像阅读超出范围索引

eqfvzcg8  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(130)

我一直在尝试使用Libpng库来创建基于PNG的软件。当我探索这个库时,似乎当我读入某些调色板图像时,然后检查我生成的2D数组,看看是否有任何索引超出范围--实际上很多都超出了范围。我也不知道为什么。
我试过chatgpt,但它没有特别的帮助。
尽管如此,它确实为我生成了这个调试代码,供我作为测试人员使用。我将提供代码和下面的文件。但首先,这里是生成的阅读/写代码。output_pixel_values函数读取每个调色板条目的值。

void read_and_write_png(const char* input_filename, const char* output_filename) {
    FILE* input_file = fopen(input_filename, "rb");
    if(!input_file) {
        printf("Can't open file %s for reading\n", input_filename);
        return;
    }

    // Initialize the reading structures.
    png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop read_info_ptr = png_create_info_struct(read_ptr);
    png_init_io(read_ptr, input_file);
    png_read_info(read_ptr, read_info_ptr);

    png_uint_32 height = png_get_image_height(read_ptr, read_info_ptr);
    png_bytepp row_pointers = (png_bytepp)malloc(sizeof(png_bytep) * height);

    for (png_uint_32 i = 0; i < height; i++) {
        row_pointers[i] = (png_bytep)malloc(png_get_rowbytes(read_ptr, read_info_ptr));
    }

    png_read_image(read_ptr, row_pointers);

    // Now that we've read the image, let's write it to another file.
    FILE* output_file = fopen(output_filename, "wb");
    if(!output_file) {
        printf("Can't open file %s for writing\n", output_filename);
        return;
    }

    // Initialize the writing structures.
    png_structp write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop write_info_ptr = png_create_info_struct(write_ptr);

    // Set up the output.
    png_init_io(write_ptr, output_file);

    // Copy the image data from the read structures to the write structures.
    png_set_IHDR(write_ptr, write_info_ptr, png_get_image_width(read_ptr, read_info_ptr),
                 png_get_image_height(read_ptr, read_info_ptr), png_get_bit_depth(read_ptr, read_info_ptr),
                 png_get_color_type(read_ptr, read_info_ptr), png_get_interlace_type(read_ptr, read_info_ptr),
                 png_get_compression_type(read_ptr, read_info_ptr), png_get_filter_type(read_ptr, read_info_ptr));

    png_colorp palette;
    int num_palette;

    if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) {
        png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
    }

    png_bytep trans_alpha = NULL;
    int num_trans = 0;
    png_color_16p trans_color = NULL;

    if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, &trans_color)) {
        png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, trans_color);
    }

    printf("Reading image now. . \n");
    sleep(5);
    output_pixel_values(read_ptr, read_info_ptr, row_pointers);
    printf("Done!!");
    
    // Set up the data in the write structure.
    png_set_rows(write_ptr, write_info_ptr, row_pointers);

    // Finally, write the image to the file.
    png_write_png(write_ptr, write_info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    // Clean up.
    fclose(input_file);
    fclose(output_file);

    png_destroy_read_struct(&read_ptr, &read_info_ptr, NULL);
    png_destroy_write_struct(&write_ptr, &write_info_ptr);

    // Free the memory associated with row_pointers
    for (png_uint_32 i = 0; i < height; i++) {
        free(row_pointers[i]);
    }
    free(row_pointers);
}

个字符
我不希望收到以下内容:

  • 索引= 96(319,96)处的像素:调色板索引超出范围 *

请让我知道,如果你能看到任何立即错误。这里是一个链接到我用过的测试仪的图像。
https://imgur.com/a/FKSNAih

yc0p9oo0

yc0p9oo01#

我试过chatgpt,但它没有特别的帮助。
尽管如此,它确实为我生成了这个调试代码,供我作为测试人员使用。
人工智能没有足够的智能来解释除了8位/像素调色板数据之外的其他数据。您可以将int index = row[x];更改为

int index, ppb = 8/bit_depth;    // pixels per byte
            switch (bit_depth)
            {
            default: printf("bit depth %d not implemented\n", bit_depth); exit(1);
            case 1:
            case 2:
            case 4:
            case 8: index = row[x/ppb]>>8-(x%ppb+1)*bit_depth&255>>8-bit_depth;
            }

字符串
或者使用png_set_packing()

相关问题