Files
caff-previewer/src/main.c
2020-11-06 04:52:57 +01:00

98 lines
2.7 KiB
C

#include <stdio.h>
#include <stdint.h>
#include "libtarga.h"
#include "magic_memory.h"
#include "pixeldata_utils.h"
#include "ciff_tools.h"
#include "caff_tools.h"
#include "utils.h"
#define LIBTARGA_ERROR_PREFIX 0x40
#define USAGE_ERROR_PREFIX 0x50
#define USAGE_ERROR_WRONG_PARAMETERS (USAGE_ERROR_PREFIX + 0x01)
// Warning: This is defined outside the pixeldata_utils.h (because this event could happen here only)
#define IMAGE_FLIP_COULD_NOT_ALLOCATE (IMAGE_FLIP_ERROR_PREFIX + 0x02)
// Mivel az egyszerűség kedvéért az egész fájlt memóriába olvassuk, jobb ha limitáljuk a méretét
#define CAFF_MAX_SIZE 536870912 // 512MB
uint8_t perform_extraction(mm_ctx context, const char *infile, const char *outfile) {
// Read the entire CAFF data to memory
uint8_t *caff_data;
uint64_t caff_data_len;
uint8_t result = read_file_to_mem(context, infile, CAFF_MAX_SIZE, &caff_data, &caff_data_len);
if (result != FILE_READ_SUCCESS) {
return result;
}
// Seek for the first CIFF
uint8_t *ciff_data;
uint64_t ciff_data_len;
result = parse_caff_get_first_ciff(caff_data, caff_data_len, &ciff_data, &ciff_data_len);
if (result != CAFF_PARSE_SUCCESS) {
return result;
}
// Extract pixel data from the CIFF
uint64_t width;
uint64_t height;
uint8_t *pixel_data;
uint64_t pixel_data_len;
result = parse_ciff_get_pixel_data(ciff_data, ciff_data_len, &pixel_data, &pixel_data_len, &width, &height);
if (result != CIFF_PARSE_SUCCESS) {
return result;
}
// Flip the image as required by libtarga
uint8_t *flipped_pixel_data = (uint8_t *) magic_malloc(context, pixel_data_len);
if (flipped_pixel_data == NULL) {
return IMAGE_FLIP_COULD_NOT_ALLOCATE;
}
result = flip_image(pixel_data, flipped_pixel_data, pixel_data_len, width, height);
if (result != IMAGE_FLIP_SUCCESS) {
return result;
}
// Write out the image to a TGA file
if (!tga_write_raw(outfile, width, height, flipped_pixel_data, TGA_TRUECOLOR_24)) {
return LIBTARGA_ERROR_PREFIX + tga_get_last_error(); // TGA errors range from 1 to 11
}
// And we are done! MagicMemory will take care of cleaning up
return 0;
}
int main(int argc, char *argv[]) {
// Check arguments
if (argc != 3) {
printf("Usage: caff_previewer [SOURCE FILE] [DESTINATION FILE]\n");
return USAGE_ERROR_WRONG_PARAMETERS;
}
// Open a magic memory context
mm_ctx context = magic_memory_begin();
// Run the program
uint8_t result = perform_extraction(context, argv[1], argv[2]);
// Free all memory used automagically
magic_cleanup(context); // In C11 we could have used atexit()
return result;
}