Doxygen for GIF.
add Extension documentations, etc.
This commit is contained in:
parent
747dcacbad
commit
337129f760
@ -3851,38 +3851,56 @@ void Save_ICO(T_IO_Context * context)
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////// GIF ////////////////////////////////////
|
//////////////////////////////////// GIF ////////////////////////////////////
|
||||||
typedef struct
|
/**
|
||||||
{
|
* @defgroup GIF GIF format
|
||||||
word Width; // Width of the complete image area
|
* Graphics Interchange Format
|
||||||
word Height; // Height of the complete image area
|
*
|
||||||
byte Resol; // Informations about the resolution (and other)
|
* The GIF format uses LZW compression and stores indexed color pictures
|
||||||
byte Backcol; // Proposed background color
|
* up to 256 colors. It has the ability to store several pictures in the same
|
||||||
byte Aspect; // Informations about aspect ratio (and other)
|
* file : GrafX2 takes advantage of this feature for storing layered images
|
||||||
} T_GIF_LSDB; // Logical Screen Descriptor Block
|
* and animations.
|
||||||
|
*
|
||||||
|
* GrafX2 implements GIF89a :
|
||||||
|
* https://www.w3.org/Graphics/GIF/spec-gif89a.txt
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Logical Screen Descriptor Block
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
word Pos_X; // X offset where the image should be pasted
|
word Width; ///< Width of the complete image area
|
||||||
word Pos_Y; // Y offset where the image should be pasted
|
word Height; ///< Height of the complete image area
|
||||||
word Image_width; // Width of image
|
byte Resol; ///< Informations about the resolution (and other)
|
||||||
word Image_height; // Height of image
|
byte Backcol; ///< Proposed background color
|
||||||
byte Indicator; // Misc image information
|
byte Aspect; ///< Informations about aspect ratio. Ratio = (Aspect + 15) / 64
|
||||||
byte Nb_bits_pixel; // Nb de bits par pixel
|
} T_GIF_LSDB;
|
||||||
} T_GIF_IDB; // Image Descriptor Block
|
|
||||||
|
|
||||||
|
/// Image Descriptor Block
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
byte Block_identifier; // 0x21
|
word Pos_X; ///< X offset where the image should be pasted
|
||||||
byte Function; // 0xF9
|
word Pos_Y; ///< Y offset where the image should be pasted
|
||||||
byte Block_size; // 4
|
word Image_width; ///< Width of image
|
||||||
byte Packed_fields; // 11100000 : Reserved
|
word Image_height; ///< Height of image
|
||||||
// 00011100 : Disposal method
|
byte Indicator; ///< Misc image information
|
||||||
// 00000010 : User input flag
|
byte Nb_bits_pixel; ///< Nb de bits par pixel
|
||||||
// 00000001 : Transparent flag
|
} T_GIF_IDB;
|
||||||
word Delay_time; // Time for this frame to stay displayed
|
|
||||||
byte Transparent_color; // Which color index acts as transparent
|
/// Graphic Control Extension
|
||||||
word Block_terminator; // 0x00
|
typedef struct
|
||||||
} T_GIF_GCE; // Graphic Control Extension
|
{
|
||||||
|
byte Block_identifier; ///< 0x21
|
||||||
|
byte Function; ///< 0xF9
|
||||||
|
byte Block_size; ///< 4
|
||||||
|
byte Packed_fields; ///< 11100000 : Reserved
|
||||||
|
///< 00011100 : Disposal method
|
||||||
|
///< 00000010 : User input flag
|
||||||
|
///< 00000001 : Transparent flag
|
||||||
|
word Delay_time; ///< Time for this frame to stay displayed
|
||||||
|
byte Transparent_color; ///< Which color index acts as transparent
|
||||||
|
word Block_terminator; ///< 0x00
|
||||||
|
} T_GIF_GCE;
|
||||||
|
|
||||||
enum DISPOSAL_METHOD
|
enum DISPOSAL_METHOD
|
||||||
{
|
{
|
||||||
@ -3892,8 +3910,9 @@ enum DISPOSAL_METHOD
|
|||||||
DISPOSAL_METHOD_RESTORE_PREVIOUS = 3,
|
DISPOSAL_METHOD_RESTORE_PREVIOUS = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// -- Tester si un fichier est au format GIF --------------------------------
|
|
||||||
|
|
||||||
|
/// @ingroup loadsaveformats GIF
|
||||||
|
/// Test if a file is GIF format
|
||||||
void Test_GIF(T_IO_Context * context, FILE * file)
|
void Test_GIF(T_IO_Context * context, FILE * file)
|
||||||
{
|
{
|
||||||
char signature[6];
|
char signature[6];
|
||||||
@ -3903,6 +3922,7 @@ void Test_GIF(T_IO_Context * context, FILE * file)
|
|||||||
|
|
||||||
if (Read_bytes(file,signature,6))
|
if (Read_bytes(file,signature,6))
|
||||||
{
|
{
|
||||||
|
/// checks if the signature (6 first bytes) is either GIF87a or GIF89a
|
||||||
if ((!memcmp(signature,"GIF87a",6))||(!memcmp(signature,"GIF89a",6)))
|
if ((!memcmp(signature,"GIF87a",6))||(!memcmp(signature,"GIF89a",6)))
|
||||||
File_error=0;
|
File_error=0;
|
||||||
}
|
}
|
||||||
@ -3911,6 +3931,7 @@ void Test_GIF(T_IO_Context * context, FILE * file)
|
|||||||
|
|
||||||
// -- Lire un fichier au format GIF -----------------------------------------
|
// -- Lire un fichier au format GIF -----------------------------------------
|
||||||
|
|
||||||
|
/// @todo avoid using global variables, define a "GIF context" instead
|
||||||
// Définition de quelques variables globales au chargement du GIF87a
|
// Définition de quelques variables globales au chargement du GIF87a
|
||||||
word GIF_nb_bits; // Nb de bits composants un code complet
|
word GIF_nb_bits; // Nb de bits composants un code complet
|
||||||
word GIF_remainder_bits; // Nb de bits encore dispos dans GIF_last_byte
|
word GIF_remainder_bits; // Nb de bits encore dispos dans GIF_last_byte
|
||||||
@ -3924,9 +3945,8 @@ word GIF_finished_interlaced_image; // L'image entrelacée est finie de charger
|
|||||||
word GIF_pass; // index de passe de l'image entrelacée
|
word GIF_pass; // index de passe de l'image entrelacée
|
||||||
FILE *GIF_file; // L'handle du fichier
|
FILE *GIF_file; // L'handle du fichier
|
||||||
|
|
||||||
// -- Lit le code à GIF_nb_bits suivant --
|
/// Reads the next code (GIF_nb_bits bits)
|
||||||
|
static word GIF_get_next_code(void)
|
||||||
word GIF_get_next_code(void)
|
|
||||||
{
|
{
|
||||||
word nb_bits_to_process=GIF_nb_bits;
|
word nb_bits_to_process=GIF_nb_bits;
|
||||||
word nb_bits_processed =0;
|
word nb_bits_processed =0;
|
||||||
@ -3964,12 +3984,11 @@ word GIF_get_next_code(void)
|
|||||||
return GIF_current_code;
|
return GIF_current_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Affiche un nouveau pixel --
|
/// Put a new pixel
|
||||||
|
static void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, int is_transparent, byte color)
|
||||||
void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, int is_transparent, byte color)
|
|
||||||
{
|
{
|
||||||
if (!is_transparent || color!=context->Transparent_color)
|
if (!is_transparent || color!=context->Transparent_color)
|
||||||
Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
|
Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
|
||||||
|
|
||||||
GIF_pos_X++;
|
GIF_pos_X++;
|
||||||
|
|
||||||
@ -4010,6 +4029,8 @@ void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, int is_transparent, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @ingroup loadsaveformats GIF
|
||||||
|
/// Load GIF file
|
||||||
void Load_GIF(T_IO_Context * context)
|
void Load_GIF(T_IO_Context * context)
|
||||||
{
|
{
|
||||||
int image_mode = -1;
|
int image_mode = -1;
|
||||||
@ -4531,9 +4552,8 @@ void Load_GIF(T_IO_Context * context)
|
|||||||
int GIF_stop; // "On peut arrêter la sauvegarde du fichier"
|
int GIF_stop; // "On peut arrêter la sauvegarde du fichier"
|
||||||
byte GIF_buffer[256]; // buffer d'écriture de bloc de données compilées
|
byte GIF_buffer[256]; // buffer d'écriture de bloc de données compilées
|
||||||
|
|
||||||
// -- Vider le buffer GIF dans le buffer KM --
|
/// Flush ::GIF_buffer
|
||||||
|
static void GIF_empty_buffer(void)
|
||||||
void GIF_empty_buffer(void)
|
|
||||||
{
|
{
|
||||||
word index;
|
word index;
|
||||||
|
|
||||||
@ -4548,9 +4568,8 @@ void Load_GIF(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Ecrit un code à GIF_nb_bits --
|
/// Write a code (GIF_nb_bits bits)
|
||||||
|
static void GIF_set_code(word Code)
|
||||||
void GIF_set_code(word Code)
|
|
||||||
{
|
{
|
||||||
word nb_bits_to_process=GIF_nb_bits;
|
word nb_bits_to_process=GIF_nb_bits;
|
||||||
word nb_bits_processed =0;
|
word nb_bits_processed =0;
|
||||||
@ -4583,9 +4602,8 @@ void Load_GIF(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -- Lire le pixel suivant --
|
/// Read the next pixel
|
||||||
|
static byte GIF_next_pixel(T_IO_Context *context, T_GIF_IDB *idb)
|
||||||
byte GIF_next_pixel(T_IO_Context *context, T_GIF_IDB *idb)
|
|
||||||
{
|
{
|
||||||
byte temp;
|
byte temp;
|
||||||
|
|
||||||
@ -4602,7 +4620,8 @@ void Load_GIF(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @ingroup loadsaveformats GIF
|
||||||
|
/// Save a GIF file
|
||||||
void Save_GIF(T_IO_Context * context)
|
void Save_GIF(T_IO_Context * context)
|
||||||
{
|
{
|
||||||
word * alphabet_prefix; // Table des préfixes des codes
|
word * alphabet_prefix; // Table des préfixes des codes
|
||||||
@ -4704,13 +4723,18 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
{
|
{
|
||||||
// La palette a été correctement écrite.
|
// La palette a été correctement écrite.
|
||||||
|
|
||||||
// Ecriture de la transparence
|
/// - "Netscape" animation extension :
|
||||||
//Write_bytes(GIF_file,"\x21\xF9\x04\x01\x00\x00\xNN\x00",8);
|
/// <pre>
|
||||||
|
/// 0x21 Extension Label
|
||||||
// "Netscape" animation extension
|
/// 0xFF Application Extension Label
|
||||||
// Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\xLL\xSS\xSS\x00",19);
|
/// 0x0B Block Size
|
||||||
// LL : 01 to loop
|
/// "NETSCAPE" Application Identifier (8 bytes)
|
||||||
// SSSS : number of loops
|
/// "2.0" Application Authentication Code (3 bytes)
|
||||||
|
/// 0x03 Sub-block Data Size
|
||||||
|
/// 0xLL 01 to loop
|
||||||
|
/// 0xSSSS (little endian) number of loops, 0 means infinite loop
|
||||||
|
/// 0x00 Block terminator </pre>
|
||||||
|
/// see http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
|
||||||
if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
|
if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
|
||||||
{
|
{
|
||||||
if (context->Nb_layers>1)
|
if (context->Nb_layers>1)
|
||||||
@ -4718,16 +4742,30 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
else if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode > IMAGE_MODE_ANIMATION)
|
else if (context->Type == CONTEXT_MAIN_IMAGE && Main.backups->Pages->Image_mode > IMAGE_MODE_ANIMATION)
|
||||||
{
|
{
|
||||||
|
/// - GrafX2 extension to store ::IMAGE_MODES :
|
||||||
|
/// <pre>
|
||||||
|
/// 0x21 Extension Label
|
||||||
|
/// 0xFF Application Extension Label
|
||||||
|
/// 0x0B Block Size
|
||||||
|
/// "GFX2MODE" Application Identifier (8 bytes)
|
||||||
|
/// "2.6" Application Authentication Code (3 bytes)
|
||||||
|
/// 0xll Sub-block Data Size
|
||||||
|
/// string label
|
||||||
|
/// 0x00 Block terminator </pre>
|
||||||
|
/// @see Constraint_mode_label()
|
||||||
const char * label = Constraint_mode_label(Main.backups->Pages->Image_mode);
|
const char * label = Constraint_mode_label(Main.backups->Pages->Image_mode);
|
||||||
size_t len = strlen(label);
|
if (label != NULL)
|
||||||
// Write extension for storing IMAGE_MODE
|
{
|
||||||
Write_byte(GIF_file,0x21); // Extension Introducer
|
size_t len = strlen(label);
|
||||||
Write_byte(GIF_file,0xff); // Extension Label
|
// Write extension for storing IMAGE_MODE
|
||||||
Write_byte(GIF_file, 11); // Block size
|
Write_byte(GIF_file,0x21); // Extension Introducer
|
||||||
Write_bytes(GIF_file, "GFX2MODE2.6", 11); // Application Identifier + Appl. Authentication Code
|
Write_byte(GIF_file,0xff); // Extension Label
|
||||||
Write_byte(GIF_file, (byte)len); // Block size
|
Write_byte(GIF_file, 11); // Block size
|
||||||
Write_bytes(GIF_file, label, len); // Data
|
Write_bytes(GIF_file, "GFX2MODE2.6", 11); // Application Identifier + Appl. Authentication Code
|
||||||
Write_byte(GIF_file, 0); // Block terminator
|
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
|
// Ecriture du commentaire
|
||||||
@ -4737,7 +4775,20 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
Write_byte(GIF_file,strlen(context->Comment));
|
Write_byte(GIF_file,strlen(context->Comment));
|
||||||
Write_bytes(GIF_file,context->Comment,strlen(context->Comment)+1);
|
Write_bytes(GIF_file,context->Comment,strlen(context->Comment)+1);
|
||||||
}
|
}
|
||||||
// Write cycling colors
|
/// - "CRNG" Color cycing extension :
|
||||||
|
/// <pre>
|
||||||
|
/// 0x21 Extension Label
|
||||||
|
/// 0xFF Application Extension Label
|
||||||
|
/// 0x0B Block Size
|
||||||
|
/// "CRNG\0\0\0\0" "CRNG" Application Identifier (8 bytes)
|
||||||
|
/// "1.0" Application Authentication Code (3 bytes)
|
||||||
|
/// 0xll Sub-block Data Size (6 bytes per color cycle)
|
||||||
|
/// For each color cycle :
|
||||||
|
/// 0xRRRR (big endian) Rate
|
||||||
|
/// 0xFFFF (big endian) Flags
|
||||||
|
/// 0xSS start (lower color index)
|
||||||
|
/// 0xEE end (higher color index)
|
||||||
|
/// 0x00 Block terminator </pre>
|
||||||
if (context->Color_cycles)
|
if (context->Color_cycles)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -5050,14 +5101,21 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
// After writing all layers
|
// After writing all layers
|
||||||
if (!File_error)
|
if (!File_error)
|
||||||
{
|
{
|
||||||
// If requested, write a specific extension for storing
|
/// - If requested, write a specific extension for storing
|
||||||
// original file path.
|
/// original file path.
|
||||||
// This is used by the backup system.
|
/// This is used by the backup system.
|
||||||
// The format is :
|
/// The format is :
|
||||||
// 21 FF 0B G F X 2 P A T H 00 00 00
|
/// <pre>
|
||||||
// <size of path (byte)> <null-terminated path>
|
/// 0x21 Extension Label
|
||||||
// <size of filename (byte)> <null-terminated filename>
|
/// 0xFF Application Extension Label
|
||||||
// 00
|
/// 0x0B Block Size
|
||||||
|
/// "GFX2PATH" "GFX2PATH" Application Identifier (8 bytes)
|
||||||
|
/// "\0\0\0" Application Authentication Code (3 bytes)
|
||||||
|
/// 0xll Sub-block Data Size : path size (including null)
|
||||||
|
/// "..path.." path (null-terminated)
|
||||||
|
/// 0xll Sub-block Data Size : filename size (including null)
|
||||||
|
/// "..file.." file name (null-terminated)
|
||||||
|
/// 0x00 Block terminator </pre>
|
||||||
if (context->Original_file_name != NULL
|
if (context->Original_file_name != NULL
|
||||||
&& context->Original_file_directory != NULL)
|
&& context->Original_file_directory != NULL)
|
||||||
{
|
{
|
||||||
@ -5108,6 +5166,7 @@ void Save_GIF(T_IO_Context * context)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @} */
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////// PCX ////////////////////////////////////
|
//////////////////////////////////// PCX ////////////////////////////////////
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user