loadsave: change Test_XXX functions to open file only once

This commit is contained in:
Thomas Bernard 2018-03-12 00:53:10 +01:00
parent b039977f5f
commit cd8291b6ff
5 changed files with 240 additions and 358 deletions

View File

@ -81,31 +81,24 @@ static void Load_PNG_Sub(T_IO_Context * context, FILE * file);
//////////////////////////////////// IMG //////////////////////////////////// //////////////////////////////////// IMG ////////////////////////////////////
// -- Tester si un fichier est au format IMG -------------------------------- // -- Tester si un fichier est au format IMG --------------------------------
void Test_IMG(T_IO_Context * context) void Test_IMG(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
T_IMG_Header IMG_header; T_IMG_Header IMG_header;
byte signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; byte signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0};
File_error=1; File_error=1;
// Ouverture du fichier
if ((file=Open_file_read(context)))
{
// Lecture et vérification de la signature // Lecture et vérification de la signature
if (Read_bytes(file,IMG_header.Filler1,6) if (Read_bytes(file,IMG_header.Filler1,6)
&& Read_word_le(file,&(IMG_header.Width)) && Read_word_le(file,&(IMG_header.Width))
&& Read_word_le(file,&(IMG_header.Height)) && Read_word_le(file,&(IMG_header.Height))
&& Read_bytes(file,IMG_header.Filler2,118) && Read_bytes(file,IMG_header.Filler2,118)
&& Read_bytes(file,IMG_header.Palette,sizeof(T_Palette)) && Read_bytes(file,IMG_header.Palette,sizeof(T_Palette))
) )
{ {
if ( (!memcmp(IMG_header.Filler1,signature,6)) if ( (!memcmp(IMG_header.Filler1,signature,6))
&& IMG_header.Width && IMG_header.Height) && IMG_header.Width && IMG_header.Height)
File_error=0; File_error=0;
}
// Fermeture du fichier
fclose(file);
} }
} }
@ -263,17 +256,14 @@ typedef struct
// -- Tester si un fichier est au format IFF -------------------------------- // -- Tester si un fichier est au format IFF --------------------------------
void Test_IFF(T_IO_Context * context, const char *sub_type) void Test_IFF(T_IO_Context * context, FILE * IFF_file, const char *sub_type)
{ {
FILE * IFF_file;
char format[4]; char format[4];
char section[4]; char section[4];
dword dummy; dword dummy;
File_error=1; File_error=1;
if ((IFF_file=Open_file_read(context)))
{
do // Dummy loop, so that all breaks jump to end. do // Dummy loop, so that all breaks jump to end.
{ {
if (! Read_bytes(IFF_file,section,4)) if (! Read_bytes(IFF_file,section,4))
@ -329,21 +319,19 @@ void Test_IFF(T_IO_Context * context, const char *sub_type)
} while (0); } while (0);
fclose(IFF_file);
}
} }
void Test_PBM(T_IO_Context * context) void Test_PBM(T_IO_Context * context, FILE * f)
{ {
Test_IFF(context, "PBM "); Test_IFF(context, f, "PBM ");
} }
void Test_LBM(T_IO_Context * context) void Test_LBM(T_IO_Context * context, FILE * f)
{ {
Test_IFF(context, "ILBM"); Test_IFF(context, f, "ILBM");
} }
void Test_ACBM(T_IO_Context * context) void Test_ACBM(T_IO_Context * context, FILE * f)
{ {
Test_IFF(context, "ACBM"); Test_IFF(context, f, "ACBM");
} }
@ -2438,25 +2426,17 @@ static int Read_INFO_ImageHeader(FILE * file, T_INFO_ImageHeader * header)
); );
} }
void Test_INFO(T_IO_Context * context) void Test_INFO(T_IO_Context * context, FILE * file)
{ {
T_INFO_Header header; T_INFO_Header header;
char filename[MAX_PATH_CHARACTERS];
FILE *file;
File_error=1; File_error=1;
Get_full_filename(filename, context->File_name, context->File_directory);
file=fopen(filename, "rb");
if (file == NULL)
return;
if (Read_INFO_Header(file, &header)) if (Read_INFO_Header(file, &header))
{ {
if (header.Magic == 0xe310 && header.Version == 1) if (header.Magic == 0xe310 && header.Version == 1)
File_error = 0; File_error = 0;
} }
fclose(file);
} }
static char * Read_INFO_String(FILE * file) static char * Read_INFO_String(FILE * file)
@ -2919,42 +2899,36 @@ typedef struct
} T_BMP_Header; } T_BMP_Header;
// -- Tester si un fichier est au format BMP -------------------------------- // -- Tester si un fichier est au format BMP --------------------------------
void Test_BMP(T_IO_Context * context) void Test_BMP(T_IO_Context * context, FILE * file)
{ {
FILE *file;
T_BMP_Header header; T_BMP_Header header;
File_error=1; File_error=1;
if ((file=Open_file_read(context))) if (Read_bytes(file,&(header.Signature),2) // "BM"
&& Read_dword_le(file,&(header.Size_1))
&& Read_word_le(file,&(header.Reserved_1))
&& Read_word_le(file,&(header.Reserved_2))
&& Read_dword_le(file,&(header.Offset))
&& Read_dword_le(file,&(header.Size_2))
&& Read_dword_le(file,&(header.Width))
&& Read_dword_le(file,(dword *)&(header.Height))
&& Read_word_le(file,&(header.Planes))
&& Read_word_le(file,&(header.Nb_bits))
&& Read_dword_le(file,&(header.Compression))
&& Read_dword_le(file,&(header.Size_3))
&& Read_dword_le(file,&(header.XPM))
&& Read_dword_le(file,&(header.YPM))
&& Read_dword_le(file,&(header.Nb_Clr))
&& Read_dword_le(file,&(header.Clr_Imprt))
)
{ {
if (Read_bytes(file,&(header.Signature),2) // "BM" if ( header.Signature[0]=='B' && header.Signature[1]=='M'
&& Read_dword_le(file,&(header.Size_1))
&& Read_word_le(file,&(header.Reserved_1))
&& Read_word_le(file,&(header.Reserved_2))
&& Read_dword_le(file,&(header.Offset))
&& Read_dword_le(file,&(header.Size_2))
&& Read_dword_le(file,&(header.Width))
&& Read_dword_le(file,(dword *)&(header.Height))
&& Read_word_le(file,&(header.Planes))
&& Read_word_le(file,&(header.Nb_bits))
&& Read_dword_le(file,&(header.Compression))
&& Read_dword_le(file,&(header.Size_3))
&& Read_dword_le(file,&(header.XPM))
&& Read_dword_le(file,&(header.YPM))
&& Read_dword_le(file,&(header.Nb_Clr))
&& Read_dword_le(file,&(header.Clr_Imprt))
)
{
if ( header.Signature[0]=='B' && header.Signature[1]=='M'
&& (header.Size_2==40 /* WINDOWS */ || header.Size_2==12 /* OS/2 */) && (header.Size_2==40 /* WINDOWS */ || header.Size_2==12 /* OS/2 */)
&& header.Width && header.Height ) && header.Width && header.Height )
{ {
File_error=0; File_error=0;
} }
}
fclose(file);
} }
} }
@ -3503,9 +3477,8 @@ typedef struct {
dword offset; dword offset;
} T_ICO_ImageEntry; } T_ICO_ImageEntry;
void Test_ICO(T_IO_Context * context) void Test_ICO(T_IO_Context * context, FILE * file)
{ {
FILE *file;
struct { struct {
word Reserved; word Reserved;
word Type; // Specifies image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid. word Type; // Specifies image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid.
@ -3514,16 +3487,12 @@ void Test_ICO(T_IO_Context * context)
File_error=1; File_error=1;
if ((file=Open_file_read(context))) if (Read_word_le(file,&(header.Reserved))
&& Read_word_le(file,&(header.Type))
&& Read_word_le(file,&(header.Count)))
{ {
if (Read_word_le(file,&(header.Reserved)) if (header.Reserved == 0 && (header.Type == 1 || header.Type == 2) && header.Count > 0)
&& Read_word_le(file,&(header.Type)) File_error=0;
&& Read_word_le(file,&(header.Count)))
{
if (header.Reserved == 0 && (header.Type == 1 || header.Type == 2) && header.Count > 0)
File_error=0;
}
fclose(file);
} }
} }
@ -3891,28 +3860,20 @@ enum DISPOSAL_METHOD
// -- Tester si un fichier est au format GIF -------------------------------- // -- Tester si un fichier est au format GIF --------------------------------
void Test_GIF(T_IO_Context * context) void Test_GIF(T_IO_Context * context, FILE * file)
{ {
char signature[6]; char signature[6];
FILE *file;
File_error=1; File_error=1;
if ((file=Open_file_read(context))) if (Read_bytes(file,signature,6))
{ {
if ( if ((!memcmp(signature,"GIF87a",6))||(!memcmp(signature,"GIF89a",6)))
(Read_bytes(file,signature,6)) &&
((!memcmp(signature,"GIF87a",6))||(!memcmp(signature,"GIF89a",6)))
)
File_error=0; File_error=0;
fclose(file);
} }
} }
// -- Lire un fichier au format GIF -----------------------------------------
// -- Lire un fichier au format GIF ----------------------------------------- // -- Lire un fichier au format GIF -----------------------------------------
// Définition de quelques variables globales au chargement du GIF87a // Définition de quelques variables globales au chargement du GIF87a
@ -5099,51 +5060,44 @@ T_PCX_Header PCX_header;
// -- Tester si un fichier est au format PCX -------------------------------- // -- Tester si un fichier est au format PCX --------------------------------
void Test_PCX(T_IO_Context * context) void Test_PCX(T_IO_Context * context, FILE * file)
{ {
FILE *file;
File_error=0; File_error=0;
if ((file=Open_file_read(context))) if (Read_byte(file,&(PCX_header.Manufacturer)) &&
Read_byte(file,&(PCX_header.Version)) &&
Read_byte(file,&(PCX_header.Compression)) &&
Read_byte(file,&(PCX_header.Depth)) &&
Read_word_le(file,&(PCX_header.X_min)) &&
Read_word_le(file,&(PCX_header.Y_min)) &&
Read_word_le(file,&(PCX_header.X_max)) &&
Read_word_le(file,&(PCX_header.Y_max)) &&
Read_word_le(file,&(PCX_header.X_dpi)) &&
Read_word_le(file,&(PCX_header.Y_dpi)) &&
Read_bytes(file,&(PCX_header.Palette_16c),48) &&
Read_byte(file,&(PCX_header.Reserved)) &&
Read_byte(file,&(PCX_header.Plane)) &&
Read_word_le(file,&(PCX_header.Bytes_per_plane_line)) &&
Read_word_le(file,&(PCX_header.Palette_info)) &&
Read_word_le(file,&(PCX_header.Screen_X)) &&
Read_word_le(file,&(PCX_header.Screen_Y)) &&
Read_bytes(file,&(PCX_header.Filler),54) )
{ {
if (Read_byte(file,&(PCX_header.Manufacturer)) && // Vu que ce header a une signature de merde et peu significative, il
Read_byte(file,&(PCX_header.Version)) && // va falloir que je teste différentes petites valeurs dont je connais
Read_byte(file,&(PCX_header.Compression)) && // l'intervalle. Grrr!
Read_byte(file,&(PCX_header.Depth)) && if ( (PCX_header.Manufacturer!=10)
Read_word_le(file,&(PCX_header.X_min)) && || (PCX_header.Compression>1)
Read_word_le(file,&(PCX_header.Y_min)) && || ( (PCX_header.Depth!=1) && (PCX_header.Depth!=2) && (PCX_header.Depth!=4) && (PCX_header.Depth!=8) )
Read_word_le(file,&(PCX_header.X_max)) && || ( (PCX_header.Plane!=1) && (PCX_header.Plane!=2) && (PCX_header.Plane!=4) && (PCX_header.Plane!=8) && (PCX_header.Plane!=3) )
Read_word_le(file,&(PCX_header.Y_max)) && || (PCX_header.X_max<PCX_header.X_min)
Read_word_le(file,&(PCX_header.X_dpi)) && || (PCX_header.Y_max<PCX_header.Y_min)
Read_word_le(file,&(PCX_header.Y_dpi)) && || (PCX_header.Bytes_per_plane_line&1) )
Read_bytes(file,&(PCX_header.Palette_16c),48) &&
Read_byte(file,&(PCX_header.Reserved)) &&
Read_byte(file,&(PCX_header.Plane)) &&
Read_word_le(file,&(PCX_header.Bytes_per_plane_line)) &&
Read_word_le(file,&(PCX_header.Palette_info)) &&
Read_word_le(file,&(PCX_header.Screen_X)) &&
Read_word_le(file,&(PCX_header.Screen_Y)) &&
Read_bytes(file,&(PCX_header.Filler),54) )
{
// Vu que ce header a une signature de merde et peu significative, il
// va falloir que je teste différentes petites valeurs dont je connais
// l'intervalle. Grrr!
if ( (PCX_header.Manufacturer!=10)
|| (PCX_header.Compression>1)
|| ( (PCX_header.Depth!=1) && (PCX_header.Depth!=2) && (PCX_header.Depth!=4) && (PCX_header.Depth!=8) )
|| ( (PCX_header.Plane!=1) && (PCX_header.Plane!=2) && (PCX_header.Plane!=4) && (PCX_header.Plane!=8) && (PCX_header.Plane!=3) )
|| (PCX_header.X_max<PCX_header.X_min)
|| (PCX_header.Y_max<PCX_header.Y_min)
|| (PCX_header.Bytes_per_plane_line&1) )
File_error=1; File_error=1;
}
else
File_error=1;
fclose(file);
} }
else
File_error=1;
} }
@ -5642,31 +5596,25 @@ typedef struct
} T_SCx_Header; } T_SCx_Header;
// -- Tester si un fichier est au format SCx -------------------------------- // -- Tester si un fichier est au format SCx --------------------------------
void Test_SCx(T_IO_Context * context) void Test_SCx(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
//byte Signature[3]; //byte Signature[3];
T_SCx_Header SCx_header; T_SCx_Header SCx_header;
File_error=1; File_error=1;
// Ouverture du fichier // Ouverture du fichier
if ((file=Open_file_read(context)))
{
// Lecture et vérification de la signature // Lecture et vérification de la signature
if (Read_bytes(file,SCx_header.Filler1,4) if (Read_bytes(file,SCx_header.Filler1,4)
&& Read_word_le(file, &(SCx_header.Width)) && Read_word_le(file, &(SCx_header.Width))
&& Read_word_le(file, &(SCx_header.Height)) && Read_word_le(file, &(SCx_header.Height))
&& Read_byte(file, &(SCx_header.Filler2)) && Read_byte(file, &(SCx_header.Filler2))
&& Read_byte(file, &(SCx_header.Planes)) && Read_byte(file, &(SCx_header.Planes))
) )
{ {
if ( (!memcmp(SCx_header.Filler1,"RIX",3)) if ( (!memcmp(SCx_header.Filler1,"RIX",3))
&& SCx_header.Width && SCx_header.Height) && SCx_header.Width && SCx_header.Height)
File_error=0; File_error=0;
}
// Fermeture du fichier
fclose(file);
} }
} }
@ -5933,23 +5881,17 @@ void Save_XPM(T_IO_Context* context)
#ifndef __no_pnglib__ #ifndef __no_pnglib__
// -- Tester si un fichier est au format PNG -------------------------------- // -- Tester si un fichier est au format PNG --------------------------------
void Test_PNG(T_IO_Context * context) void Test_PNG(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
byte png_header[8]; byte png_header[8];
File_error=1; File_error=1;
// Ouverture du fichier // Lecture du header du fichier
if ((file=Open_file_read(context))) if (Read_bytes(file,png_header,8))
{ {
// Lecture du header du fichier if ( !png_sig_cmp(png_header, 0, 8))
if (Read_bytes(file,png_header,8)) File_error=0;
{
if ( !png_sig_cmp(png_header, 0, 8))
File_error=0;
}
fclose(file);
} }
} }

