PNG与IDAT调色板基础,具有BTYPE = 00为没有COM pression,现在用的Adler32 code [英] A palette base PNG with IDAT that has BTYPE=00 for no compression, now with Adler32 code

查看:437
本文介绍了PNG与IDAT调色板基础,具有BTYPE = 00为没有COM pression,现在用的Adler32 code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一些code,它构建简单的基于调色板的PNG文件,而无需的libpng。输出文件,在此阶段仅有IHDR,PLTE,IDAT(×3)和IEND块。这可能是在IDAT块的像素指标值有点唯一不同的是没有COM pressed,那就是各种的zlib /块头字节如下:


  • CMF = 0x78。

  • FLG =为0x9c(这里也有一些其他的值,但始终与第5位清零)。

  • 块头字节= 0×01(BFINAL = 1,BTYPE = 00)。

从我可以看到code建立正确的文件,但有些图像浏览器拒绝完全显示图像,如果在所有。


  • MS Paint是幸福的。

  • GIMP是幸福的。

  • LibreOffice的抽奖是幸福的。

  • 短萃取浓缩咖啡>>致命错误读取PNG图像文件:没有足够的COM pressed数据

  • ImageMagick的识别>>:没有足够的图像数据`20160317_PNG_064.png'@错误/ png.c / MagickPNGErrorHandler / 1645

  • 侏儒之眼>>不够的图像数据。

我与混合的结果把文件通过一些不同的工具,再一次。


  • 使用OptiPNG >>不够的图像数据。

  • pngchunks没有报告任何错误。

  • pngcheck没有报告任何错误。

下面是该文件的十六进制查看20160317_PNG_064.png

它生成的图片是这个小的8x8像素的图片

所以我是有点穷途末路的,以什么来尝试下。任何及所有援助AP preciated。

EDIT_000
已经缩小的问题向的Adler32计算在这里,通过@马克阿德勒中,code,我使用来计算,在主函数测试数据的Adler32值的要求。顺便说一句,这是不花哨,我code非常详细。

 的#include<&stdio.h中GT;将#define DEBUG静态常量无符号长GC_ADLER32_BASE = 0xFFF1; //最大素比65536越小65521。无符号长Adler32_Update
        (
        无符号长的Adler32,
        无符号字符*缓冲区,
        unsigned int类型BufferLength中
        )
{
    无符号长ulW0;
    无符号长ulW1;
    无符号整型uiW0;
#IFDEF DEBUG
    的printf(\\ n);
    的printf(传入的Adler32值.................为0x%.8X \\ N的Adler32);
#万一
    ulW0 =的Adler32和放大器; 0xFFFF的;
    ulW1 =(的Adler32>> 0×0010)及0xFFFF的;
#IFDEF DEBUG
    的printf(Inital总和值..................为0x%.8X,为0x%.8X \\ n,ulW0,ulW1);
#万一
    对于(uiW0 = 0×0000; uiW0< BufferLength中,uiW0 = uiW0 + 0×0001)
        {
        ulW0 =(ulW0 +缓冲区[uiW0])%GC_ADLER32_BASE;
        ulW1 =(ulW1 + ulW0)%GC_ADLER32_BASE;
        }
#IFDEF DEBUG
    的printf(最后的总和值...................了0x%.8X,为0x%.8X \\ n,ulW0,ulW1);
#万一
    的Adler32 =(ulW1<< 0×0010)| ulW0;
#IFDEF DEBUG
    的printf(传出的Adler32值.................为0x%.8X \\ N的Adler32);
#万一
    返回(的Adler32);
}
无符号长Adler32_Get
        (
        无符号字符*缓冲区,
        unsigned int类型BufferLength中
        )
{
    unsigned long类型的Adler32;    的Adler32 = 0x00000001L;
    的Adler32 = Adler32_Update(的Adler32,缓冲,BufferLength中);
    返回(的Adler32);
}
INT主要
    (
    unsigned int类型ARGC,
    无符号字符* ARG []
    )
{
    unsigned long类型的Adler32;
    unsigned char型数据[272] =
        {
    为0x00,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×01,0×01,0×01,0×01,0×01,0×01,0×01,
    为0x01,0x00时,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×01,0×01,0×01,0×01,0×01,0×01,
    0×01,0×01,0×00,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×01,0×01,0×01,0×01,0×01,
    0×01,0×01,0×01,0×00,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×01,0×01,0×01,0×01,
    0×01,0×01,0×01,0×01,0×00,0×02,0×02,0×02,0×02,0×01,0×01,0×01,0×01,0×00,0×00,0×00,
    0×00,0×00,0×00,0×00,0×00,0×00,0×02,0×02,0×02,0×02,0×01,0×01,0×01,0×01,0×00,0×00,
    0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×02,0×02,0×02,0×02,0×01,0×01,0×01,0×01,0×00,
    0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×02,0×02,0×02,0×02,0×01,0×01,0×01,0×01,
    0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×00,0×01,0×01,0×01,0×01,0×02,0×02,0×02,
    0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×00,0×01,0×01,0×01,0×01,0×02,0×02,
    0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×00,0×01,0×01,0×01,0×01,0×02,
    0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×00,0×01,0×01,0×01,0×01,
    0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0×00,0×01,0×01,0×01,
    0×01,0×00,0×00,0×00,0×00,0×01,0×01,0×01,0×01,0×02,0×02,0×02,0×02,0×00,0×01,0×01,
    0×01,0×01,0×00,0×00,0×00,0×00,0×01,0×01,0×01,0×01,0×02,0×02,0×02,0×02,0×00,0×01,
    0×01,0×01,0×01,0×00,0×00,0×00,0×00,0×01,0×01,0×01,0×01,0×02,0×02,0×02,0×02,0×00,
    0×01,0×01,0×01,0×01,0×00,0×00,0×00,0×00,0×01,0×01,0×01,0×01,0X02,0X02,0X02,0X02
        };
    的Adler32 = Adler32_Get(数据,sizeof的(数据));
    的printf(\\ n);
    的printf(本的Adler32值是..........................为0x%.8X \\ N的Adler32);
    回报(0×00);
}


解决方案

无论是计算的Adler-32值不正确。对于数据的正确Adler-32值是 0x10080061 ,应存储在流中的 10 08 00 61 。如果我修复链接文件,并进行了新的CRC为大块,然后一切都很好。

固定的形象是:

固定

I am working on some code that builds simple palette based PNG files without libpng. The output file, at this stage only has IHDR, PLTE, IDAT(x3) and IEND chunks. The only thing which is possibly a bit different in that the pixel index values in the IDAT chunk are not compressed, that is the various zlib / block header bytes are as follows.

  • CMF = 0x78.
  • FLG = 0x9C (have also a few other values here but always with bit 5 clear).
  • Block header byte = 0x01 (BFINAL = 1, BTYPE = 00).

From what I can see the code builds the file correctly, however some image viewers refuse to display the image completely, if at all.

  • MS Paint is happy.
  • GIMP is happy.
  • LibreOffice Draw is happy.
  • Ristretto >> Fatal error reading PNG image file: Not enough compressed data.
  • ImageMagick >> identify: Not enough image data `20160317_PNG_064.png' @ error/png.c/MagickPNGErrorHandler/1645.
  • Eye of Gnome >> not enough image data.

