PNG loading. Don't try saving yet, it's pkm-saving code
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@569 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
8ba5bc178a
commit
0575684810
2
Makefile
2
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)
|
||||
|
||||
9
const.h
9
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!)
|
||||
|
||||
18
global.h
18
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];
|
||||
|
||||
322
loadsave.c
322
loadsave.c
@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <png.h>
|
||||
|
||||
#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;x<num_palette;x++)
|
||||
{
|
||||
Principal_Palette[x].R=x;
|
||||
Principal_Palette[x].V=x;
|
||||
Principal_Palette[x].B=x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// conversion des fichiers de moins de 256 couleurs
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
png_set_packing(png_ptr);
|
||||
if (Config.Clear_palette)
|
||||
memset(Principal_Palette,0,sizeof(T_Palette));
|
||||
}
|
||||
png_get_PLTE(png_ptr, info_ptr, &palette,
|
||||
&num_palette);
|
||||
for (x=0;x<num_palette;x++)
|
||||
{
|
||||
Principal_Palette[x].R=palette[x].red;
|
||||
Principal_Palette[x].V=palette[x].green;
|
||||
Principal_Palette[x].B=palette[x].blue;
|
||||
}
|
||||
//free(palette);
|
||||
}
|
||||
Set_palette(Principal_Palette);
|
||||
Remapper_fileselect();
|
||||
//
|
||||
|
||||
Principal_Largeur_image=info_ptr->width;
|
||||
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; y<Principal_Hauteur_image; y++)
|
||||
row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
for (y=0; y<Principal_Hauteur_image; y++)
|
||||
for (x=0; x<Principal_Largeur_image; x++)
|
||||
Pixel_de_chargement(x, y, row_pointers[y][x]);
|
||||
|
||||
}
|
||||
else
|
||||
Erreur_fichier=2;
|
||||
|
||||
/* cleanup heap allocation */
|
||||
for (y=0; y<Principal_Hauteur_image; y++)
|
||||
free(row_pointers[y]);
|
||||
free(row_pointers);
|
||||
}
|
||||
else
|
||||
Erreur_fichier=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Close_lecture();*/
|
||||
}
|
||||
else // Lecture header impossible: Erreur ne modifiant pas l'image
|
||||
Erreur_fichier=1;
|
||||
|
||||
fclose(Fichier);
|
||||
}
|
||||
else // Ouv. fichier impossible: Erreur ne modifiant pas l'image
|
||||
Erreur_fichier=1;
|
||||
}
|
||||
|
||||
void Save_PNG(void)
|
||||
{
|
||||
char Nom_du_fichier[TAILLE_CHEMIN_FICHIER];
|
||||
FILE *Fichier;
|
||||
T_Header_PKM Head;
|
||||
dword Compteur_de_pixels;
|
||||
dword Taille_image;
|
||||
word Compteur_de_repetitions;
|
||||
byte Derniere_couleur;
|
||||
byte Valeur_pixel;
|
||||
byte Taille_commentaire;
|
||||
|
||||
|
||||
|
||||
// Construction du header
|
||||
memcpy(Head.Ident,"PKM",3);
|
||||
Head.Methode=0;
|
||||
Trouver_recon(&Head.Recon1,&Head.Recon2);
|
||||
Head.Largeur=Principal_Largeur_image;
|
||||
Head.Hauteur=Principal_Hauteur_image;
|
||||
memcpy(Head.Palette,Principal_Palette,sizeof(T_Palette));
|
||||
Palette_256_to_64(Head.Palette);
|
||||
|
||||
// Calcul de la taille du Post-Header
|
||||
Head.Jump=9; // 6 pour les dimensions de l'ecran + 3 pour la back-color
|
||||
Taille_commentaire=strlen(Principal_Commentaire);
|
||||
if (Taille_commentaire)
|
||||
Head.Jump+=Taille_commentaire+2;
|
||||
|
||||
|
||||
Nom_fichier_complet(Nom_du_fichier,0);
|
||||
|
||||
Erreur_fichier=0;
|
||||
|
||||
// Ouverture du fichier
|
||||
if ((Fichier=fopen(Nom_du_fichier,"wb")))
|
||||
{
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
Head.Largeur = SDL_Swap16(Head.Largeur);
|
||||
Head.Hauteur = SDL_Swap16(Head.Hauteur);
|
||||
Head.Jump = SDL_Swap16(Head.Jump);
|
||||
#endif
|
||||
|
||||
// Ecriture du header
|
||||
if (write_bytes(Fichier,&Head,sizeof(T_Header_PKM)))
|
||||
{
|
||||
Init_ecriture();
|
||||
|
||||
// Ecriture du commentaire
|
||||
// (Compteur_de_pixels est utilisé ici comme simple indice de comptage)
|
||||
if (Taille_commentaire)
|
||||
{
|
||||
Ecrire_octet(Fichier,0);
|
||||
Ecrire_octet(Fichier,Taille_commentaire);
|
||||
for (Compteur_de_pixels=0; Compteur_de_pixels<Taille_commentaire; Compteur_de_pixels++)
|
||||
Ecrire_octet(Fichier,Principal_Commentaire[Compteur_de_pixels]);
|
||||
}
|
||||
// Ecriture des dimensions de l'écran
|
||||
Ecrire_octet(Fichier,1);
|
||||
Ecrire_octet(Fichier,4);
|
||||
Ecrire_octet(Fichier,Largeur_ecran&0xFF);
|
||||
Ecrire_octet(Fichier,Largeur_ecran>>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) && (!Erreur_fichier) )
|
||||
{
|
||||
Compteur_de_pixels++;
|
||||
Compteur_de_repetitions=1;
|
||||
Derniere_couleur=Valeur_pixel;
|
||||
if(Compteur_de_pixels<Taille_image)
|
||||
{
|
||||
Valeur_pixel=Lit_pixel_de_sauvegarde(Compteur_de_pixels % Principal_Largeur_image,Compteur_de_pixels / Principal_Largeur_image);
|
||||
}
|
||||
while ( (Valeur_pixel==Derniere_couleur)
|
||||
&& (Compteur_de_pixels<Taille_image)
|
||||
&& (Compteur_de_repetitions<65535) )
|
||||
{
|
||||
Compteur_de_pixels++;
|
||||
Compteur_de_repetitions++;
|
||||
if(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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user