View File

@ -28,79 +28,79 @@
#include "loadsave.h" #include "loadsave.h"
// -- PKM ------------------------------------------------------------------- // -- PKM -------------------------------------------------------------------
void Test_PKM(T_IO_Context *); void Test_PKM(T_IO_Context *, FILE *);
void Load_PKM(T_IO_Context *); void Load_PKM(T_IO_Context *);
void Save_PKM(T_IO_Context *); void Save_PKM(T_IO_Context *);
// -- IFF ------------------------------------------------------------------- // -- IFF -------------------------------------------------------------------
void Test_LBM(T_IO_Context *); void Test_LBM(T_IO_Context *, FILE *);
void Test_PBM(T_IO_Context *); void Test_PBM(T_IO_Context *, FILE *);
void Test_ACBM(T_IO_Context *); void Test_ACBM(T_IO_Context *, FILE *);
void Load_IFF(T_IO_Context *); void Load_IFF(T_IO_Context *);
void Save_IFF(T_IO_Context *); void Save_IFF(T_IO_Context *);
// -- GIF ------------------------------------------------------------------- // -- GIF -------------------------------------------------------------------
void Test_GIF(T_IO_Context *); void Test_GIF(T_IO_Context *, FILE *);
void Load_GIF(T_IO_Context *); void Load_GIF(T_IO_Context *);
void Save_GIF(T_IO_Context *); void Save_GIF(T_IO_Context *);
// -- PCX ------------------------------------------------------------------- // -- PCX -------------------------------------------------------------------
void Test_PCX(T_IO_Context *); void Test_PCX(T_IO_Context *, FILE *);
void Load_PCX(T_IO_Context *); void Load_PCX(T_IO_Context *);
void Save_PCX(T_IO_Context *); void Save_PCX(T_IO_Context *);
// -- BMP ------------------------------------------------------------------- // -- BMP -------------------------------------------------------------------
void Test_BMP(T_IO_Context *); void Test_BMP(T_IO_Context *, FILE *);
void Load_BMP(T_IO_Context *); void Load_BMP(T_IO_Context *);
void Save_BMP(T_IO_Context *); void Save_BMP(T_IO_Context *);
// -- IMG ------------------------------------------------------------------- // -- IMG -------------------------------------------------------------------
void Test_IMG(T_IO_Context *); void Test_IMG(T_IO_Context *, FILE *);
void Load_IMG(T_IO_Context *); void Load_IMG(T_IO_Context *);
void Save_IMG(T_IO_Context *); void Save_IMG(T_IO_Context *);
// -- SCx ------------------------------------------------------------------- // -- SCx -------------------------------------------------------------------
void Test_SCx(T_IO_Context *); void Test_SCx(T_IO_Context *, FILE *);
void Load_SCx(T_IO_Context *); void Load_SCx(T_IO_Context *);
void Save_SCx(T_IO_Context *); void Save_SCx(T_IO_Context *);
// -- CEL ------------------------------------------------------------------- // -- CEL -------------------------------------------------------------------
void Test_CEL(T_IO_Context *); void Test_CEL(T_IO_Context *, FILE *);
void Load_CEL(T_IO_Context *); void Load_CEL(T_IO_Context *);
void Save_CEL(T_IO_Context *); void Save_CEL(T_IO_Context *);
// -- KCF ------------------------------------------------------------------- // -- KCF -------------------------------------------------------------------
void Test_KCF(T_IO_Context *); void Test_KCF(T_IO_Context *, FILE *);
void Load_KCF(T_IO_Context *); void Load_KCF(T_IO_Context *);
void Save_KCF(T_IO_Context *); void Save_KCF(T_IO_Context *);
// -- PAL ------------------------------------------------------------------- // -- PAL -------------------------------------------------------------------
void Test_PAL(T_IO_Context *); void Test_PAL(T_IO_Context *, FILE *);
void Load_PAL(T_IO_Context *); void Load_PAL(T_IO_Context *);
void Save_PAL(T_IO_Context *); void Save_PAL(T_IO_Context *);
// -- GPL ------------------------------------------------------------------- // -- GPL -------------------------------------------------------------------
void Test_GPL(T_IO_Context *); void Test_GPL(T_IO_Context *, FILE *);
void Load_GPL(T_IO_Context *); void Load_GPL(T_IO_Context *);
void Save_GPL(T_IO_Context *); void Save_GPL(T_IO_Context *);
// -- PI1 ------------------------------------------------------------------- // -- PI1 -------------------------------------------------------------------
void Test_PI1(T_IO_Context *); void Test_PI1(T_IO_Context *, FILE *);
void Load_PI1(T_IO_Context *); void Load_PI1(T_IO_Context *);
void Save_PI1(T_IO_Context *); void Save_PI1(T_IO_Context *);
// -- PC1 ------------------------------------------------------------------- // -- PC1 -------------------------------------------------------------------
void Test_PC1(T_IO_Context *); void Test_PC1(T_IO_Context *, FILE *);
void Load_PC1(T_IO_Context *); void Load_PC1(T_IO_Context *);
void Save_PC1(T_IO_Context *); void Save_PC1(T_IO_Context *);
// -- NEO ------------------------------------------------------------------- // -- NEO -------------------------------------------------------------------
void Test_NEO(T_IO_Context *); void Test_NEO(T_IO_Context *, FILE *);
void Load_NEO(T_IO_Context *); void Load_NEO(T_IO_Context *);
void Save_NEO(T_IO_Context *); void Save_NEO(T_IO_Context *);
// -- C64 ------------------------------------------------------------------- // -- C64 -------------------------------------------------------------------
void Test_C64(T_IO_Context *); void Test_C64(T_IO_Context *, FILE *);
void Load_C64(T_IO_Context *); void Load_C64(T_IO_Context *);
void Save_C64(T_IO_Context *); void Save_C64(T_IO_Context *);
@ -108,12 +108,12 @@ void Save_C64(T_IO_Context *);
void Save_SCR(T_IO_Context *); void Save_SCR(T_IO_Context *);
// -- CM5 (Amstrad CPC) // -- CM5 (Amstrad CPC)
void Test_CM5(T_IO_Context *); void Test_CM5(T_IO_Context *, FILE *);
void Load_CM5(T_IO_Context *); void Load_CM5(T_IO_Context *);
void Save_CM5(T_IO_Context *); void Save_CM5(T_IO_Context *);
// -- PPH (Amstrad CPC) // -- PPH (Amstrad CPC)
void Test_PPH(T_IO_Context *); void Test_PPH(T_IO_Context *, FILE *);
void Load_PPH(T_IO_Context *); void Load_PPH(T_IO_Context *);
void Save_PPH(T_IO_Context *); void Save_PPH(T_IO_Context *);
@ -122,19 +122,19 @@ void Save_PPH(T_IO_Context *);
void Save_XPM(T_IO_Context*); void Save_XPM(T_IO_Context*);
// -- ICO (Windows ICO) // -- ICO (Windows ICO)
void Test_ICO(T_IO_Context *); void Test_ICO(T_IO_Context *, FILE *);
void Load_ICO(T_IO_Context *); void Load_ICO(T_IO_Context *);
void Save_ICO(T_IO_Context *); void Save_ICO(T_IO_Context *);
// -- PNG ------------------------------------------------------------------- // -- PNG -------------------------------------------------------------------
#ifndef __no_pnglib__ #ifndef __no_pnglib__
void Test_PNG(T_IO_Context *); void Test_PNG(T_IO_Context *, FILE *);
void Load_PNG(T_IO_Context *); void Load_PNG(T_IO_Context *);
void Save_PNG(T_IO_Context *); void Save_PNG(T_IO_Context *);
#endif #endif
// -- INFO (Amiga ICONS) ---------------------------------------------------- // -- INFO (Amiga ICONS) ----------------------------------------------------
void Test_INFO(T_IO_Context *); void Test_INFO(T_IO_Context *, FILE *);
void Load_INFO(T_IO_Context *); void Load_INFO(T_IO_Context *);
#endif #endif

