Search code examples
cpngzlibdeflate

C - zlib - png crc32/deflate


I'm doing an homework to read a png file through zlib in C and I always have checksum not equal to png crc. How I shoul take from zlib? I've been on it for 5 hours and I'm going crazy.
Thank you for any help/suggestions!

if (ng_utils_open_file("dinosauro_quadrato.png", &png_content))
    goto quit;

char* png_signature = "\x89PNG\r\n\x1a\n";
size_t signature_length = SDL_strlen(png_signature);

char* png_file_signature = (char*)SDL_malloc(signature_length + 1);
SDL_strlcpy(png_file_signature, png_content, signature_length + 1);

if (SDL_strcmp(png_signature, png_file_signature) == 0)
{
    SDL_Log("PNG signature valid");
    Uint32 offset = 8;
    
    Uint32 chunk_length;
    SDL_memcpy(&chunk_length, png_content + offset, 4);
    chunk_length = ng_utils_big_to_little_endian(chunk_length);
    SDL_Log("Chunk Length: (%d) %d", offset, chunk_length);
    offset += 4;

    char chunk_type[5];
    SDL_strlcpy(chunk_type, png_content + offset, 5);
    SDL_Log("Chunk Type: (%d) %s", offset, chunk_type);
    offset += 4;

    char* chunk_data = (char*)SDL_malloc(chunk_length + 1);
    SDL_strlcpy(chunk_data, png_content + offset, chunk_length + 1);
    SDL_Log("Chunk Data: (%d) %s", offset, chunk_data);
    offset += chunk_length;

    Uint32 crc = crc32(0, (unsigned char*)chunk_type, 4);
    Uint32 checksum = crc32(crc, (unsigned char*)chunk_data, 4);

    Uint32 chunk_crc;
    SDL_memcpy(&chunk_crc, png_content + offset, 4);
    chunk_crc = ng_utils_big_to_little_endian(chunk_crc);
    SDL_Log("Chunk Crc: (%d) %d", offset, chunk_crc);
    offset += 4;

    //unsigned int crc2 = crc32(0, (unsigned char*)"Hello World", 11);
    //printf("crc32 is %u\n", crc2);

    if (chunk_crc != checksum)
    {
        SDL_Log("%d != %d", chunk_crc, checksum);
        goto quit;
    }

}
else
{
    SDL_Log("PNG signature invalid");
}

Solution

  • You're only computing the CRC of the type and the first four bytes of the data. You want Uint32 checksum = crc32(crc, (unsigned char*)chunk_data, chunk_length);.