malloc return check in Save_GIF()

also translated comments from French to English
This commit is contained in:
Thomas Bernard 2020-12-20 18:18:30 +01:00
parent 6b6f8790d5
commit 6f21c7e753
No known key found for this signature in database
GPG Key ID: DB511043A31ACAAF

View File

@ -831,6 +831,14 @@ static byte GIF_next_pixel(T_IO_Context *context, T_GIF_context *gif, T_GIF_IDB
return temp; return temp;
} }
struct gif_alphabet {
word prefix[4096]; // code prefix array
word suffix[4096]; // code suffix array
word daughter[4096]; // daughter strings array (greater length)
word sister[4096]; // sister strings array (same length)
word free; // first free slot in the alphabet
word max; // maximum number of entry in the alphabet
};
/// Save a GIF file /// Save a GIF file
void Save_GIF(T_IO_Context * context) void Save_GIF(T_IO_Context * context)
@ -838,12 +846,7 @@ void Save_GIF(T_IO_Context * context)
FILE * GIF_file; FILE * GIF_file;
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
word * alphabet_prefix; // Table des préfixes des codes struct gif_alphabet * alphabet;
word * alphabet_suffix; // Table des suffixes des codes
word * alphabet_daughter; // Table des chaînes filles (plus longues)
word * alphabet_sister; // Table des chaînes soeurs (même longueur)
word alphabet_free; // Position libre dans l'alphabet
word alphabet_max; // Nombre d'entrées possibles dans l'alphabet
word start; // Code précédent (sert au linkage des chaînes) word start; // Code précédent (sert au linkage des chaînes)
int descend; // Booléen "On vient de descendre" int descend; // Booléen "On vient de descendre"
@ -873,10 +876,13 @@ void Save_GIF(T_IO_Context * context)
// La signature du fichier a été correctement écrite. // La signature du fichier a été correctement écrite.
// Allocation de mémoire pour les tables // Allocation de mémoire pour les tables
alphabet_prefix = (word *)GFX2_malloc(4096*sizeof(word)); alphabet = (struct gif_alphabet *)GFX2_malloc(sizeof(struct gif_alphabet));
alphabet_suffix = (word *)GFX2_malloc(4096*sizeof(word)); if (alphabet == NULL)
alphabet_daughter = (word *)GFX2_malloc(4096*sizeof(word)); {
alphabet_sister = (word *)GFX2_malloc(4096*sizeof(word)); File_error = 1;
fclose(GIF_file);
return;
}
// On initialise le LSDB du fichier // On initialise le LSDB du fichier
if (Config.Screen_size_in_GIF && Screen_width >= context->Width && Screen_height >= context->Height) if (Config.Screen_size_in_GIF && Screen_width >= context->Width && Screen_height >= context->Height)
@ -1173,14 +1179,14 @@ void Save_GIF(T_IO_Context * context)
GIF.stop=0; GIF.stop=0;
// Réintialisation de la table: // Réintialisation de la table:
alphabet_free=clear + 2; // 258 for 8bpp alphabet->free = clear + 2; // 258 for 8bpp
GIF.nb_bits =IDB.Nb_bits_pixel + 1; // 9 for 8 bpp GIF.nb_bits = IDB.Nb_bits_pixel + 1; // 9 for 8 bpp
alphabet_max =clear+clear-1; // 511 for 8bpp alphabet->max = clear+clear-1; // 511 for 8bpp
GIF_set_code(GIF_file, &GIF, GIF_buffer, clear); //256 for 8bpp GIF_set_code(GIF_file, &GIF, GIF_buffer, clear); //256 for 8bpp
for (start=0;start<4096;start++) for (start=0; start<4096; start++)
{ {
alphabet_daughter[start] = GIF_INVALID_CODE; alphabet->daughter[start] = GIF_INVALID_CODE;
alphabet_sister[start] = GIF_INVALID_CODE; alphabet->sister[start] = GIF_INVALID_CODE;
} }
////////////////////////////////////////////// COMPRESSION LZW // ////////////////////////////////////////////// COMPRESSION LZW //
@ -1194,12 +1200,12 @@ void Save_GIF(T_IO_Context * context)
// look for (current_string,current_char) in the alphabet // look for (current_string,current_char) in the alphabet
while ( (index != GIF_INVALID_CODE) && while ( (index != GIF_INVALID_CODE) &&
( (current_string!=alphabet_prefix[index]) || ( (current_string != alphabet->prefix[index]) ||
(current_char !=alphabet_suffix[index]) ) ) (current_char != alphabet->suffix[index]) ) )
{ {
descend=0; descend = 0;
start=index; start = index;
index=alphabet_sister[index]; index = alphabet->sister[index];
} }
if (index != GIF_INVALID_CODE) if (index != GIF_INVALID_CODE)
@ -1208,9 +1214,9 @@ void Save_GIF(T_IO_Context * context)
// We have found (current_string,current_char) in the alphabet // We have found (current_string,current_char) in the alphabet
// at the index position. So go on and prepare for then next character // at the index position. So go on and prepare for then next character
descend=1; descend = 1;
start=current_string=index; start = current_string = index;
index=alphabet_daughter[index]; index = alphabet->daughter[index];
} }
else else
{ {
@ -1218,44 +1224,44 @@ void Save_GIF(T_IO_Context * context)
// so write current_string to the Gif stream // so write current_string to the Gif stream
GIF_set_code(GIF_file, &GIF, GIF_buffer, current_string); GIF_set_code(GIF_file, &GIF, GIF_buffer, current_string);
if(alphabet_free < 4096) { if(alphabet->free < 4096) {
// link current_string and the new one // link current_string and the new one
if (descend) if (descend)
alphabet_daughter[start]=alphabet_free; alphabet->daughter[start] = alphabet->free;
else else
alphabet_sister[start]=alphabet_free; alphabet->sister[start] = alphabet->free;
// add (current_string,current_char) to the alphabet // add (current_string,current_char) to the alphabet
alphabet_prefix[alphabet_free]=current_string; alphabet->prefix[alphabet->free] = current_string;
alphabet_suffix[alphabet_free]=current_char; alphabet->suffix[alphabet->free] = current_char;
alphabet_free++; alphabet->free++;
} }
if (alphabet_free >= 4096) if (alphabet->free >= 4096)
{ {
// clear alphabet // clear alphabet
GIF_set_code(GIF_file, &GIF, GIF_buffer, clear); // 256 for 8bpp GIF_set_code(GIF_file, &GIF, GIF_buffer, clear); // 256 for 8bpp
alphabet_free=clear+2; // 258 for 8bpp alphabet->free=clear+2; // 258 for 8bpp
GIF.nb_bits =IDB.Nb_bits_pixel + 1; // 9 for 8bpp GIF.nb_bits = IDB.Nb_bits_pixel + 1; // 9 for 8bpp
alphabet_max =clear+clear-1; // 511 for 8bpp alphabet->max = clear+clear-1; // 511 for 8bpp
for (start=0;start<4096;start++) for (start=0;start<4096;start++)
{ {
alphabet_daughter[start] = GIF_INVALID_CODE; alphabet->daughter[start] = GIF_INVALID_CODE;
alphabet_sister[start] = GIF_INVALID_CODE; alphabet->sister[start] = GIF_INVALID_CODE;
} }
} }
else if (alphabet_free>alphabet_max+1) else if (alphabet->free > (alphabet->max + 1))
{ {
// On augmente le nb de bits // On augmente le nb de bits
GIF.nb_bits++; GIF.nb_bits++;
alphabet_max = (1<<GIF.nb_bits)-1; alphabet->max = (1<<GIF.nb_bits)-1;
} }
// initialize current_string as the string "current_char" // initialize current_string as the string "current_char"
index=alphabet_daughter[current_char]; index = alphabet->daughter[current_char];
start=current_string=current_char; start = current_string = current_char;
descend=1; descend = 1;
} }
} }
@ -1264,18 +1270,18 @@ void Save_GIF(T_IO_Context * context)
// Write the last code (before EOF) // Write the last code (before EOF)
GIF_set_code(GIF_file, &GIF, GIF_buffer, current_string); GIF_set_code(GIF_file, &GIF, GIF_buffer, current_string);
// we need to update alphabet_free / GIF.nb_bits here because // we need to update alphabet->free / GIF.nb_bits here because
// the decoder will update them after each code, // the decoder will update them after each code,
// so in very rare cases there might be a problem if we // so in very rare cases there might be a problem if we
// don't do it. // don't do it.
// see http://pulkomandy.tk/projects/GrafX2/ticket/125 // see http://pulkomandy.tk/projects/GrafX2/ticket/125
if(alphabet_free < 4096) if(alphabet->free < 4096)
{ {
alphabet_free++; alphabet->free++;
if ((alphabet_free > alphabet_max+1) && (GIF.nb_bits < 12)) if ((alphabet->free > alphabet->max+1) && (GIF.nb_bits < 12))
{ {
GIF.nb_bits++; GIF.nb_bits++;
alphabet_max = (1 << GIF.nb_bits) - 1; alphabet->max = (1 << GIF.nb_bits) - 1;
} }
} }
@ -1351,10 +1357,7 @@ void Save_GIF(T_IO_Context * context)
File_error=1; File_error=1;
// Libération de la mémoire utilisée par les tables // Libération de la mémoire utilisée par les tables
free(alphabet_sister); free(alphabet);
free(alphabet_daughter);
free(alphabet_suffix);
free(alphabet_prefix);
} // On a pu écrire la signature du fichier } // On a pu écrire la signature du fichier
else else