View File

@ -532,6 +532,7 @@ void Load_image(T_IO_Context *context)
const T_Format *format = &(File_formats[FORMAT_ALL_FILES+1]); // Format du fichier à charger const T_Format *format = &(File_formats[FORMAT_ALL_FILES+1]); // Format du fichier à charger
int i; int i;
byte old_cursor_shape; byte old_cursor_shape;
FILE * f;
// Not sure it's the best place... // Not sure it's the best place...
context->Color_cycles=0; context->Color_cycles=0;
@ -540,11 +541,19 @@ void Load_image(T_IO_Context *context)
// charger le format du fichier: // charger le format du fichier:
File_error=1; File_error=1;
f = Open_file_read(context);
if (f == NULL)
{
Warning("Cannot open file for reading");
Error(0);
return;
}
if (context->Format>FORMAT_ALL_FILES) if (context->Format>FORMAT_ALL_FILES)
{ {
format = Get_fileformat(context->Format); format = Get_fileformat(context->Format);
if (format->Test) if (format->Test)
format->Test(context); format->Test(context, f);
} }
if (File_error) if (File_error)
@ -558,14 +567,16 @@ void Load_image(T_IO_Context *context)
if (format->Test == NULL) if (format->Test == NULL)
continue; continue;
fseek(f, 0, SEEK_SET); // rewind
// On appelle le testeur du format: // On appelle le testeur du format:
format->Test(context); format->Test(context, f);
// On s'arrête si le fichier est au bon format: // On s'arrête si le fichier est au bon format:
if (File_error==0) if (File_error==0)
break; break;
} }
} }
fclose(f);
if (File_error) if (File_error)
{ {
context->Format = DEFAULT_FILEFORMAT; context->Format = DEFAULT_FILEFORMAT;

View File

@ -116,6 +116,7 @@ typedef struct
#define PREVIEW_HEIGHT 80 #define PREVIEW_HEIGHT 80
/// Type of a function that can be called for a T_IO_Context. Kind of a method. /// Type of a function that can be called for a T_IO_Context. Kind of a method.
typedef void (* Func_IO_Test) (T_IO_Context *, FILE *);
typedef void (* Func_IO) (T_IO_Context *); typedef void (* Func_IO) (T_IO_Context *);
/* /*
@ -165,15 +166,15 @@ void Delete_safety_backups(void);
/// Data for an image file format. /// Data for an image file format.
typedef struct { typedef struct {
byte Identifier; ///< Identifier for this format in enum :FILE_FORMATS byte Identifier; ///< Identifier for this format in enum :FILE_FORMATS
char *Label; ///< Five-letter label const char *Label; ///< Five-letter label
Func_IO Test; ///< Function which tests if the file is of this format Func_IO_Test Test; ///< Function which tests if the file is of this format
Func_IO Load; ///< Function which loads an image of this format Func_IO Load; ///< Function which loads an image of this format
Func_IO Save; ///< Function which saves an image of this format Func_IO Save; ///< Function which saves an image of this format
byte Palette_only; ///< Boolean, true if this format saves/loads only the palette. byte Palette_only; ///< Boolean, true if this format saves/loads only the palette.
byte Comment; ///< This file format allows a text comment byte Comment; ///< This file format allows a text comment
byte Supports_layers; ///< Boolean, true if this format preserves layers on saving byte Supports_layers; ///< Boolean, true if this format preserves layers on saving
char *Default_extension; ///< Default file extension const char *Default_extension; ///< Default file extension
char *Extensions; ///< List of semicolon-separated file extensions const char *Extensions; ///< List of semicolon-separated file extensions
} T_Format; } T_Format;
/// Array of the known file formats /// Array of the known file formats

View File

@ -47,70 +47,60 @@
// //
// -- Test wether a file is in PAL format -------------------------------- // -- Test wether a file is in PAL format --------------------------------
void Test_PAL(T_IO_Context * context) void Test_PAL(T_IO_Context * context, FILE * file)
{ {
char buffer[32]; char buffer[32];
FILE *file;
long file_size; long file_size;
File_error = 1; File_error = 1;
if ((file = Open_file_read(context))) file_size = File_length_file(file);
// First check for GrafX2 legacy palette format. The simplest one, 768 bytes
// of RGB data. It is a raw dump of the T_Palette structure. There is no
// header at all, so we check for the file size.
if (file_size == sizeof(T_Palette))
File_error = 0;
else
{ {
file_size = File_length_file(file); // Bigger (or smaller ?) files may be in other formats. These have an
// First check for GrafX2 legacy palette format. The simplest one, 768 bytes // header, so look for it.
// of RGB data. It is a raw dump of the T_Palette structure. There is no fread(buffer, 1, 8, file);
// header at all, so we check for the file size. if (strncmp(buffer,"JASC-PAL",8) == 0)
if (file_size == sizeof(T_Palette))
File_error = 0;
else
{ {
// Bigger (or smaller ?) files may be in other formats. These have an // JASC file format, used by Paint Shop Pro and GIMP. This is also the
// header, so look for it. // one used for saving, as it brings greater interoperability.
File_error = 0;
}
else if(strncmp(buffer,"RIFF", 4) == 0)
{
// Microsoft RIFF file
// This is a data container (similar to IFF). We only check the first
// chunk header, and give up if that's not a palette.
fseek(file, 8, SEEK_SET);
fread(buffer, 1, 8, file); fread(buffer, 1, 8, file);
if (strncmp(buffer,"JASC-PAL",8) == 0) if (strncmp(buffer, "PAL data", 8) == 0)
{ {
// JASC file format, used by Paint Shop Pro and GIMP. This is also the
// one used for saving, as it brings greater interoperability.
File_error = 0; File_error = 0;
} }
else if(strncmp(buffer,"RIFF", 4) == 0)
{
// Microsoft RIFF file
// This is a data container (similar to IFF). We only check the first
// chunk header, and give up if that's not a palette.
fseek(file, 8, SEEK_SET);
fread(buffer, 1, 8, file);
if (strncmp(buffer, "PAL data", 8) == 0)
{
File_error = 0;
}
}
} }
fclose(file);
} }
} }
void Test_GPL(T_IO_Context * context) void Test_GPL(T_IO_Context * context, FILE * file)
{ {
char buffer[16]; char buffer[16];
FILE *file;
long file_size; long file_size;
File_error = 1; File_error = 1;
if ((file = Open_file_read(context))) file_size = File_length_file(file);
{ if (file_size > 33) {
file_size = File_length_file(file); // minimum header length == 33
if (file_size > 33) { // "GIMP Palette" == 12
// minimum header length == 33 fread(buffer, 1, 12, file);
// "GIMP Palette" == 12 if (strncmp(buffer,"GIMP Palette",12) == 0)
fread(buffer, 1, 12, file); File_error = 0;
if (strncmp(buffer,"GIMP Palette",12) == 0)
File_error = 0;
}
} }
fclose(file);
} }
// skip the padding before a space-padded field. // skip the padding before a space-padded field.
@ -381,34 +371,27 @@ typedef struct
} T_PKM_Header; } T_PKM_Header;
// -- Tester si un fichier est au format PKM -------------------------------- // -- Tester si un fichier est au format PKM --------------------------------
void Test_PKM(T_IO_Context * context) void Test_PKM(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
T_PKM_Header header; T_PKM_Header header;
File_error=1; File_error=1;
// Ouverture du fichier // Lecture du header du fichier
if ((file=Open_file_read(context))) if (Read_bytes(file,&header.Ident,3) &&
Read_byte(file,&header.Method) &&
Read_byte(file,&header.Recog1) &&
Read_byte(file,&header.Recog2) &&
Read_word_le(file,&header.Width) &&
Read_word_le(file,&header.Height) &&
Read_bytes(file,&header.Palette,sizeof(T_Palette)) &&
Read_word_le(file,&header.Jump))
{ {
// Lecture du header du fichier // On regarde s'il y a la signature PKM suivie de la méthode 0.
if (Read_bytes(file,&header.Ident,3) && // La constante "PKM" étant un chaîne, elle se termine toujours par 0.
Read_byte(file,&header.Method) && // Donc pas la peine de s'emm...er à regarder si la méthode est à 0.
Read_byte(file,&header.Recog1) && if ( (!memcmp(&header,"PKM",4)) && header.Width && header.Height)
Read_byte(file,&header.Recog2) && File_error=0;
Read_word_le(file,&header.Width) &&
Read_word_le(file,&header.Height) &&
Read_bytes(file,&header.Palette,sizeof(T_Palette)) &&
Read_word_le(file,&header.Jump))
{
// On regarde s'il y a la signature PKM suivie de la méthode 0.
// La constante "PKM" étant un chaîne, elle se termine toujours par 0.
// Donc pas la peine de s'emm...er à regarder si la méthode est à 0.
if ( (!memcmp(&header,"PKM",4)) && header.Width && header.Height)
File_error=0;
}
fclose(file);
} }
} }
@ -836,21 +819,15 @@ typedef struct
// -- Tester si un fichier est au format CEL -------------------------------- // -- Tester si un fichier est au format CEL --------------------------------
void Test_CEL(T_IO_Context * context) void Test_CEL(T_IO_Context * context, FILE * file)
{ {
int size; int size;
FILE *file;
T_CEL_Header1 header1; T_CEL_Header1 header1;
T_CEL_Header2 header2; T_CEL_Header2 header2;
int file_size; int file_size;
File_error=0; File_error=0;
if (! (file=Open_file_read(context)))
{
File_error = 1;
return;
}
file_size = File_length_file(file); file_size = File_length_file(file);
if (Read_word_le(file,&header1.Width) && if (Read_word_le(file,&header1.Width) &&
Read_word_le(file,&header1.Height) ) Read_word_le(file,&header1.Height) )
@ -888,7 +865,6 @@ void Test_CEL(T_IO_Context * context)
{ {
File_error=1; File_error=1;
} }
fclose(file);
} }
@ -1151,17 +1127,14 @@ typedef struct
// -- Tester si un fichier est au format KCF -------------------------------- // -- Tester si un fichier est au format KCF --------------------------------
void Test_KCF(T_IO_Context * context) void Test_KCF(T_IO_Context * context, FILE * file)
{ {
FILE *file;
T_KCF_Header header1; T_KCF_Header header1;
T_CEL_Header2 header2; T_CEL_Header2 header2;
int pal_index; int pal_index;
int color_index; int color_index;
File_error=0; File_error=0;
if ((file=Open_file_read(context)))
{
if (File_length_file(file)==320) if (File_length_file(file)==320)
{ {
for (pal_index=0;pal_index<10 && !File_error;pal_index++) for (pal_index=0;pal_index<10 && !File_error;pal_index++)
@ -1199,10 +1172,6 @@ void Test_KCF(T_IO_Context * context)
else else
File_error=1; File_error=1;
} }
fclose(file);
}
else
File_error=1;
} }
@ -1621,18 +1590,13 @@ void PI1_save_ranges(T_IO_Context * context, byte * buffer, int size)
} }
} }
// -- Tester si un fichier est au format PI1 -------------------------------- // -- Tester si un fichier est au format PI1 --------------------------------
void Test_PI1(T_IO_Context * context) void Test_PI1(T_IO_Context * context, FILE * file)
{ {
FILE * file; // Fichier du fichier
int size; // Taille du fichier int size; // Taille du fichier
word resolution; // Résolution de l'image word resolution; // Résolution de l'image
File_error=1; File_error=1;
// Ouverture du fichier
if ((file=Open_file_read(context)))
{
// Vérification de la taille // Vérification de la taille
size=File_length_file(file); size=File_length_file(file);
if ((size==32034) || (size==32066)) if ((size==32034) || (size==32066))
@ -1644,9 +1608,6 @@ void Test_PI1(T_IO_Context * context)
File_error=0; File_error=0;
} }
} }
// Fermeture du fichier
fclose(file);
}
} }
@ -1937,18 +1898,13 @@ void PC1_1line_to_4bp(byte * src,byte * dst0,byte * dst1,byte * dst2,byte * dst3
// -- Tester si un fichier est au format PC1 -------------------------------- // -- Tester si un fichier est au format PC1 --------------------------------
void Test_PC1(T_IO_Context * context) void Test_PC1(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
int size; // Taille du fichier int size; // Taille du fichier
word resolution; // Résolution de l'image word resolution; // Résolution de l'image
File_error=1; File_error=1;
// Ouverture du fichier
if ((file=Open_file_read(context)))
{
// Vérification de la taille // Vérification de la taille
size=File_length_file(file); size=File_length_file(file);
if ((size<=32066)) if ((size<=32066))
@ -1960,9 +1916,6 @@ void Test_PC1(T_IO_Context * context)
File_error=0; File_error=0;
} }
} }
// Fermeture du fichier
fclose(file);
}
} }
@ -2112,18 +2065,13 @@ void Save_PC1(T_IO_Context * context)
//////////////////////////////////// NEO //////////////////////////////////// //////////////////////////////////// NEO ////////////////////////////////////
void Test_NEO(T_IO_Context * context) void Test_NEO(T_IO_Context * context, FILE * file)
{ {
FILE *file; // Fichier du fichier
int size; // Taille du fichier int size; // Taille du fichier
word resolution; // Résolution de l'image word resolution; // Résolution de l'image
File_error=1; File_error=1;
// Ouverture du fichier
if ((file=Open_file_read(context)))
{
// Vérification de la taille // Vérification de la taille
size=File_length_file(file); size=File_length_file(file);
if ((size==32128)) if ((size==32128))
@ -2142,10 +2090,6 @@ void Test_NEO(T_IO_Context * context)
File_error |= 0; File_error |= 0;
} }
} }
// Fermeture du fichier
fclose(file);
}
} }
void Load_NEO(T_IO_Context * context) void Load_NEO(T_IO_Context * context)
@ -2269,40 +2213,29 @@ void Save_NEO(T_IO_Context * context)
//////////////////////////////////// C64 //////////////////////////////////// //////////////////////////////////// C64 ////////////////////////////////////
void Test_C64(T_IO_Context * context) void Test_C64(T_IO_Context * context, FILE * file)
{ {
FILE* file; long file_size;
long file_size;
file = Open_file_read(context); file_size = File_length_file(file);
switch (file_size)
if (file) {
{ // case 1000: // screen or color
file_size = File_length_file(file); // case 1002: // (screen or color) + loadaddr
switch (file_size) case 8000: // raw bitmap
{ case 8002: // raw bitmap with loadaddr
// case 1000: // screen or color case 9000: // bitmap + ScreenRAM
// case 1002: // (screen or color) + loadaddr case 9002: // bitmap + ScreenRAM + loadaddr
case 8000: // raw bitmap case 10001: // multicolor
case 8002: // raw bitmap with loadaddr case 10003: // multicolor + loadaddr
case 9000: // bitmap + ScreenRAM case 17472: // FLI (BlackMail)
case 9002: // bitmap + ScreenRAM + loadaddr case 17474: // FLI (BlackMail) + loadaddr
case 10001: // multicolor case 10277: // multicolor CDU-Paint + loadaddr
case 10003: // multicolor + loadaddr File_error = 0;
case 17472: // FLI (BlackMail) break;
case 17474: // FLI (BlackMail) + loadaddr default: // then we don't know for now.
case 10277: // multicolor CDU-Paint + loadaddr File_error = 1;
File_error = 0; }
break;
default: // then we don't know for now.
File_error = 1;
}
fclose (file);
}
else
{
File_error = 1;
}
} }
void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *screen_ram) void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *screen_ram)
@ -3095,7 +3028,7 @@ void Save_C64(T_IO_Context * context)
// SCR (Amstrad CPC) // SCR (Amstrad CPC)
void Test_SCR(T_IO_Context * context) void Test_SCR(T_IO_Context * context, FILE * file)
{ {
// Mmh... not sure what we could test. Any idea ? // Mmh... not sure what we could test. Any idea ?
// The palette file can be tested, if it exists and have the right size it's // The palette file can be tested, if it exists and have the right size it's
@ -3105,6 +3038,7 @@ void Test_SCR(T_IO_Context * context)
// An AMSDOS header would be a good indication but in some cases it may not // An AMSDOS header would be a good indication but in some cases it may not
// be there // be there
(void)context; // unused (void)context; // unused
(void)file;
} }
void Load_SCR(T_IO_Context * context) void Load_SCR(T_IO_Context * context)
@ -3185,28 +3119,24 @@ void Save_SCR(T_IO_Context * context)
// This is a format designed by SyX. There is one .GFX file in the usual amstrad format, // This is a format designed by SyX. There is one .GFX file in the usual amstrad format,
// and a .CM5 file with the palette, which varies over time. // and a .CM5 file with the palette, which varies over time.
void Test_CM5(T_IO_Context * context) void Test_CM5(T_IO_Context * context, FILE * file)
{ {
// check cm5 file size == 2049 bytes // check cm5 file size == 2049 bytes
FILE *file; FILE *file_gfx;
long file_size; long file_size;
File_error = 1; File_error = 1;
file = Open_file_read(context);
if (file == NULL)
return;
file_size = File_length_file(file); file_size = File_length_file(file);
fclose(file);
if (file_size != 2049) if (file_size != 2049)
return; return;
// check existence of a .GFX file with the same name // check existence of a .GFX file with the same name
file = Open_file_read_with_alternate_ext(context, "gfx"); file_gfx = Open_file_read_with_alternate_ext(context, "gfx");
if (file == NULL) if (file_gfx == NULL)
return; return;
file_size = File_length_file(file); file_size = File_length_file(file_gfx);
fclose(file); fclose(file_gfx);
if (file_size != 18432) if (file_size != 18432)
return; return;
@ -3469,9 +3399,9 @@ void Save_CM5(T_IO_Context* context)
// //
// - The standard CPC formats can also be encapsulated into a PPH file. // - The standard CPC formats can also be encapsulated into a PPH file.
*/ */
void Test_PPH(T_IO_Context * context) void Test_PPH(T_IO_Context * context, FILE * file)
{ {
FILE *file; FILE *file_oddeve;
byte buffer[6]; byte buffer[6];
unsigned long file_size; unsigned long file_size;
unsigned int w, h; unsigned int w, h;
@ -3479,45 +3409,41 @@ void Test_PPH(T_IO_Context * context)
File_error = 1; File_error = 1;
file = Open_file_read(context);
if (file == NULL)
return;
// First check file size is large enough to hold the header // First check file size is large enough to hold the header
file_size = File_length_file(file); file_size = File_length_file(file);
if (file_size < 11) { if (file_size < 11) {
File_error = 1; File_error = 1;
goto abort; return;
} }
// File is large enough for the header, now check if the data makes some sense // File is large enough for the header, now check if the data makes some sense
if (!Read_bytes(file, buffer, 6)) if (!Read_bytes(file, buffer, 6))
goto abort; return;
if (buffer[0] > 5) { if (buffer[0] > 5) {
// Unknown mode // Unknown mode
File_error = 2; File_error = 2;
goto abort; return;
} }
w = buffer[1] | (buffer[2] << 8); w = buffer[1] | (buffer[2] << 8);
if (w < 2 || w > 384) { if (w < 2 || w > 384) {
// Invalid width // Invalid width
File_error = 3; File_error = 3;
goto abort; return;
} }
h = buffer[3] | (buffer[4] << 8); h = buffer[3] | (buffer[4] << 8);
if (h < 1 || h > 272) { if (h < 1 || h > 272) {
// Invalid height // Invalid height
File_error = 4; File_error = 4;
goto abort; return;
} }
if (buffer[5] < 1 || buffer[5] > 28) if (buffer[5] < 1 || buffer[5] > 28)
{ {
// Invalid palettes count // Invalid palettes count
File_error = 5; File_error = 5;
goto abort; return;
} }
expected = 6; // Size of header expected = 6; // Size of header
switch(buffer[0]) switch(buffer[0])
@ -3528,7 +3454,7 @@ void Test_PPH(T_IO_Context * context)
// Palette size should be 16 bytes, only 1 palette. // Palette size should be 16 bytes, only 1 palette.
if (buffer[5] != 1) { if (buffer[5] != 1) {
File_error = 7; File_error = 7;
goto abort; return;
} }
expected += 16; expected += 16;
break; break;
@ -3542,7 +3468,7 @@ void Test_PPH(T_IO_Context * context)
// Palette size should be 2 bytes // Palette size should be 2 bytes
if (buffer[5] != 1) { if (buffer[5] != 1) {
File_error = 7; File_error = 7;
goto abort; return;
} }
expected += 2; expected += 2;
break; break;
@ -3551,31 +3477,33 @@ void Test_PPH(T_IO_Context * context)
if (file_size != expected) if (file_size != expected)
{ {
File_error = 6; File_error = 6;
goto abort; return;
} }
fclose (file);
// check existence of .ODD/.EVE files with the same name // check existence of .ODD/.EVE files with the same name
// and the right size // and the right size
expected = w * h / 4; expected = w * h / 4;
file = Open_file_read_with_alternate_ext(context, "odd"); file_oddeve = Open_file_read_with_alternate_ext(context, "odd");
if (file == NULL) if (file_oddeve == NULL)
goto abort; return;
file_size = File_length_file(file); file_size = File_length_file(file_oddeve);
fclose (file); fclose (file_oddeve);
file = Open_file_read_with_alternate_ext(context, "eve"); if (file_size != expected)
if (file == NULL)
goto abort;
if (file_size != File_length_file(file) || file_size != expected)
{ {
File_error = 8; File_error = 8;
goto abort; return;
}
file_oddeve = Open_file_read_with_alternate_ext(context, "eve");
if (file_oddeve == NULL)
return;
file_size = File_length_file(file_oddeve);
fclose(file_oddeve);
if (file_size != expected)
{
File_error = 8;
return;
} }
File_error = 0; File_error = 0;
abort:
if (file != NULL)
fclose(file);
} }