我正在尝试为一个类创建一个方法,该方法仅读取PNG文件直到IHDR Image header 的末尾(不包含其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将char格式化为int格式),但我仍在寻找一种C++解决方案。

谢谢

最佳答案

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

请参见同一引用中的“7.1整数和字节顺序”:



然后是说明它的图表。

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

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

关于c++ - C++ PNG header 误读IHDR数据块的长度,宽度和高度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22411996/

10-15 00:39