From e943a6867f0e37f5eb68e9911a1971f747ed7531 Mon Sep 17 00:00:00 2001 From: TazyFoundSoup Date: Fri, 19 Dec 2025 17:20:02 +1100 Subject: feat(png): add ff_next_chunk function --- src/format/image/png.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src/format/image') diff --git a/src/format/image/png.c b/src/format/image/png.c index 6adfe86..266f4f6 100644 --- a/src/format/image/png.c +++ b/src/format/image/png.c @@ -5,13 +5,13 @@ ff_result ff_png_isvalid(FILE *file) { char raw_sig[8]; if (fread(raw_sig, sizeof(char), 8, file) != 8) { - // Inable to read first 8 bytes + // Unable to read first 8 bytes fclose(file); return FF_RESULT_ERROR_INVALID_FILE; } if (memcmp(raw_sig, PNG_SIGNATURE, 8) != 0) { - // Signiture did not match + // Signature did not match fclose(file); return FF_RESULT_ERROR_INVALID_FILE_SIGNITURE; } @@ -34,4 +34,59 @@ ff_result ff_open_png(const char *filepath, ff_png_ctx **out_ctx) { } // TODO: Parse +} + +ff_result ff_next_chunk(FILE *file, ff_png_chunk **out_chunk) { + // 1. Read length (4 bytes): We have to read the first 4 bytes to know how many bytes to read for data + uint32_t length_buffer; + + if (fread(&length_buffer, sizeof(sizeof(ff_byte) * 4), 1, file) != 1) { + return FF_RESULT_ERROR_READ_FILE_FAILURE; + } + + // Get the big endian value of the length buffer + uint32_t data_chunk_length = get_big_endian(length_buffer); + + // 2. Read type (ditto) + // (we are really just doing the same as before and we don't have to move any positions cause + // thank god, FILE can already do that, *ascends*) + uint32_t type_buffer; + + if (fread(&type_buffer, sizeof(sizeof(ff_byte) * 4), 1, file) != 1) { + return FF_RESULT_ERROR_READ_FILE_FAILURE; + } + + // Get the big endian value of the type buffer + // It needs to be mapped to the enum though + uint32_t chunk_type = get_big_endian(type_buffer); + + // 3. Read data (data_chunk_length bytes) + uint32_t *data_buffer = (uint32_t)malloc(data_chunk_length * sizeof(ff_byte)); + + if (fread(data_buffer, sizeof(ff_byte), data_chunk_length, file) != data_chunk_length) { + free(data_buffer); + return FF_RESULT_ERROR_READ_FILE_FAILURE; + } + + // 4. Read CRC (4 bytes) + // However, I don't think we need to use the data right now + // so we can just read and store it + uint32_t crc_buffer; + + if (fread(&crc_buffer, sizeof(sizeof(ff_byte) * 4), 1, file) != 1) { + free(data_buffer); + return FF_RESULT_ERROR_READ_FILE_FAILURE; + } + + uint16_t crc = get_big_endian(crc_buffer); + + // 5. Create a chunk struct and return it + ff_png_chunk *out = (ff_png_chunk *)malloc(sizeof(ff_png_chunk)); + out->length = data_chunk_length; + out->type = chunk_type; + out->data = data_buffer; + out->crc = crc; + *out_chunk = out; + + return FF_RESULT_OK; } \ No newline at end of file -- cgit v1.2.3