Search code examples
c++pngcorrupt

PNG chunk reader, invalid length


I am currently working on writing my own png reader, I was working on the reading of the individual chunks and it seems to read the first 2 chunks correctly but when it comes to the IDAT chunk it comes up with a ridiculous size.

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;
}

Using the debugger it reads the first 2 chunks as

Type : IDHR
Length : 13 Bytes

Type : sRGB
Length : 1 Byte

Type : IDAT
Length : 4294967201 Bytes

Thats arround 2.3 gb of data and the png is 462kb. Any ideas why its going wrong ?

Source picture : http://i.cubeupload.com/sCHXFV.png


Solution

  • The problem is with the reversal of byte order and left shifts. The sign of the result of the shift operation is the same as the sign of the value being shifted. So shifting a signed char would behave differently from what you expect.

    To fix, change the type of the length array to unsigned char.