PNG 块读取器,长度无效

PNG chunk reader, invalid length

本文关键字:无效 读取 PNG      更新时间:2023-10-16

我目前正在编写自己的 png 阅读器,我正在阅读各个块,它似乎可以正确读取前 2 个块,但是当涉及到IDAT 块它提出了一个荒谬的大小。

bool LoadImage(char * path, Image * target)
{
std::ifstream file;
file.open("Lenna.png", std::ios::in | std::ios::binary);
if(!file.is_open())
    return -false;
std::cout << "Opened file : Lenna.png" <<  std::endl;
struct stat filestatus;
if (stat("Lenna.png", &filestatus) != 0)
    return false;
unsigned int fileSize = filestatus.st_size;
unsigned int bytesRead = 8;
file.seekg(8, std::ios::beg);
while(bytesRead < fileSize)
{
    //Read the length, type, then the data and at last the crc(Cyclic redundancy crap, whatever that may be)
    char length [4];
    file.read(length, 4);
    //Reverse the 4 bytes due to network type writing.
    unsigned int dataLength = (length[0] << 24) | (length[1] << 16) | (length[2] << 8) | length[3];
    char type [4];
    file.read(type, 4);
    char * data = new char[dataLength];
    file.read(data, dataLength);
    char crc [4];
    file.read(crc, 4);
    bytesRead += 12 + dataLength;
}
return true;
}

使用调试器,它将前 2 个块读取为

类型 : IDHR
长度 : 13 字节

类型 : sRGB
长度 : 1 字节

型号 : IDAT
长度 : 4294967201 字节

这大约是2.3 GB的数据,png是462kb。知道为什么会出错吗?

来源图片:http://i.cubeupload.com/sCHXFV.png

问题在于字节顺序和左移的反转。移位操作结果的符号与正在移位的值的符号相同。因此,移动已签名char的行为将与您预期的不同。

若要修复,请将length数组的类型更改为 unsigned char

>您需要声明长度unsigned char以便对字节值>= 128 进行签名扩展不会字节。这就是你最终得到0xffffffa1,你或负值的方式。