Width and height of the PNG header

I am experimenting with reading the width and height of a PNG file. This is my code:

struct TImageSize { int width; int height; }; bool getPngSize(const char *fileName, TImageSize &is) { std::ifstream file(fileName, std::ios_base::binary | std::ios_base::in); if (!file.is_open() || !file) { file.close(); return false; } // Skip PNG file signature file.seekg(9, std::ios_base::cur); // First chunk: IHDR image header // Skip Chunk Length file.seekg(4, std::ios_base::cur); // Skip Chunk Type file.seekg(4, std::ios_base::cur); __int32 width, height; file.read((char*)&width, 4); file.read((char*)&height, 4); std::cout << file.tellg(); is.width = width; is.height = height; file.close(); return true; } 

If I try to read, for example, this image from Wikipedia , I get these incorrect values:

252097920 (should be 800)
139985408 (should be 600)

Note that the function does not return false, so the contents of the variable width and height must come from the file.

+4
source share
2 answers

It looks like you are off byte:

 // Skip PNG file signature file.seekg(9, std::ios_base::cur); 

The PNG Specification says the header is 8 bytes long, so you want instead of "9" instead of "8". Line items start at 0.

Also note that the specification says that integers are in a network (big-endian) order , so you may need or need to use ntohl () or otherwise convert byte order if you are on a little-endian system.

It might be worth using libpng or stb_image or something similar, rather than trying to analyze png yourself, if you don't, to find out.

+8
source

When you look at "Portable Network Graphics," he says the signature is 8 bytes, not 9.

Also, are you sure your system has the same byte order as the PNG standard? ntohl (3) will provide the correct byte order. It is also available for windows.

+3
source

All Articles