PNG块读取器,长度无效

时间:2012-05-13 14:47:16

标签: c++ png corrupt

我目前正在编写自己的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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

您需要声明长度unsigned char,因此字节值上的符号扩展&gt; = 128不是 byte 。你最后得到的是0xffffffa1,你还是负值。