From 3f73faf04bb5a64b4b03b27186748807d8ce6590 Mon Sep 17 00:00:00 2001 From: Pedro Portela Date: Thu, 5 Jun 2025 21:21:23 +0200 Subject: [PATCH] Partial implementation of read_chunk function --- img_png.c | 74 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/img_png.c b/img_png.c index 5c50c11..ac0f1de 100644 --- a/img_png.c +++ b/img_png.c @@ -14,16 +14,51 @@ uint32_t char_to_uint32 (unsigned char* input) { return val; } -uint8_t* img_png_decode(FILE *fp) { - unsigned char buffer[BUFSIZE]; - unsigned char magic[8]; - enum chunk_state { - LENGTH, - TYPE, - DATA, - CRC - }; +int read_chunk(FILE *fp) { + struct img_png_chunk cur_chunk; + + // Read chunk length + unsigned char len[4]; + if(fread(len, sizeof(*len), 4, fp) < 4) { + fprintf(stderr, "Couldn\'t read chunk length.\n"); + exit(EXIT_FAILURE); + } + + cur_chunk.length = char_to_uint32(len); + printf("Chunk length: %lu\n", (unsigned long) cur_chunk.length); + // Read chunk type + if(fread(cur_chunk.chunk_type, sizeof(*cur_chunk.chunk_type), 4, fp) < 4) { + fprintf(stderr, "Couldn\'t read chunk type.\n"); + exit(EXIT_FAILURE); + } + printf("Chunk type: %.*s\n", 4, cur_chunk.chunk_type); + + // Read chunk data + size_t chunk_size = cur_chunk.length / sizeof(unsigned char); + printf("Chunk size: %zu\n", chunk_size); + cur_chunk.chunk_data = malloc(chunk_size); + + if(!cur_chunk.chunk_data) { + perror("Failed to allocate chunk data!"); + exit(EXIT_FAILURE); + } + + if(fread(cur_chunk.chunk_data, 1, cur_chunk.length, fp) != cur_chunk.length) { + if(feof(fp)) { + fprintf(stderr, "File ended prematurely.\n"); + exit(EXIT_FAILURE); + } + fprintf(stderr, "Failed to read chunk data!\n"); + exit(EXIT_FAILURE); + } + + return feof(fp); +} + +uint8_t* img_png_decode(FILE *fp) { + unsigned char magic[8]; + // Check PNG Magic if(fread(magic, sizeof(*magic), 8, fp) < 8) { fprintf(stderr, "Couldn\'t read PNG magic."); @@ -38,24 +73,12 @@ uint8_t* img_png_decode(FILE *fp) { 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); - } - } - } + // Read chunk + + while (read_chunk(fp) == 0); + if(!feof(fp)) { perror("fread() failed!"); exit(EXIT_FAILURE); @@ -64,4 +87,3 @@ uint8_t* img_png_decode(FILE *fp) { return NULL; } -