From c5a52242be997fd650c25450d12a163dcc89189f Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Mon, 10 Dec 2018 23:40:33 +0100 Subject: [PATCH] Save and load Image mode in GIF file. Add the extension GFX2MODE --- src/fileformats.c | 38 +++++++++++++++++++++++++++++++++++++- src/oldies.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/oldies.h | 14 ++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/fileformats.c b/src/fileformats.c index 45abd72e..52f073ab 100644 --- a/src/fileformats.c +++ b/src/fileformats.c @@ -89,6 +89,7 @@ #include "pages.h" #include "windows.h" // Best_color() #include "fileformats.h" +#include "oldies.h" #ifndef __no_pnglib__ static void Load_PNG_Sub(T_IO_Context * context, FILE * file); @@ -4011,6 +4012,7 @@ void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, int is_transparent, b void Load_GIF(T_IO_Context * context) { + int image_mode = -1; char signature[6]; word * alphabet_stack; // Pile de décodage d'une chaîne @@ -4174,6 +4176,7 @@ void Load_GIF(T_IO_Context * context) { char aeb[0x0B]; Read_bytes(GIF_file,aeb, 0x0B); + GFX2_Log(GFX2_DEBUG, "GIF extension \"%.11s\"\n", aeb); if (File_error) ; else if (!memcmp(aeb,"NETSCAPE2.0",0x0B)) @@ -4259,6 +4262,20 @@ void Load_GIF(T_IO_Context * context) if (size_to_read!=0) File_error=1; } + else if (0 == memcmp(aeb, "GFX2MODE", 8)) + { + Read_byte(GIF_file,&size_to_read); + if (size_to_read > 0) + { // read the image mode. We'll set it after having loaded all layers. + char * label = malloc((size_t)size_to_read + 1); + Read_bytes(GIF_file, label, size_to_read); + label[size_to_read] = '\0'; + image_mode = Constraint_mode_from_label(label); + GFX2_Log(GFX2_DEBUG, " mode = %s (%d)\n", label, image_mode); + Read_byte(GIF_file,&size_to_read); + free(label); + } + } else { // Unknown extension, skip. @@ -4482,6 +4499,10 @@ void Load_GIF(T_IO_Context * context) if (!Read_byte(GIF_file,&block_identifier)) File_error=2; } + + // set the mode that have been read previously. + if (image_mode > 0) + Set_image_mode(context, image_mode); } // Le fichier contenait un LSDB else File_error=1; @@ -4691,9 +4712,24 @@ void Save_GIF(T_IO_Context * context) // LL : 01 to loop // SSSS : number of loops if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { if (context->Nb_layers>1) Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19); - + } + else if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode > IMAGE_MODE_ANIMATION) + { + const char * label = Constraint_mode_label(Main.backups->Pages->Image_mode); + size_t len = strlen(label); + // Write extension for storing IMAGE_MODE + Write_byte(GIF_file,0x21); // Extension Introducer + Write_byte(GIF_file,0xff); // Extension Label + Write_byte(GIF_file, 11); // Block size + Write_bytes(GIF_file, "GFX2MODE2.6", 11); // Application Identifier + Appl. Authentication Code + Write_byte(GIF_file, (byte)len); // Block size + Write_bytes(GIF_file, label, len); // Data + Write_byte(GIF_file, 0); // Block terminator + } + // Ecriture du commentaire if (context->Comment[0]) { diff --git a/src/oldies.c b/src/oldies.c index 340b6009..62ba7ccb 100644 --- a/src/oldies.c +++ b/src/oldies.c @@ -82,6 +82,50 @@ static int count_trailing_zeros(unsigned int value) } #endif +static const struct { + enum IMAGE_MODES mode; + const char * label; +} image_modes_labels[] = { + { IMAGE_MODE_LAYERED, "LAYERED" }, + { IMAGE_MODE_ANIMATION, "ANIMATION" }, + { IMAGE_MODE_ZX, "ZX_SPECTRUM" }, + { IMAGE_MODE_GBC, "GAMEBOYCOLOR" }, + { IMAGE_MODE_THOMSON, "THOMSON40COL" }, + { IMAGE_MODE_EGX, "CPC_EGX" }, + { IMAGE_MODE_EGX2, "CPC_EGX2" }, + { IMAGE_MODE_MODE5, "CPC_MODE5" }, + { IMAGE_MODE_RASTER, "CPC_RASTER" }, + { IMAGE_MODE_C64HIRES, "C64_HIRES" }, + { IMAGE_MODE_C64MULTI, "C64_MULTICOLOR" }, + { IMAGE_MODE_C64FLI, "C64_FLI" }, + { IMAGE_MODE_HGR, "APPLE2_HGR" }, + { IMAGE_MODE_DHGR, "APPLE2_DHGR" } +}; + +const char * Constraint_mode_label(enum IMAGE_MODES mode) +{ + unsigned int i; + + for (i = 0; i < sizeof(image_modes_labels)/sizeof(image_modes_labels[0]); i++) + { + if (image_modes_labels[i].mode == mode) + return image_modes_labels[i].label; + } + return NULL; +} + +int Constraint_mode_from_label(const char * label) +{ + unsigned int i; + + for (i = 0; i < sizeof(image_modes_labels)/sizeof(image_modes_labels[0]); i++) + { + if (0 == strcmp(image_modes_labels[i].label, label)) + return (int)image_modes_labels[i].mode; + } + return -1; +} + #if 0 static void Set_Pixel_in_layer(word x,word y, byte layer, byte color) { diff --git a/src/oldies.h b/src/oldies.h index 26f444f3..612fbf8e 100644 --- a/src/oldies.h +++ b/src/oldies.h @@ -24,6 +24,20 @@ #include "loadsave.h" +/** + * identifier for each Image mode + * + * @return an ASCII label for the mode + */ +const char * Constraint_mode_label(enum IMAGE_MODES mode); + +/** + * Search constraint mode for a label + * + * @return -1 for unknown mode or one of ::IMAGE_MODES value + */ +int Constraint_mode_from_label(const char * label); + /** @defgroup c64 Commodore 64 * Some C64 video mode related functions * @{