2
votes

I'm attempting to mimic the function used for creating CRC's in PNG files, I'm using the autodin II polynomial and the source code from:
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c

My tests have all been for the IHDR chunk, so my parameters have been:
crc - 0xffffffff and 0 (both have been suggested)
buff - the address of the IHDR Chunk's type.
length - the IHDR Chunk's length + 4 (the length of the chunk's data + the length of the type)

I printed the calculated CRC in binary, which I compared to the actual CRC of the chunk. I can see no similarities (little-big endian, reversed bits, XOR'd, etc).

This is the data for the IHDR chunk (hexadecimal format):
length(big endian): d0 00 00 00 (13)
type: 49 48 44 52
data: 00 00 01 77 00 00 01 68 08 06 00 00 00
existing CRC: b0 bb 40 ac

If anyone can tell me why my calculations are off, or give me a CRC32 function that will work I would greatly appreciate it. Thank-you!

1
I can't see 13 bytes of data. Anyway, you need to include the type ID ('IHDR') in your CRC32 calculation, that is, you need to pass a buffer of 17 bytes to the crc32 function.Jigsore
@Jigsore, I corrected the data, thanks. I misinterpreted my output.Alter

1 Answers

2
votes

The CRC-32 algorithm used in PNG images is described here: http://www.w3.org/TR/PNG-Structure.html#CRC-algorithm (there's also a link to C code for doing test calculations).

But as @Jigsore pointed out, you won't get sensible results from the data you posted here. You've given us a 4-byte type identifier and what looks like 7.5 bytes of data to follow it. There should be a total of 13 bytes according to the length header.

EDIT: This works using the function from w3.org:

int main() {
    char input[] = { 0x49,0x48,0x44,0x52,0x00,0x00,0x01,0x77,0x00,
                     0x00,0x01,0x68,0x08,0x06,0x00,0x00,0x00 };
    printf("%08lx\n",crc(input,17));
    return 0;
}

Output: ac40bbb0