我正在研究一些不使用libpng构建基于调色板的简单PNG文件的代码。输出文件,在此阶段只有IHDR,PLTE,IDAT(x3)和IEND块。唯一可能有点不同的是IDAT块中的像素索引值没有被压缩,即各种zlib /块头字节如下。
从我可以看到的代码正确构建文件,但是一些图像查看器拒绝完全显示图像,如果有的话。
我已将文件放在几个不同的工具中,同样结果不一。
以下是hex view of the file 20160317_PNG_064.png
它生成的图片是small 8x8 pixel image。
所以接下来要尝试什么,我有点死路一条。任何和所有的帮助表示赞赏。
EDIT_000 根据@Mark Adler的要求,将问题缩小到Adler32计算是我用来在主函数中用测试数据计算Adler32值的代码。顺便说一句,这不是很花哨,而且编码非常详细。
#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);
}