diff --git a/share/grafx2/scripts/pal_db_SetC64Palette.lua b/share/grafx2/scripts/pal_db_SetC64Palette.lua index 0f77c7e3..26a38cf0 100644 --- a/share/grafx2/scripts/pal_db_SetC64Palette.lua +++ b/share/grafx2/scripts/pal_db_SetC64Palette.lua @@ -42,7 +42,7 @@ if OK == true then if clean == 1 then - for c = #colors+1, 255, 1 do + for c = #colors+1, 256, 1 do setcolor(c-1,0,0,0) end end diff --git a/src/fileformats.c b/src/fileformats.c index fc71ccbf..433935f1 100644 --- a/src/fileformats.c +++ b/src/fileformats.c @@ -1848,6 +1848,8 @@ void Load_GIF(T_IO_Context * context) if (size_to_read>nb_char_to_keep) fseek(GIF_file,size_to_read-nb_char_to_keep,SEEK_CUR); } + // Lecture de la taille du bloc suivant: + Read_byte(GIF_file,&size_to_read); break; case 0xF9: // Graphics Control Extension // Prévu pour la transparence @@ -1871,15 +1873,73 @@ void Load_GIF(T_IO_Context * context) } else File_error=2; + // Lecture de la taille du bloc suivant: + Read_byte(GIF_file,&size_to_read); break; + case 0xFF: // Application Extension + // Normally, always a 11-byte block + if (size_to_read == 0x0B) + { + char aeb[0x0B]; + Read_bytes(GIF_file,aeb, 0x0B); + if (File_error) + ; + else if (!memcmp(aeb,"NETSCAPE2.0",0x0B)) + { + // The well-known Netscape extension. + // Nothing to do, just skip sub-block + do + { + if (! Read_byte(GIF_file,&size_to_read)) + File_error=1; + fseek(GIF_file,size_to_read,SEEK_CUR); + } while (!File_error && size_to_read!=0); + } + else if (!memcmp(aeb,"GFX2PATH\x00\x00\x00",0x0B)) + { + // Original file path + if (context->Original_file_name && context->Original_file_directory) + { + Read_byte(GIF_file,&size_to_read); + if (!File_error && size_to_read) + { + Read_bytes(GIF_file,context->Original_file_directory, size_to_read); + Read_byte(GIF_file,&size_to_read); + if (!File_error && size_to_read) + { + Read_bytes(GIF_file,context->Original_file_name, size_to_read); + Read_byte(GIF_file,&size_to_read); // Normally 0 + } + } + } + else + { + // Nothing to do, just skip sub-block + Read_byte(GIF_file,&size_to_read); + while (size_to_read!=0 && !File_error) + { + fseek(GIF_file,size_to_read,SEEK_CUR); + Read_byte(GIF_file,&size_to_read); + } + } + } + } + else + { + fseek(GIF_file,size_to_read,SEEK_CUR); + // Lecture de la taille du bloc suivant: + Read_byte(GIF_file,&size_to_read); + } + break; + default: // On saute le bloc: fseek(GIF_file,size_to_read,SEEK_CUR); + // Lecture de la taille du bloc suivant: + Read_byte(GIF_file,&size_to_read); break; } - // Lecture de la taille du bloc suivant: - Read_byte(GIF_file,&size_to_read); } } break; @@ -2421,6 +2481,31 @@ void Save_GIF(T_IO_Context * context) // After writing all layers if (!File_error) { + // If requested, write a specific extension for storing + // original file path. + // This is used by the backup system. + // The format is : + // 21 FF 0B G F X 2 P A T H 00 00 00 + // + // + // 00 + if (context->Original_file_name != NULL + && context->Original_file_directory != NULL) + { + long name_size = 1+strlen(context->Original_file_name); + long dir_size = 1+strlen(context->Original_file_directory); + if (name_size<256 && dir_size<256) + { + if (! Write_bytes(GIF_file,"\x21\xFF\x0BGFX2PATH\x00\x00\x00", 14) + || ! Write_byte(GIF_file,dir_size) + || ! Write_bytes(GIF_file, context->Original_file_directory, dir_size) + || ! Write_byte(GIF_file,name_size) + || ! Write_bytes(GIF_file, context->Original_file_name, name_size) + || ! Write_byte(GIF_file,0)) + File_error=1; + } + } + // On écrit un GIF TERMINATOR, exigé par SVGA et SEA. if (! Write_byte(GIF_file,'\x3B')) File_error=1; diff --git a/src/loadsave.c b/src/loadsave.c index 113fd0a9..1b632fd6 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -740,8 +740,17 @@ void Load_image(T_IO_Context *context) // Transfer the data to main image. if (!format->Palette_only) { - strcpy(Main_backups->Pages->Filename,context->File_name); - strcpy(Main_backups->Pages->File_directory,context->File_directory); + if (context->Original_file_name && context->Original_file_name[0] + && context->Original_file_directory && context->Original_file_directory[0]) + { + strcpy(Main_backups->Pages->Filename,context->Original_file_name); + strcpy(Main_backups->Pages->File_directory,context->Original_file_directory); + } + else + { + strcpy(Main_backups->Pages->Filename,context->File_name); + strcpy(Main_backups->Pages->File_directory,context->File_directory); + } // On considère que l'image chargée n'est plus modifiée Main_image_is_modified=0; @@ -1051,6 +1060,12 @@ void Init_context_preview(T_IO_Context * context, char *file_name, char *file_di context->Format = Main_fileformat; // FIXME ? } +// Setup for loading/saving an intermediate backup +void Init_context_backup_image(T_IO_Context * context, char *file_name, char *file_directory) +{ + Init_context_layered_image(context, file_name, file_directory); +} + /// Setup for loading/saving the current main image void Init_context_layered_image(T_IO_Context * context, char *file_name, char *file_directory) { @@ -1276,8 +1291,15 @@ byte Process_backups(T_String_list **list) { // Load this file T_IO_Context context; - Init_context_layered_image(&context, files_vector[i], Config_directory); + char file_name[MAX_PATH_CHARACTERS]=""; + char file_directory[MAX_PATH_CHARACTERS]=""; + + Init_context_backup_image(&context, files_vector[i], Config_directory); + // Provide buffers to read original location + context.Original_file_name = file_name; + context.Original_file_directory = file_directory; Load_image(&context); + Main_image_is_modified=1; Destroy_context(&context); Redraw_layered_image(); Display_all_screen(); @@ -1381,8 +1403,12 @@ void Rotate_safety_backups(void) sprintf(file_name, "%c%6.6d.bkp", Main_safety_backup_prefix, (Uint32)Main_safety_number); - Init_context_layered_image(&context, file_name, Config_directory); + Init_context_backup_image(&context, file_name, Config_directory); context.Format=FORMAT_GIF; + // Provide original file data, to store as a GIF Application Extension + context.Original_file_name = Main_backups->Pages->Filename; + context.Original_file_directory = Main_backups->Pages->File_directory; + Save_image(&context); Destroy_context(&context); diff --git a/src/loadsave.h b/src/loadsave.h index 2e56cdc3..f82383b9 100644 --- a/src/loadsave.h +++ b/src/loadsave.h @@ -65,6 +65,11 @@ typedef struct byte *Target_address; /// Pitch: Difference of addresses between one pixel and the one just "below" it long Pitch; + + /// Original file name, stored in GIF file + char * Original_file_name; + /// Original file directory, stored in GIF file + char * Original_file_directory; /// Internal: during load, marks which layer is being loaded. short Current_layer; @@ -101,6 +106,8 @@ void Pixel_load_in_brush (word x_pos, word y_pos, byte color); void Init_context_preview(T_IO_Context * context, char *file_name, char *file_directory); // Setup for loading/saving the current main image void Init_context_layered_image(T_IO_Context * context, char *file_name, char *file_directory); +// Setup for loading/saving an intermediate backup +void Init_context_backup_image(T_IO_Context * context, char *file_name, char *file_directory); // Setup for loading/saving the flattened version of current main image void Init_context_flat_image(T_IO_Context * context, char *file_name, char *file_directory); // Setup for loading/saving the user's brush