c++ PNG报头误读了IHDR数据块的长度、宽度和高度
C++ PNG header missread IHDR data chunk length, width and height
我试图为一个类创建一个方法,该方法简单地读取PNG文件直到IHDR图像头(没有其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("%dn", PNGheader.nb);
for(int i = 0; i < 4; i++)
printf("%d ", PNGheader.ImageHeader[i]);
printf("n");
printf("%dn", PNGheader.width );
printf("%dn", PNGheader.height );
printf("%dn", PNGheader.bitDepth );
printf("%dn", PNGheader.colorType );
printf("%dn", PNGheader.compressionMethod );
printf("%dn", PNGheader.filterMethod );
printf("%dn", 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网站上写的那样;数据块的长度值存储在"一个四字节的无符号整数"中。图像的宽度和高度也是如此。所以我也尝试了unsigned int和unsigned short,但似乎都不起作用。
即使我使用printfs(我不知道如何用cout将字符格式化为int),如果可能的话,我正在寻找c++解决方案。
谢谢
您的机器或您的编译器使用相反的顺序来存储多字节值。
参见同一参考文献中的"7.1整数和字节顺序":
所有需要一个以上字节的整数必须按网络字节顺序排列…
后面跟着一个说明它的图表。
要获得字节数的正确值,使用预定义的函数之一反转它们(我永远记不起哪个函数做什么;请参阅如何编写(可移植的)反向网络字节顺序?)或自己编写。
您的样例值218103808
显示0xD000000
时,以十六进制印刷;反转字节产生正确的,预期的结果0xD
或13
。
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 从高度动态的C 数据模型中更新QML:计时器与属性绑定
- 对高度冗余的数据使用什么压缩算法
- 通过在CGAL中传递高度、宽度、深度和数据指针来创建Image_3实例
- 转换SRTM数据时为负高度
- c++ PNG报头误读了IHDR数据块的长度、宽度和高度