I have put the file through a few different tools, again with mixed results.

  • optipng >> not enough image data.
  • pngchunks does not report any errors.
  • pngcheck does not report any errors.

Here is the hex view of the file 20160317_PNG_064.png

The picture it does generate is this small 8x8 pixel image.

So I am at a bit of a dead end as to what to try next. Any and all assistance is appreciated.

EDIT_000 Having narrowed down the issue to the Adler32 calculation here is, as requested by @Mark Adler, the code that I am using to calculate the Adler32 value with test data in the main function. Btw, it is not fancy and I code very verbose.

#include <stdio.h>

#define     DEBUG

static const unsigned long GC_ADLER32_BASE = 0xFFF1;   // Largest prime smaller than 65536 is 65521.

unsigned long Adler32_Update
        (
        unsigned long Adler32,
        unsigned char *Buffer,
        unsigned int BufferLength
        )
{
    unsigned long   ulW0;
    unsigned long   ulW1;
    unsigned int    uiW0;
#ifdef DEBUG
    printf("\n");
    printf("        Incoming Adler32 value.................0x%.8X\n", Adler32);
#endif
    ulW0 = Adler32 & 0xFFFF;
    ulW1 = (Adler32 >> 0x0010) & 0xFFFF;
#ifdef DEBUG
    printf("        Inital sum values are..................0x%.8X, 0x%.8X\n", ulW0, ulW1);
#endif
    for (uiW0 = 0x0000; uiW0 < BufferLength; uiW0 = uiW0 + 0x0001)
        {
        ulW0 = (ulW0 + Buffer[uiW0]) % GC_ADLER32_BASE;
        ulW1 = (ulW1 + ulW0) % GC_ADLER32_BASE;
        }
#ifdef DEBUG
    printf("        Final sum values are...................0x%.8X, 0x%.8X\n", ulW0, ulW1);
#endif
    Adler32 = (ulW1 << 0x0010) | ulW0;
#ifdef DEBUG
    printf("        Outgoing Adler32 value.................0x%.8X\n", Adler32);
#endif
    return (Adler32);
}


unsigned long Adler32_Get
        (
        unsigned char *Buffer,
        unsigned int BufferLength
        )
{
    unsigned long   Adler32;

    Adler32 = 0x00000001L;
    Adler32 = Adler32_Update(Adler32, Buffer, BufferLength);
    return (Adler32);
}


int main
    (
    unsigned int    argc,
    unsigned char   *arg[]
    )
{
    unsigned long   Adler32;
    unsigned char data[272] = 
        {
    0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
    0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 
    0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 
    0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 
    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 
    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 
    0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02
        };
    Adler32 = Adler32_Get(data, sizeof(data));
    printf("\n");
    printf("The Adler32 value is ..........................0x%.8X\n", Adler32);
    return(0x00);
}

解决方案

Whatever is calculating the Adler-32 value is incorrect. The correct Adler-32 value for the data is 0x10080061, which should be stored in the stream as 10 08 00 61. If I fix that in the linked file, and make a new CRC for that chunk, then all is good.

The fixed image is:

这篇关于PNG与IDAT调色板基础,具有BTYPE = 00为没有COM pression,现在用的Adler32 code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