From 7e630e3e68064660ace3653fd34f55066f5d38c2 Mon Sep 17 00:00:00 2001 From: Pedro Portela Date: Thu, 5 Jun 2025 20:40:23 +0200 Subject: [PATCH] Reads chunk length --- img_png.c | 66 +++++++++++++++++++++++++++++++++++++++++++++---------- img_png.h | 7 +++--- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/img_png.c b/img_png.c index a0ee188..5c50c11 100644 --- a/img_png.c +++ b/img_png.c @@ -1,23 +1,67 @@ #include #include #include +#include #include "img_png.h" -uint8_t* img_png_decode(FILE *fp) { - unsigned char buffer[8]; - size_t bufsize = sizeof(buffer) / sizeof((buffer)[0]); - - size_t ret = fread(buffer, sizeof(*buffer), bufsize, fp); +#define BUFSIZE 1024 - if(ret != bufsize) { - fprintf(stderr, "fread() failed. Expected %zu bytes, got %zu\n", bufsize, ret); - return NULL; +const unsigned char img_png_signature[] = {0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n'}; + +uint32_t char_to_uint32 (unsigned char* input) { + uint32_t val = (input[0] << 24) + (input[1] << 16) + (input[2] << 8) + input[3]; + + return val; +} + +uint8_t* img_png_decode(FILE *fp) { + unsigned char buffer[BUFSIZE]; + unsigned char magic[8]; + enum chunk_state { + LENGTH, + TYPE, + DATA, + CRC + }; + + // Check PNG Magic + if(fread(magic, sizeof(*magic), 8, fp) < 8) { + fprintf(stderr, "Couldn\'t read PNG magic."); + exit(EXIT_FAILURE); } - printf("PNG Magic: %#04x%02x%02x%02x%02x%02x%02x%02x\n", buffer[0], buffer[1], buffer[2], - buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); + if(memcmp(magic, img_png_signature, 8) != 0) { + fprintf(stderr, "Invalid PNG magic\n"); + exit(EXIT_FAILURE); + } + + printf("PNG Magic: %#04x%02x%02x%02x%02x%02x%02x%02x\n", magic[0], magic[1], magic[2], + magic[3], magic[4], magic[5], magic[6], magic[7]); + + // After the magic number is read, we should hit the length of the chunk first. + enum chunk_state state = LENGTH; + struct img_png_chunk cur_chunk; + while(fread(buffer, sizeof(*buffer), BUFSIZE, fp) > 0){ + // Refine later!!! + + switch (state) { + case LENGTH: { + unsigned char length[4]; + for (size_t i = 0; i < 4; i++) { + length[i] = buffer[i]; + } + cur_chunk.length = char_to_uint32(length); + printf("Chunk length: %lu\n", (unsigned long)cur_chunk.length); + } + } + } + + if(!feof(fp)) { + perror("fread() failed!"); + exit(EXIT_FAILURE); + } + return NULL; } - diff --git a/img_png.h b/img_png.h index 506ea91..e809744 100644 --- a/img_png.h +++ b/img_png.h @@ -1,13 +1,12 @@ #include #include -//const unsigned char img_png_signature[] = {0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n'}; struct img_png_chunk { - int length; - int chunk_type; + uint32_t length; + char chunk_type[4]; char* chunk_data; - int crc; + uint32_t crc; }; uint8_t* img_png_decode (FILE* fp);