From efb8fb17036ed99b7d40bbc5c7c6442147bc1249 Mon Sep 17 00:00:00 2001 From: marcsello Date: Tue, 3 Nov 2020 19:45:17 +0100 Subject: [PATCH] Implemented CIFF parser --- CMakeLists.txt | 2 +- src/ciff_tools.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ciff_tools.h | 29 +++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/ciff_tools.c create mode 100644 src/ciff_tools.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f89a820..97931c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(caff_previewer C) set(CMAKE_C_STANDARD 11) -add_executable(caff_previewer src/main.c src/magic_memory.c src/magic_memory.h src/libtarga.c src/libtarga.h) \ No newline at end of file +add_executable(caff_previewer src/main.c src/magic_memory.c src/magic_memory.h src/ciff_tools.h src/ciff_tools.c src/libtarga.c src/libtarga.h) \ No newline at end of file diff --git a/src/ciff_tools.c b/src/ciff_tools.c new file mode 100644 index 0000000..8a83539 --- /dev/null +++ b/src/ciff_tools.c @@ -0,0 +1,83 @@ +// +// Created by marcsello on 03/11/2020. +// + +#include "ciff_tools.h" +#include "stdbool.h" + +uint8_t contains(const uint8_t* data, uint64_t data_len, uint8_t what) { + for (uint64_t i = 0; i < data_len; i++) { + if (data[i] == what) { + return true; + } + } + return false; +} + + +uint8_t parse_ciff_from_mem(const uint8_t* data, uint64_t data_len, uint64_t* width, uint64_t* height, uint64_t* pixel_data_starts) { + /** + * Igazából, ezek többnyire csak változatos ellenőrzések + * A függvény validálja a CIFF fájl tartalmát, majd ha ez sikeres volt, akkor megmondja + * - A kép dimenzióit + * - Hogy hol kezdődik a pixel információ a képben + * Az, hogy a kép információt kimásolja-e, az a programozóra van bízva. + */ + + // Read out the static part of the header (If we have at least header bytes) + if (data_len < sizeof(ciff_static_header_t)) { + return CIFF_PARSE_HEADER_TOO_SHORT; + } + ciff_static_header_t* header_info = (struct ciff_static_header_t*)data; + + // Do some preflight checks + // Check if the magic is valid... + if (header_info->magic != 0x43494646) { + return CIFF_PARSE_HEADER_BAD_MAGIC; + } + + // Check if the fields in the header seems valid (none of the size fields larger than the whole file) + if ((header_info->header_size > data_len) || (header_info->content_size > data_len)) { + return CIFF_PARSE_HEADER_LENGTHS_INCORRECT; + } + + if ((header_info->header_size+header_info->content_size) > data_len) { + return CIFF_PARSE_HEADER_LENGTHS_INCORRECT; + } + + // Pre-Calculate some variables and check against those as well + uint64_t calculated_pixeldata_length_by_header = header_info->width * header_info->height * 3; + if (data_len < calculated_pixeldata_length_by_header) { + // The number of pixels defined in the header is larger than the while file + return CIFF_PARSE_HEADER_DIMENSIONS_INCORRECT; + } + + if (calculated_pixeldata_length_by_header != header_info->content_size) { + return CIFF_PARSE_HEADER_DIMENSIONS_INCORRECT; + } + + uint64_t calculated_total_length_by_header = calculated_pixeldata_length_by_header + header_info->header_size; + if (calculated_total_length_by_header != data_len) { + // The header + pixel data is not equals the length of the file + return CIFF_PARSE_HEADER_LENGTHS_INCORRECT; + } + + // Do some other checks to validate the header + + // According the specifications, the header must contain a newline character after the static fields + if (!contains(data+sizeof(struct ciff_static_header_t),header_info->header_size,'\n')) { + return CIFF_PARSE_UNKNOWN_ERROR; + } + + // According to specifications, the last byte of the header must be a \0 + if (data[header_info->header_size-1] != 0) { + return CIFF_PARSE_UNKNOWN_ERROR; + } + + // Set return data + *width = header_info->width; + *height = header_info->height; + *pixel_data_starts = header_info->header_size; + return CIFF_PARSE_SUCCESS; + +} \ No newline at end of file diff --git a/src/ciff_tools.h b/src/ciff_tools.h new file mode 100644 index 0000000..d00e109 --- /dev/null +++ b/src/ciff_tools.h @@ -0,0 +1,29 @@ +// +// Created by marcsello on 03/11/2020. +// + +#ifndef CAFF_PREVIEWER_CIFF_TOOLS_H +#define CAFF_PREVIEWER_CIFF_TOOLS_H + +#include +#include "magic_memory.h" + +#define CIFF_PARSE_UNKNOWN_ERROR 1 +#define CIFF_PARSE_HEADER_LENGTHS_INCORRECT 2 +#define CIFF_PARSE_HEADER_DIMENSIONS_INCORRECT 3 +#define CIFF_PARSE_HEADER_TOO_SHORT 4 +#define CIFF_PARSE_HEADER_BAD_MAGIC 5 +#define CIFF_PARSE_SUCCESS 0 + +typedef struct __attribute__ ((packed)) ciff_static_header_t { + uint32_t magic; // should be equal to 0x43494646 + uint64_t header_size; + uint64_t content_size; + uint64_t width; + uint64_t height; +} ciff_static_header_t; + + +uint8_t parse_ciff_from_mem(const uint8_t* data, uint64_t data_len, uint64_t* width, uint64_t* height, uint64_t* pixel_data_starts); + +#endif //CAFF_PREVIEWER_CIFF_TOOLS_H