首页 文章

C PNG标头读取IHDR数据块长度,宽度和高度

提问于
浏览
1

我正在尝试为一个类创建一个方法,只需读取PNG文件直到IHDR Image头的末尾(没有CRC32块 . 麻烦来自每个“多个字节”整数(即IHDR数据块长度,宽度和高度) . 这是我的代码:

#include <iostream>
#include <fstream>
using namespace std;

typedef struct PNG_HEADER pngHeader;
struct PNG_HEADER{
    unsigned char PNGSignature[8];
    size_t nb;
    unsigned char ImageHeader[4];
    size_t width;
    size_t height;
    unsigned char bitDepth;
    unsigned char colorType;
    unsigned char compressionMethod;
    unsigned char filterMethod;
    unsigned char interlaceMethod;
};

class testPNG{

public:

    bool readPNGHeader(string filename){
        pngHeader PNGheader;

        ifstream file(filename.data(), std::ios_base::binary);

        if(!file.is_open())
            return false;

        if( !file.read((char *)&PNGheader, sizeof(PNGheader)))
            return false;


        for(int i = 0; i < 8; i++)
                printf("%d ", PNGheader.PNGSignature[i]);

        printf("\n");
        printf("%d\n", PNGheader.nb);

        for(int i = 0; i < 4; i++)
                printf("%d ", PNGheader.ImageHeader[i]);

        printf("\n");
        printf("%d\n", PNGheader.width );
        printf("%d\n", PNGheader.height );
        printf("%d\n", PNGheader.bitDepth );
        printf("%d\n", PNGheader.colorType );
        printf("%d\n", PNGheader.compressionMethod );
        printf("%d\n", PNGheader.filterMethod );
        printf("%d\n", PNGheader.interlaceMethod );

        return true;
    }
};


int main(void)
{
    testPNG test;
    test.readPNGHeader("test.png");

    return 0;
}

打印结果是这样的(评论显然没有显示在控制台上):

137 80 78 71 13 10 26 10 //[PNG Signature OK!][1]
218103808                //this should read 13 as the length is the sum of the number of byte needed for each data field contained in the IHDR Data chunk that follows the IHDR Image Header chunk.
73 72 68 82              //[IHDR Image Header chunk OK!][2]
1879244800               //fail to give the correct width
973078528                //fail to give the correct height
8                        // OK!
6                        // OK!
0                        // OK!
0                        // OK!
0                        // OK!

因为它写在w3c网站上; (数据块的)长度值存储在"A four-byte unsigned integer"中 . 图像的the width and height也是如此 . 所以我尝试了unsigned int和unsigned short,但似乎没什么用 .

即使我使用printfs(我不知道如何将字符格式化为cout的int),我正在寻找一个C解决方案,如果可能的话 .

谢谢

1 回答

  • 3

    您的机器或编译器使用反向顺序来存储多字节值 .

    请参阅相同参考中的“7.1整数和字节顺序”:

    所有需要多个字节的整数应按网络字节顺序排列...

    然后是一个说明它的图表 .

    要获得正确的字节数值,请使用其中一个预定义函数(其中我永远无法回想起哪个函数;请阅读How do you write (portably) reverse network byte order?)或编写自己的函数来反转它们 .

    以十六进制打印时,样本值 218103808 显示 0xD000000 ;反转字节会产生正确的预期结果 0xD13 .

相关问题