summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tinyff/common.h17
-rw-r--r--include/tinyff/image/png.h5
-rw-r--r--src/common.c8
-rw-r--r--src/format/image/png.c59
4 files changed, 85 insertions, 4 deletions
diff --git a/include/tinyff/common.h b/include/tinyff/common.h
new file mode 100644
index 0000000..d53adae
--- /dev/null
+++ b/include/tinyff/common.h
@@ -0,0 +1,17 @@
+// Common header for tinyff library
+// Not recommended to be included directly
+#ifndef TINYFF_COMMON_H
+#define TINYFF_COMMON_H
+
+#include <stdint.h>
+
+// Human readable number types
+// NOTE: The only reason I created these was so
+// that debugging will be easier
+typedef uint8_t ff_byte;
+
+// Functions
+
+static inline uint32_t get_big_endian(const uint8_t *buffer);
+
+#endif \ No newline at end of file
diff --git a/include/tinyff/image/png.h b/include/tinyff/image/png.h
index 78b92e4..95ab94f 100644
--- a/include/tinyff/image/png.h
+++ b/include/tinyff/image/png.h
@@ -5,9 +5,10 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
+#include <stdlib.h>
#include "tinyff/result.h"
-
+#include "tinyff/common.h"
static const unsigned char PNG_SIGNATURE[8] = {
@@ -50,6 +51,6 @@ typedef struct {
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/src/common.c b/src/common.c
new file mode 100644
index 0000000..9dea3e4
--- /dev/null
+++ b/src/common.c
@@ -0,0 +1,8 @@
+#include "tinyff/common.h"
+
+static inline uint32_t get_big_endian(const uint8_t *buffer) {
+ return (uint32_t)(buffer[0] << 24) |
+ (uint32_t)(buffer[1] << 16) |
+ (uint32_t)(buffer[2] << 8) |
+ (uint32_t)(buffer[3]);
+} \ No newline at end of file
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