I have a need to find the dimensions of images online without downloading them. To accomplish this I do this:
+ (CGSize) getImageDimensions:(NSString *)url {
According to the PNG specification:
The first eight bytes of a PNG file always contain the following (decimal) values: 137 80 78 71 13 10 26 10
So you have to read those to make sure you really have a PNG file.
Then,
The IHDR chunk must appear FIRST. It contains:
Width: 4 bytes
Height: 4 bytes
etc...
So according to the structure of chunks, you first have to read the four bytes representing the length of the chunk's data field, then the four bytes representing the chunk's name, then the two 32-bit integers representing width and height, eight bytes in total.
So, the exact minimal number of bytes you must read in order to determine width and height is 8 + 4 + 4 + 8 = 24 bytes.
Once you have your NSData object, you simply have to access the bytes that it contains:
unsigned char buffer[24];
[data getBytes:buffer length:24];
Optionally, but I recommend it strongly, check that you indeed have a PNG file:
unsigned char png_header[] = {137, 80, 78, 71, 13, 10, 26, 10};
if (memcmp(buffer, png_header, 8)) {
// this is not a PNG !
}
Make sure you have an IHDR:
unsigned char ihdr_name[] = "IHDR";
if (memcmp(buffer+8+4, ihdr_name, 4)) {
// not an IHDR chunk, invalid PNG file
}
Width and height can be accessed as big-endian encoded unsigned ints at offset 24 minus 8 and minus 4 bytes respectively:
unsigned int width = OSReadBigInt32(buffer + 24 - 8);
unsigned int height = OSReadBigInt32(buffer + 24 - 4);
Edit: Fixed buffer reading code: PNG actually stores integers in big-endian.