Implemented CIFF parser
This commit is contained in:
parent
f1188602fd
commit
efb8fb1703
@ -3,4 +3,4 @@ project(caff_previewer C)
|
|||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
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)
|
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)
|
83
src/ciff_tools.c
Normal file
83
src/ciff_tools.c
Normal file
@ -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;
|
||||||
|
|
||||||
|
}
|
29
src/ciff_tools.h
Normal file
29
src/ciff_tools.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Created by marcsello on 03/11/2020.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CAFF_PREVIEWER_CIFF_TOOLS_H
|
||||||
|
#define CAFF_PREVIEWER_CIFF_TOOLS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#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
|
Loading…
Reference in New Issue
Block a user