首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个带有IDAT的调色板基PNG,它没有压缩BTYPE=00,现在使用Adler32代码。

一个带有IDAT的调色板基PNG,它没有压缩BTYPE=00,现在使用Adler32代码。
EN

Stack Overflow用户
提问于 2016-03-17 20:10:17
回答 2查看 562关注 0票数 1

我正在编写一些代码,这些代码不需要libpng就可以构建基于简单调色板的PNG文件。在这个阶段,输出文件只有IHDR、PLTE、IDAT(x3)和IEND块。唯一可能有所不同的地方是IDAT块中的像素索引值没有被压缩,即各种zlib /块头字节如下所示。

  • CMF = 0x78。
  • FLG = 0x9C (这里还有一些其他值,但始终是位5清除的)。
  • 块头字节= 0x01 (BFINAL = 1,BTYPE = 00)。

根据我所看到的,代码正确地构建了文件,但是一些图像查看器拒绝完全显示图像,如果有的话。

  • 佩奇女士很高兴。
  • 瘸子很开心。
  • LibreOffice抽签是快乐的。
  • Ristretto >>读取PNG图像文件时发生致命错误:压缩数据不足。
  • ImageMagick >>标识:没有足够的图像数据`20160317_PNG_064.png‘@ error/png.c/MagickPNGErrorHandler/1645。
  • Gnome眼>>图像数据不足。

我已经通过了几个不同的工具文件,也有不同的结果。

  • >>图像数据不足。
  • pngchunks不报告任何错误。
  • pngcheck不报告任何错误。

这是064.png

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

因此,对于接下来该尝试什么,我处于一个死胡同。如有任何及所有的协助,我们将不胜感激。

按照@Mark的请求,EDIT_000将问题缩小到了Adler32计算,这是我用来计算主函数中的测试数据的Adler32值的代码。顺便说一句,这不是很花哨,我的代码非常详细。

代码语言:javascript
复制
#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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-18 05:20:13

计算Adler-32值的任何内容都是不正确的。数据的正确Adler-32值是0x10080061,它应该以10 08 00 61的形式存储在流中。如果我在链接文件中修复它,并为该块创建一个新的CRC,那么一切都是好的。

固定图像是:

票数 3
EN

Stack Overflow用户

发布于 2016-03-17 20:40:30

作为PNG规范的合著者,我相信这个文件是完全符合的.PNG规范将“泄气”的定义推迟到1951年,并且RFC显式地允许BTYPE=0节。您可能希望与那些有问题的程序的作者联系,并报告一个错误,并将您的文件附加为示例输入。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36070759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档