Changes based on response

Signed-off-by: Balazs Toldi <balazs@toldi.eu>
This commit is contained in:
Balazs Toldi 2023-05-29 20:04:16 +02:00
parent 053ba8d04f
commit 79487c849e
Signed by: Bazsalanszky
GPG key ID: 6C7D440036F99D58
4 changed files with 166 additions and 124 deletions

122
caff.c
View file

@ -1,23 +1,26 @@
#include "caff.h" #include "caff.h"
#include <webp/encode.h>
void print_credits(CAFF_Credits* credits){ void print_credits(CAFF_Credits *credits)
{
printf("Creator:%s\n", credits->creator); printf("Creator:%s\n", credits->creator);
printf("Date:%d.%d.%d %d:%d\n", credits->year, credits->month, credits->day, credits->hour, credits->minute); 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)
void caff_init_animation_list(CAFF_Animation_List *a) { {
a->array = NULL; a->array = NULL;
a->length = 0; a->length = 0;
a->size = 0; a->size = 0;
} }
void caff_add_animation_list(CAFF_Animation_List *a, CAFF_Animation element) { void caff_add_animation_list(CAFF_Animation_List *a, CAFF_Animation element)
if (a->length == a->size) { {
if (a->length == a->size)
{
a->size = (a->size == 0) ? 1 : a->size * 2; a->size = (a->size == 0) ? 1 : a->size * 2;
CAFF_Animation *new_array = realloc(a->array, a->size * sizeof(CAFF_Animation)); CAFF_Animation *new_array = realloc(a->array, a->size * sizeof(CAFF_Animation));
if(!new_array){ if (!new_array)
{
printf("Failed to allocate memory!\n"); printf("Failed to allocate memory!\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -26,36 +29,43 @@ void caff_add_animation_list(CAFF_Animation_List *a, CAFF_Animation element) {
a->array[a->length++] = element; a->array[a->length++] = element;
} }
void caff_free_animtion_list(CAFF_Animation_List *a) { void caff_free_animtion_list(CAFF_Animation_List *a)
{
free(a->array); free(a->array);
a->array = NULL; a->array = NULL;
a->length = a->size = 0; a->length = a->size = 0;
} }
CAFF* caff_parse_file(const char* filename) { CAFF *caff_parse_file(const char *filename)
{
FILE *file = fopen(filename, "rb"); FILE *file = fopen(filename, "rb");
if (!file) { if (!file)
{
printf("Failed to open CAFF file: %s\n", filename); printf("Failed to open CAFF file: %s\n", filename);
return NULL; return NULL;
} }
CAFF *caff = malloc(sizeof(CAFF)); CAFF *caff = malloc(sizeof(CAFF));
if(!caff){ if (!caff)
{
printf("Failed to allocate memory for CAFF!\n"); printf("Failed to allocate memory for CAFF!\n");
return NULL; return NULL;
} }
caff->bytes_read = 0;
caff->credits = NULL; caff->credits = NULL;
caff->header = NULL; caff->header = NULL;
caff_init_animation_list(&caff->animations); caff_init_animation_list(&caff->animations);
size_t anim_count = 0; size_t anim_count = 0;
while (!feof(file)) { while (!feof(file))
{
uint8_t id; uint8_t id;
uint64_t length; uint64_t length;
fread(&id, 1, 1, file); fread(&id, sizeof(uint8_t), 1, file);
fread(&length, 8, 1, file); fread(&length, sizeof(uint64_t), 1, file);
switch (id) { switch (id)
{
case 0x1: case 0x1:
// Do not replace the header after it is initialized // Do not replace the header after it is initialized
if (!caff->header) if (!caff->header)
@ -69,8 +79,10 @@ CAFF* caff_parse_file(const char* filename) {
break; break;
case 0x3: case 0x3:
anim_count++; anim_count++;
if(caff->header && caff->header->num_anim == anim_count){ if (caff->header && caff->header->num_anim == anim_count)
goto end; {
fclose(file);
return caff;
} }
// You might want to append to a list of animations here. // You might want to append to a list of animations here.
CAFF_Animation *anim = read_animation(file); CAFF_Animation *anim = read_animation(file);
@ -78,51 +90,57 @@ CAFF* caff_parse_file(const char* filename) {
caff_add_animation_list(&caff->animations, *anim); caff_add_animation_list(&caff->animations, *anim);
free(anim); free(anim);
// We only need the first image now... // We only need the first image now...
goto end; fclose(file);
break; return caff;
default: default:
// Random bytes should not cause an error // Random bytes should not cause an error
printf("Unknown block ID: %u\n", id); printf("Unknown block ID: %u\n", id);
goto end; fclose(file);
return caff;
} }
} }
end:
fclose(file); fclose(file);
printf("Parse END!\n"); printf("Parse END!\n");
return caff; return caff;
} }
CAFF_Header* read_header(FILE* file) { CAFF_Header *read_header(FILE *file)
{
CAFF_Header *header = malloc(sizeof(CAFF_Header)); CAFF_Header *header = malloc(sizeof(CAFF_Header));
if (!header) { if (!header)
{
printf("Failed to allocate memory for CAFF header\n"); printf("Failed to allocate memory for CAFF header\n");
return NULL; return NULL;
} }
// Read the magic string. // 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"); printf("Failed to read magic string from CAFF header\n");
free(header); free(header);
return NULL; return NULL;
} }
// Check the magic string. // 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"); printf("Invalid magic string in CAFF header\n");
free(header); free(header);
return NULL; return NULL;
} }
// Read the header size. // 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"); printf("Failed to read header size from CAFF header\n");
free(header); free(header);
return NULL; return NULL;
} }
// Read the number of animations. // 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"); printf("Failed to read number of animations from CAFF header\n");
free(header); free(header);
return NULL; return NULL;
@ -131,27 +149,30 @@ CAFF_Header* read_header(FILE* file) {
return header; return header;
} }
CAFF_Credits *read_credits(FILE *file)
CAFF_Credits* read_credits(FILE* file) { {
CAFF_Credits *credits = malloc(sizeof(CAFF_Credits)); CAFF_Credits *credits = malloc(sizeof(CAFF_Credits));
if (!credits) { if (!credits)
{
printf("Failed to allocate memory for CAFF credits\n"); printf("Failed to allocate memory for CAFF credits\n");
return NULL; return NULL;
} }
// Read the creation date and time. // Read the creation date and time.
if (fread(&credits->year, 2, 1, file) != 1 || if (fread(&credits->year, sizeof(uint16_t), 1, file) != 1 ||
fread(&credits->month, 1, 1, file) != 1 || fread(&credits->month, sizeof(uint8_t), 1, file) != 1 ||
fread(&credits->day, 1, 1, file) != 1 || fread(&credits->day, sizeof(uint8_t), 1, file) != 1 ||
fread(&credits->hour, 1, 1, file) != 1 || fread(&credits->hour, sizeof(uint8_t), 1, file) != 1 ||
fread(&credits->minute, 1, 1, file) != 1) { fread(&credits->minute, sizeof(uint8_t), 1, file) != 1)
{
printf("Failed to read creation date and time from CAFF credits\n"); printf("Failed to read creation date and time from CAFF credits\n");
free(credits); free(credits);
return NULL; return NULL;
} }
// Read the length of the creator field. // 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"); printf("Failed to read length of creator field from CAFF credits\n");
free(credits); free(credits);
return NULL; return NULL;
@ -159,14 +180,16 @@ CAFF_Credits* read_credits(FILE* file) {
// Allocate memory for the creator field. // Allocate memory for the creator field.
credits->creator = malloc(credits->creator_len + 1); 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"); printf("Failed to allocate memory for creator field in CAFF credits\n");
free(credits); free(credits);
return NULL; return NULL;
} }
// Read the creator field. // 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"); printf("Failed to read creator field from CAFF credits\n");
free(credits->creator); free(credits->creator);
free(credits); free(credits);
@ -179,16 +202,18 @@ CAFF_Credits* read_credits(FILE* file) {
return credits; return credits;
} }
CAFF_Animation *read_animation(FILE *file)
CAFF_Animation* read_animation(FILE* file) { {
CAFF_Animation *animation = malloc(sizeof(CAFF_Animation)); CAFF_Animation *animation = malloc(sizeof(CAFF_Animation));
if (!animation) { if (!animation)
{
printf("Failed to allocate memory for CAFF animation\n"); printf("Failed to allocate memory for CAFF animation\n");
return NULL; return NULL;
} }
// Read the duration. // 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"); printf("Failed to read duration from CAFF animation\n");
free(animation); free(animation);
return NULL; return NULL;
@ -196,7 +221,8 @@ CAFF_Animation* read_animation(FILE* file) {
// Read the CIFF image. // Read the CIFF image.
animation->ciff = read_ciff(file); animation->ciff = read_ciff(file);
if (!animation->ciff) { if (!animation->ciff)
{
printf("Failed to read CIFF image from CAFF animation\n"); printf("Failed to read CIFF image from CAFF animation\n");
free(animation); free(animation);
return NULL; return NULL;
@ -205,21 +231,23 @@ CAFF_Animation* read_animation(FILE* file) {
return animation; return animation;
} }
void caff_free(CAFF *caff)
void caff_free(CAFF* caff) { {
// Free the header // Free the header
free(caff->header); free(caff->header);
caff->header = NULL; caff->header = NULL;
// Free the credits // Free the credits
if (caff->credits->creator) { if (caff->credits->creator)
{
free(caff->credits->creator); free(caff->credits->creator);
} }
free(caff->credits); free(caff->credits);
caff->credits = NULL; caff->credits = NULL;
// Free the animations // 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); free_ciff(caff->animations.array[i].ciff);
} }
caff_free_animtion_list(&caff->animations); caff_free_animtion_list(&caff->animations);

1
caff.h
View file

@ -36,6 +36,7 @@ typedef struct {
CAFF_Header* header; // The CAFF header CAFF_Header* header; // The CAFF header
CAFF_Credits* credits; // The CAFF credits CAFF_Credits* credits; // The CAFF credits
CAFF_Animation_List animations; // The CAFF animations CAFF_Animation_List animations; // The CAFF animations
uint64_t bytes_read;
} CAFF; } CAFF;
CAFF* caff_parse_file(const char* filename); CAFF* caff_parse_file(const char* filename);
CAFF_Header* read_header(FILE* file); CAFF_Header* read_header(FILE* file);

62
ciff.c
View file

@ -4,30 +4,38 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
CIFF *read_ciff(FILE *file)
{
CIFF* read_ciff(FILE* file) { if (!file)
{
if (!file) {
printf("Failed to open file!\n"); printf("Failed to open file!\n");
return NULL; return NULL;
} }
CIFF *ciff = malloc(sizeof(CIFF)); CIFF *ciff = malloc(sizeof(CIFF));
if (!ciff) { if (!ciff)
{
printf("Failed to allocate memory for CIFF structure\n"); printf("Failed to allocate memory for CIFF structure\n");
fclose(file); fclose(file);
return NULL; return NULL;
} }
// Read the header // Read the header
fread(ciff->magic, 4, 1, file); fread(ciff->magic, sizeof(uint32_t), 1, file);
fread(&ciff->header_size, 8, 1, file); fread(&ciff->header_size, sizeof(uint64_t), 1, file);
fread(&ciff->content_size, 8, 1, file); fread(&ciff->content_size, sizeof(uint64_t), 1, file);
fread(&ciff->width, 8, 1, file); fread(&ciff->width, sizeof(uint64_t), 1, file);
fread(&ciff->height, 8, 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 // 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"); printf("File is not a CIFF file\n");
free(ciff); free(ciff);
fclose(file); fclose(file);
@ -36,7 +44,8 @@ CIFF* read_ciff(FILE* file) {
// Read the caption // Read the caption
ciff->caption = malloc(ciff->header_size); // overestimate the size ciff->caption = malloc(ciff->header_size); // overestimate the size
if (!ciff->caption) { if (!ciff->caption)
{
printf("Failed to allocate memory for caption\n"); printf("Failed to allocate memory for caption\n");
free(ciff); free(ciff);
fclose(file); fclose(file);
@ -45,8 +54,9 @@ CIFF* read_ciff(FILE* file) {
char c; char c;
size_t i = 0; size_t i = 0;
do { do
fread(&c, 1, 1, file); {
fread(&c, sizeof(char), 1, file);
ciff->caption[i++] = c; ciff->caption[i++] = c;
} while (c != '\n'); } while (c != '\n');
ciff->caption[i] = '\0'; // null-terminate the string ciff->caption[i] = '\0'; // null-terminate the string
@ -54,7 +64,8 @@ CIFF* read_ciff(FILE* file) {
// Read the tags // 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 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)); ciff->tags = malloc(tags_size * sizeof(char));
if (!ciff->tags) { if (!ciff->tags)
{
printf("Failed to allocate memory for tags\n"); printf("Failed to allocate memory for tags\n");
free(ciff->caption); free(ciff->caption);
free(ciff); free(ciff);
@ -62,7 +73,8 @@ CIFF* read_ciff(FILE* file) {
return NULL; 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"); printf("Failed to read tags!\n");
free(ciff->caption); free(ciff->caption);
free(ciff); free(ciff);
@ -72,7 +84,8 @@ CIFF* read_ciff(FILE* file) {
// Read the pixels // Read the pixels
ciff->pixels = malloc(ciff->content_size); ciff->pixels = malloc(ciff->content_size);
if (!ciff->pixels) { if (!ciff->pixels)
{
printf("Failed to allocate memory for pixel data\n"); printf("Failed to allocate memory for pixel data\n");
free(ciff->caption); free(ciff->caption);
free(ciff); free(ciff);
@ -81,16 +94,17 @@ CIFF* read_ciff(FILE* file) {
} }
fread(ciff->pixels, ciff->content_size, 1, file); fread(ciff->pixels, ciff->content_size, 1, file);
return ciff; 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_compress_struct cinfo;
struct jpeg_error_mgr jerr; struct jpeg_error_mgr jerr;
FILE *outfile = fopen(out_filename, "wb"); FILE *outfile = fopen(out_filename, "wb");
if (!outfile) { if (!outfile)
{
printf("Failed to open output file: %s\n", out_filename); printf("Failed to open output file: %s\n", out_filename);
return; return;
} }
@ -110,7 +124,8 @@ void generate_jpg(CIFF* ciff, const char* out_filename) {
jpeg_start_compress(&cinfo, TRUE); jpeg_start_compress(&cinfo, TRUE);
JSAMPROW row_pointer[1]; 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]; row_pointer[0] = &ciff->pixels[cinfo.next_scanline * ciff->width * 3];
jpeg_write_scanlines(&cinfo, row_pointer, 1); jpeg_write_scanlines(&cinfo, row_pointer, 1);
} }
@ -122,9 +137,8 @@ void generate_jpg(CIFF* ciff, const char* out_filename) {
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
} }
void free_ciff(CIFF *ciff)
{
void free_ciff(CIFF* ciff) {
free(ciff->caption); free(ciff->caption);
free(ciff->pixels); free(ciff->pixels);
free(ciff->tags); free(ciff->tags);

1
main.c
View file

@ -50,7 +50,6 @@ int main(int argc, char **argv)
} }
else else
{ {
free_ciff(ciff); free_ciff(ciff);
} }
return 0; return 0;