diff options
| -rw-r--r-- | include/tinyff/image/png.h | 38 | ||||
| -rw-r--r-- | include/tinyff/result.h | 3 | ||||
| -rw-r--r-- | src/format/image/png.c | 81 |
3 files changed, 44 insertions, 78 deletions
diff --git a/include/tinyff/image/png.h b/include/tinyff/image/png.h index 85ed179..b2f400f 100644 --- a/include/tinyff/image/png.h +++ b/include/tinyff/image/png.h @@ -28,31 +28,35 @@ typedef struct { } ff_png_ctx; - -typedef enum { - FF_PNG_CHUNK_TYPE_IHDR, - FF_PNG_CHUNK_TYPE_PLTE, - FF_PNG_CHUNK_TYPE_IDAT, - FF_PNG_CHUNK_TYPE_IEND, - - // There are more, - // but these ones will be - // enough for now - - FF_PNG_CHUNK_TYPE_UNKNOWN, -} ff_png_chunk_type; - - typedef struct { uint32_t length; - ff_png_chunk_type type; + const char *type; uint32_t *data; // length bytes (maximum is uint32_t) uint32_t crc; } ff_png_chunk; +// Chunk handling + +typedef (*ff_png_chunk_handler_ptr)(uint8_t *data, size_t len, ff_png_ctx* ctx); + +typedef struct { + const char *type; + ff_png_chunk_handler_ptr handler; +} ff_png_chunk_handler; + +const ff_png_chunk_handler ff_png_chunk_handlers[] = { + {"IHDR", NULL}, + {"IDAT", NULL}, + {"IEND", NULL}, + + + {NULL, NULL} // Terminator +}; + +void ff_png_header_handler(uint8_t *data, size_t len, ff_png_ctx* ctx); + ff_result ff_png_isvalid(FILE *file); ff_result ff_open_png(const char *filepath, ff_png_ctx **out_ctx); -ff_result ff_next_chunk(FILE *file, ff_png_chunk **out_chunk); #endif diff --git a/include/tinyff/result.h b/include/tinyff/result.h index 27b1ce4..9b17d4a 100644 --- a/include/tinyff/result.h +++ b/include/tinyff/result.h @@ -9,6 +9,9 @@ typedef enum { FF_RESULT_ERROR_INVALID_FILE, FF_RESULT_ERROR_READ_FILE_FAILURE, + // Memory + FF_RESULT_ERROR_MEMORY_ALLOCATION, + // More will be created when more errors occur } ff_result; diff --git a/src/format/image/png.c b/src/format/image/png.c index 9c7664f..1170af2 100644 --- a/src/format/image/png.c +++ b/src/format/image/png.c @@ -1,6 +1,8 @@ #include "tinyff/image/png.h" #include "png.h" + + ff_result ff_png_isvalid(FILE *file) { char raw_sig[8]; @@ -31,67 +33,24 @@ ff_result ff_open_png(const char *filepath, ff_png_ctx **out_ctx) { return ff_png_isvalid(ctx.raw); } - // TODO: Parse + // This is a heavy W.I.P + } -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 - uint32_t chunk_type_raw = get_big_endian(type_buffer); - - ff_png_chunk_type chunk_type; - - if (memcmp(chunk_type_raw, "IHDR", 4)) chunk_type = FF_PNG_CHUNK_TYPE_IHDR; - else if (memcmp(chunk_type_raw, "IDAT", 4)) chunk_type = FF_PNG_CHUNK_TYPE_IDAT; - else if (memcmp(chunk_type_raw, "IEND", 4)) chunk_type = FF_PNG_CHUNK_TYPE_IEND; - else if (memcmp(chunk_type_raw, "PLTE", 4)) chunk_type = FF_PNG_CHUNK_TYPE_PLTE; - else chunk_type = FF_PNG_CHUNK_TYPE_UNKNOWN; - - // 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; +void ff_png_header_handler(uint8_t *data, size_t len, ff_png_ctx *ctx) +{ + if (len != 13) return; // Invalid length + printf("Width: %d\n", get_big_endian(data)); + printf("Height: %d\n", get_big_endian(data + 4)); + printf("Bit depth: %d\n", (unsigned char)data[8]); + printf("Color type: %d\n", (unsigned char)data[9]); + printf("Compression method: %d\n", (unsigned char)data[10]); + printf("Filter method: %d\n", (unsigned char)data[11]); + printf("Interlace method: %d\n", (unsigned char)data[12]); + + // Store in context + ctx->width = get_big_endian(data); + ctx->height = get_big_endian(data + 4); + ctx->bit_depth = (unsigned char)data[8]; + ctx->color_type = (unsigned char)data[9]; }
\ No newline at end of file |
