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

时间:2014-03-14 17:33:47

标签: c++ png

我正在尝试为一个只读取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的内容),但如果可能的话,我正在寻找一个C ++解决方案。

谢谢

1 个答案:

答案 0 :(得分:3)

您的计算机或编译器使用反向顺序存储多字节值。

参见同一参考文献中的“7.1整数和字节顺序”:

  

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

后面是一个说明它的图表。

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

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