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
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
.