diff --git a/Makefile b/Makefile index 94616602..b8145183 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ ifdef COMSPEC BIN = grafx2.exe CFGBIN = gfxcfg.exe COPT = -W -Wall -Wdeclaration-after-statement -O -g -ggdb `sdl-config --cflags` $(TTFCOPT) - LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) + LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng CC = gcc OBJDIR = obj/win32 # Resources (icon) diff --git a/const.h b/const.h index 4c8a5706..cae6da56 100644 --- a/const.h +++ b/const.h @@ -89,9 +89,9 @@ // Les différents formats de fichiers: -#define NB_FORMATS_CONNUS 12 // Nombre de formats connus (devrait être la valeur maximale de NB_FORMATS_LOAD et NB_FORMATS_SAVE, mais plus généralement: Card({NB_FORMATS_LOAD} UNION {NB_FORMATS_SAVE})) -#define NB_FORMATS_LOAD 12 // Nombre de formats que l'on sait charger -#define NB_FORMATS_SAVE 12 // Nombre de formats que l'on sait sauver +#define NB_FORMATS_CONNUS 13 // Nombre de formats connus (devrait être la valeur maximale de NB_FORMATS_LOAD et NB_FORMATS_SAVE, mais plus généralement: Card({NB_FORMATS_LOAD} UNION {NB_FORMATS_SAVE})) +#define NB_FORMATS_LOAD 13 // Nombre de formats que l'on sait charger +#define NB_FORMATS_SAVE 13 // Nombre de formats que l'on sait sauver enum FORMATS_RECONNUS { @@ -106,7 +106,8 @@ enum FORMATS_RECONNUS FORMAT_PC1, // | l'on doit aller piocher ces FORMAT_CEL, // | données. FORMAT_KCF, // | - FORMAT_PAL // | + FORMAT_PAL, // | + FORMAT_PNG // | }; #define FORMAT_PAR_DEFAUT FORMAT_GIF // Format par défaut (ah bon? oh!) diff --git a/global.h b/global.h index 47502213..a221c498 100644 --- a/global.h +++ b/global.h @@ -675,7 +675,8 @@ void Rien_du_tout(void); "pc1", // PC1 "cel", // CEL "kcf", // KCF - "pal" // PAL + "pal", // PAL + "png", // PNG }; // Fonction à appeler pour vérifier la signature du fichier @@ -692,7 +693,8 @@ void Rien_du_tout(void); Test_PC1, // PC1 Test_CEL, // CEL Test_KCF, // KCF - Test_PAL // PAL + Test_PAL, // PAL + Test_PNG // PNG }; // Fonction à appeler pour charger l'image @@ -709,7 +711,8 @@ void Rien_du_tout(void); Load_PC1, // PC1 Load_CEL, // CEL Load_KCF, // KCF - Load_PAL // PAL + Load_PAL, // PAL + Load_PNG // PNG }; // Fonction à appeler pour sauvegarder l'image @@ -726,7 +729,8 @@ void Rien_du_tout(void); Save_PC1, // PC1 Save_CEL, // CEL Save_KCF, // KCF - Save_PAL // PAL + Save_PAL, // PAL + Save_PNG // PNG }; // indique si l'on doit considérer que l'image n'est plus modifiée @@ -743,7 +747,8 @@ void Rien_du_tout(void); 1, // PC1 1, // CEL 0, // KCF - 0 // PAL + 0, // PAL + 1 // PNG }; // Le format de fichier autorise un commentaire @@ -760,7 +765,8 @@ void Rien_du_tout(void); 0, // PC1 0, // CEL 0, // KCF - 0 // PAL + 0, // PAL + 0 // PNG }; #else extern char Format_Extension[NB_FORMATS_CONNUS][4]; diff --git a/loadsave.c b/loadsave.c index aa4a4352..3d381bac 100644 --- a/loadsave.c +++ b/loadsave.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "const.h" #include "struct.h" @@ -5346,3 +5347,324 @@ void Load_TGA(char * nom,Bitmap24B * dest,int * larg,int * haut) } fclose(fichier); } + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// PNG //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +// -- Tester si un fichier est au format PNG -------------------------------- +void Test_PNG(void) +{ + FILE *Fichier; // Fichier du fichier + char Nom_du_fichier[TAILLE_CHEMIN_FICHIER]; // Nom complet du fichier + char PNG_header[8]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + if ((Fichier=fopen(Nom_du_fichier, "rb"))) + { + // Lecture du header du fichier + if (read_bytes(Fichier,PNG_header,8)) + { + if ( !png_sig_cmp(PNG_header, 0, 8)) + Erreur_fichier=0; + } + fclose(Fichier); + } +} + +png_bytep * row_pointers; +// -- Lire un fichier au format PNG ----------------------------------------- +void Load_PNG(void) +{ + FILE *Fichier; // Fichier du fichier + char Nom_du_fichier[TAILLE_CHEMIN_FICHIER]; // Nom complet du fichier + char PNG_header[8]; + dword Taille_image; + long Taille_du_fichier; + struct stat Informations_Fichier; + + png_structp png_ptr; + png_infop info_ptr; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=fopen(Nom_du_fichier, "rb"))) + { + stat(Nom_du_fichier,&Informations_Fichier); + Taille_du_fichier=Informations_Fichier.st_size; + + if (read_bytes(Fichier,PNG_header,8)) + { + if ( !png_sig_cmp(PNG_header, 0, 8)) + { + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr) + { + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr) + { + png_byte color_type; + png_byte bit_depth; + + if (!setjmp(png_jmpbuf(png_ptr))) + { + png_init_io(png_ptr, Fichier); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + color_type = info_ptr->color_type; + bit_depth = info_ptr->bit_depth; + + if (bit_depth <= 8 && (color_type == PNG_COLOR_TYPE_PALETTE || PNG_COLOR_TYPE_GRAY)) + { + Initialiser_preview(info_ptr->width,info_ptr->height,Taille_du_fichier,FORMAT_PNG); + + if (Erreur_fichier==0) + { + int x,y; + png_colorp palette; + int num_palette; + + if (color_type == PNG_COLOR_TYPE_GRAY) + { + if (bit_depth < 8) + png_set_gray_1_2_4_to_8(png_ptr); + // palette de niveaux de gris + for (x=0;xwidth; + Principal_Hauteur_image=info_ptr->height; + Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); + Principal_Commentaire[0]='\0'; // On efface le commentaire + + png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + /* read file */ + if (!setjmp(png_jmpbuf(png_ptr))) + { + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * Principal_Hauteur_image); + for (y=0; yrowbytes); + png_read_image(png_ptr, row_pointers); + + for (y=0; y>8); + Ecrire_octet(Fichier,Hauteur_ecran&0xFF); + Ecrire_octet(Fichier,Hauteur_ecran>>8); + // Ecriture de la back-color + Ecrire_octet(Fichier,2); + Ecrire_octet(Fichier,1); + Ecrire_octet(Fichier,Back_color); + + // Routine de compression PKM de l'image + Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); + Compteur_de_pixels=0; + Valeur_pixel=Lit_pixel_de_sauvegarde(0,0); + + while ( (Compteur_de_pixels=Taille_image) break; + Valeur_pixel=Lit_pixel_de_sauvegarde(Compteur_de_pixels % Principal_Largeur_image,Compteur_de_pixels / Principal_Largeur_image); + } + + if ( (Derniere_couleur!=Head.Recon1) && (Derniere_couleur!=Head.Recon2) ) + { + if (Compteur_de_repetitions==1) + Ecrire_octet(Fichier,Derniere_couleur); + else + if (Compteur_de_repetitions==2) + { + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Derniere_couleur); + } + else + if ( (Compteur_de_repetitions>2) && (Compteur_de_repetitions<256) ) + { // RECON1/couleur/nombre + Ecrire_octet(Fichier,Head.Recon1); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } + else + if (Compteur_de_repetitions>=256) + { // RECON2/couleur/hi(nombre)/lo(nombre) + Ecrire_octet(Fichier,Head.Recon2); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions>>8); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } + } + else + { + if (Compteur_de_repetitions<256) + { + Ecrire_octet(Fichier,Head.Recon1); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } + else + { + Ecrire_octet(Fichier,Head.Recon2); + Ecrire_octet(Fichier,Derniere_couleur); + Ecrire_octet(Fichier,Compteur_de_repetitions>>8); + Ecrire_octet(Fichier,Compteur_de_repetitions&0xFF); + } + } + } + + Close_ecriture(Fichier); + } + else + Erreur_fichier=1; + fclose(Fichier); + } + else + { + Erreur_fichier=1; + fclose(Fichier); + } + // S'il y a eu une erreur de sauvegarde, on ne va tout de même pas laisser + // ce fichier pourri traîner... Ca fait pas propre. + if (Erreur_fichier) + remove(Nom_du_fichier); +} diff --git a/loadsave.h b/loadsave.h index eb1abc97..8792eabe 100644 --- a/loadsave.h +++ b/loadsave.h @@ -90,3 +90,8 @@ void Save_PI1(void); void Test_PC1(void); void Load_PC1(void); void Save_PC1(void); + +// -- PNG ------------------------------------------------------------------- +void Test_PNG(void); +void Load_PNG(void); +void Save_PNG(void);