diff --git a/caff.c b/caff.c index fdbcc84..463dea2 100644 --- a/caff.c +++ b/caff.c @@ -1,128 +1,146 @@ #include "caff.h" -#include -void print_credits(CAFF_Credits* credits){ - printf("Creator:%s\n",credits->creator); - printf("Date:%d.%d.%d %d:%d\n",credits->year,credits->month,credits->day,credits->hour,credits->minute); +void print_credits(CAFF_Credits *credits) +{ + printf("Creator:%s\n", credits->creator); + printf("Date:%d.%d.%d %d:%d\n", credits->year, credits->month, credits->day, credits->hour, credits->minute); } - -void caff_init_animation_list(CAFF_Animation_List *a) { - a->array = NULL; - a->length = 0; - a->size = 0; +void caff_init_animation_list(CAFF_Animation_List *a) +{ + a->array = NULL; + a->length = 0; + a->size = 0; } -void caff_add_animation_list(CAFF_Animation_List *a, CAFF_Animation element) { - if (a->length == a->size) { - a->size =(a->size == 0) ? 1 : a->size*2; - CAFF_Animation* new_array = realloc(a->array, a->size * sizeof(CAFF_Animation)); - if(!new_array){ - printf("Failed to allocate memory!\n"); - exit(EXIT_FAILURE); +void caff_add_animation_list(CAFF_Animation_List *a, CAFF_Animation element) +{ + if (a->length == a->size) + { + a->size = (a->size == 0) ? 1 : a->size * 2; + CAFF_Animation *new_array = realloc(a->array, a->size * sizeof(CAFF_Animation)); + if (!new_array) + { + printf("Failed to allocate memory!\n"); + exit(EXIT_FAILURE); + } + a->array = new_array; } - a->array = new_array; - } - a->array[a->length++] = element; + a->array[a->length++] = element; } -void caff_free_animtion_list(CAFF_Animation_List *a) { - free(a->array); - a->array = NULL; - a->length = a->size = 0; +void caff_free_animtion_list(CAFF_Animation_List *a) +{ + free(a->array); + a->array = NULL; + a->length = a->size = 0; } -CAFF* caff_parse_file(const char* filename) { - FILE* file = fopen(filename, "rb"); - if (!file) { +CAFF *caff_parse_file(const char *filename) +{ + FILE *file = fopen(filename, "rb"); + if (!file) + { printf("Failed to open CAFF file: %s\n", filename); return NULL; } - CAFF* caff = malloc(sizeof(CAFF)); - if(!caff){ + CAFF *caff = malloc(sizeof(CAFF)); + if (!caff) + { printf("Failed to allocate memory for CAFF!\n"); return NULL; } + caff->bytes_read = 0; caff->credits = NULL; caff->header = NULL; caff_init_animation_list(&caff->animations); - + size_t anim_count = 0; - while (!feof(file)) { + while (!feof(file)) + { uint8_t id; uint64_t length; - fread(&id, 1, 1, file); - fread(&length, 8, 1, file); + fread(&id, sizeof(uint8_t), 1, file); + fread(&length, sizeof(uint64_t), 1, file); - switch (id) { - case 0x1: - // Do not replace the header after it is initialized - if(!caff->header) + switch (id) + { + case 0x1: + // Do not replace the header after it is initialized + if (!caff->header) caff->header = read_header(file); - break; - case 0x2: - // Do not replace the credits after it is initialized - if(!caff->credits) + break; + case 0x2: + // Do not replace the credits after it is initialized + if (!caff->credits) caff->credits = read_credits(file); - print_credits(caff->credits ); - break; - case 0x3: - anim_count++; - if(caff->header && caff->header->num_anim == anim_count){ - goto end; - } - // You might want to append to a list of animations here. - CAFF_Animation* anim = read_animation(file); - - caff_add_animation_list(&caff->animations,*anim); - free(anim); - // We only need the first image now... - goto end; - break; - default: - // Random bytes should not cause an error - printf("Unknown block ID: %u\n", id); - goto end; + print_credits(caff->credits); + break; + case 0x3: + anim_count++; + if (caff->header && caff->header->num_anim == anim_count) + { + fclose(file); + return caff; + } + // You might want to append to a list of animations here. + CAFF_Animation *anim = read_animation(file); + + caff_add_animation_list(&caff->animations, *anim); + free(anim); + // We only need the first image now... + fclose(file); + return caff; + default: + // Random bytes should not cause an error + printf("Unknown block ID: %u\n", id); + fclose(file); + return caff; } } -end: - + fclose(file); printf("Parse END!\n"); return caff; } -CAFF_Header* read_header(FILE* file) { - CAFF_Header* header = malloc(sizeof(CAFF_Header)); - if (!header) { +CAFF_Header *read_header(FILE *file) +{ + CAFF_Header *header = malloc(sizeof(CAFF_Header)); + if (!header) + { printf("Failed to allocate memory for CAFF header\n"); return NULL; } // Read the magic string. - if (fread(header->magic, 1, 4, file) != 4) { + if (fread(header->magic, sizeof(char), 4, file) != 4) + { printf("Failed to read magic string from CAFF header\n"); free(header); return NULL; } // Check the magic string. - if (strncmp(header->magic, "CAFF", 4) != 0) { + if (strncmp(header->magic, "CAFF", 4) != 0) + { printf("Invalid magic string in CAFF header\n"); free(header); return NULL; } // Read the header size. - if (fread(&header->header_size, 8, 1, file) != 1) { + if (fread(&header->header_size, sizeof(uint64_t), 1, file) != 1) + { printf("Failed to read header size from CAFF header\n"); free(header); return NULL; } // Read the number of animations. - if (fread(&header->num_anim, 8, 1, file) != 1) { + if (fread(&header->num_anim, sizeof(uint64_t), 1, file) != 1) + { printf("Failed to read number of animations from CAFF header\n"); free(header); return NULL; @@ -131,27 +149,30 @@ CAFF_Header* read_header(FILE* file) { return header; } - -CAFF_Credits* read_credits(FILE* file) { - CAFF_Credits* credits = malloc(sizeof(CAFF_Credits)); - if (!credits) { +CAFF_Credits *read_credits(FILE *file) +{ + CAFF_Credits *credits = malloc(sizeof(CAFF_Credits)); + if (!credits) + { printf("Failed to allocate memory for CAFF credits\n"); return NULL; } // Read the creation date and time. - if (fread(&credits->year, 2, 1, file) != 1 || - fread(&credits->month, 1, 1, file) != 1 || - fread(&credits->day, 1, 1, file) != 1 || - fread(&credits->hour, 1, 1, file) != 1 || - fread(&credits->minute, 1, 1, file) != 1) { + if (fread(&credits->year, sizeof(uint16_t), 1, file) != 1 || + fread(&credits->month, sizeof(uint8_t), 1, file) != 1 || + fread(&credits->day, sizeof(uint8_t), 1, file) != 1 || + fread(&credits->hour, sizeof(uint8_t), 1, file) != 1 || + fread(&credits->minute, sizeof(uint8_t), 1, file) != 1) + { printf("Failed to read creation date and time from CAFF credits\n"); free(credits); return NULL; } // Read the length of the creator field. - if (fread(&credits->creator_len, 8, 1, file) != 1) { + if (fread(&credits->creator_len, sizeof(uint64_t), 1, file) != 1) + { printf("Failed to read length of creator field from CAFF credits\n"); free(credits); return NULL; @@ -159,14 +180,16 @@ CAFF_Credits* read_credits(FILE* file) { // Allocate memory for the creator field. credits->creator = malloc(credits->creator_len + 1); - if (!credits->creator) { + if (!credits->creator) + { printf("Failed to allocate memory for creator field in CAFF credits\n"); free(credits); return NULL; } // Read the creator field. - if (fread(credits->creator, 1, credits->creator_len, file) != credits->creator_len) { + if (fread(credits->creator, 1, credits->creator_len, file) != credits->creator_len) + { printf("Failed to read creator field from CAFF credits\n"); free(credits->creator); free(credits); @@ -179,16 +202,18 @@ CAFF_Credits* read_credits(FILE* file) { return credits; } - -CAFF_Animation* read_animation(FILE* file) { - CAFF_Animation* animation = malloc(sizeof(CAFF_Animation)); - if (!animation) { +CAFF_Animation *read_animation(FILE *file) +{ + CAFF_Animation *animation = malloc(sizeof(CAFF_Animation)); + if (!animation) + { printf("Failed to allocate memory for CAFF animation\n"); return NULL; } // Read the duration. - if (fread(&animation->duration, 8, 1, file) != 1) { + if (fread(&animation->duration, sizeof(uint64_t), 1, file) != 1) + { printf("Failed to read duration from CAFF animation\n"); free(animation); return NULL; @@ -196,7 +221,8 @@ CAFF_Animation* read_animation(FILE* file) { // Read the CIFF image. animation->ciff = read_ciff(file); - if (!animation->ciff) { + if (!animation->ciff) + { printf("Failed to read CIFF image from CAFF animation\n"); free(animation); return NULL; @@ -205,21 +231,23 @@ CAFF_Animation* read_animation(FILE* file) { return animation; } - -void caff_free(CAFF* caff) { +void caff_free(CAFF *caff) +{ // Free the header free(caff->header); caff->header = NULL; // Free the credits - if (caff->credits->creator) { + if (caff->credits->creator) + { free(caff->credits->creator); } free(caff->credits); caff->credits = NULL; - + // Free the animations - for (size_t i = 0; i < caff->animations.length; i++) { + for (size_t i = 0; i < caff->animations.length; i++) + { free_ciff(caff->animations.array[i].ciff); } caff_free_animtion_list(&caff->animations); diff --git a/caff.h b/caff.h index 0e1bc08..2d9ec2f 100644 --- a/caff.h +++ b/caff.h @@ -36,6 +36,7 @@ typedef struct { CAFF_Header* header; // The CAFF header CAFF_Credits* credits; // The CAFF credits CAFF_Animation_List animations; // The CAFF animations + uint64_t bytes_read; } CAFF; CAFF* caff_parse_file(const char* filename); CAFF_Header* read_header(FILE* file); diff --git a/ciff.c b/ciff.c index caf033c..b904d4a 100644 --- a/ciff.c +++ b/ciff.c @@ -4,30 +4,38 @@ #include #include +CIFF *read_ciff(FILE *file) +{ -CIFF* read_ciff(FILE* file) { - - if (!file) { + if (!file) + { printf("Failed to open file!\n"); return NULL; } - CIFF* ciff = malloc(sizeof(CIFF)); - if (!ciff) { + CIFF *ciff = malloc(sizeof(CIFF)); + if (!ciff) + { printf("Failed to allocate memory for CIFF structure\n"); fclose(file); return NULL; } // Read the header - fread(ciff->magic, 4, 1, file); - fread(&ciff->header_size, 8, 1, file); - fread(&ciff->content_size, 8, 1, file); - fread(&ciff->width, 8, 1, file); - fread(&ciff->height, 8, 1, file); - + fread(ciff->magic, sizeof(uint32_t), 1, file); + fread(&ciff->header_size, sizeof(uint64_t), 1, file); + fread(&ciff->content_size, sizeof(uint64_t), 1, file); + fread(&ciff->width, sizeof(uint64_t), 1, file); + fread(&ciff->height, sizeof(uint64_t), 1, file); + if (ciff->width * ciff->height*3 < ciff->content_size) + { + printf("w:%ld h:%ld s:%ld",ciff->width,ciff->height,ciff->content_size); + printf("Invalid CIFF size!\n"); + ciff->content_size = ciff->width * ciff->height*3; + } // Ensure the file is actually a CIFF file - if (strncmp(ciff->magic, "CIFF", 4) != 0) { + if (strncmp(ciff->magic, "CIFF", 4) != 0) + { printf("File is not a CIFF file\n"); free(ciff); fclose(file); @@ -36,7 +44,8 @@ CIFF* read_ciff(FILE* file) { // Read the caption ciff->caption = malloc(ciff->header_size); // overestimate the size - if (!ciff->caption) { + if (!ciff->caption) + { printf("Failed to allocate memory for caption\n"); free(ciff); fclose(file); @@ -45,34 +54,38 @@ CIFF* read_ciff(FILE* file) { char c; size_t i = 0; - do { - fread(&c, 1, 1, file); + do + { + fread(&c, sizeof(char), 1, file); ciff->caption[i++] = c; } while (c != '\n'); ciff->caption[i] = '\0'; // null-terminate the string - size_t caption_lenth= i; + size_t caption_lenth = i; // Read the tags - size_t tags_size = ciff->header_size-sizeof(char)*4-sizeof(uint64_t)*4-caption_lenth; // Size for the rest of the header - ciff->tags = malloc(tags_size*sizeof(char)); - if (!ciff->tags) { + size_t tags_size = ciff->header_size - sizeof(char) * 4 - sizeof(uint64_t) * 4 - caption_lenth; // Size for the rest of the header + ciff->tags = malloc(tags_size * sizeof(char)); + if (!ciff->tags) + { printf("Failed to allocate memory for tags\n"); free(ciff->caption); free(ciff); fclose(file); return NULL; } - - if(fread(ciff->tags, tags_size, 1, file) != 1) { + + if (fread(ciff->tags, tags_size, sizeof(uint8_t), file) != 1) + { printf("Failed to read tags!\n"); free(ciff->caption); free(ciff); fclose(file); return NULL; } - + // Read the pixels ciff->pixels = malloc(ciff->content_size); - if (!ciff->pixels) { + if (!ciff->pixels) + { printf("Failed to allocate memory for pixel data\n"); free(ciff->caption); free(ciff); @@ -81,16 +94,17 @@ CIFF* read_ciff(FILE* file) { } fread(ciff->pixels, ciff->content_size, 1, file); - return ciff; } -void generate_jpg(CIFF* ciff, const char* out_filename) { +void generate_jpg(CIFF *ciff, const char *out_filename) +{ struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; - FILE* outfile = fopen(out_filename, "wb"); - if (!outfile) { + FILE *outfile = fopen(out_filename, "wb"); + if (!outfile) + { printf("Failed to open output file: %s\n", out_filename); return; } @@ -102,7 +116,7 @@ void generate_jpg(CIFF* ciff, const char* out_filename) { cinfo.image_width = ciff->width; cinfo.image_height = ciff->height; - cinfo.input_components = 3; // number of color components per pixel + cinfo.input_components = 3; // number of color components per pixel cinfo.in_color_space = JCS_RGB; // color space of input image jpeg_set_defaults(&cinfo); @@ -110,7 +124,8 @@ void generate_jpg(CIFF* ciff, const char* out_filename) { jpeg_start_compress(&cinfo, TRUE); JSAMPROW row_pointer[1]; - while (cinfo.next_scanline < cinfo.image_height) { + while (cinfo.next_scanline < cinfo.image_height) + { row_pointer[0] = &ciff->pixels[cinfo.next_scanline * ciff->width * 3]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } @@ -122,9 +137,8 @@ void generate_jpg(CIFF* ciff, const char* out_filename) { jpeg_destroy_compress(&cinfo); } - - -void free_ciff(CIFF* ciff) { +void free_ciff(CIFF *ciff) +{ free(ciff->caption); free(ciff->pixels); free(ciff->tags); diff --git a/main.c b/main.c index f2fdca7..bcc6f9f 100644 --- a/main.c +++ b/main.c @@ -50,7 +50,6 @@ int main(int argc, char **argv) } else { - free_ciff(ciff); } return 0;