diff options
| author | TazyFoundSoup <gardendistrict0x0@outlook.com> | 2026-01-15 20:28:07 +1100 |
|---|---|---|
| committer | TazyFoundSoup <gardendistrict0x0@outlook.com> | 2026-01-15 20:28:07 +1100 |
| commit | 165d2bd7dde7ab55eced4556e8b1b9128276aa7b (patch) | |
| tree | 24d0b3f4264b6627066aa82195f5fdb257682006 | |
| parent | d0fc19a97c7f115dca25f2b39b6a9fbe337b31a3 (diff) | |
feat(png): Refactor PNG handling to use stream interface
| -rw-r--r-- | include/tinyff/image/png.h | 29 | ||||
| -rw-r--r-- | include/tinyff/result.h | 4 | ||||
| -rw-r--r-- | src/format/image/png.c | 38 |
3 files changed, 42 insertions, 29 deletions
diff --git a/include/tinyff/image/png.h b/include/tinyff/image/png.h index c9f3378..8858fd7 100644 --- a/include/tinyff/image/png.h +++ b/include/tinyff/image/png.h @@ -9,6 +9,7 @@ #include "tinyff/result.h" #include "tinyff/common.h" +#include "tinyff/stream.h" static const unsigned char PNG_SIGNATURE[8] = { @@ -22,8 +23,8 @@ typedef enum { } ff_png_mode; typedef struct { - // Raw file handle - FILE *raw; + // Raw stream handle + ff_stream *raw; // Image dimensions uint32_t width; @@ -69,6 +70,16 @@ typedef struct { ff_png_chunk_handler_ptr handler; } ff_png_chunk_handler; +// Handler declarations +// Massive W.I.P + +// Required by definition +ff_result ff_png_header_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IHDR +ff_result ff_png_palette_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // PLTE +ff_result ff_png_data_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IDAT +ff_result ff_png_end_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IEND + + const ff_png_chunk_handler ff_png_chunk_handlers[] = { {"IHDR", ff_png_header_handler}, {"IDAT", ff_png_data_handler}, @@ -81,20 +92,10 @@ const ff_png_chunk_handler ff_png_chunk_handlers[] = { {NULL, NULL} // Terminator }; -// Handler declarations -// Massive W.I.P - -// Required by definition -ff_result ff_png_header_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IHDR -ff_result ff_png_palette_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // PLTE -ff_result ff_png_data_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IDAT -ff_result ff_png_end_handler(uint8_t *buf, size_t len, ff_png_ctx* ctx); // IEND -// PLTE is a funny one -// Its only required for indexed color types -ff_result ff_png_isvalid(FILE *file); -ff_result ff_open_png(const char *filepath, ff_png_ctx **out_ctx); +ff_result ff_png_isvalid(ff_stream *stream); +ff_result ff_open_png(ff_stream *stream, ff_png_ctx **out_ctx); #endif diff --git a/include/tinyff/result.h b/include/tinyff/result.h index daea32e..49919ed 100644 --- a/include/tinyff/result.h +++ b/include/tinyff/result.h @@ -12,10 +12,12 @@ typedef enum { // -- ERRORS -- // File - FF_RESULT_ERROR_INVALID_FILE_SIGNITURE, FF_RESULT_ERROR_INVALID_FILE, FF_RESULT_ERROR_READ_FILE_FAILURE, + // Media specific + FF_RESULT_ERROR_INVALID_PNG_SIGNITURE, // PNG + // Memory FF_RESULT_ERROR_MEMORY_ALLOCATION, diff --git a/src/format/image/png.c b/src/format/image/png.c index 11f4093..7de02d7 100644 --- a/src/format/image/png.c +++ b/src/format/image/png.c @@ -2,12 +2,12 @@ #include "tinyff/dbg.h" #include "png.h" -ff_result ff_png_isvalid(FILE *file) +ff_result ff_png_isvalid(ff_stream *stream) { ff_dprintf("png: validating signature\n"); char raw_sig[8]; - if (fread(raw_sig, 1, 8, file) != 8) { + if (stream->read(raw_sig, 8, stream->user) != 8) { ff_dprintf("png: failed to read signature bytes\n"); return FF_RESULT_ERROR_INVALID_FILE; } @@ -20,37 +20,47 @@ ff_result ff_png_isvalid(FILE *file) if (memcmp(raw_sig, PNG_SIGNATURE, 8) != 0) { ff_dprintf("png: signature mismatch\n"); - return FF_RESULT_ERROR_INVALID_FILE_SIGNITURE; + return FF_RESULT_ERROR_INVALID_PNG_SIGNITURE; } ff_dprintf("png: signature valid\n"); return FF_RESULT_OK; } -ff_result ff_open_png(const char *filepath, ff_png_ctx **out_ctx) +ff_result ff_open_png(ff_stream *stream, ff_png_ctx **out_ctx) { - ff_dprintf("png: opening file '%s'\n", filepath); - ff_png_ctx ctx; - ctx.raw = fopen(filepath, "rb"); + ff_png_ctx *ctx = malloc(sizeof(ff_png_ctx)); + if (!ctx) return FF_RESULT_ERROR_MEMORY_ALLOCATION; - if (!ctx.raw) { - ff_dprintf("png: fopen failed\n"); + // Init + memset(ctx, 0, sizeof(*ctx)); + ctx->image_mode = FF_PNG_MODE_NONE; + ctx->raw = stream; + ctx->last_error = FF_RESULT_OK; + + + if (ctx->raw->read == NULL) { + ff_dprintf("png: stream failed to read\n"); + free(ctx); + ctx->last_error = FF_RESULT_ERROR_READ_FILE_FAILURE; return FF_RESULT_ERROR_READ_FILE_FAILURE; } - ff_dprintf("png: file opened successfully\n"); + ff_dprintf("png: stream read successfully\n"); - ff_result res = ff_png_isvalid(ctx.raw); + ff_result res = ff_png_isvalid(ctx->raw); if (res != FF_RESULT_OK) { ff_dprintf("png: validation failed (%d)\n", res); - fclose(ctx.raw); + free(ctx); + ctx->last_error = res; return res; } ff_dprintf("png: validation passed\n"); + ctx->valid = true; - *out_ctx = NULL; + *out_ctx = ctx; ff_dprintf("png: open_png reached WIP end\n"); return FF_RESULT_OK; @@ -88,7 +98,7 @@ ff_result ff_png_header_handler(uint8_t *buf, size_t len, ff_png_ctx *ctx) return FF_RESULT_OK; } -ff_result ff_png_chunk_palette_handler(uint8_t *buf, size_t len, ff_png_ctx *ctx) +ff_result ff_png_palette_handler(uint8_t *buf, size_t len, ff_png_ctx *ctx) { ff_dprintf("png: PLTE chunk received (len=%zu)\n", len); |
