diff --git a/Makefile b/Makefile index 03907701..11dde8ef 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC = powerpc-linux-gnu-gcc COPT = -Wall -Os -c LOPT = -lSDL -o grafx2 diff --git a/divers.c b/divers.c index 6d3cd7b9..b98afdc3 100644 --- a/divers.c +++ b/divers.c @@ -7,15 +7,6 @@ // Gestion du mode texte de départ (pour pouvoir y retourner en cas de problème byte Recuperer_nb_lignes(void) { - /* - mov ax,1130h - xor bh,bh - push es - int 10h - pop es - inc dl - mov [esp+28],dl - */ puts("Recuperer_nb_lignes non implémenté!\n"); return 0; } @@ -44,15 +35,15 @@ word Palette_Compter_nb_couleurs_utilisees(dword* Tableau) //On va maintenant compter dans la table les couleurs utilisées: Couleur=0; - do - { - if (Tableau[Couleur]!=0) - Nombre_Couleurs++; - Couleur++; - } - while(Couleur!=0); //On sort quand on a fait le tour (la var est sur 8 bits donc 255+1=0) + do + { + if (Tableau[Couleur]!=0) + Nombre_Couleurs++; + Couleur++; + } + while(Couleur!=0); //On sort quand on a fait le tour (la var est sur 8 bits donc 255+1=0) - return Nombre_Couleurs; + return Nombre_Couleurs; } void Set_palette(T_Palette Palette) @@ -72,11 +63,13 @@ void Set_palette(T_Palette Palette) void Attendre_fin_de_click(void) { - do - { - SDL_PumpEvents(); - } - while(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1)); //On attend tant que le bouton est enfoncé (TODO: vérif clic droit aussi ?) + SDL_Event event; + + //On attend que l'utilisateur relache la souris. Tous les autres évènements + //sont ignorés + while(SDL_PollEvent(&event) && event.type == SDL_MOUSEBUTTONUP); + + //On indique à la gestion des E/S que le bouton est laché et on rend la main Mouse_K=0; INPUT_Nouveau_Mouse_K=0; } @@ -104,19 +97,23 @@ void Effacer_image_courante_Stencil(byte Couleur, byte * Pochoir) void Effacer_image_courante(byte Couleur) // Effacer l'image courante avec une certaine couleur { - puts("Effacer_image_courante non implémenté!\n"); + memset( + Principal_Ecran , + Couleur , + Principal_Largeur_image * Principal_Hauteur_image + ); } void Sensibilite_souris(word X,word Y) { - puts("Sensibilite_souris non implémenté!\n"); + puts("Sensibilite_souris non implémenté!"); } void Get_input(void) //Gestion des évènements: mouvement de la souris, clic sur les boutons, et utilisation du clavier. { SDL_Event event; - + Touche=0; Touche_ASCII=0; // Par défaut, il n'y a pas d'action sur le clavier. @@ -127,7 +124,7 @@ void Get_input(void) case SDL_MOUSEMOTION: //Mouvement de la souris INPUT_Nouveau_Mouse_X = event.motion.x*Mouse_Facteur_de_correction_X; - INPUT_Nouveau_Mouse_Y = event.motion.y*Mouse_Facteur_de_correction_Y; + INPUT_Nouveau_Mouse_Y = event.motion.y*Mouse_Facteur_de_correction_Y; break; case SDL_MOUSEBUTTONDOWN: //Clic sur un des boutons de la souris @@ -135,47 +132,28 @@ void Get_input(void) break; case SDL_KEYDOWN: //Appui sur une touche du clavier - puts("Get-Input: clavier pas géré !"); + + //On met le scancode dans Touche" + Touche = event.key.keysym.scancode; + + //On ajoute aussi l'état des modifiers + #define ekkm event.key.keysym.mod + if (ekkm & (KMOD_LSHIFT | KMOD_RSHIFT) + { + Touche |= 0x0100; + } + if (ekkm & (KMOD_LCTRL | KMOD_RCTRL) + { + Touche |= 0x0200; + } + if (ekkm & (KMOD_LALT | KMOD_RALT) + { + Touche |= 0x0400; + } + + //Cas particulier: déplacement du curseur avec haut bas gauche droite + //On doit interpréter ça comme un mvt de la souris /* - ; Sinon, appel à l'interruption pour connaître son scancode - - mov ah,10h - int 16h - - ; AH = Scancode - ; AL = Caractère ASCII - - ; On place le scan code dans la partie basse de [Touche] - - mov byte ptr[Touche],ah - mov Touche_ASCII,al ; ... et le code ASCII dans Touche_ASCII - - ; Appel à l'interruption pour connaitre l'état des touches de contrôle - - mov ah,02h - int 16h - - ; AL = Etat des touches de contrôle - - - ; On oublie les informations sur Insert, CapsLock, NumLock et ScrollLock - - and al,00001111b - - ; On associe les deux Shifts (2 bits de poids faible) - - mov ah,al - and ah,00000001b - shr al,1 - or al,ah - - ; On met le resultat dans la partie haute de [Touche] - - mov byte ptr[Touche+1],al - - - ; On gère le cas où [Touche] est un déplacement du curseur - mov ax,Touche ; Test [Touche] = Emulation de MOUSE UP @@ -272,9 +250,9 @@ void Get_input(void) int 33h break; */ - } + } } - + /* Get_input_Pas_de_touche: @@ -668,7 +646,7 @@ void Rotate_180_deg_LOWLEVEL(void) void Tempo_jauge(byte Vitesse) //Boucle d'attente pour faire bouger les scrollbars à une vitesse correcte { - while (Vitesse!=0) + while (Vitesse!=0) { Wait_VBL(); Vitesse--; diff --git a/files.c b/files.c index 4542c406..4c5ad447 100644 --- a/files.c +++ b/files.c @@ -1,10 +1,10 @@ -#include "const.h" -#include "struct.h" -#include "global.h" -#include "graph.h" -#include "divers.h" -#include -#include +#include "const.h" +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "divers.h" +#include +#include #include #include @@ -15,37 +15,37 @@ #include -#include "linux.h" - -#define COULEUR_FICHIER_NORMAL CM_Clair // Couleur du texte pour une ligne de fichier non s‚lectionn‚ -#define COULEUR_REPERTOIRE_NORMAL CM_Fonce // Couleur du texte pour une ligne de r‚pertoire non s‚lectionn‚ -#define COULEUR_FOND_NORMAL CM_Noir // Couleur du fond pour une ligne non s‚lectionn‚e -#define COULEUR_FICHIER_SELECT CM_Blanc // Couleur du texte pour une ligne de fichier s‚lectionn‚e -#define COULEUR_REPERTOIRE_SELECT CM_Clair // Couleur du texte pour une ligne de rep‚rtoire s‚lectionn‚e -#define COULEUR_FOND_SELECT CM_Fonce // Couleur du fond pour une ligne s‚lectionn‚e - - -int Determiner_repertoire_courant(void) -// Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur (avec le nom du -// disque) -// -// Renvoie 1 s'il y a e–t une erreur d'accŠs -{ - return (getcwd(Principal_Repertoire_courant,256)==NULL); -} - - -int Repertoire_existe(char * Repertoire) -// D‚termine si un r‚pertoire pass‚ en paramŠtre existe ou non dans le -// r‚pertoire courant. -{ - DIR* Enreg; // Structure de lecture des ‚l‚ments - - if (strcmp(Repertoire,"..")==0) - return 1; - else - { - // On va chercher si le r‚pertoire existe … l'aide d'un Opendir. S'il +#include "linux.h" + +#define COULEUR_FICHIER_NORMAL CM_Clair // Couleur du texte pour une ligne de fichier non sélectionné +#define COULEUR_REPERTOIRE_NORMAL CM_Fonce // Couleur du texte pour une ligne de répertoire non sélectionné +#define COULEUR_FOND_NORMAL CM_Noir // Couleur du fond pour une ligne non sélectionnée +#define COULEUR_FICHIER_SELECT CM_Blanc // Couleur du texte pour une ligne de fichier sélectionnée +#define COULEUR_REPERTOIRE_SELECT CM_Clair // Couleur du texte pour une ligne de repértoire sélectionnée +#define COULEUR_FOND_SELECT CM_Fonce // Couleur du fond pour une ligne sélectionnée + + +int Determiner_repertoire_courant(void) +// Modifie Principal_Repertoire_courant en y mettant sa nouvelle valeur (avec le nom du +// disque) +// +// Renvoie 1 s'il y a eu une erreur d'accès +{ + return (getcwd(Principal_Repertoire_courant,256)==NULL); +} + + +int Repertoire_existe(char * Repertoire) +// Détermine si un répertoire passé en paramètre existe ou non dans le +// répertoire courant. +{ + DIR* Enreg; // Structure de lecture des éléments + + if (strcmp(Repertoire,"..")==0) + return 1; + else + { + // On va chercher si le répertoire existe à l'aide d'un Opendir. S'il // renvoie NULL c'est que le répertoire n'est pas accessible... Enreg=opendir(Repertoire); @@ -55,15 +55,15 @@ int Repertoire_existe(char * Repertoire) { closedir(Enreg); return 1; - } - } -} - - -int Fichier_existe(char * Fichier) -// D‚termine si un fichier pass‚ en paramŠtre existe ou non dans le -// r‚pertoire courant. -{ + } + } +} + + +int Fichier_existe(char * Fichier) +// D‚termine si un fichier pass‚ en paramŠtre existe ou non dans le +// r‚pertoire courant. +{ struct stat* buf; int Resultat; @@ -72,468 +72,468 @@ int Fichier_existe(char * Fichier) return(errno!=ENOENT); else return 1; - -} - - - -// Conventions: -// -// * Le fileselect modifie le r‚pertoire courant. Ceci permet de n'avoir -// qu'un findfirst dans le r‚pertoire courant … faire: - - -// -- D‚struction de la liste chaŒn‚e --------------------------------------- -void Detruire_liste_du_fileselect(void) -// Cette proc‚dure d‚truit la chaine des fichiers. Elle doit ˆtre appel‚e -// avant de rappeler la fonction Lire_liste_des_fichiers, ainsi qu'en fin de -// programme. -{ - // Pointeur temporaire de destruction - struct Element_de_liste_de_fileselect * Element_temporaire; - - while (Liste_du_fileselect!=NULL) - { - // On m‚morise l'adresse du premier ‚l‚ment de la liste - Element_temporaire =Liste_du_fileselect; - // On fait avancer la tˆte de la liste - Liste_du_fileselect=Liste_du_fileselect->Suivant; - // Et on efface l'ancien premier ‚l‚ment de la liste - free(Element_temporaire); - } -} - - -// -- Formatage graphique des noms de fichier / r‚pertoire ------------------ -char * Nom_formate(char * Nom) -{ - static char Resultat[13]; - int Curseur; - int Autre_curseur; - - if (strcmp(Nom,"..")==0) - { - strcpy(Resultat,".. "); - } - else - { - strcpy(Resultat," . "); - // On commence par recopier la partie pr‚c‚dent le point: - for (Curseur=0;( (Nom[Curseur]!='.') && (Nom[Curseur]!='\0') );Curseur++) - Resultat[Curseur]=Nom[Curseur]; - - // Ensuite on recopie la partie qui suit le point (si n‚cessaire): - if (Nom[Curseur]) - { - for (Curseur++,Autre_curseur=9;Nom[Curseur]!='\0';Curseur++,Autre_curseur++) - Resultat[Autre_curseur]=Nom[Curseur]; - } - } - return Resultat; -} - - -// -- Rajouter … la liste des ‚l‚ments de la liste un ‚l‚ment --------------- -void Ajouter_element_a_la_liste(struct dirent* Enreg) -// Cette proc‚dure ajoute … la liste chain‚e un fichier pass‚ en argument. -{ - // Pointeur temporaire d'insertion - struct Element_de_liste_de_fileselect * Element_temporaire; - - // On alloue de la place pour un nouvel ‚l‚ment - Element_temporaire=(struct Element_de_liste_de_fileselect *)malloc(sizeof(struct Element_de_liste_de_fileselect)); - - // On met … jour le nouvel emplacement: - strcpy(Element_temporaire->Nom,Nom_formate(Enreg->d_name)); - Element_temporaire->Type =(Enreg->d_type == DT_DIR); - - Element_temporaire->Suivant =Liste_du_fileselect; - Element_temporaire->Precedent=NULL; - - if (Liste_du_fileselect!=NULL) - Liste_du_fileselect->Precedent=Element_temporaire; - Liste_du_fileselect=Element_temporaire; -} - - -// -- Lecture d'une liste de fichiers --------------------------------------- -void Lire_liste_des_fichiers(byte Format_demande) -// Cette proc‚dure charge dans la liste chain‚e les fichiers dont l'extension -// correspond au format demand‚. -{ - int Attribut; // Attribut des fichiers/r‚pertoires … lire + +} + + + +// Conventions: +// +// * Le fileselect modifie le r‚pertoire courant. Ceci permet de n'avoir +// qu'un findfirst dans le r‚pertoire courant … faire: + + +// -- D‚struction de la liste chaŒn‚e --------------------------------------- +void Detruire_liste_du_fileselect(void) +// Cette proc‚dure d‚truit la chaine des fichiers. Elle doit ˆtre appel‚e +// avant de rappeler la fonction Lire_liste_des_fichiers, ainsi qu'en fin de +// programme. +{ + // Pointeur temporaire de destruction + struct Element_de_liste_de_fileselect * Element_temporaire; + + while (Liste_du_fileselect!=NULL) + { + // On m‚morise l'adresse du premier ‚l‚ment de la liste + Element_temporaire =Liste_du_fileselect; + // On fait avancer la tˆte de la liste + Liste_du_fileselect=Liste_du_fileselect->Suivant; + // Et on efface l'ancien premier ‚l‚ment de la liste + free(Element_temporaire); + } +} + + +// -- Formatage graphique des noms de fichier / r‚pertoire ------------------ +char * Nom_formate(char * Nom) +{ + static char Resultat[13]; + int Curseur; + int Autre_curseur; + + if (strcmp(Nom,"..")==0) + { + strcpy(Resultat,".. "); + } + else + { + strcpy(Resultat," . "); + // On commence par recopier la partie pr‚c‚dent le point: + for (Curseur=0;( (Nom[Curseur]!='.') && (Nom[Curseur]!='\0') );Curseur++) + Resultat[Curseur]=Nom[Curseur]; + + // Ensuite on recopie la partie qui suit le point (si n‚cessaire): + if (Nom[Curseur]) + { + for (Curseur++,Autre_curseur=9;Nom[Curseur]!='\0';Curseur++,Autre_curseur++) + Resultat[Autre_curseur]=Nom[Curseur]; + } + } + return Resultat; +} + + +// -- Rajouter … la liste des ‚l‚ments de la liste un ‚l‚ment --------------- +void Ajouter_element_a_la_liste(struct dirent* Enreg) +// Cette proc‚dure ajoute … la liste chain‚e un fichier pass‚ en argument. +{ + // Pointeur temporaire d'insertion + struct Element_de_liste_de_fileselect * Element_temporaire; + + // On alloue de la place pour un nouvel ‚l‚ment + Element_temporaire=(struct Element_de_liste_de_fileselect *)malloc(sizeof(struct Element_de_liste_de_fileselect)); + + // On met … jour le nouvel emplacement: + strcpy(Element_temporaire->Nom,Nom_formate(Enreg->d_name)); + Element_temporaire->Type =(Enreg->d_type == DT_DIR); + + Element_temporaire->Suivant =Liste_du_fileselect; + Element_temporaire->Precedent=NULL; + + if (Liste_du_fileselect!=NULL) + Liste_du_fileselect->Precedent=Element_temporaire; + Liste_du_fileselect=Element_temporaire; +} + + +// -- Lecture d'une liste de fichiers --------------------------------------- +void Lire_liste_des_fichiers(byte Format_demande) +// Cette proc‚dure charge dans la liste chain‚e les fichiers dont l'extension +// correspond au format demand‚. +{ + int Attribut; // Attribut des fichiers/r‚pertoires … lire DIR* Repertoire_Courant; //Répertoire courant - struct dirent* Enreg; // Structure de lecture des ‚l‚ments - char Filtre[6]="*."; // Place pour ‚crire "*.XXX" et un '\0' - - char Chaine[20]; - - // Tout d'abord, on d‚duit du format demand‚ un filtre … utiliser: - if (Format_demande) // Format (extension) sp‚cifique - strcat(Filtre,Format_Extension[Format_demande-1]); - else // *.* - strcat(Filtre,"*"); - - - // Ensuite, on vide la liste actuelle: - Detruire_liste_du_fileselect(); - // AprŠs effacement, il ne reste ni fichier ni r‚pertoire dans la liste - Liste_Nb_fichiers=0; - Liste_Nb_repertoires=0; - + struct dirent* Enreg; // Structure de lecture des ‚l‚ments + char Filtre[6]="*."; // Place pour ‚crire "*.XXX" et un '\0' + + char Chaine[20]; + + // Tout d'abord, on d‚duit du format demand‚ un filtre … utiliser: + if (Format_demande) // Format (extension) sp‚cifique + strcat(Filtre,Format_Extension[Format_demande-1]); + else // *.* + strcat(Filtre,"*"); + + + // Ensuite, on vide la liste actuelle: + Detruire_liste_du_fileselect(); + // AprŠs effacement, il ne reste ni fichier ni r‚pertoire dans la liste + Liste_Nb_fichiers=0; + Liste_Nb_repertoires=0; + // On lit tous les r‚pertoires: - Repertoire_Courant=opendir(getcwd(NULL,0)); + Repertoire_Courant=opendir(getcwd(NULL,0)); /* -Ceci est à revoir... pas tout à fait géré pareil sous linux... - Attribut=(_A_NORMAL|_A_SUBDIR|//_A_RDONLY|_A_ARCH| - (_A_HIDDEN & Config.Lire_les_repertoires_caches)| - (_A_SYSTEM & Config.Lire_les_repertoires_systemes)); -*/ - Enreg=readdir(Repertoire_Courant); - while (Enreg) - { - // Si l'‚l‚ment n'est pas le r‚pertoire courant - if ( (strcmp(Enreg->d_name,".")!=0) && - // et que l'‚l‚ment trouv‚ est r‚ellement un r‚pertoire - (Enreg->d_type == DT_DIR) ) - { - // On rajoute le r‚pertore … la liste - Ajouter_element_a_la_liste(Enreg); - Liste_Nb_repertoires++; - } - // On cherche l'‚l‚ment suivant - Enreg=readdir(Repertoire_Courant); - } - - // Enfin, on lit les fichiers du format demand‚: - -/* -Ici aussi, à revoir... - Attribut=(_A_NORMAL|_A_SYSTEM|//_A_RDONLY|_A_ARCH| - (_A_HIDDEN & Config.Lire_les_fichiers_caches)); -*/ - - rewinddir(Repertoire_Courant); - Enreg=readdir(Repertoire_Courant); - while (Enreg) +Ceci est à revoir... pas tout à fait géré pareil sous linux... + Attribut=(_A_NORMAL|_A_SUBDIR|//_A_RDONLY|_A_ARCH| + (_A_HIDDEN & Config.Lire_les_repertoires_caches)| + (_A_SYSTEM & Config.Lire_les_repertoires_systemes)); +*/ + Enreg=readdir(Repertoire_Courant); + while (Enreg) { - if (Enreg->d_type==DT_REG) //Il s'agit bien d'un fichier - { - // On rajoute le fichier … la liste - Ajouter_element_a_la_liste(Enreg); - Liste_Nb_fichiers++; - } - // On cherche l'‚l‚ment suivant - Enreg=readdir(Repertoire_Courant); + // Si l'‚l‚ment n'est pas le r‚pertoire courant + if ( (strcmp(Enreg->d_name,".")!=0) && + // et que l'‚l‚ment trouv‚ est r‚ellement un r‚pertoire + (Enreg->d_type == DT_DIR) ) + { + // On rajoute le r‚pertore … la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_repertoires++; + } + // On cherche l'‚l‚ment suivant + Enreg=readdir(Repertoire_Courant); } - closedir(Repertoire_Courant); - - Liste_Nb_elements=Liste_Nb_repertoires+Liste_Nb_fichiers; -} - - -// -- Tri de la liste des fichiers et r‚pertoires --------------------------- -void Trier_la_liste_des_fichiers(void) -// Tri la liste chain‚e existante dans l'ordre suivant: -// -// * Les r‚pertoires d'abord, dans l'ordre alphab‚tique de leur nom -// * Les fichiers ensuite, dans l'ordre alphab‚tique de leur nom -{ - byte La_liste_est_triee; // Bool‚en "La liste est tri‚e" - byte Inversion; // Bool‚en "Il faut inverser les ‚l‚ments" - struct Element_de_liste_de_fileselect * Element_precedent; - struct Element_de_liste_de_fileselect * Element_courant; - struct Element_de_liste_de_fileselect * Element_suivant; - struct Element_de_liste_de_fileselect * Element_suivant_le_suivant; - - // Avant de trier quoi que ce soit, on v‚rifie qu'il y ait suffisamment - // d'‚l‚ments pour qu'il soit possibles qu'ils soient en d‚sordre: - if (Liste_Nb_elements>1) - { - do - { - // Par d‚faut, on considŠre que la liste est tri‚e - La_liste_est_triee=1; - - Element_courant=Liste_du_fileselect; - Element_suivant=Element_courant->Suivant; - - while ( (Element_courant!=NULL) && (Element_suivant!=NULL) ) - { - // On commence par supposer qu'il n'y pas pas besoin d'inversion - Inversion=0; - - // Ensuite, on v‚rifie si les deux ‚l‚ments sont bien dans l'ordre ou - // non: - - // Si l'‚l‚ment courant est un fichier est que le suivant est - // un r‚pertoire -> Inversion - if ( (Element_courant->Type==0) && (Element_suivant->Type==1) ) - Inversion=1; - // Si les deux ‚l‚ments sont de mˆme type et que le nom du suivant - // est plus petit que celui du courant -> Inversion - else if ( (Element_courant->Type==Element_suivant->Type) && - (strcmp(Element_courant->Nom,Element_suivant->Nom)>0) ) - Inversion=1; - - - if (Inversion) - { - // Si les deux ‚l‚ments n‚cessitent d'ˆtre invers‚: - - // On les inverses: - - // On note avant tout les ‚l‚ments qui encapsulent nos deux amis - Element_precedent =Element_courant->Precedent; - Element_suivant_le_suivant=Element_suivant->Suivant; - - // On permute le chaŒnage des deux ‚l‚ments entree eux - Element_courant->Suivant =Element_suivant_le_suivant; - Element_courant->Precedent=Element_suivant; - Element_suivant->Suivant =Element_courant; - Element_suivant->Precedent=Element_precedent; - - // On tente un chaŒnage des ‚l‚ments encapsulant les compŠres: - if (Element_precedent!=NULL) - Element_precedent->Suivant=Element_suivant; - if (Element_suivant_le_suivant!=NULL) - Element_suivant_le_suivant->Precedent=Element_courant; - - // On fait bien attention … modifier la tˆte de liste en cas de besoin - if (Element_courant==Liste_du_fileselect) - Liste_du_fileselect=Element_suivant; - - // Ensuite, on se pr‚pare … ‚tudier les ‚l‚ments pr‚c‚dents: - Element_courant=Element_precedent; - - // Et on constate que la liste n'‚tait pas encore g‚nialement tri‚e - La_liste_est_triee=0; - } - else - { - // Si les deux ‚l‚ments sont dans l'ordre: - - // On passe aux suivants - Element_courant=Element_courant->Suivant; - Element_suivant=Element_suivant->Suivant; - } - } - } - while (!La_liste_est_triee); - } -} - - -// -- Affichage des ‚l‚ments de la liste de fichier / r‚pertoire ------------ -void Afficher_la_liste_des_fichiers(short Decalage_premier,short Decalage_select) -// -// Decalage_premier = D‚calage entre le premier fichier visible dans le -// s‚lecteur et le premier fichier de la liste -// -// Decalage_select = D‚calage entre le premier fichier visible dans le -// s‚lecteur et le fichier s‚lectionn‚ dans la liste -// -{ - struct Element_de_liste_de_fileselect * Element_courant; - byte Indice; // Indice du fichier qu'on affiche (0 -> 9) - byte Couleur_texte; - byte Couleur_fond; - - - // On v‚rifie s'il y a au moins 1 fichier dans la liste: - if (Liste_Nb_elements>0) - { - // On commence par chercher … pointer sur le premier fichier visible: - Element_courant=Liste_du_fileselect; - for (;Decalage_premier>0;Decalage_premier--) - Element_courant=Element_courant->Suivant; - - // Pour chacun des 10 ‚l‚ments inscriptibles … l'‚cran - for (Indice=0;Indice<10;Indice++) - { - // S'il est s‚lectionn‚: - if (!Decalage_select) - { - // Si c'est un fichier - if (Element_courant->Type==0) - Couleur_texte=COULEUR_FICHIER_SELECT; - else - Couleur_texte=COULEUR_REPERTOIRE_SELECT; - - Couleur_fond=COULEUR_FOND_SELECT; - } - else - { - // Si c'est un fichier - if (Element_courant->Type==0) - Couleur_texte=COULEUR_FICHIER_NORMAL; - else - Couleur_texte=COULEUR_REPERTOIRE_NORMAL; - - Couleur_fond=COULEUR_FOND_NORMAL; - } - - // On affiche l'‚l‚ment - Print_dans_fenetre(9,90+(Indice<<3),Element_courant->Nom,Couleur_texte,Couleur_fond); - - // On passe … la ligne suivante - Decalage_select--; - Element_courant=Element_courant->Suivant; - if (!Element_courant) - break; - } // Fin de la boucle d'affichage - - } // Fin du test d'existence de fichiers -} - - -// -- R‚cup‚rer le libell‚ d'un ‚l‚ment de la liste ------------------------- -void Determiner_element_de_la_liste(short Decalage_premier,short Decalage_select,char * Libelle) -// -// Decalage_premier = D‚calage entre le premier fichier visible dans le -// s‚lecteur et le premier fichier de la liste -// -// Decalage_select = D‚calage entre le premier fichier visible dans le -// s‚lecteur et le fichier … r‚cup‚rer -// -// Libelle = Chaine de r‚ception du libell‚ de l'‚l‚ment -// -{ - struct Element_de_liste_de_fileselect * Element_courant; - char * Curseur; - - - // On v‚rifie s'il y a au moins 1 fichier dans la liste: - if (Liste_Nb_elements>0) - { - // On commence par chercher … pointer sur le premier fichier visible: - Element_courant=Liste_du_fileselect; - for (;Decalage_premier>0;Decalage_premier--) - Element_courant=Element_courant->Suivant; - - // Ensuite, on saute autant d'‚l‚ments que le d‚calage demand‚: - for (;Decalage_select>0;Decalage_select--) - Element_courant=Element_courant->Suivant; - - // On recopie la chaŒne en la d‚formatant (i.e. tous les chars sauf ' ') - for (Curseur=Element_courant->Nom;*Curseur!='\0';Curseur++) - if (*Curseur!=' ') - *(Libelle++)=*Curseur; - *Libelle='\0'; - } // Fin du test d'existence de fichiers -} - - -// ----------------- D‚placements dans la liste de fichiers ----------------- - -void Select_Scroll_Down(short * Decalage_premier,short * Decalage_select) -// Fait scroller vers le bas le s‚lecteur de fichier... (si possible) -{ - if ( ((*Decalage_select)<9) - && ( (*Decalage_select)+1 < Liste_Nb_elements ) ) - // Si la s‚lection peut descendre - Afficher_la_liste_des_fichiers(*Decalage_premier,++(*Decalage_select)); - else // Sinon, descendre la fenˆtre (si possible) - if ((*Decalage_premier)+100) - // Si la s‚lection peut monter - Afficher_la_liste_des_fichiers(*Decalage_premier,--(*Decalage_select)); - else // Sinon, monter la fenˆtre (si possible) - if ((*Decalage_premier)>0) - Afficher_la_liste_des_fichiers(--(*Decalage_premier),*Decalage_select); -} - - -void Select_Page_Down(short * Decalage_premier,short * Decalage_select) -{ - if (Liste_Nb_elements-1>*Decalage_premier+*Decalage_select) - { - if (*Decalage_select<9) - { - if (Liste_Nb_elements<10) - { - *Decalage_premier=0; - *Decalage_select=Liste_Nb_elements-1; - } - else *Decalage_select=9; - } - else - { - if (Liste_Nb_elements>*Decalage_premier+18) - *Decalage_premier+=9; - else - { - *Decalage_premier=Liste_Nb_elements-10; - *Decalage_select=9; - } - } - } - Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); -} - - -void Select_Page_Up(short * Decalage_premier,short * Decalage_select) -{ - if (*Decalage_premier+*Decalage_select>0) - { - if (*Decalage_select>0) - *Decalage_select=0; - else - { - if (*Decalage_premier>9) - *Decalage_premier-=9; - else - *Decalage_premier=0; - } - } - Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); -} - - -void Select_End(short * Decalage_premier,short * Decalage_select) -{ - if (Liste_Nb_elements<10) - { - *Decalage_premier=0; - *Decalage_select=Liste_Nb_elements-1; - } - else - { - *Decalage_premier=Liste_Nb_elements-10; - *Decalage_select=9; - } - Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); -} - - -void Select_Home(short * Decalage_premier,short * Decalage_select) -{ - Afficher_la_liste_des_fichiers((*Decalage_premier)=0,(*Decalage_select)=0); -} - - - -short Calculer_decalage_click_dans_fileselector(void) -/* - Renvoie le d‚calage dans le s‚lecteur de fichier sur lequel on a click‚. - Renvoie le d‚calage du dernier fichier si on a click‚ au del…. - Renvoie -1 si le s‚lecteur est vide. -*/ -{ - short Decalage_calcule; - - Decalage_calcule=(((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-90)>>3; - if (Decalage_calcule>=Liste_Nb_elements) - Decalage_calcule=Liste_Nb_elements-1; - - return Decalage_calcule; -} + // Enfin, on lit les fichiers du format demand‚: + +/* +Ici aussi, à revoir... + Attribut=(_A_NORMAL|_A_SYSTEM|//_A_RDONLY|_A_ARCH| + (_A_HIDDEN & Config.Lire_les_fichiers_caches)); +*/ + + rewinddir(Repertoire_Courant); + Enreg=readdir(Repertoire_Courant); + while (Enreg) + { + if (Enreg->d_type==DT_REG) //Il s'agit bien d'un fichier + { + // On rajoute le fichier … la liste + Ajouter_element_a_la_liste(Enreg); + Liste_Nb_fichiers++; + } + // On cherche l'‚l‚ment suivant + Enreg=readdir(Repertoire_Courant); + } + + closedir(Repertoire_Courant); + + Liste_Nb_elements=Liste_Nb_repertoires+Liste_Nb_fichiers; +} + + +// -- Tri de la liste des fichiers et r‚pertoires --------------------------- +void Trier_la_liste_des_fichiers(void) +// Tri la liste chain‚e existante dans l'ordre suivant: +// +// * Les r‚pertoires d'abord, dans l'ordre alphab‚tique de leur nom +// * Les fichiers ensuite, dans l'ordre alphab‚tique de leur nom +{ + byte La_liste_est_triee; // Bool‚en "La liste est tri‚e" + byte Inversion; // Bool‚en "Il faut inverser les ‚l‚ments" + struct Element_de_liste_de_fileselect * Element_precedent; + struct Element_de_liste_de_fileselect * Element_courant; + struct Element_de_liste_de_fileselect * Element_suivant; + struct Element_de_liste_de_fileselect * Element_suivant_le_suivant; + + // Avant de trier quoi que ce soit, on v‚rifie qu'il y ait suffisamment + // d'‚l‚ments pour qu'il soit possibles qu'ils soient en d‚sordre: + if (Liste_Nb_elements>1) + { + do + { + // Par d‚faut, on considŠre que la liste est tri‚e + La_liste_est_triee=1; + + Element_courant=Liste_du_fileselect; + Element_suivant=Element_courant->Suivant; + + while ( (Element_courant!=NULL) && (Element_suivant!=NULL) ) + { + // On commence par supposer qu'il n'y pas pas besoin d'inversion + Inversion=0; + + // Ensuite, on v‚rifie si les deux ‚l‚ments sont bien dans l'ordre ou + // non: + + // Si l'‚l‚ment courant est un fichier est que le suivant est + // un r‚pertoire -> Inversion + if ( (Element_courant->Type==0) && (Element_suivant->Type==1) ) + Inversion=1; + // Si les deux ‚l‚ments sont de mˆme type et que le nom du suivant + // est plus petit que celui du courant -> Inversion + else if ( (Element_courant->Type==Element_suivant->Type) && + (strcmp(Element_courant->Nom,Element_suivant->Nom)>0) ) + Inversion=1; + + + if (Inversion) + { + // Si les deux ‚l‚ments n‚cessitent d'ˆtre invers‚: + + // On les inverses: + + // On note avant tout les ‚l‚ments qui encapsulent nos deux amis + Element_precedent =Element_courant->Precedent; + Element_suivant_le_suivant=Element_suivant->Suivant; + + // On permute le chaŒnage des deux ‚l‚ments entree eux + Element_courant->Suivant =Element_suivant_le_suivant; + Element_courant->Precedent=Element_suivant; + Element_suivant->Suivant =Element_courant; + Element_suivant->Precedent=Element_precedent; + + // On tente un chaŒnage des ‚l‚ments encapsulant les compŠres: + if (Element_precedent!=NULL) + Element_precedent->Suivant=Element_suivant; + if (Element_suivant_le_suivant!=NULL) + Element_suivant_le_suivant->Precedent=Element_courant; + + // On fait bien attention … modifier la tˆte de liste en cas de besoin + if (Element_courant==Liste_du_fileselect) + Liste_du_fileselect=Element_suivant; + + // Ensuite, on se pr‚pare … ‚tudier les ‚l‚ments pr‚c‚dents: + Element_courant=Element_precedent; + + // Et on constate que la liste n'‚tait pas encore g‚nialement tri‚e + La_liste_est_triee=0; + } + else + { + // Si les deux ‚l‚ments sont dans l'ordre: + + // On passe aux suivants + Element_courant=Element_courant->Suivant; + Element_suivant=Element_suivant->Suivant; + } + } + } + while (!La_liste_est_triee); + } +} + + +// -- Affichage des ‚l‚ments de la liste de fichier / r‚pertoire ------------ +void Afficher_la_liste_des_fichiers(short Decalage_premier,short Decalage_select) +// +// Decalage_premier = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le premier fichier de la liste +// +// Decalage_select = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le fichier s‚lectionn‚ dans la liste +// +{ + struct Element_de_liste_de_fileselect * Element_courant; + byte Indice; // Indice du fichier qu'on affiche (0 -> 9) + byte Couleur_texte; + byte Couleur_fond; + + + // On v‚rifie s'il y a au moins 1 fichier dans la liste: + if (Liste_Nb_elements>0) + { + // On commence par chercher … pointer sur le premier fichier visible: + Element_courant=Liste_du_fileselect; + for (;Decalage_premier>0;Decalage_premier--) + Element_courant=Element_courant->Suivant; + + // Pour chacun des 10 ‚l‚ments inscriptibles … l'‚cran + for (Indice=0;Indice<10;Indice++) + { + // S'il est s‚lectionn‚: + if (!Decalage_select) + { + // Si c'est un fichier + if (Element_courant->Type==0) + Couleur_texte=COULEUR_FICHIER_SELECT; + else + Couleur_texte=COULEUR_REPERTOIRE_SELECT; + + Couleur_fond=COULEUR_FOND_SELECT; + } + else + { + // Si c'est un fichier + if (Element_courant->Type==0) + Couleur_texte=COULEUR_FICHIER_NORMAL; + else + Couleur_texte=COULEUR_REPERTOIRE_NORMAL; + + Couleur_fond=COULEUR_FOND_NORMAL; + } + + // On affiche l'‚l‚ment + Print_dans_fenetre(9,90+(Indice<<3),Element_courant->Nom,Couleur_texte,Couleur_fond); + + // On passe … la ligne suivante + Decalage_select--; + Element_courant=Element_courant->Suivant; + if (!Element_courant) + break; + } // Fin de la boucle d'affichage + + } // Fin du test d'existence de fichiers +} + + +// -- R‚cup‚rer le libell‚ d'un ‚l‚ment de la liste ------------------------- +void Determiner_element_de_la_liste(short Decalage_premier,short Decalage_select,char * Libelle) +// +// Decalage_premier = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le premier fichier de la liste +// +// Decalage_select = D‚calage entre le premier fichier visible dans le +// s‚lecteur et le fichier … r‚cup‚rer +// +// Libelle = Chaine de r‚ception du libell‚ de l'‚l‚ment +// +{ + struct Element_de_liste_de_fileselect * Element_courant; + char * Curseur; + + + // On v‚rifie s'il y a au moins 1 fichier dans la liste: + if (Liste_Nb_elements>0) + { + // On commence par chercher … pointer sur le premier fichier visible: + Element_courant=Liste_du_fileselect; + for (;Decalage_premier>0;Decalage_premier--) + Element_courant=Element_courant->Suivant; + + // Ensuite, on saute autant d'‚l‚ments que le d‚calage demand‚: + for (;Decalage_select>0;Decalage_select--) + Element_courant=Element_courant->Suivant; + + // On recopie la chaŒne en la d‚formatant (i.e. tous les chars sauf ' ') + for (Curseur=Element_courant->Nom;*Curseur!='\0';Curseur++) + if (*Curseur!=' ') + *(Libelle++)=*Curseur; + *Libelle='\0'; + } // Fin du test d'existence de fichiers +} + + +// ----------------- D‚placements dans la liste de fichiers ----------------- + +void Select_Scroll_Down(short * Decalage_premier,short * Decalage_select) +// Fait scroller vers le bas le s‚lecteur de fichier... (si possible) +{ + if ( ((*Decalage_select)<9) + && ( (*Decalage_select)+1 < Liste_Nb_elements ) ) + // Si la s‚lection peut descendre + Afficher_la_liste_des_fichiers(*Decalage_premier,++(*Decalage_select)); + else // Sinon, descendre la fenˆtre (si possible) + if ((*Decalage_premier)+100) + // Si la s‚lection peut monter + Afficher_la_liste_des_fichiers(*Decalage_premier,--(*Decalage_select)); + else // Sinon, monter la fenˆtre (si possible) + if ((*Decalage_premier)>0) + Afficher_la_liste_des_fichiers(--(*Decalage_premier),*Decalage_select); +} + + +void Select_Page_Down(short * Decalage_premier,short * Decalage_select) +{ + if (Liste_Nb_elements-1>*Decalage_premier+*Decalage_select) + { + if (*Decalage_select<9) + { + if (Liste_Nb_elements<10) + { + *Decalage_premier=0; + *Decalage_select=Liste_Nb_elements-1; + } + else *Decalage_select=9; + } + else + { + if (Liste_Nb_elements>*Decalage_premier+18) + *Decalage_premier+=9; + else + { + *Decalage_premier=Liste_Nb_elements-10; + *Decalage_select=9; + } + } + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_Page_Up(short * Decalage_premier,short * Decalage_select) +{ + if (*Decalage_premier+*Decalage_select>0) + { + if (*Decalage_select>0) + *Decalage_select=0; + else + { + if (*Decalage_premier>9) + *Decalage_premier-=9; + else + *Decalage_premier=0; + } + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_End(short * Decalage_premier,short * Decalage_select) +{ + if (Liste_Nb_elements<10) + { + *Decalage_premier=0; + *Decalage_select=Liste_Nb_elements-1; + } + else + { + *Decalage_premier=Liste_Nb_elements-10; + *Decalage_select=9; + } + Afficher_la_liste_des_fichiers(*Decalage_premier,*Decalage_select); +} + + +void Select_Home(short * Decalage_premier,short * Decalage_select) +{ + Afficher_la_liste_des_fichiers((*Decalage_premier)=0,(*Decalage_select)=0); +} + + + +short Calculer_decalage_click_dans_fileselector(void) +/* + Renvoie le d‚calage dans le s‚lecteur de fichier sur lequel on a click‚. + Renvoie le d‚calage du dernier fichier si on a click‚ au del…. + Renvoie -1 si le s‚lecteur est vide. +*/ +{ + short Decalage_calcule; + + Decalage_calcule=(((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-90)>>3; + if (Decalage_calcule>=Liste_Nb_elements) + Decalage_calcule=Liste_Nb_elements-1; + + return Decalage_calcule; +} diff --git a/gfx2.cfg b/gfx2.cfg index 6d2d8ac2..d827fb22 100644 Binary files a/gfx2.cfg and b/gfx2.cfg differ diff --git a/loadsave.c b/loadsave.c index e0da70aa..7d6dffa9 100644 --- a/loadsave.c +++ b/loadsave.c @@ -1,5323 +1,5325 @@ #define _XOPEN_SOURCE -#include "const.h" -#include "struct.h" -#include "global.h" -#include "graph.h" -#include "divers.h" -#include "pages.h" -#include "op_c.h" -#include -#include -#include +#include "const.h" +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "divers.h" +#include "pages.h" +#include "op_c.h" +#include +#include +#include #include #include #include #include "boutons.h" -#include "linux.h" - -// On déclare méchamment le prototype de Erreur pour éviter de faire un -// fichier "main.h": -void Erreur(int Code); - - -// Chargement des pixels dans l'écran principal -void Pixel_Chargement_dans_ecran_courant(word Pos_X,word Pos_Y,byte Couleur) -{ - //if ((Pos_X>=0) && (Pos_Y>=0)) //Toujours vrai ? - if ((Pos_X=0) && (Pos_Y>=0)) - if ((Pos_X=0) && (Pos_Y>=0)) - if ((Pos_X> 5) << 5) | - ((V >> 5) << 2) | - ((B >> 6)); - Pixel(Preview_Pos_X+(Pos_X/Preview_Facteur_X), - Preview_Pos_Y+(Pos_Y/Preview_Facteur_Y), - Couleur); - } -} - -// Création d'une palette fake -void Palette_fake_24b(T_Palette Palette) -{ - int Couleur; - - // Génération de la palette - for (Couleur=0;Couleur<256;Couleur++) - { - Palette[Couleur].R=((Couleur & 0xE0)>>5)<<3; - Palette[Couleur].V=((Couleur & 0x1C)>>2)<<3; - Palette[Couleur].B=((Couleur & 0x03)>>0)<<4; - } -} - -// Supplément à faire lors de l'initialisation d'une preview dans le cas -// d'une image 24b -void Initialiser_preview_24b(int Largeur,int Hauteur) -{ - if (Pixel_de_chargement==Pixel_Chargement_dans_preview) - { - // Aiguillage du chargement 24b - Pixel_Chargement_24b=Pixel_Chargement_dans_preview_24b; - - // Changement de palette - Palette_fake_24b(Principal_Palette); - Set_palette(Principal_Palette); - Remapper_fileselect(); - } - else - { - // Aiguillage du chargement 24b - Pixel_Chargement_24b=Pixel_Chargement_dans_buffer_24b; - - // Allocation du buffer 24b - Buffer_image_24b= - (struct Composantes *)Emprunter_memoire_de_page(Largeur*Hauteur*sizeof(struct Composantes)); - if (!Buffer_image_24b) - { - // Afficher un message d'erreur - - // Pour ˆtre s–r que ce soit lisible. - Calculer_couleurs_menu_optimales(Principal_Palette); - Message_Memoire_insuffisante(); - if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) - Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante - else - Erreur_fichier=3; // 3 => Chargement de brosse échoué - } - else - Image_24b=1; // On a un buffer à traiter en fin de chargement - } -} - - - - -void Initialiser_preview(short Largeur,short Hauteur,long Taille,int Format) -// -// Cette procédure doit ˆtre appelée par les routines de chargement -// d'images. -// Elle doit ˆtre appelée entre le moment o— l'on connait la dimension de -// l'image (dimension réelle, pas dimension tronquée) et l'affichage du -// premier point. -// -{ - char Chaine[256]; - int Image_en_24b; - - Image_en_24b=Format & FORMAT_24B; - Format =Format & (~FORMAT_24B); - - if (Pixel_de_chargement==Pixel_Chargement_dans_preview) - { - // Préparation du chargement d'une preview: - - // Affichage des données "Image size:" - if ((Largeur<10000) && (Hauteur<10000)) - { - Num2str(Largeur,Chaine,4); - Num2str(Hauteur,Chaine+5,4); - Chaine[4]='x'; - Print_dans_fenetre(226,55,Chaine,CM_Noir,CM_Clair); - } - else - { - Print_dans_fenetre(226,55,"VERY BIG!",CM_Noir,CM_Clair); - } - - // Affichage de la taille du fichier - if (Taille<1048576) - { - // Le fichier fait moins d'un Mega, on affiche sa taille direct - Num2str(Taille,Chaine,9); - Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); - } - else if ((Taille/1024)<10000000) - { - // Le fichier fait plus d'un Mega, on peut afficher sa taille en Ko - Num2str(Taille/1024,Chaine,7); - Chaine[7]='K'; - Chaine[8]='b'; - Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); - } - else - { - // Le fichier fait plus de 10 Giga octets (cas trŠs rare :)) - Print_dans_fenetre(226,63,"TOO BIG!!",CM_Noir,CM_Clair); - } - - // Affichage du vrai format - if (Format!=Principal_Format) - { - Print_dans_fenetre( 27,74,"but is:",CM_Fonce,CM_Clair); - Print_dans_fenetre( 83,74,Format_Extension[Format-1],CM_Noir,CM_Clair); - } - - // On efface le commentaire précédent - Block(Fenetre_Pos_X+46*Menu_Facteur_X,Fenetre_Pos_Y+176*Menu_Facteur_Y, - Menu_Facteur_X<<8,Menu_Facteur_Y<<3,CM_Clair); - // Affichage du commentaire - if (Format_Commentaire[Format-1]) - Print_dans_fenetre(46,176,Principal_Commentaire,CM_Noir,CM_Clair); - - // Calculs des données nécessaires à l'affichage de la preview: - Preview_Facteur_X=Round_div_max(Largeur,122*Menu_Facteur_X); - Preview_Facteur_Y=Round_div_max(Hauteur, 82*Menu_Facteur_Y); - - if ( (!Config.Maximize_preview) && (Preview_Facteur_X!=Preview_Facteur_Y) ) - { - if (Preview_Facteur_X>Preview_Facteur_Y) - Preview_Facteur_Y=Preview_Facteur_X; - else - Preview_Facteur_X=Preview_Facteur_Y; - } - - Preview_Pos_X=Fenetre_Pos_X+180*Menu_Facteur_X; - Preview_Pos_Y=Fenetre_Pos_Y+ 89*Menu_Facteur_Y; - - // On nettoie la zone o— va s'afficher la preview: - Block(Preview_Pos_X,Preview_Pos_Y, - Round_div_max(Largeur,Preview_Facteur_X), - Round_div_max(Hauteur,Preview_Facteur_Y), - CM_Noir); - } - else - { - if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) - { - if (Backup_avec_nouvelles_dimensions(0,Largeur,Hauteur)) - { - // La nouvelle page a pu ˆtre allouée, elle est pour l'instant pleine - // de 0s. Elle fait Principal_Largeur_image de large. - // Normalement tout va bien, tout est sous contr“le... - } - else - { - // Afficher un message d'erreur - - // Pour ˆtre s–r que ce soit lisible. - Calculer_couleurs_menu_optimales(Principal_Palette); - Message_Memoire_insuffisante(); - Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante - } - } - else // chargement dans la brosse - { - free(Brosse); - free(Smear_Brosse); - Brosse=(byte *)malloc(Largeur*Hauteur); - Brosse_Largeur=Largeur; - Brosse_Hauteur=Hauteur; - if (Brosse) - { - Smear_Brosse=(byte *)malloc(Largeur*Hauteur); - if (!Smear_Brosse) - Erreur_fichier=3; - } - else - Erreur_fichier=3; - } - } - - if (!Erreur_fichier) - if (Image_en_24b) - Initialiser_preview_24b(Largeur,Hauteur); -} - - - -void Dessiner_preview_palette(void) -{ - short Indice; - short Preview_Pos_X=Fenetre_Pos_X+186*Menu_Facteur_X; - short Preview_Pos_Y=Fenetre_Pos_Y+ 90*Menu_Facteur_Y; - - if (Pixel_de_chargement==Pixel_Chargement_dans_preview) - for (Indice=0; Indice<256; Indice++) - Block(Preview_Pos_X+(((Indice>>4)*7)*Menu_Facteur_X), - Preview_Pos_Y+(((Indice&15)*5)*Menu_Facteur_Y), - 5*Menu_Facteur_X,5*Menu_Facteur_Y,Indice); -} - - - -// Calcul du nom complet du fichier -void Nom_fichier_complet(char * Nom_du_fichier, byte Sauve_Colorix) -{ - byte Pos; - - strcpy(Nom_du_fichier,Principal_Repertoire_fichier); - - if (Nom_du_fichier[strlen(Nom_du_fichier)-1]!='\\') - strcat(Nom_du_fichier,"\\"); - - // Si on est en train de sauvegarder une image Colorix, on calcule son ext. - if (Sauve_Colorix) - { - Pos=strlen(Principal_Nom_fichier)-1; - if (Principal_Nom_fichier[Pos]=='?') - { - if (Principal_Largeur_image<=320) - Principal_Nom_fichier[Pos]='I'; - else - { - if (Principal_Largeur_image<=360) - Principal_Nom_fichier[Pos]='Q'; - else - { - if (Principal_Largeur_image<=640) - Principal_Nom_fichier[Pos]='F'; - else - { - if (Principal_Largeur_image<=800) - Principal_Nom_fichier[Pos]='N'; - else - Principal_Nom_fichier[Pos]='O'; - } - } - } - } - } - - strcat(Nom_du_fichier,Principal_Nom_fichier); -} - - -///////////////////////////////////////////////////////////////////////////// -// Gestion des lectures et écritures // -///////////////////////////////////////////////////////////////////////////// - -byte * Tampon_lecture; -word Index_lecture; - -void Init_lecture(void) -{ - Tampon_lecture=(byte *)malloc(64000); - Index_lecture=64000; -} - -byte Lire_octet(int Fichier) -{ - if (++Index_lecture>=64000) - { - if (read(Fichier,Tampon_lecture,64000)<=0) - Erreur_fichier=2; - Index_lecture=0; - } - return Tampon_lecture[Index_lecture]; -} - -void Close_lecture(void) -{ - free(Tampon_lecture); -} - -// -------------------------------------------------------------------------- - -byte * Tampon_ecriture; -word Index_ecriture; - -void Init_ecriture(void) -{ - Tampon_ecriture=(byte *)malloc(64000); - Index_ecriture=0; -} - -void Ecrire_octet(int Fichier, byte Octet) -{ - Tampon_ecriture[Index_ecriture++]=Octet; - if (Index_ecriture>=64000) - { - if (write(Fichier,Tampon_ecriture,64000)==-1) - Erreur_fichier=1; - Index_ecriture=0; - } -} - -void Close_ecriture(int Fichier) -{ - if (Index_ecriture) - if (write(Fichier,Tampon_ecriture,Index_ecriture)==-1) - Erreur_fichier=1; - free(Tampon_ecriture); -} - - - -///////////////////////////////////////////////////////////////////////////// - -void (/*__interrupt __near*/ *Ancien_handler_clavier)(void); -void /*__interrupt __near*/ Nouveau_handler_clavier(void) -{ +#include "linux.h" + +// On déclare méchamment le prototype de Erreur pour éviter de faire un +// fichier "main.h": +void Erreur(int Code); + + +// Chargement des pixels dans l'écran principal +void Pixel_Chargement_dans_ecran_courant(word Pos_X,word Pos_Y,byte Couleur) +{ + //if ((Pos_X>=0) && (Pos_Y>=0)) //Toujours vrai ? + if ((Pos_X=0) && (Pos_Y>=0)) + if ((Pos_X=0) && (Pos_Y>=0)) + if ((Pos_X> 5) << 5) | + ((V >> 5) << 2) | + ((B >> 6)); + Pixel(Preview_Pos_X+(Pos_X/Preview_Facteur_X), + Preview_Pos_Y+(Pos_Y/Preview_Facteur_Y), + Couleur); + } +} + +// Création d'une palette fake +void Palette_fake_24b(T_Palette Palette) +{ + int Couleur; + + // Génération de la palette + for (Couleur=0;Couleur<256;Couleur++) + { + Palette[Couleur].R=((Couleur & 0xE0)>>5)<<3; + Palette[Couleur].V=((Couleur & 0x1C)>>2)<<3; + Palette[Couleur].B=((Couleur & 0x03)>>0)<<4; + } +} + +// Supplément à faire lors de l'initialisation d'une preview dans le cas +// d'une image 24b +void Initialiser_preview_24b(int Largeur,int Hauteur) +{ + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + { + // Aiguillage du chargement 24b + Pixel_Chargement_24b=Pixel_Chargement_dans_preview_24b; + + // Changement de palette + Palette_fake_24b(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + { + // Aiguillage du chargement 24b + Pixel_Chargement_24b=Pixel_Chargement_dans_buffer_24b; + + // Allocation du buffer 24b + Buffer_image_24b= + (struct Composantes *)Emprunter_memoire_de_page(Largeur*Hauteur*sizeof(struct Composantes)); + if (!Buffer_image_24b) + { + // Afficher un message d'erreur + + // Pour ˆtre s–r que ce soit lisible. + Calculer_couleurs_menu_optimales(Principal_Palette); + Message_Memoire_insuffisante(); + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante + else + Erreur_fichier=3; // 3 => Chargement de brosse échoué + } + else + Image_24b=1; // On a un buffer à traiter en fin de chargement + } +} + + + + +void Initialiser_preview(short Largeur,short Hauteur,long Taille,int Format) +// +// Cette procédure doit ˆtre appelée par les routines de chargement +// d'images. +// Elle doit ˆtre appelée entre le moment o— l'on connait la dimension de +// l'image (dimension réelle, pas dimension tronquée) et l'affichage du +// premier point. +// +{ + char Chaine[256]; + int Image_en_24b; + + Image_en_24b=Format & FORMAT_24B; + Format =Format & (~FORMAT_24B); + + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + { + // Préparation du chargement d'une preview: + + // Affichage des données "Image size:" + if ((Largeur<10000) && (Hauteur<10000)) + { + Num2str(Largeur,Chaine,4); + Num2str(Hauteur,Chaine+5,4); + Chaine[4]='x'; + Print_dans_fenetre(226,55,Chaine,CM_Noir,CM_Clair); + } + else + { + Print_dans_fenetre(226,55,"VERY BIG!",CM_Noir,CM_Clair); + } + + // Affichage de la taille du fichier + if (Taille<1048576) + { + // Le fichier fait moins d'un Mega, on affiche sa taille direct + Num2str(Taille,Chaine,9); + Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); + } + else if ((Taille/1024)<10000000) + { + // Le fichier fait plus d'un Mega, on peut afficher sa taille en Ko + Num2str(Taille/1024,Chaine,7); + Chaine[7]='K'; + Chaine[8]='b'; + Print_dans_fenetre(226,63,Chaine,CM_Noir,CM_Clair); + } + else + { + // Le fichier fait plus de 10 Giga octets (cas trŠs rare :)) + Print_dans_fenetre(226,63,"TOO BIG!!",CM_Noir,CM_Clair); + } + + // Affichage du vrai format + if (Format!=Principal_Format) + { + Print_dans_fenetre( 27,74,"but is:",CM_Fonce,CM_Clair); + Print_dans_fenetre( 83,74,Format_Extension[Format-1],CM_Noir,CM_Clair); + } + + // On efface le commentaire précédent + Block(Fenetre_Pos_X+46*Menu_Facteur_X,Fenetre_Pos_Y+176*Menu_Facteur_Y, + Menu_Facteur_X<<8,Menu_Facteur_Y<<3,CM_Clair); + // Affichage du commentaire + if (Format_Commentaire[Format-1]) + Print_dans_fenetre(46,176,Principal_Commentaire,CM_Noir,CM_Clair); + + // Calculs des données nécessaires à l'affichage de la preview: + Preview_Facteur_X=Round_div_max(Largeur,122*Menu_Facteur_X); + Preview_Facteur_Y=Round_div_max(Hauteur, 82*Menu_Facteur_Y); + + if ( (!Config.Maximize_preview) && (Preview_Facteur_X!=Preview_Facteur_Y) ) + { + if (Preview_Facteur_X>Preview_Facteur_Y) + Preview_Facteur_Y=Preview_Facteur_X; + else + Preview_Facteur_X=Preview_Facteur_Y; + } + + Preview_Pos_X=Fenetre_Pos_X+180*Menu_Facteur_X; + Preview_Pos_Y=Fenetre_Pos_Y+ 89*Menu_Facteur_Y; + + // On nettoie la zone o— va s'afficher la preview: + Block(Preview_Pos_X,Preview_Pos_Y, + Round_div_max(Largeur,Preview_Facteur_X), + Round_div_max(Hauteur,Preview_Facteur_Y), + CM_Noir); + } + else + { + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + { + if (Backup_avec_nouvelles_dimensions(0,Largeur,Hauteur)) + { + // La nouvelle page a pu ˆtre allouée, elle est pour l'instant pleine + // de 0s. Elle fait Principal_Largeur_image de large. + // Normalement tout va bien, tout est sous contr“le... + } + else + { + // Afficher un message d'erreur + + // Pour ˆtre s–r que ce soit lisible. + Calculer_couleurs_menu_optimales(Principal_Palette); + Message_Memoire_insuffisante(); + Erreur_fichier=1; // 1 => On n'a pas perdu l'image courante + } + } + else // chargement dans la brosse + { + free(Brosse); + free(Smear_Brosse); + Brosse=(byte *)malloc(Largeur*Hauteur); + Brosse_Largeur=Largeur; + Brosse_Hauteur=Hauteur; + if (Brosse) + { + Smear_Brosse=(byte *)malloc(Largeur*Hauteur); + if (!Smear_Brosse) + Erreur_fichier=3; + } + else + Erreur_fichier=3; + } + } + + if (!Erreur_fichier) + if (Image_en_24b) + Initialiser_preview_24b(Largeur,Hauteur); +} + + + +void Dessiner_preview_palette(void) +{ + short Indice; + short Preview_Pos_X=Fenetre_Pos_X+186*Menu_Facteur_X; + short Preview_Pos_Y=Fenetre_Pos_Y+ 90*Menu_Facteur_Y; + + if (Pixel_de_chargement==Pixel_Chargement_dans_preview) + for (Indice=0; Indice<256; Indice++) + Block(Preview_Pos_X+(((Indice>>4)*7)*Menu_Facteur_X), + Preview_Pos_Y+(((Indice&15)*5)*Menu_Facteur_Y), + 5*Menu_Facteur_X,5*Menu_Facteur_Y,Indice); +} + + + +// Calcul du nom complet du fichier +void Nom_fichier_complet(char * Nom_du_fichier, byte Sauve_Colorix) +{ + byte Pos; + + strcpy(Nom_du_fichier,Principal_Repertoire_fichier); + + //On va ajouter un / à la fin du chemin s'il n'y est pas encore + //Attention sous windows il faut un \... + if (Nom_du_fichier[strlen(Nom_du_fichier)-1]!='/') + strcat(Nom_du_fichier,"/"); + + // Si on est en train de sauvegarder une image Colorix, on calcule son ext. + if (Sauve_Colorix) + { + Pos=strlen(Principal_Nom_fichier)-1; + if (Principal_Nom_fichier[Pos]=='?') + { + if (Principal_Largeur_image<=320) + Principal_Nom_fichier[Pos]='I'; + else + { + if (Principal_Largeur_image<=360) + Principal_Nom_fichier[Pos]='Q'; + else + { + if (Principal_Largeur_image<=640) + Principal_Nom_fichier[Pos]='F'; + else + { + if (Principal_Largeur_image<=800) + Principal_Nom_fichier[Pos]='N'; + else + Principal_Nom_fichier[Pos]='O'; + } + } + } + } + } + + strcat(Nom_du_fichier,Principal_Nom_fichier); +} + + +///////////////////////////////////////////////////////////////////////////// +// Gestion des lectures et écritures // +///////////////////////////////////////////////////////////////////////////// + +byte * Tampon_lecture; +word Index_lecture; + +void Init_lecture(void) +{ + Tampon_lecture=(byte *)malloc(64000); + Index_lecture=64000; +} + +byte Lire_octet(int Fichier) +{ + if (++Index_lecture>=64000) + { + if (read(Fichier,Tampon_lecture,64000)<=0) + Erreur_fichier=2; + Index_lecture=0; + } + return Tampon_lecture[Index_lecture]; +} + +void Close_lecture(void) +{ + free(Tampon_lecture); +} + +// -------------------------------------------------------------------------- + +byte * Tampon_ecriture; +word Index_ecriture; + +void Init_ecriture(void) +{ + Tampon_ecriture=(byte *)malloc(64000); + Index_ecriture=0; +} + +void Ecrire_octet(int Fichier, byte Octet) +{ + Tampon_ecriture[Index_ecriture++]=Octet; + if (Index_ecriture>=64000) + { + if (write(Fichier,Tampon_ecriture,64000)==-1) + Erreur_fichier=1; + Index_ecriture=0; + } +} + +void Close_ecriture(int Fichier) +{ + if (Index_ecriture) + if (write(Fichier,Tampon_ecriture,Index_ecriture)==-1) + Erreur_fichier=1; + free(Tampon_ecriture); +} + + + +///////////////////////////////////////////////////////////////////////////// + +void (/*__interrupt __near*/ *Ancien_handler_clavier)(void); +void /*__interrupt __near*/ Nouveau_handler_clavier(void) +{ /* A revoir ... - _disable(); - if (!Erreur_fichier) - Erreur_fichier=-1; - _enable(); + _disable(); + if (!Erreur_fichier) + Erreur_fichier=-1; + _enable(); _chain_intr(Ancien_handler_clavier); */ - ; -} - - -// -------- Modifier la valeur du code d'erreur d'accŠs à un fichier -------- -// On n'est pas obligé d'utiliser cette fonction à chaque fois mais il est -// important de l'utiliser dans les cas du type: -// if (!Erreur_fichier) *** else Erreur_fichier=***; -// En fait, dans le cas o— l'on modifie Erreur_fichier alors qu'elle contient -// dŠjà un code d'erreur. -void Modif_Erreur_fichier(int Nouvelle_valeur) -{ - if (Erreur_fichier>=0) - Erreur_fichier=Nouvelle_valeur; -} - - -// -- Charger n'importe connu quel type de fichier d'image (ou palette) ----- -void Charger_image(byte Image) -{ - int Indice; // Indice de balayage des formats - int Format; // Format du fichier à charger - - - // On place par défaut Erreur_fichier à vrai au cas o— on ne sache pas - // charger le format du fichier: - Erreur_fichier=1; - - if (Principal_Format!=0) - { - Format_Test[Principal_Format-1](); - if (!Erreur_fichier) - // Si dans le sélecteur il y a un format valide on le prend tout de suite - Format=Principal_Format-1; - } - - if (Erreur_fichier) - { - // Sinon, on va devoir scanner les différents formats qu'on connait pour - // savoir à quel format est le fichier: - for (Indice=0;Indice=0) + Erreur_fichier=Nouvelle_valeur; +} + + +// -- Charger n'importe connu quel type de fichier d'image (ou palette) ----- +void Charger_image(byte Image) +{ + int Indice; // Indice de balayage des formats + int Format; // Format du fichier à charger + + + // On place par défaut Erreur_fichier à vrai au cas o— on ne sache pas + // charger le format du fichier: + Erreur_fichier=1; + + if (Principal_Format!=0) + { + Format_Test[Principal_Format-1](); + if (!Erreur_fichier) + // Si dans le sélecteur il y a un format valide on le prend tout de suite + Format=Principal_Format-1; + } + + if (Erreur_fichier) + { + // Sinon, on va devoir scanner les différents formats qu'on connait pour + // savoir à quel format est le fichier: + for (Indice=0;Indice0) - Erreur(0); - - if (Image_24b) - { - // On vient de charger une image 24b - if (!Erreur_fichier) - { - // Le chargement a réussi, on peut faire la conversion en 256 couleurs - if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) - { - // Cas d'un chargement dans l'image - if (Convert_bitmap_24B_to_256(Principal_Ecran,Buffer_image_24b,Principal_Largeur_image,Principal_Hauteur_image,Principal_Palette)) - Erreur_fichier=2; - } - else - { - // Cas d'un chargement dans la brosse - if (Convert_bitmap_24B_to_256(Brosse,Buffer_image_24b,Brosse_Largeur,Brosse_Hauteur,Principal_Palette)) - Erreur_fichier=2; - } - if (!Erreur_fichier) - Palette_256_to_64(Principal_Palette); - } - - free(Buffer_image_24b); - } - - if (Image) - { - if ( (Erreur_fichier!=1) && (Format_Backup_done[Format]) ) - { - // On considŠre que l'image chargée n'est plus modifiée - Principal_Image_modifiee=0; - // Et on documente la variable Principal_Format_fichier avec la valeur: - Principal_Format_fichier=Format+1; - - // Correction des dimensions - if (Principal_Largeur_image<1) - Principal_Largeur_image=1; - if (Principal_Hauteur_image<1) - Principal_Hauteur_image=1; - } - else if (Erreur_fichier!=1) - { - // On considŠre que l'image chargée est encore modifiée - Principal_Image_modifiee=1; - // Et on documente la variable Principal_Format_fichier avec la valeur: - Principal_Format_fichier=Format+1; - } - else - { - // Dans ce cas, on sait que l'image n'a pas changé, mais ses - // paramŠtres (dimension, palette, ...) si. Donc on les restaures. - Download_infos_page_principal(Principal_Backups->Pages); - } - } - } - else - // Sinon, l'appelant sera au courant de l'échec grƒce à Erreur_fichier; - // et si on s'apprˆtait à faire un chargement définitif de l'image (pas - // une preview), alors on flash l'utilisateur. - if (Pixel_de_chargement!=Pixel_Chargement_dans_preview) - Erreur(0); -} - - -// -- Sauver n'importe quel type connu de fichier d'image (ou palette) ------ -void Sauver_image(byte Image) -{ - // On place par défaut Erreur_fichier à vrai au cas o— on ne sache pas - // sauver le format du fichier: (Est-ce vraiment utile??? Je ne crois pas!) - Erreur_fichier=1; - - Lit_pixel_de_sauvegarde=(Image)?Lit_pixel_dans_ecran_courant:Lit_pixel_dans_brosse; - - Format_Save[Principal_Format_fichier-1](); - - if (Erreur_fichier) - Erreur(0); - else - { - if ((Image) && (Format_Backup_done[Principal_Format_fichier-1])) - Principal_Image_modifiee=0; - } -} - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// PAL //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -// -- Tester si un fichier est au format PAL -------------------------------- -void Test_PAL(void) -{ - int Fichier; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - long Taille_du_fichier; // Taille du fichier - struct stat* Informations_Fichier=NULL; - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=1; - - // Ouverture du fichier - Fichier=open(Nom_du_fichier,O_RDONLY); - if (Fichier!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - // Lecture de la taille du fichier - Taille_du_fichier=Informations_Fichier->st_size; - close(Fichier); - // Le fichier ne peut ˆtre au format PAL que si sa taille vaut 768 octets - if (Taille_du_fichier==sizeof(T_Palette)) - Erreur_fichier=0; - } -} - - -// -- Lire un fichier au format PAL ----------------------------------------- -void Load_PAL(void) -{ - int Handle; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - //long Taille_du_fichier; // Taille du fichier - - - Nom_fichier_complet(Nom_du_fichier,0); - Erreur_fichier=0; - - // Ouverture du fichier - Handle=open(Nom_du_fichier,O_RDONLY); - if (Handle!=-1) - { - // Initialiser_preview(???); // Pas possible... pas d'image... - - // Lecture du fichier dans Principal_Palette - if (read(Handle,Principal_Palette,sizeof(T_Palette))==sizeof(T_Palette)) - { - Set_palette(Principal_Palette); - Remapper_fileselect(); - - // On dessine une preview de la palette (si chargement=preview) - Dessiner_preview_palette(); - } - else - Erreur_fichier=2; - - // Fermeture du fichier - close(Handle); - } - else - // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur - Erreur_fichier=1; -} - - -// -- Sauver un fichier au format PAL --------------------------------------- -void Save_PAL(void) -{ - int Fichier; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - //long Taille_du_fichier; // Taille du fichier - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - // Ouverture du fichier - Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); - if (Fichier!=-1) - { - // Enregistrement de Principal_Palette dans le fichier - if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) - { - Erreur_fichier=1; - close(Fichier); - remove(Nom_du_fichier); - } - else // Ecriture correcte => Fermeture normale du fichier - close(Fichier); - } - else // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur - { - Erreur_fichier=1; - close(Fichier); - remove(Nom_du_fichier); - // On se fout du résultat de l'opération car si ‡a - // renvoie 0 c'est que le fichier avait été partiel- - // -lement écrit, sinon pas du tout. Or dans tous les - // cas ‡a revient au mˆme pour nous: Sauvegarde ratée! - } -} - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// IMG //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -// -- Tester si un fichier est au format IMG -------------------------------- -void Test_IMG(void) -{ - int Handle; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - struct Header - { - byte Filler1[6]; - word Largeur; - word Hauteur; - byte Filler2[118]; - T_Palette Palette; - } IMG_Header; - byte Signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=1; - - // Ouverture du fichier - Handle=open(Nom_du_fichier,O_RDONLY); - if (Handle!=-1) - { - // Lecture et vérification de la signature - if ((read(Handle,&IMG_Header,sizeof(struct Header)))==sizeof(struct Header)) - { - if ( (!memcmp(IMG_Header.Filler1,Signature,6)) - && IMG_Header.Largeur && IMG_Header.Hauteur) - Erreur_fichier=0; - } - // Fermeture du fichier - close(Handle); - } -} - - -// -- Lire un fichier au format IMG ----------------------------------------- -void Load_IMG(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - byte * Buffer; - int Fichier; - word Pos_X,Pos_Y; - long Largeur_lue; - long Taille_du_fichier; - struct Header - { - byte Filler1[6]; - word Largeur; - word Hauteur; - byte Filler2[118]; - T_Palette Palette; - } IMG_Header; - struct stat* Informations_Fichier=NULL; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - - if (read(Fichier,&IMG_Header,sizeof(struct Header))==sizeof(struct Header)) - { - Buffer=(byte *)malloc(IMG_Header.Largeur); - - Initialiser_preview(IMG_Header.Largeur,IMG_Header.Hauteur,Taille_du_fichier,FORMAT_IMG); - if (Erreur_fichier==0) - { - // On commence par passer la palette en 256 comme ‡a, si la nouvelle - // palette a moins de 256 coul, la précédente ne souffrira pas d'un - // assombrissement préjudiciable. - Palette_64_to_256(Principal_Palette); - // On peut maintenant transférer la nouvelle palette - memcpy(Principal_Palette,IMG_Header.Palette,sizeof(T_Palette)); - Palette_256_to_64(Principal_Palette); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - Principal_Largeur_image=IMG_Header.Largeur; - Principal_Hauteur_image=IMG_Header.Hauteur; - - for (Pos_Y=0;(Pos_Yst_size; - - if (read(Fichier,&Head,sizeof(struct Header))==sizeof(struct Header)) - { - Principal_Commentaire[0]='\0'; // On efface le commentaire - if (Head.Jump) - { - Indice=0; - while ( (IndiceTAILLE_COMMENTAIRE) - { - Couleur=Octet; // On se sert de Couleur comme - Octet=TAILLE_COMMENTAIRE; // variable temporaire - Couleur-=TAILLE_COMMENTAIRE; - } - else - Couleur=0; - - if (read(Fichier,Principal_Commentaire,Octet)==Octet) - { - Indice+=Octet; - Principal_Commentaire[Octet]='\0'; - if (Couleur) - if (lseek(Fichier,Couleur,SEEK_CUR)==-1) - Erreur_fichier=2; - } - else - Erreur_fichier=2; - } - else - Erreur_fichier=2; - break; - - case 1 : // Dimensions de l'écran d'origine - if (read(Fichier,&Octet,1)==1) - { - if (Octet==4) - { - Indice+=4; - if ( (read(Fichier,&Ecran_original_X,2)!=2) - || (read(Fichier,&Ecran_original_Y,2)!=2) ) - Erreur_fichier=2; - } - else - Erreur_fichier=2; - } - else - Erreur_fichier=2; - break; - - case 2 : // Couleur de transparence - if (read(Fichier,&Octet,1)==1) - { - if (Octet==1) - { - Indice++; - if (read(Fichier,&Back_color,1)!=1) - Erreur_fichier=2; - } - else - Erreur_fichier=2; - } - else - Erreur_fichier=2; - break; - - default: - if (read(Fichier,&Octet,1)==1) - { - Indice+=Octet; - if (lseek(Fichier,Octet,SEEK_CUR)==-1) - Erreur_fichier=2; - } - else - Erreur_fichier=2; - } - } - else - Erreur_fichier=2; - } - if ( (!Erreur_fichier) && (Indice!=Head.Jump) ) - Erreur_fichier=2; - } - - Init_lecture(); - - if (!Erreur_fichier) - { - Initialiser_preview(Head.Largeur,Head.Hauteur,Taille_du_fichier,FORMAT_PKM); - if (Erreur_fichier==0) - { - Principal_Largeur_image=Head.Largeur; - Principal_Hauteur_image=Head.Hauteur; - Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); - - memcpy(Principal_Palette,Head.Palette,sizeof(T_Palette)); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - Compteur_de_donnees_packees=0; - Compteur_de_pixels=0; - Taille_pack=(Informations_Fichier->st_size)-sizeof(struct Header)-Head.Jump; - - // Boucle de décompression: - while ( (Compteur_de_pixels>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_pixels2) && (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; - close(Fichier); - } - else - { - Erreur_fichier=1; - close(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); -} - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// LBM //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -// -- Tester si un fichier est au format LBM -------------------------------- - - int LBM_Fichier; - - // ------------ Lire et traduire une valeur au format Motorola ------------ - dword Lire_long(void) - { - dword Temp; - dword Valeur; - - if (read(LBM_Fichier,&Valeur,4)!=4) - Erreur_fichier=1; - swab((char *)&Valeur,(char *)&Temp,4); - return ((Temp>>16)+(Temp<<16)); - } - - -void Test_LBM(void) -{ - char Nom_du_fichier[256]; - char Format[4]; - char Section[4]; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - if (read(LBM_Fichier,Section,4)!=4) - Erreur_fichier=1; - else - if (memcmp(Section,"FORM",4)) - Erreur_fichier=1; - else - { - Lire_long(); // On aurait pu vérifier que ce long est égal à la taille - // du fichier - 8, mais ‡a aurait interdit de charger des - // fichiers tronqués (et déjà que c'est chiant de perdre - // une partie du fichier il faut quand mˆme pouvoir en - // garder un peu... Sinon, moi je pleure :'( !!! ) - if (read(LBM_Fichier,Format,4)!=4) - Erreur_fichier=1; - else - if ( (memcmp(Format,"ILBM",4)) && (memcmp(Format,"PBM ",4)) ) - Erreur_fichier=1; - } - close(LBM_Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Lire un fichier au format LBM ----------------------------------------- - - byte * LBM_Buffer; - byte Image_HAM; - byte HBPm1; // Header.BitPlanes-1 - - // ---------------- Adapter la palette pour les images HAM ---------------- - void Adapter_Palette_HAM(void) - { - short I,J,Temp; - byte Couleur; - - if (Image_HAM==6) - { - for (I=1; I<=14; I++) - { - // On recopie a palette de base - memcpy(Principal_Palette+(I<<4),Principal_Palette,48); - // On modifie les teintes de cette palette - for (J=0; J<16; J++) - { - Couleur=(I<<4)+J; - if (I<=7) - { - if (I&1) - { - Temp=Principal_Palette[J].R+16; - Principal_Palette[Couleur].R=(Temp<63)?Temp:63; - } - if (I&2) - { - Temp=Principal_Palette[J].V+16; - Principal_Palette[Couleur].V=(Temp<63)?Temp:63; - } - if (I&4) - { - Temp=Principal_Palette[J].B+16; - Principal_Palette[Couleur].B=(Temp<63)?Temp:63; - } - } - else - { - if ((I-7)&1) - { - Temp=Principal_Palette[J].R-16; - Principal_Palette[Couleur].R=(Temp>=0)?Temp:0; - } - if ((I-7)&2) - { - Temp=Principal_Palette[J].V-16; - Principal_Palette[Couleur].V=(Temp>=0)?Temp:0; - } - if ((I-7)&4) - { - Temp=Principal_Palette[J].B-16; - Principal_Palette[Couleur].B=(Temp>=0)?Temp:0; - } - } - } - } - // Ici, il reste les 16 derniŠres couleurs à modifier - for (I=240,J=0; J<16; I++,J++) - { - Temp=Principal_Palette[J].R+8; - Principal_Palette[I].R=(Temp<63)?Temp:63; - Temp=Principal_Palette[J].V+8; - Principal_Palette[I].V=(Temp<63)?Temp:63; - Temp=Principal_Palette[J].B+8; - Principal_Palette[I].B=(Temp<63)?Temp:63; - } - } - else if (Image_HAM==8) - { - for (I=1; I<=3; I++) - { - // On recopie la palette de base - memcpy(Principal_Palette+(I<<6),Principal_Palette,192); - // On modifie les teintes de cette palette - for (J=0; J<64; J++) - { - Couleur=(I<<6)+J; - switch (I) - { - case 1 : - Temp=Principal_Palette[J].R+16; - Principal_Palette[Couleur].R=(Temp<63)?Temp:63; - break; - case 2 : - Temp=Principal_Palette[J].V+16; - Principal_Palette[Couleur].V=(Temp<63)?Temp:63; - break; - default: - Temp=Principal_Palette[J].B+16; - Principal_Palette[Couleur].B=(Temp<63)?Temp:63; - } - } - } - } - else // Image 64 couleurs sauvée en 32. - { - for (I=0; I<32; I++) - { - J=I+32; - Principal_Palette[J].R=Principal_Palette[I].R>>1; - Principal_Palette[J].V=Principal_Palette[I].V>>1; - Principal_Palette[J].B=Principal_Palette[I].B>>1; - } - } - } - - // ------------------------- Attendre une section ------------------------- - byte Wait_for(byte * Section_attendue) - { - // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur) - dword Taille_section; - byte Section_lue[4]; - - if (read(LBM_Fichier,Section_lue,4)!=4) - return 0; - while (memcmp(Section_lue,Section_attendue,4)) // Sect. pas encore trouvée - { - Taille_section=Lire_long(); - if (Erreur_fichier) - return 0; - if (Taille_section&1) - Taille_section++; - if (lseek(LBM_Fichier,Taille_section,SEEK_CUR)==-1) - return 0; - if (read(LBM_Fichier,Section_lue,4)!=4) - return 0; - } - return 1; - } - - // ----------------------- Afficher une ligne ILBM ------------------------ - void Draw_ILBM_line(short Pos_Y, short Vraie_taille_ligne) - { - byte Couleur; - byte Rouge,Vert,Bleu; - byte Temp; - short Pos_X; - - if (Image_HAM<=1) // ILBM - { - for (Pos_X=0; Pos_X>2; - Couleur=Meilleure_couleur(Rouge,Vert,Bleu); - break; - case 0x02: // Rouge - Rouge=Temp>>2; - Couleur=Meilleure_couleur(Rouge,Vert,Bleu); - break; - case 0x03: // Vert - Vert=Temp>>2; - Couleur=Meilleure_couleur(Rouge,Vert,Bleu); - break; - default: // Nouvelle couleur - Couleur=Temp; - Rouge=Principal_Palette[Couleur].R; - Vert =Principal_Palette[Couleur].V; - Bleu =Principal_Palette[Couleur].B; - } - Pixel_de_chargement(Pos_X,Pos_Y,Couleur); - } - } - } - - -void Load_LBM(void) -{ - char Nom_du_fichier[256]; - //int Fichier; - struct Header_LBM - { - word Width; - word Height; - short Xorg; // Inutile - short Yorg; // Inutile - byte Bit_planes; - byte Mask; - byte Compression; - byte Pad1; // Inutile - word Transp_col; - byte Xaspect; // Inutile - byte Yaspect; // Inutile - short Xscreen; - short Yscreen; - } Header; - char Format[4]; - char Section[4]; - byte Octet; - short B256; - dword Nb_couleurs; - dword Taille_image; - short Pos_X; - short Pos_Y; - short Compteur; - short Taille_ligne; // Taille d'une ligne en octets - short Vraie_taille_ligne; // Taille d'une ligne en pixels - byte Couleur; - long Taille_du_fichier; - struct stat* Informations_Fichier=NULL; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - - // On avance dans le fichier (pas besoin de tester ce qui l'a déjà été) - read(LBM_Fichier,Section,4); - Lire_long(); - read(LBM_Fichier,Format,4); - if (!Wait_for((byte *)"BMHD")) - Erreur_fichier=1; - Lire_long(); - - // Maintenant on lit le header pour pouvoir commencer le chargement de l'image - if ( (read(LBM_Fichier,&Header,sizeof(struct Header_LBM))==sizeof(struct Header_LBM)) - && Header.Width && Header.Height) - { - if ( (Header.Bit_planes) && (Wait_for((byte *)"CMAP")) ) - { - Nb_couleurs=Lire_long()/3; - - if (((int)1< il faut copier les 32 coul. - } // sur les 32 suivantes et assombrir ces derniŠres. - else - { - if ((Header.Bit_planes==6) || (Header.Bit_planes==8)) - Image_HAM=Header.Bit_planes; - else - // Erreur_fichier=1; /* C'est censé ˆtre incorrect mais j'ai */ - Image_HAM=0; /* trouvé un fichier comme ‡a, alors... */ - } - } - else - Image_HAM=0; - - if ( (!Erreur_fichier) && (Nb_couleurs>=2) && (Nb_couleurs<=256) ) - { - HBPm1=Header.Bit_planes-1; - if (Header.Mask==1) - Header.Bit_planes++; - - // Deluxe paint le fait... alors on le fait... - Back_color=Header.Transp_col; - - // On commence par passer la palette en 256 comme ‡a, si la nouvelle - // palette a moins de 256 coul, la précédente ne souffrira pas d'un - // assombrissement préjudiciable. - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - else - Palette_64_to_256(Principal_Palette); - // On peut maintenant charger la nouvelle palette - if (read(LBM_Fichier,Principal_Palette,3*Nb_couleurs)==(3*Nb_couleurs)) - { - Palette_256_to_64(Principal_Palette); - if (Image_HAM) - Adapter_Palette_HAM(); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - // On lit l'octet de padding du CMAP si la taille est impaire - if (Nb_couleurs&1) - if (read(LBM_Fichier,&Octet,1)==1) - Erreur_fichier=2; - - if ( (Wait_for((byte *)"BODY")) && (!Erreur_fichier) ) - { - Taille_image=Lire_long(); - swab((char *)&Header.Width ,(char *)&Principal_Largeur_image,2); - swab((char *)&Header.Height,(char *)&Principal_Hauteur_image,2); - - swab((char *)&Header.Xscreen,(char *)&Ecran_original_X,2); - swab((char *)&Header.Yscreen,(char *)&Ecran_original_Y,2); - - Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_LBM); - if (Erreur_fichier==0) - { - if (!memcmp(Format,"ILBM",4)) // "ILBM": InterLeaved BitMap - { - // Calcul de la taille d'une ligne ILBM (pour les images ayant des dimensions exotiques) - if (Principal_Largeur_image & 15) - { - Vraie_taille_ligne=( (Principal_Largeur_image+16) >> 4 ) << 4; - Taille_ligne=( (Principal_Largeur_image+16) >> 4 )*(Header.Bit_planes<<1); - } - else - { - Vraie_taille_ligne=Principal_Largeur_image; - Taille_ligne=(Principal_Largeur_image>>3)*Header.Bit_planes; - } - - if (!Header.Compression) - { // non compressé - LBM_Buffer=(byte *)malloc(Taille_ligne); - for (Pos_Y=0; ((Pos_Y127) - { - Couleur=Lire_octet(LBM_Fichier); - B256=(short)(256-Octet); - for (Compteur=0; Compteur<=B256; Compteur++) - if (Pos_X127) - { - Couleur=Lire_octet(LBM_Fichier); - B256=256-Octet; - for (Compteur=0; Compteur<=B256; Compteur++) - Pixel_de_chargement(Pos_X++,Pos_Y,Couleur); - } - else - for (Compteur=0; Compteur<=Octet; Compteur++) - Pixel_de_chargement(Pos_X++,Pos_Y,Lire_octet(LBM_Fichier)); - } - } - Close_lecture(); - } - } - } - } - else - Modif_Erreur_fichier(2); - } - else - { - // On restore l'ancienne palette en cas d'erreur... - Palette_256_to_64(Principal_Palette); - // ... ce qui permet de ne renvoyer qu'une erreur 1 (pas de modif) - Erreur_fichier=1; - } - } - else - Modif_Erreur_fichier(1); - } - else - Erreur_fichier=1; - } - else - Erreur_fichier=1; - - close(LBM_Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Sauver un fichier au format LBM --------------------------------------- - - byte LBM_File_de_couleurs[129]; - word LBM_Taille_de_file; - byte LBM_Mode_repetition; - - // ----------- Traduire et écrire une valeur au format Motorola ----------- - void Ecrire_long(dword Valeur) - { - dword Temp; - - swab((char *)&Valeur,(char *)&Temp,4); - Valeur=(Temp>>16)+(Temp<<16); - if (write(LBM_Fichier,&Valeur,4)==-1) - Erreur_fichier=1; - } - - // ------------- Ecrire les couleurs que l'on vient de traiter ------------ - void Transferer_couleurs(void) - { - byte Indice; - - if (LBM_Taille_de_file>0) - { - if (LBM_Mode_repetition) - { - Ecrire_octet(LBM_Fichier,257-LBM_Taille_de_file); - Ecrire_octet(LBM_Fichier,LBM_File_de_couleurs[0]); - } - else - { - Ecrire_octet(LBM_Fichier,LBM_Taille_de_file-1); - for (Indice=0; Indice et on a 3 couleurs qui se suivent - { - LBM_Taille_de_file-=2; - Transferer_couleurs(); - LBM_File_de_couleurs[0]=Couleur; - LBM_File_de_couleurs[1]=Couleur; - LBM_File_de_couleurs[2]=Couleur; - LBM_Taille_de_file=3; - LBM_Mode_repetition=1; - } - } - else // La couleur n'est pas la mˆme que la précédente - { - if (!LBM_Mode_repetition) // On conserve le mode... - { - LBM_File_de_couleurs[LBM_Taille_de_file++]=Couleur; - if (LBM_Taille_de_file==128) - Transferer_couleurs(); - } - else // On change de mode... - { - Transferer_couleurs(); - LBM_File_de_couleurs[LBM_Taille_de_file]=Couleur; - LBM_Taille_de_file++; - } - } - } - } - - -void Save_LBM(void) -{ - char Nom_du_fichier[256]; - struct Header_LBM - { - word Width; - word Height; - short Xorg; // Inutile - short Yorg; // Inutile - byte BitPlanes; - byte Mask; - byte Compression; - byte Pad1; // Inutile - word Transp_col; // Inutile - byte Xaspect; // Inutile - byte Yaspect; // Inutile - short Xscreen; - short Yscreen; - } Header; - word Pos_X; - word Pos_Y; - byte Octet; - word Vraie_largeur; - struct stat* Informations_Fichier=NULL; - - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - - // Ouverture du fichier - LBM_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); - if (LBM_Fichier!=-1) - { - write(LBM_Fichier,"FORM",4); - Ecrire_long(0); // On mettra la taille à jour à la fin - - write(LBM_Fichier,"PBM BMHD",8); - Ecrire_long(20); - - // On corrige la largeur de l'image pour qu'elle soit multiple de 2 - Vraie_largeur=Principal_Largeur_image+(Principal_Largeur_image&1); - - //swab((byte *)&Vraie_largeur,(byte *)&Header.Width,2); - swab((byte *)&Principal_Largeur_image,(byte *)&Header.Width,2); - swab((byte *)&Principal_Hauteur_image,(byte *)&Header.Height,2); - Header.Xorg=0; - Header.Yorg=0; - Header.BitPlanes=8; - Header.Mask=0; - Header.Compression=1; - Header.Pad1=0; - Header.Transp_col=Back_color; - Header.Xaspect=1; - Header.Yaspect=1; - swab((byte *)&Largeur_ecran,(byte *)&Header.Xscreen,2); - swab((byte *)&Hauteur_ecran,(byte *)&Header.Yscreen,2); - - write(LBM_Fichier,&Header,sizeof(struct Header_LBM)); - - write(LBM_Fichier,"CMAP",4); - Ecrire_long(sizeof(T_Palette)); - - Palette_64_to_256(Principal_Palette); - write(LBM_Fichier,Principal_Palette,sizeof(T_Palette)); - Palette_256_to_64(Principal_Palette); - - write(LBM_Fichier,"BODY",4); - Ecrire_long(0); // On mettra la taille à jour à la fin - - Init_ecriture(); - - LBM_Taille_de_file=0; - - for (Pos_Y=0; ((Pos_Yst_size)-824); - - if (!Erreur_fichier) - { - lseek(LBM_Fichier,4,SEEK_SET); - - // Si la taille de la section de l'image (taille fichier-8) est - // impaire, on rajoute un 0 (Padding) à la fin. - if ((Informations_Fichier->st_size) & 1) - { - Ecrire_long((Informations_Fichier->st_size)-7); - lseek(LBM_Fichier,0,SEEK_END); - Octet=0; - if (write(LBM_Fichier,&Octet,1)==-1) - Erreur_fichier=1; - } - else - Ecrire_long((Informations_Fichier->st_size)-8); - - close(LBM_Fichier); - - if (Erreur_fichier) - remove(Nom_du_fichier); - } - else - { - Erreur_fichier=1; - close(LBM_Fichier); - remove(Nom_du_fichier); - } - } - else // Il y a eu une erreur lors du compactage => on efface le fichier - remove(Nom_du_fichier); - } - else - Erreur_fichier=1; -} - - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// BMP //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -// -- Tester si un fichier est au format BMP -------------------------------- -void Test_BMP(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct BMP_Header - { - word Signature; // ='BM' = 0x4D42 - long Taille_1; // =Taille du fichier - word Reserv_1; // =0 - word Reserv_2; // =0 - long Decalage; // Nb octets avant les données bitmap - - long Taille_2; // =40 - long Largeur; - long Hauteur; - word Plans; // =1 - word Nb_bits; // =1,4,8 ou 24 - long Compression; - long Taille_3; - long XPM; - long YPM; - long Nb_Clr; - long Clr_Imprt; - } Header; - - - Erreur_fichier=1; - Nom_fichier_complet(Nom_du_fichier,0); - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) - if ( (Header.Signature==0x4D42) && (Header.Taille_2==40) - && Header.Largeur && Header.Hauteur ) - Erreur_fichier=0; - close(Fichier); - } -} - - -// -- Charger un fichier au format BMP -------------------------------------- -void Load_BMP(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct BMP_Header - { - word Signature; // ='BM' = 0x4D42 - long Taille_1; // =Taille du fichier - word Reserv_1; // =0 - word Reserv_2; // =0 - long Decalage; // Nb octets avant les données bitmap - - long Taille_2; // =40 - long Largeur; - long Hauteur; - word Plans; // =1 - word Nb_bits; // =1,4,8 ou 24 - long Compression; - long Taille_3; - long XPM; - long YPM; - long Nb_Clr; - long Clr_Imprt; - } Header; - byte * Buffer; - word Indice; - byte Palette_locale[256][4]; // R,V,B,0 - word Nb_Couleurs; - short Pos_X; - short Pos_Y; - word Taille_ligne; - byte A,B,C=0; - long Taille_du_fichier; - struct stat* Informations_Fichier=NULL; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - - if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) - { - switch (Header.Nb_bits) - { - case 1 : - case 4 : - case 8 : - if (Header.Nb_Clr) - Nb_Couleurs=Header.Nb_Clr; - else - Nb_Couleurs=1<>3; - - Buffer=(byte *)malloc(Taille_ligne); - for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) - { - if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) - for (Pos_X=0; Pos_X>1] & 0xF); - else - Pixel_de_chargement(Pos_X,Pos_Y,Buffer[Pos_X>>1] >> 4 ); - break; - case 1 : - if ( Buffer[Pos_X>>3] & (0x80>>(Pos_X&7)) ) - Pixel_de_chargement(Pos_X,Pos_Y,1); - else - Pixel_de_chargement(Pos_X,Pos_Y,0); - } - else - Erreur_fichier=2; - } - free(Buffer); - break; - - case 1 : // Compression RLE 8 bits - Pos_X=0; - Pos_Y=Principal_Hauteur_image-1; - - Init_lecture(); - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - while ( (!Erreur_fichier) && ((A)||(B!=1)) ) - { - if (A) // Encoded mode - for (Indice=1; Indice<=A; Indice++) - Pixel_de_chargement(Pos_X++,Pos_Y,B); - else // Absolute mode - switch (B) - { - case 0 : // End of line - Pos_X=0; - Pos_Y--; - break; - case 1 : // End of bitmap - break; - case 2 : // Delta - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - Pos_X+=A; - Pos_Y-=B; - break; - default: // Nouvelle série - while (B) - { - A=Lire_octet(Fichier); - C=Lire_octet(Fichier); - Pixel_de_chargement(Pos_X++,Pos_Y,A); - if (--B) - { - Pixel_de_chargement(Pos_X++,Pos_Y,C); - B--; - } - } - } - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - } - Close_lecture(); - break; - - case 2 : // Compression RLE 4 bits - Pos_X=0; - Pos_Y=Principal_Hauteur_image-1; - - Init_lecture(); - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - while ( (!Erreur_fichier) && ((A)||(B!=1)) ) - { - if (A) // Encoded mode (A fois les 1/2 pixels de B) - for (Indice=1; Indice<=A; Indice++) - { - if (Indice & 1) - Pixel_de_chargement(Pos_X,Pos_Y,B>>4); - else - Pixel_de_chargement(Pos_X,Pos_Y,B&0xF); - Pos_X++; - } - else // Absolute mode - switch (B) - { - case 0 : //End of line - Pos_X=0; - Pos_Y--; - break; - case 1 : // End of bitmap - break; - case 2 : // Delta - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - Pos_X+=A; - Pos_Y-=B; - break; - default: // Nouvelle série (B 1/2 pixels bruts) - for (Indice=1; ((Indice<=B) && (!Erreur_fichier)); Indice++,Pos_X++) - { - if (Indice&1) - { - C=Lire_octet(Fichier); - Pixel_de_chargement(Pos_X,Pos_Y,C>>4); - } - else - Pixel_de_chargement(Pos_X,Pos_Y,C&0xF); - } - // On lit l'octet rendant le nombre d'octets pair, si - // nécessaire. Encore un truc de crétin "made in MS". - if ( ((B&3)==1) || ((B&3)==2) ) - Lire_octet(Fichier); - } - A=Lire_octet(Fichier); - B=Lire_octet(Fichier); - } - Close_lecture(); - } - close(Fichier); - } - else - { - close(Fichier); - Erreur_fichier=1; - } - } - } - else - { - // Image 24 bits!!! - Erreur_fichier=0; - - Principal_Largeur_image=Header.Largeur; - Principal_Hauteur_image=Header.Hauteur; - Initialiser_preview(Header.Largeur,Header.Hauteur,Taille_du_fichier,FORMAT_BMP | FORMAT_24B); - - if (Erreur_fichier==0) - { - Taille_ligne=Principal_Largeur_image*3; - Pos_X=(Taille_ligne % 4); // Pos_X sert de variable temporaire - if (Pos_X>0) - Taille_ligne+=(4-Pos_X); - - Buffer=(byte *)malloc(Taille_ligne); - for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) - { - if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) - for (Pos_X=0,Indice=0; Pos_X> 3)+1) << 3; - else - Taille_ligne=Principal_Largeur_image; - - Header.Signature =0x4D42; - Header.Taille_1 =(Taille_ligne*Principal_Hauteur_image)+1078; - Header.Reserv_1 =0; - Header.Reserv_2 =0; - Header.Decalage =1078; - Header.Taille_2 =40; - Header.Largeur =Taille_ligne; - Header.Hauteur =Principal_Hauteur_image; - Header.Plans =1; - Header.Nb_bits =8; - Header.Compression=0; - Header.Taille_3 =0; - Header.XPM =0; - Header.YPM =0; - Header.Nb_Clr =0; - Header.Clr_Imprt =0; - - if (write(Fichier,&Header,sizeof(struct BMP_Header))!=-1) - { - // Chez Bill, ils ont dit: "On va mettre les couleur dans l'ordre - // inverse, et pour faire chier, on va les mettre sur une échelle de - // 0 à 255 parce que le standard VGA c'est de 0 à 63 (logique!). Et - // puis comme c'est pas assez débile, on va aussi y rajouter un octet - // toujours à 0 pour forcer les gens à s'acheter des gros disques - // durs... Comme ‡a, ‡a fera passer la pillule lorsqu'on sortira - // Windows 95." ... - Palette_64_to_256(Principal_Palette); - for (Indice=0; Indice<256; Indice++) - { - Palette_locale[Indice][0]=Principal_Palette[Indice].B; - Palette_locale[Indice][1]=Principal_Palette[Indice].V; - Palette_locale[Indice][2]=Principal_Palette[Indice].R; - Palette_locale[Indice][3]=0; - } - Palette_256_to_64(Principal_Palette); - - if (write(Fichier,Palette_locale,1024)!=-1) - { - Init_ecriture(); - - // ... Et Bill, il a dit: "OK les gars! Mais seulement si vous rangez - // les pixels dans l'ordre inverse, mais que sur les Y quand-mˆme - // parce que faut pas pousser." - for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) - for (Pos_X=0; Pos_X>=Nb_bits_en_cours; - Nb_bits_traites +=Nb_bits_en_cours; - Nb_bits_a_traiter-=Nb_bits_en_cours; - GIF_Rest_bits -=Nb_bits_en_cours; - } - - return GIF_Code_actuel; - } - - // -- Affiche un nouveau pixel -- - - void GIF_Nouveau_pixel(byte Couleur) - { - Pixel_de_chargement(GIF_Pos_X,GIF_Pos_Y,Couleur); - - GIF_Pos_X++; - - if (GIF_Pos_X>=Principal_Largeur_image) - { - GIF_Pos_X=0; - - if (!GIF_Entrelacee) - GIF_Pos_Y++; - else - { - switch (GIF_Passe) - { - case 0 : GIF_Pos_Y+=8; - break; - case 1 : GIF_Pos_Y+=8; - break; - case 2 : GIF_Pos_Y+=4; - break; - default: GIF_Pos_Y+=2; - } - - if (GIF_Pos_Y>=Principal_Hauteur_image) - { - switch(++GIF_Passe) - { - case 1 : GIF_Pos_Y=4; - break; - case 2 : GIF_Pos_Y=2; - break; - case 3 : GIF_Pos_Y=1; - break; - case 4 : GIF_Image_entrelacee_terminee=1; - } - } - } - } - } - - -void Load_GIF(void) -{ - char Nom_du_fichier[256]; - char Signature[6]; - - word * Alphabet_Pile; // Pile de décodage d'une chaŒne - word * Alphabet_Prefixe; // Table des préfixes des codes - word * Alphabet_Suffixe; // Table des suffixes des codes - word Alphabet_Free; // Position libre dans l'alphabet - word Alphabet_Max; // Nombre d'entrées possibles dans l'alphabet - word Alphabet_Pos_pile; // Position dans la pile de décodage d'un chaŒne - - struct Type_LSDB - { - word Largeur; // Largeur de l'écran virtuel - word Hauteur; // Hauteur de l'écran virtuel - byte Resol; // Informations sur la résolution (et autres) - byte Backcol; // Couleur de fond - byte Aspect; // Informations sur l'aspect ratio (et autres) - } LSDB; // Logical Screen Descriptor Block - - struct Type_IDB - { - word Pos_X; // Abscisse o— devrait ˆtre affichée l'image - word Pos_Y; // Ordonnée o— devrait ˆtre affichée l'image - word Largeur_image; // Largeur de l'image - word Hauteur_image; // Hauteur de l'image - byte Indicateur; // Informations diverses sur l'image - byte Nb_bits_pixel; // Nb de bits par pixel - } IDB; // Image Descriptor Block - - word Nb_couleurs; // Nombre de couleurs dans l'image - word Indice_de_couleur; // Indice de traitement d'une couleur - word Taille_de_lecture; // Nombre de données à lire (divers) - //word Indice_de_lecture; // Indice de lecture des données (divers) - byte Block_indicateur; // Code indicateur du type de bloc en cours - word Nb_bits_initial; // Nb de bits au début du traitement LZW - word Cas_special=0; // Mémoire pour le cas spécial - word Code_ancien=0; // Code précédent - word Read_byte; // Sauvegarde du code en cours de lecture - word Valeur_Clr; // Valeur <=> Clear tables - word Valeur_Eof; // Valeur <=> Fin d'image - long Taille_du_fichier; - struct stat* Informations_Fichier=NULL; - - - /////////////////////////////////////////////////// FIN DES DECLARATIONS // - - - GIF_Pos_X=0; - GIF_Pos_Y=0; - GIF_Last_byte=0; - GIF_Rest_bits=0; - GIF_Rest_byte=0; - - Nom_fichier_complet(Nom_du_fichier,0); - - if ((GIF_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - - if ( (read(GIF_Fichier,Signature,6)==6) && - ( (memcmp(Signature,"GIF87a",6)==0) || - (memcmp(Signature,"GIF89a",6)==0) ) ) - { - // Allocation de mémoire pour les tables & piles de traitement: - Alphabet_Pile =(word *)malloc(4096*sizeof(word)); - Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); - Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); - - if (read(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) - { - // Lecture du Logical Screen Descriptor Block réussie: - - Ecran_original_X=LSDB.Largeur; - Ecran_original_Y=LSDB.Hauteur; - - // Palette globale dispo = (LSDB.Resol and $80) - // Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1 - // Nombre de bits/pixel = (LSDB.Resol and $07)+1 - // Ordre de Classement = (LSDB.Aspect and $80) - - Alphabet_Pos_pile=0; - GIF_Last_byte =0; - GIF_Rest_bits =0; - GIF_Rest_byte =0; - - Nb_couleurs=(1 << ((LSDB.Resol & 0x07)+1)); - Nb_bits_initial=(LSDB.Resol & 0x07)+2; - - if (LSDB.Resol & 0x80) - { - // Palette globale dispo: - - // On commence par passer la palette en 256 comme ‡a, si la - // nouvelle palette a moins de 256 coul, la précédente ne souffrira - // pas d'un assombrissement préjudiciable. - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - else - Palette_64_to_256(Principal_Palette); - - // On peut maintenant charger la nouvelle palette: - if (!(LSDB.Aspect & 0x80)) - // Palette dans l'ordre: - read(GIF_Fichier,Principal_Palette,Nb_couleurs*3); - else - { - // Palette triée par composantes: - for (Indice_de_couleur=0;Indice_de_couleurValeur_Clr) - { - Alphabet_Pile[Alphabet_Pos_pile++]=Alphabet_Suffixe[GIF_Code_actuel]; - GIF_Code_actuel=Alphabet_Prefixe[GIF_Code_actuel]; - } - - Cas_special=Alphabet_Pile[Alphabet_Pos_pile++]=GIF_Code_actuel; - - do - GIF_Nouveau_pixel(Alphabet_Pile[--Alphabet_Pos_pile]); - while (Alphabet_Pos_pile!=0); - - Alphabet_Prefixe[Alphabet_Free ]=Code_ancien; - Alphabet_Suffixe[Alphabet_Free++]=GIF_Code_actuel; - Code_ancien=Read_byte; - - if (Alphabet_Free>Alphabet_Max) - { - if (GIF_Nb_bits<12) - Alphabet_Max =((1 << (++GIF_Nb_bits))-1); - } - } - else // Code Clear rencontré - { - GIF_Nb_bits =Nb_bits_initial; - Alphabet_Max =((1 << GIF_Nb_bits)-1); - Alphabet_Free =Nb_couleurs+2; - Cas_special =GIF_Get_next_code(); - Code_ancien =GIF_Code_actuel; - GIF_Nouveau_pixel(GIF_Code_actuel); - } - } - else - Erreur_fichier=2; - } // Code End-Of-Information ou erreur de fichier rencontré - - Close_lecture(); - - if (Erreur_fichier>=0) - if ( /* (GIF_Pos_X!=0) || */ - ( ( (!GIF_Entrelacee) && (GIF_Pos_Y!=Principal_Hauteur_image) ) || - ( (GIF_Entrelacee) && (!GIF_Image_entrelacee_terminee) ) - ) ) - Erreur_fichier=2; - } // Le fichier contenait un IDB - else - Erreur_fichier=2; - - } // Le fichier contenait une image - else - Erreur_fichier=2; - - } // Le fichier contenait un LSDB - else - Erreur_fichier=1; - - // Libération de la mémoire utilisée par les tables & piles de traitement: - free(Alphabet_Suffixe); - free(Alphabet_Prefixe); - free(Alphabet_Pile); - } // Le fichier contenait au moins la signature GIF87a ou GIF89a - else - Erreur_fichier=1; - - close(GIF_Fichier); - - } // Le fichier était ouvrable - else - Erreur_fichier=1; -} - - -// -- Sauver un fichier au format GIF --------------------------------------- - - int GIF_Arret; // "On peut arrˆter la sauvegarde du fichier" - byte GIF_Buffer[256]; // Buffer d'écriture de bloc de données compilées - - // -- Vider le buffer GIF dans le buffer KM -- - - void GIF_Vider_le_buffer(void) - { - word Indice; - - if (GIF_Rest_byte) - { - GIF_Buffer[0]=GIF_Rest_byte; - - for (Indice=0;Indice<=GIF_Rest_byte;Indice++) - Ecrire_octet(GIF_Fichier,GIF_Buffer[Indice]); - - GIF_Rest_byte=0; - } - } - - // -- Ecrit un code à GIF_Nb_bits -- - - void GIF_Set_code(word Code) - { - word Nb_bits_a_traiter=GIF_Nb_bits; - word Nb_bits_traites =0; - word Nb_bits_en_cours; - - while (Nb_bits_a_traiter) - { - Nb_bits_en_cours=(Nb_bits_a_traiter<=(8-GIF_Rest_bits))?Nb_bits_a_traiter:(8-GIF_Rest_bits); - - GIF_Last_byte|=(Code & ((1<>=Nb_bits_en_cours; - GIF_Rest_bits +=Nb_bits_en_cours; - Nb_bits_traites +=Nb_bits_en_cours; - Nb_bits_a_traiter-=Nb_bits_en_cours; - - if (GIF_Rest_bits==8) // Il ne reste plus de bits à coder sur l'octet courant - { - // Ecrire l'octet à balancer: - GIF_Buffer[++GIF_Rest_byte]=GIF_Last_byte; - - // Si on a atteint la fin du bloc de Raster Data - if (GIF_Rest_byte==255) - // On doit vider le buffer qui est maintenant plein - GIF_Vider_le_buffer(); - - GIF_Last_byte=0; - GIF_Rest_bits=0; - } - } - } - - - // -- Lire le pixel suivant -- - - byte GIF_Pixel_suivant(void) - { - byte Temp; - - Temp=Lit_pixel_de_sauvegarde(GIF_Pos_X,GIF_Pos_Y); - - if (++GIF_Pos_X>=Principal_Largeur_image) - { - GIF_Pos_X=0; - if (++GIF_Pos_Y>=Principal_Hauteur_image) - GIF_Arret=1; - } - - return Temp; - } - - - -void Save_GIF(void) -{ - char Nom_du_fichier[256]; - - word * Alphabet_Prefixe; // Table des préfixes des codes - word * Alphabet_Suffixe; // Table des suffixes des codes - word * Alphabet_Fille; // Table des chaŒnes filles (plus longues) - word * Alphabet_Soeur; // 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 Depart; // Code précédent (sert au linkage des chaŒnes) - int Descente; // Booléen "On vient de descendre" - - struct Type_LSDB - { - word Largeur; // Largeur de l'écran virtuel |_ Dimensions de l'image si 1 - word Hauteur; // Hauteur de l'écran virtuel | seule image dans le fichier (ce qui est notre cas) - byte Resol; // Informations sur la résolution (et autres) - byte Backcol; // Couleur de fond - byte Aspect; // Informations sur l'aspect ratio (et autres) - } LSDB; // Logical Screen Descriptor Block - - struct Type_IDB - { - word Pos_X; // Abscisse o— devrait ˆtre affichée l'image - word Pos_Y; // Ordonnée o— devrait ˆtre affichée l'image - word Largeur_image; // Largeur de l'image - word Hauteur_image; // Hauteur de l'image - byte Indicateur; // Informations diverses sur l'image - byte Nb_bits_pixel; // Nb de bits par pixel - } IDB; // Image Descriptor Block - - byte Block_indicateur; // Code indicateur du type de bloc en cours - word Chaine_en_cours; // Code de la chaŒne en cours de traitement - byte Caractere; // CaractŠre à coder - word Indice; // Indice de recherche de chaŒne - - - /////////////////////////////////////////////////// FIN DES DECLARATIONS // - - - GIF_Pos_X=0; - GIF_Pos_Y=0; - GIF_Last_byte=0; - GIF_Rest_bits=0; - GIF_Rest_byte=0; - - Nom_fichier_complet(Nom_du_fichier,0); - - GIF_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); - if (GIF_Fichier!=-1) - { - // On écrit la signature du fichier - if (write(GIF_Fichier,"GIF87a",6)==6) - { - // La signature du fichier a été correctement écrite. - - // Allocation de mémoire pour les tables - Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); - Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); - Alphabet_Fille =(word *)malloc(4096*sizeof(word)); - Alphabet_Soeur =(word *)malloc(4096*sizeof(word)); - - // On initialise le LSDB du fichier - if (Config.Taille_ecran_dans_GIF) - { - LSDB.Largeur=Largeur_ecran; - LSDB.Hauteur=Hauteur_ecran; - } - else - { - LSDB.Largeur=Principal_Largeur_image; - LSDB.Hauteur=Principal_Hauteur_image; - } - LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette - LSDB.Backcol=0; - LSDB.Aspect =0; // Palette normale - - // On sauve le LSDB dans le fichier - - if (write(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) - { - // Le LSDB a été correctement écrit. - - // On sauve la palette - - Palette_64_to_256(Principal_Palette); - if (write(GIF_Fichier,Principal_Palette,768)==768) - { - // La palette a été correctement écrite. - - // Le jour o— on se servira des blocks d'extensions pour placer - // des commentaires, on le fera ici. - - // On va écrire un block indicateur d'IDB et l'IDB du fichier - - Block_indicateur=0x2C; - IDB.Pos_X=0; - IDB.Pos_Y=0; - IDB.Largeur_image=Principal_Largeur_image; - IDB.Hauteur_image=Principal_Hauteur_image; - IDB.Indicateur=0x07; // Image non entrelacée, pas de palette locale. - IDB.Nb_bits_pixel=8; // Image 256 couleurs; - - if ( (write(GIF_Fichier,&Block_indicateur,1)==1) && - (write(GIF_Fichier,&IDB,sizeof(struct Type_IDB))==sizeof(struct Type_IDB)) ) - { - // Le block indicateur d'IDB et l'IDB ont étés correctements - // écrits. - - Init_ecriture(); - - Indice=4096; - Erreur_fichier=0; - GIF_Arret=0; - - // Réintialisation de la table: - Alphabet_Free=258; - GIF_Nb_bits =9; - Alphabet_Max =511; - GIF_Set_code(256); - for (Depart=0;Depart<4096;Depart++) - { - Alphabet_Fille[Depart]=4096; - Alphabet_Soeur[Depart]=4096; - } - - ////////////////////////////////////////////// COMPRESSION LZW // - - Depart=Chaine_en_cours=GIF_Pixel_suivant(); - Descente=1; - - do - { - Caractere=GIF_Pixel_suivant(); - - // On regarde si dans la table on aurait pas une chaŒne - // équivalente à Chaine_en_cours+Caractere - - while ( (Indice0xFFF) - { - // Réintialisation de la table: - GIF_Set_code(256); - Alphabet_Free=258; - GIF_Nb_bits =9; - Alphabet_Max =511; - for (Depart=0;Depart<4096;Depart++) - { - Alphabet_Fille[Depart]=4096; - Alphabet_Soeur[Depart]=4096; - } - } - else if (Alphabet_Free>Alphabet_Max+1) - { - // On augmente le nb de bits - - GIF_Nb_bits++; - Alphabet_Max=(1< 16c , 1 => 256c - word Bytes_per_plane_line;// Doit toujours ˆtre pair - word Palette_info; // 1 => Couleur , 2 => Gris (ignoré à partir de la version 4) - word Screen_X; // |_ Dimensions de - word Screen_Y; // | l'écran d'origine - byte Filler[54]; // Ca... J'adore! - } Header; // Je hais ce header! - - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) - { - // 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 ( (Header.Manufacturer!=10) - || (Header.Compression>1) - || ( (Header.Depth!=1) && (Header.Depth!=2) && (Header.Depth!=4) && (Header.Depth!=8) ) - || ( (Header.Plane!=1) && (Header.Plane!=2) && (Header.Plane!=4) && (Header.Plane!=8) && (Header.Plane!=3) ) - || (Header.X_max>((Reduction_moins_1-(Pos_X%Reduction))*Depth)) & Masque; - Pixel_de_chargement(Pos_X,Pos_Y,Couleur); - } - } - -void Load_PCX(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct PCX_Header - { - byte Manufacturer; // |_ Il font chier ces cons! Ils auraient pu - byte Version; // | mettre une vraie signature! - byte Compression; // L'image est-elle compressée? - byte Depth; // Nombre de bits pour coder un pixel (inutile puisqu'on se sert de Plane) - word X_min; // |_ Coin haut-gauche | - word Y_min; // | de l'image |_ (Crétin!) - word X_max; // |_ Coin bas-droit | - word Y_max; // | de l'image | - word X_dpi; // |_ Densité de |_ (Presque inutile parce que - word Y_dpi; // | l'image | aucun moniteur n'est pareil!) - byte Palette_16c[48]; // Palette 16 coul (inutile pour 256c) (débile!) - byte Reserved; // Ca me plait ‡a aussi! - byte Plane; // 4 => 16c , 1 => 256c , ... - word Bytes_per_plane_line;// Doit toujours ˆtre pair - word Palette_info; // 1 => Couleur , 2 => Gris (ignoré à partir de la version 4) - word Screen_X; // |_ Dimensions de - word Screen_Y; // | l'écran d'origine - byte Filler[54]; // Ca... J'adore! - } Header; // Je hais ce header! - short Taille_ligne; - short Vraie_taille_ligne; // Largeur de l'image corrigée - short Largeur_lue; - short Pos_X; - short Pos_Y; - byte Octet1; - byte Octet2; - byte Indice; - dword Nb_couleurs; - long Taille_du_fichier; - byte Palette_CGA[9]={ 84,252,252, 252, 84,252, 252,252,252}; - - long Position; - long Taille_image; - byte * Buffer; - struct stat* Informations_Fichier =NULL; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - - if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) - { - Principal_Largeur_image=Header.X_max-Header.X_min+1; - Principal_Hauteur_image=Header.Y_max-Header.Y_min+1; - - Ecran_original_X=Header.Screen_X; - Ecran_original_Y=Header.Screen_Y; - - if (Header.Plane!=3) - { - Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_PCX); - if (Erreur_fichier==0) - { - // On prépare la palette à accueillir les valeurs du fichier PCX - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - else - Palette_64_to_256(Principal_Palette); - Nb_couleurs=(dword)(1<4) - memcpy(Principal_Palette,Header.Palette_16c,48); - else - { - Principal_Palette[1].R=0; - Principal_Palette[1].V=0; - Principal_Palette[1].B=0; - Octet1=Header.Palette_16c[3]>>5; - if (Nb_couleurs==4) - { // Pal. CGA "alakon" (du Turc Allahkoum qui signifie "à la con" :)) - memcpy(Principal_Palette+1,Palette_CGA,9); - if (!(Octet1&2)) - { - Principal_Palette[1].B=84; - Principal_Palette[2].B=84; - Principal_Palette[3].B=84; - } - } // Palette monochrome (on va dire que c'est du N&B) - else - { - Principal_Palette[1].R=252; - Principal_Palette[1].V=252; - Principal_Palette[1].B=252; - } - } - - // On se positionne à la fin du fichier - 769 octets pour voir s'il y - // a une palette. - if ( (Header.Depth==8) && (Header.Version>=5) && (Taille_du_fichier>sizeof(T_Palette)) ) - { - lseek(Fichier,Taille_du_fichier-(sizeof(T_Palette)+1),SEEK_SET); - // On regarde s'il y a une palette aprŠs les données de l'image - if (read(Fichier,&Octet1,1)==1) - if (Octet1==12) // Lire la palette si c'est une image en 256 couleurs - { - // On lit la palette 256c que ces crétins ont foutue à la fin du fichier - if (read(Fichier,Principal_Palette,sizeof(T_Palette))!=sizeof(T_Palette)) - Erreur_fichier=2; - } - } - Palette_256_to_64(Principal_Palette); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - // Maintenant qu'on a lu la palette que ces crétins sont allés foutre - // à la fin, on retourne juste aprŠs le header pour lire l'image. - lseek(Fichier,sizeof(struct PCX_Header),SEEK_SET); - - if (!Erreur_fichier) - { - Taille_ligne=Header.Bytes_per_plane_line*Header.Plane; - Vraie_taille_ligne=(short)Header.Bytes_per_plane_line<<3; - // On se sert de données LBM car le dessin de ligne en moins de 256 - // couleurs se fait comme avec la structure ILBM. - Image_HAM=0; - HBPm1=Header.Plane-1; - LBM_Buffer=(byte *)malloc(Taille_ligne); - - // Chargement de l'image - if (Header.Compression) // Image compressée - { - Init_lecture(); - - Taille_image=(long)Header.Bytes_per_plane_line*Principal_Hauteur_image; - - if (Header.Depth==8) // 256 couleurs (1 plan) - { - for (Position=0; ((Position=Taille_ligne) - { - for (Pos_X=0; Pos_X=Taille_ligne) - { - for (Pos_X=0; Pos_X1) || (Last_pixel>=0xC0) ) - Ecrire_octet(Fichier,Compteur|0xC0); - Ecrire_octet(Fichier,Last_pixel); - - } - } - - // Ecriture de l'octet (12) indiquant que la palette arrive - if (!Erreur_fichier) - Ecrire_octet(Fichier,12); - - Close_ecriture(Fichier); - - // Ecriture de la palette - if (!Erreur_fichier) - { - if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) - Erreur_fichier=1; - } - } - else - Erreur_fichier=1; - - close(Fichier); - - if (Erreur_fichier) - remove(Nom_du_fichier); - - // On remet la palette à son état normal - Palette_256_to_64(Principal_Palette); - } - else - Erreur_fichier=1; -} - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// CEL //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -// -- Tester si un fichier est au format CEL -------------------------------- - -void Test_CEL(void) -{ - char Nom_du_fichier[256]; - int Taille; - int Fichier; - struct CEL_Header1 - { - word Width; // Largeur de l'image - word Height; // Hauteur de l'image - } Header1; - struct CEL_Header2 - { - byte Signa[4]; // Signature du format - byte Kind; // Type de fichier ($10=PALette $20=BitMaP) - byte Nbbits; // Nombre de bits - word Filler1; // ??? - word Largeur; // Largeur de l'image - word Hauteur; // Hauteur de l'image - word Decalage_X; // Decalage en X de l'image - word Decalage_Y; // Decalage en Y de l'image - byte Filler2[16]; // ??? - } Header2; - struct stat* Informations_Fichier =NULL; - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) - { - // Vu que ce header n'a pas de signature, il va falloir tester la - // cohérence de la dimension de l'image avec celle du fichier. - stat(Nom_du_fichier,Informations_Fichier); - Taille=(Informations_Fichier->st_size)-sizeof(struct CEL_Header1); - if ( (!Taille) || ( (((Header1.Width+1)>>1)*Header1.Height)!=Taille ) ) - { - // Tentative de reconnaissance de la signature des nouveaux fichiers - - lseek(Fichier,0,SEEK_SET); - if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) - { - if (memcmp(Header2.Signa,"KiSS",4)==0) - { - if (Header2.Kind!=0x20) - Erreur_fichier=1; - } - else - Erreur_fichier=1; - } - else - Erreur_fichier=1; - } - } - else - Erreur_fichier=1; - - close(Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Lire un fichier au format CEL ----------------------------------------- - -void Load_CEL(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct CEL_Header1 - { - word Width; // Largeur de l'image - word Height; // Hauteur de l'image - } Header1; - struct CEL_Header2 - { - byte Signa[4]; // Signature du format - byte Kind; // Type de fichier ($10=PALette $20=BitMaP) - byte Nbbits; // Nombre de bits - word Filler1; // ??? - word Largeur; // Largeur de l'image - word Hauteur; // Hauteur de l'image - word Decalage_X; // Decalage en X de l'image - word Decalage_Y; // Decalage en Y de l'image - byte Filler2[16]; // ??? - } Header2; - short Pos_X; - short Pos_Y; - byte Dernier_octet=0; - long Taille_du_fichier; - struct stat* Informations_Fichier=NULL; - - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) { - stat(Nom_du_fichier,Informations_Fichier); - Taille_du_fichier=Informations_Fichier->st_size; - if ( (Taille_du_fichier>sizeof(struct CEL_Header1)) - && ( (((Header1.Width+1)>>1)*Header1.Height)==(Taille_du_fichier-sizeof(struct CEL_Header1)) ) ) - { - // Chargement d'un fichier CEL sans signature (vieux fichiers) - Principal_Largeur_image=Header1.Width; - Principal_Hauteur_image=Header1.Height; - Ecran_original_X=Principal_Largeur_image; - Ecran_original_Y=Principal_Hauteur_image; - Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); - if (Erreur_fichier==0) - { - // Chargement de l'image - Init_lecture(); - for (Pos_Y=0;((Pos_Y> 4)); - } - else - Pixel_de_chargement(Pos_X,Pos_Y,(Dernier_octet & 15)); - Close_lecture(); - } - } - else - { - // On réessaye avec le nouveau format - - lseek(Fichier,0,SEEK_SET); - if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) - { - // Chargement d'un fichier CEL avec signature (nouveaux fichiers) - - Principal_Largeur_image=Header2.Largeur+Header2.Decalage_X; - Principal_Hauteur_image=Header2.Hauteur+Header2.Decalage_Y; - Ecran_original_X=Principal_Largeur_image; - Ecran_original_Y=Principal_Hauteur_image; - Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); - if (Erreur_fichier==0) - { - // Chargement de l'image - Init_lecture(); - - if (!Erreur_fichier) - { - // Effacement du décalage - for (Pos_Y=0;Pos_Y> 4)); - } - else - Pixel_de_chargement(Pos_X+Header2.Decalage_X,Pos_Y+Header2.Decalage_Y,(Dernier_octet & 15)); - break; - - case 8: - for (Pos_Y=0;((Pos_Y16 sont utilisées dans l'image - for (Pos_X=16;((Pos_X<256) && (!Utilisation[Pos_X]));Pos_X++); - - if (Pos_X==256) - { - // Cas d'une image 16 couleurs (écriture à l'ancien format) - - Header1.Width =Principal_Largeur_image; - Header1.Height=Principal_Hauteur_image; - - if (write(Fichier,&Header1,sizeof(struct CEL_Header1))!=-1) - { - // Sauvegarde de l'image - Init_ecriture(); - for (Pos_Y=0;((Pos_Y>4)!=0) - Erreur_fichier=1; - } - else - { - if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) - { - if (memcmp(Header2.Signa,"KiSS",4)==0) - { - if (Header2.Kind!=0x10) - Erreur_fichier=1; - } - else - Erreur_fichier=1; - } - else - Erreur_fichier=1; - } - close(Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Lire un fichier au format KCF ----------------------------------------- - -void Load_KCF(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct KCF_Header - { - struct - { - struct - { - byte Octet1; - byte Octet2; - } Couleur[16]; - } Palette[10]; - } Buffer; - struct CEL_Header2 - { - byte Signa[4]; // Signature du format - byte Kind; // Type de fichier ($10=PALette $20=BitMaP) - byte Nbbits; // Nombre de bits - word Filler1; // ??? - word Largeur; // Largeur de l'image ou nb de couleurs définies - word Hauteur; // Hauteur de l'image ou nb de palettes définies - word Decalage_X; // Decalage en X de l'image - word Decalage_Y; // Decalage en Y de l'image - byte Filler2[16]; // ??? - } Header2; - byte Octet[3]; - int Indice_palette; - int Indice_couleur; - int Indice; - long Taille_du_fichier; - - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - Taille_du_fichier=filelength(Fichier); - if (Taille_du_fichier==sizeof(struct KCF_Header)) - { - // Fichier KCF à l'ancien format - - if (read(Fichier,&Buffer,sizeof(struct KCF_Header))==sizeof(struct KCF_Header)) - { - // Initialiser_preview(???); // Pas possible... pas d'image... - - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - - // Chargement de la palette - for (Indice_palette=0;Indice_palette<10;Indice_palette++) - for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) - { - Indice=16+(Indice_palette*16)+Indice_couleur; - Principal_Palette[Indice].R=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 >> 4) << 2); - Principal_Palette[Indice].B=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 & 15) << 2); - Principal_Palette[Indice].V=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2 & 15) << 2); - } - - for (Indice=0;Indice<16;Indice++) - { - Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; - Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; - Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; - } - - Set_palette(Principal_Palette); - Remapper_fileselect(); - } - else - Erreur_fichier=1; - } - else - { - // Fichier KCF au nouveau format - - if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) - { - // Initialiser_preview(???); // Pas possible... pas d'image... - - Indice=(Header2.Nbbits==12)?16:0; - for (Indice_palette=0;Indice_palette> 4) << 2; - Principal_Palette[Indice].B=(Octet[0] & 15) << 2; - Principal_Palette[Indice].V=(Octet[1] & 15) << 2; - break; - - case 24: // RRRR RRRR | VVVV VVVV | BBBB BBBB - read(Fichier,Octet,3); - Principal_Palette[Indice].R=Octet[0]>>2; - Principal_Palette[Indice].V=Octet[1]>>2; - Principal_Palette[Indice].B=Octet[2]>>2; - } - - Indice++; - } - } - - if (Header2.Nbbits==12) - for (Indice=0;Indice<16;Indice++) - { - Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; - Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; - Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; - } - - Set_palette(Principal_Palette); - Remapper_fileselect(); - } - else - Erreur_fichier=1; - } - close(Fichier); - } - else - Erreur_fichier=1; - - if (!Erreur_fichier) Dessiner_preview_palette(); -} - - -// -- Ecrire un fichier au format KCF --------------------------------------- - -void Save_KCF(void) -{ - char Nom_du_fichier[256]; - int Fichier; - struct KCF_Header - { - struct - { - struct - { - byte Octet1; - byte Octet2; - } Couleur[16]; - } Palette[10]; - } Buffer; - struct CEL_Header2 - { - byte Signa[4]; // Signature du format - byte Kind; // Type de fichier ($10=PALette $20=BitMaP) - byte Nbbits; // Nombre de bits - word Filler1; // ??? - word Largeur; // Largeur de l'image ou nb de couleurs définies - word Hauteur; // Hauteur de l'image ou nb de palettes définies - word Decalage_X; // Decalage en X de l'image - word Decalage_Y; // Decalage en Y de l'image - byte Filler2[16]; // ??? - } Header2; - byte Octet[3]; - int Indice_palette; - int Indice_couleur; - int Indice; - dword Utilisation[256]; // Table d'utilisation de couleurs - - // On commence par compter l'utilisation de chaque couleurs - Palette_Compter_nb_couleurs_utilisees(Utilisation); - - Erreur_fichier=0; - Nom_fichier_complet(Nom_du_fichier,0); - if ((Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP))!=-1) - { - // Sauvegarde de la palette - - // On regarde si des couleurs >16 sont utilisées dans l'image - for (Indice=16;((Indice<256) && (!Utilisation[Indice]));Indice++); - - if (Indice==256) - { - // Cas d'une image 16 couleurs (écriture à l'ancien format) - - for (Indice_palette=0;Indice_palette<10;Indice_palette++) - for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) - { - Indice=16+(Indice_palette*16)+Indice_couleur; - Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1=((Principal_Palette[Indice].R>>2)<<4) | (Principal_Palette[Indice].B>>2); - Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2=Principal_Palette[Indice].V>>2; - } - - if (write(Fichier,&Buffer,sizeof(struct KCF_Header))!=sizeof(struct KCF_Header)) - Erreur_fichier=1; - } - else - { - // Cas d'une image 256 couleurs (écriture au nouveau format) - - memcpy(Header2.Signa,"KiSS",4); // Initialisation de la signature - Header2.Kind=0x10; // Initialisation du type (PALette) - Header2.Nbbits=24; // Initialisation du nombre de bits - Header2.Filler1=0; // Initialisation du filler 1 (???) - Header2.Largeur=256; // Initialisation du nombre de couleurs - Header2.Hauteur=1; // Initialisation du nombre de palettes - Header2.Decalage_X=0; // Initialisation du décalage X - Header2.Decalage_Y=0; // Initialisation du décalage Y - for (Indice=0;Indice<16;Indice++) // Initialisation du filler 2 (???) - Header2.Filler2[Indice]=0; - - if (write(Fichier,&Header2,sizeof(struct CEL_Header2))!=sizeof(struct CEL_Header2)) - Erreur_fichier=1; - - for (Indice=0;(Indice<256) && (!Erreur_fichier);Indice++) - { - Octet[0]=Principal_Palette[Indice].R<<2; - Octet[1]=Principal_Palette[Indice].V<<2; - Octet[2]=Principal_Palette[Indice].B<<2; - if (write(Fichier,Octet,3)!=3) - Erreur_fichier=1; - } - } - - close(Fichier); - - if (Erreur_fichier) - remove(Nom_du_fichier); - } - else - Erreur_fichier=1; -} - - - - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// SCx //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -// -- Tester si un fichier est au format SCx -------------------------------- -void Test_SCx(void) -{ - int Handle; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - //byte Signature[3]; - struct Header - { - byte Filler1[4]; - word Largeur; - word Hauteur; - byte Filler2; - byte Plans; - } SCx_Header; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=1; - - // Ouverture du fichier - Handle=open(Nom_du_fichier,O_RDONLY); - if (Handle!=-1) - { - // Lecture et vérification de la signature - if ((read(Handle,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) - { - if ( (!memcmp(SCx_Header.Filler1,"RIX",3)) - && SCx_Header.Largeur && SCx_Header.Hauteur) - Erreur_fichier=0; - } - // Fermeture du fichier - close(Handle); - } -} - - -// -- Lire un fichier au format SCx ----------------------------------------- -void Load_SCx(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - int Fichier; - word Pos_X,Pos_Y; - long Taille,Vraie_taille; - long Taille_du_fichier; - struct Header - { - byte Filler1[4]; - word Largeur; - word Hauteur; - byte Filler2; - byte Plans; - } SCx_Header; - T_Palette SCx_Palette; - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - Taille_du_fichier=filelength(Fichier); - - if ((read(Fichier,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) - { - Initialiser_preview(SCx_Header.Largeur,SCx_Header.Hauteur,Taille_du_fichier,FORMAT_SCx); - if (Erreur_fichier==0) - { - if (!SCx_Header.Plans) - Taille=sizeof(T_Palette); - else - Taille=sizeof(struct Composantes)*(1<>3)*SCx_Header.Plans; - Vraie_taille=(Taille/SCx_Header.Plans)<<3; - LBM_Buffer=(byte *)malloc(Taille); - HBPm1=SCx_Header.Plans-1; - Image_HAM=0; - - for (Pos_Y=0;(Pos_Y>=1; - } -} - -//// CODAGE d'une partie d'IMAGE //// - -void PI1_16p_to_8b(byte * Src,byte * Dst) -{ - int i; // Indice du pixel à calculer - word masque; // Masque de codage - word w0,w1,w2,w3; // Les 4 words bien ordonnés de la destination - - masque=0x8000; - w0=w1=w2=w3=0; - for (i=0;i<16;i++) - { - // Pour coder le pixel nøi, il faut modifier les 4 words sur leur bit - // correspondant à celui du masque - - w0|=(Src[i] & 0x01)?masque:0x00; - w1|=(Src[i] & 0x02)?masque:0x00; - w2|=(Src[i] & 0x04)?masque:0x00; - w3|=(Src[i] & 0x08)?masque:0x00; - masque>>=1; - } - Dst[0]=w0 >> 8; - Dst[1]=w0 & 0x00FF; - Dst[2]=w1 >> 8; - Dst[3]=w1 & 0x00FF; - Dst[4]=w2 >> 8; - Dst[5]=w2 & 0x00FF; - Dst[6]=w3 >> 8; - Dst[7]=w3 & 0x00FF; -} - -//// DECODAGE de la PALETTE //// - -void PI1_Decoder_palette(byte * Src,byte * Pal) -{ - int i; // Numéro de la couleur traitée - int ip; // Indice dans la palette - word w; // Word contenant le code - - // Schéma d'un word = - // - // Low High - // VVVV RRRR | 0000 BBBB - // 0321 0321 | 0321 - - ip=0; - for (i=0;i<16;i++) - { - w=((word)Src[(i*2)+1]<<8) | Src[(i*2)+0]; - - // Traitement des couleurs rouge, verte et bleue: - Pal[ip++]=(((w & 0x0007) << 1) | ((w & 0x0008) >> 3)) << 2; - Pal[ip++]=(((w & 0x7000) >> 11) | ((w & 0x8000) >> 15)) << 2; - Pal[ip++]=(((w & 0x0700) >> 7) | ((w & 0x0800) >> 11)) << 2; - } -} - -//// CODAGE de la PALETTE //// - -void PI1_Coder_palette(byte * Pal,byte * Dst) -{ - int i; // Numéro de la couleur traitée - int ip; // Indice dans la palette - word w; // Word contenant le code - - // Schéma d'un word = - // - // Low High - // VVVV RRRR | 0000 BBBB - // 0321 0321 | 0321 - - ip=0; - for (i=0;i<16;i++) - { - // Traitement des couleurs rouge, verte et bleue: - w =(((word)Pal[ip] & 0x38) >> 3) | (((word)Pal[ip] & 0x04) << 1); ip++; - w|=(((word)Pal[ip] & 0x38) << 9) | (((word)Pal[ip] & 0x04) << 13); ip++; - w|=(((word)Pal[ip] & 0x38) << 5) | (((word)Pal[ip] & 0x04) << 9); ip++; - - Dst[(i*2)+0]=w & 0x00FF; - Dst[(i*2)+1]=(w>>8); - } -} - - -// -- Tester si un fichier est au format PI1 -------------------------------- -void Test_PI1(void) -{ - int Handle; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - int Taille; // Taille du fichier - word Res; // Résolution de l'image - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=1; - - // Ouverture du fichier - Handle=open(Nom_du_fichier,O_RDONLY); - if (Handle!=-1) - { - // Vérification de la taille - Taille=filelength(Handle); - if ((Taille==32034) || (Taille==32066)) - { - // Lecture et vérification de la résolution - if ((read(Handle,&Res,2))==2) - { - if (Res==0x0000) - Erreur_fichier=0; - } - } - // Fermeture du fichier - close(Handle); - } -} - - -// -- Lire un fichier au format PI1 ----------------------------------------- -void Load_PI1(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - int Fichier; - word Pos_X,Pos_Y; - byte * buffer; - byte * ptr; - byte pixels[320]; - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - // allocation d'un buffer mémoire - buffer=(byte *)malloc(32034); - if (buffer!=NULL) - { - // Lecture du fichier dans le buffer - if (read(Fichier,buffer,32034)==32034) - { - // Initialisation de la preview - Initialiser_preview(320,200,filelength(Fichier),FORMAT_PI1); - if (Erreur_fichier==0) - { - // Initialisation de la palette - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - PI1_Decoder_palette(buffer+2,(byte *)Principal_Palette); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - Principal_Largeur_image=320; - Principal_Hauteur_image=200; - - // Chargement/décompression de l'image - ptr=buffer+34; - for (Pos_Y=0;Pos_Y<200;Pos_Y++) - { - for (Pos_X=0;Pos_X<(320>>4);Pos_X++) - { - PI1_8b_to_16p(ptr,pixels+(Pos_X<<4)); - ptr+=8; - } - for (Pos_X=0;Pos_X<320;Pos_X++) - Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); - } - } - } - else - Erreur_fichier=1; - free(buffer); - } - else - Erreur_fichier=1; - close(Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Sauver un fichier au format PI1 --------------------------------------- -void Save_PI1(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - int Fichier; - short Pos_X,Pos_Y; - byte * buffer; - byte * ptr; - byte pixels[320]; - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - // Ouverture du fichier - Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); - if (Fichier!=-1) - { - // allocation d'un buffer mémoire - buffer=(byte *)malloc(32034); - // Codage de la résolution - buffer[0]=0x00; - buffer[1]=0x00; - // Codage de la palette - PI1_Coder_palette((byte *)Principal_Palette,buffer+2); - // Codage de l'image - ptr=buffer+34; - for (Pos_Y=0;Pos_Y<200;Pos_Y++) - { - // Codage de la ligne - memset(pixels,0,320); - if (Pos_Y>4);Pos_X++) - { - PI1_16p_to_8b(pixels+(Pos_X<<4),ptr); - ptr+=8; - } - } - - if (write(Fichier,buffer,32034)==32034) - { - close(Fichier); - } - else // Erreur d'écriture (disque plein ou protégé) - { - close(Fichier); - remove(Nom_du_fichier); - Erreur_fichier=1; - } - // Libération du buffer mémoire - free(buffer); - } - else - { - close(Fichier); - remove(Nom_du_fichier); - Erreur_fichier=1; - } -} - - - - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -//////////////////////////////////// PC1 //////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -//// DECOMPRESSION d'un buffer selon la méthode PACKBITS //// - -void PC1_Decompresser_PackBits(byte * Src,byte * Dst) -{ - int is,id; // Les indices de parcour des buffers - int n; // Octet de contr“le - - for (is=id=0;id<32000;) - { - n=Src[is++]; - - if (n & 0x80) - { - // Recopier Src[is] -n+1 fois - n=257-n; - for (;(n>0) && (id<32000);n--) - Dst[id++]=Src[is]; - is++; - } - else - { - // Recopier n+1 octets littéralement - n=n+1; - for (;(n>0) && (id<32000);n--) - Dst[id++]=Src[is++]; - } - - // Contr“le des erreurs - if (n>0) - Erreur_fichier=1; - } -} - -//// COMPRESSION d'un buffer selon la méthode PACKBITS //// - -void PC1_Compresser_PackBits(byte * Src,byte * Dst,int TailleS,int * TailleD) -{ - int is; // Indice dans la source - int id; // Indice dans la destination - int ir; // Indice de la répétition - int n; // Taille des séquences - int repet; // "Il y a répétition" - - for (is=id=0;is0;n--) - Dst[id++]=Src[is++]; - } - - // On code la partie sans répétitions - if (repet) - { - // On compte la quantité de fois qu'il faut répéter la valeur - for (ir+=3;ir>=1; - } - } -} - -//// CODAGE d'une partie d'IMAGE //// - -// Transformation d'1 ligne de pixels en 4 plans de bits - -void PC1_1lp_to_4pb(byte * Src,byte * Dst0,byte * Dst1,byte * Dst2,byte * Dst3) -{ - int i,j; // Compteurs - int ip; // Indice du pixel à calculer - byte masque; // Masque de decodage - byte b0,b1,b2,b3; // Les 4 octets des plans bits sources - - ip=0; - // Pour chacun des 40 octets des plans de bits - for (i=0;i<40;i++) - { - // Pour chacun des 8 bits des octets - masque=0x80; - b0=b1=b2=b3=0; - for (j=0;j<8;j++) - { - b0|=(Src[ip] & 0x01)?masque:0x00; - b1|=(Src[ip] & 0x02)?masque:0x00; - b2|=(Src[ip] & 0x04)?masque:0x00; - b3|=(Src[ip] & 0x08)?masque:0x00; - ip++; - masque>>=1; - } - Dst0[i]=b0; - Dst1[i]=b1; - Dst2[i]=b2; - Dst3[i]=b3; - } -} - - -// -- Tester si un fichier est au format PC1 -------------------------------- -void Test_PC1(void) -{ - int Handle; // Handle du fichier - char Nom_du_fichier[256]; // Nom complet du fichier - int Taille; // Taille du fichier - word Res; // Résolution de l'image - - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=1; - - // Ouverture du fichier - Handle=open(Nom_du_fichier,O_RDONLY); - if (Handle!=-1) - { - // Vérification de la taille - Taille=filelength(Handle); - if ((Taille<=32066)) - { - // Lecture et vérification de la résolution - if ((read(Handle,&Res,2))==2) - { - if (Res==0x0080) - Erreur_fichier=0; - } - } - // Fermeture du fichier - close(Handle); - } -} - - -// -- Lire un fichier au format PC1 ----------------------------------------- -void Load_PC1(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - int Fichier; - int Taille; - word Pos_X,Pos_Y; - byte * buffercomp; - byte * bufferdecomp; - byte * ptr; - byte pixels[320]; - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) - { - Taille=filelength(Fichier); - // allocation des buffers mémoire - buffercomp=(byte *)malloc(Taille); - bufferdecomp=(byte *)malloc(32000); - if ( (buffercomp!=NULL) && (bufferdecomp!=NULL) ) - { - // Lecture du fichier dans le buffer - if (read(Fichier,buffercomp,Taille)==Taille) - { - // Initialisation de la preview - Initialiser_preview(320,200,filelength(Fichier),FORMAT_PC1); - if (Erreur_fichier==0) - { - // Initialisation de la palette - if (Config.Clear_palette) - memset(Principal_Palette,0,sizeof(T_Palette)); - PI1_Decoder_palette(buffercomp+2,(byte *)Principal_Palette); - Set_palette(Principal_Palette); - Remapper_fileselect(); - - Principal_Largeur_image=320; - Principal_Hauteur_image=200; - - // Décompression du buffer - PC1_Decompresser_PackBits(buffercomp+34,bufferdecomp); - - // Décodage de l'image - ptr=bufferdecomp; - for (Pos_Y=0;Pos_Y<200;Pos_Y++) - { - // Décodage de la scanline - PC1_4pb_to_1lp(ptr,ptr+40,ptr+80,ptr+120,pixels); - ptr+=160; - // Chargement de la ligne - for (Pos_X=0;Pos_X<320;Pos_X++) - Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); - } - } - } - else - Erreur_fichier=1; - free(bufferdecomp); - free(buffercomp); - } - else - { - Erreur_fichier=1; - if (bufferdecomp) free(bufferdecomp); - if (buffercomp) free(buffercomp); - } - close(Fichier); - } - else - Erreur_fichier=1; -} - - -// -- Sauver un fichier au format PC1 --------------------------------------- -void Save_PC1(void) -{ - char Nom_du_fichier[256]; // Nom complet du fichier - int Fichier; - int Taille; - short Pos_X,Pos_Y; - byte * buffercomp; - byte * bufferdecomp; - byte * ptr; - byte pixels[320]; - - Nom_fichier_complet(Nom_du_fichier,0); - - Erreur_fichier=0; - // Ouverture du fichier - Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); - if (Fichier!=-1) - { - // Allocation des buffers mémoire - bufferdecomp=(byte *)malloc(32000); - buffercomp =(byte *)malloc(64066); - // Codage de la résolution - buffercomp[0]=0x80; - buffercomp[1]=0x00; - // Codage de la palette - PI1_Coder_palette((byte *)Principal_Palette,buffercomp+2); - // Codage de l'image - ptr=bufferdecomp; - for (Pos_Y=0;Pos_Y<200;Pos_Y++) - { - // Codage de la ligne - memset(pixels,0,320); - if (Pos_Y0) + Erreur(0); + + if (Image_24b) + { + // On vient de charger une image 24b + if (!Erreur_fichier) + { + // Le chargement a réussi, on peut faire la conversion en 256 couleurs + if (Pixel_de_chargement==Pixel_Chargement_dans_ecran_courant) + { + // Cas d'un chargement dans l'image + if (Convert_bitmap_24B_to_256(Principal_Ecran,Buffer_image_24b,Principal_Largeur_image,Principal_Hauteur_image,Principal_Palette)) + Erreur_fichier=2; + } + else + { + // Cas d'un chargement dans la brosse + if (Convert_bitmap_24B_to_256(Brosse,Buffer_image_24b,Brosse_Largeur,Brosse_Hauteur,Principal_Palette)) + Erreur_fichier=2; + } + if (!Erreur_fichier) + Palette_256_to_64(Principal_Palette); + } + + free(Buffer_image_24b); + } + + if (Image) + { + if ( (Erreur_fichier!=1) && (Format_Backup_done[Format]) ) + { + // On considŠre que l'image chargée n'est plus modifiée + Principal_Image_modifiee=0; + // Et on documente la variable Principal_Format_fichier avec la valeur: + Principal_Format_fichier=Format+1; + + // Correction des dimensions + if (Principal_Largeur_image<1) + Principal_Largeur_image=1; + if (Principal_Hauteur_image<1) + Principal_Hauteur_image=1; + } + else if (Erreur_fichier!=1) + { + // On considŠre que l'image chargée est encore modifiée + Principal_Image_modifiee=1; + // Et on documente la variable Principal_Format_fichier avec la valeur: + Principal_Format_fichier=Format+1; + } + else + { + // Dans ce cas, on sait que l'image n'a pas changé, mais ses + // paramŠtres (dimension, palette, ...) si. Donc on les restaures. + Download_infos_page_principal(Principal_Backups->Pages); + } + } + } + else + // Sinon, l'appelant sera au courant de l'échec grƒce à Erreur_fichier; + // et si on s'apprˆtait à faire un chargement définitif de l'image (pas + // une preview), alors on flash l'utilisateur. + if (Pixel_de_chargement!=Pixel_Chargement_dans_preview) + Erreur(0); +} + + +// -- Sauver n'importe quel type connu de fichier d'image (ou palette) ------ +void Sauver_image(byte Image) +{ + // On place par défaut Erreur_fichier à vrai au cas o— on ne sache pas + // sauver le format du fichier: (Est-ce vraiment utile??? Je ne crois pas!) + Erreur_fichier=1; + + Lit_pixel_de_sauvegarde=(Image)?Lit_pixel_dans_ecran_courant:Lit_pixel_dans_brosse; + + Format_Save[Principal_Format_fichier-1](); + + if (Erreur_fichier) + Erreur(0); + else + { + if ((Image) && (Format_Backup_done[Principal_Format_fichier-1])) + Principal_Image_modifiee=0; + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// PAL //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +// -- Tester si un fichier est au format PAL -------------------------------- +void Test_PAL(void) +{ + int Fichier; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + long Taille_du_fichier; // Taille du fichier + struct stat* Informations_Fichier=NULL; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_RDONLY); + if (Fichier!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + // Lecture de la taille du fichier + Taille_du_fichier=Informations_Fichier->st_size; + close(Fichier); + // Le fichier ne peut ˆtre au format PAL que si sa taille vaut 768 octets + if (Taille_du_fichier==sizeof(T_Palette)) + Erreur_fichier=0; + } +} + + +// -- Lire un fichier au format PAL ----------------------------------------- +void Load_PAL(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + //long Taille_du_fichier; // Taille du fichier + + + Nom_fichier_complet(Nom_du_fichier,0); + Erreur_fichier=0; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + // Lecture du fichier dans Principal_Palette + if (read(Handle,Principal_Palette,sizeof(T_Palette))==sizeof(T_Palette)) + { + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // On dessine une preview de la palette (si chargement=preview) + Dessiner_preview_palette(); + } + else + Erreur_fichier=2; + + // Fermeture du fichier + close(Handle); + } + else + // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PAL --------------------------------------- +void Save_PAL(void) +{ + int Fichier; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + //long Taille_du_fichier; // Taille du fichier + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // Enregistrement de Principal_Palette dans le fichier + if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) + { + Erreur_fichier=1; + close(Fichier); + remove(Nom_du_fichier); + } + else // Ecriture correcte => Fermeture normale du fichier + close(Fichier); + } + else // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur + { + Erreur_fichier=1; + close(Fichier); + remove(Nom_du_fichier); + // On se fout du résultat de l'opération car si ‡a + // renvoie 0 c'est que le fichier avait été partiel- + // -lement écrit, sinon pas du tout. Or dans tous les + // cas ‡a revient au mˆme pour nous: Sauvegarde ratée! + } +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// IMG //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format IMG -------------------------------- +void Test_IMG(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + struct Header + { + byte Filler1[6]; + word Largeur; + word Hauteur; + byte Filler2[118]; + T_Palette Palette; + } IMG_Header; + byte Signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Lecture et vérification de la signature + if ((read(Handle,&IMG_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + if ( (!memcmp(IMG_Header.Filler1,Signature,6)) + && IMG_Header.Largeur && IMG_Header.Hauteur) + Erreur_fichier=0; + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format IMG ----------------------------------------- +void Load_IMG(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + byte * Buffer; + int Fichier; + word Pos_X,Pos_Y; + long Largeur_lue; + long Taille_du_fichier; + struct Header + { + byte Filler1[6]; + word Largeur; + word Hauteur; + byte Filler2[118]; + T_Palette Palette; + } IMG_Header; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&IMG_Header,sizeof(struct Header))==sizeof(struct Header)) + { + Buffer=(byte *)malloc(IMG_Header.Largeur); + + Initialiser_preview(IMG_Header.Largeur,IMG_Header.Hauteur,Taille_du_fichier,FORMAT_IMG); + if (Erreur_fichier==0) + { + // On commence par passer la palette en 256 comme ‡a, si la nouvelle + // palette a moins de 256 coul, la précédente ne souffrira pas d'un + // assombrissement préjudiciable. + Palette_64_to_256(Principal_Palette); + // On peut maintenant transférer la nouvelle palette + memcpy(Principal_Palette,IMG_Header.Palette,sizeof(T_Palette)); + Palette_256_to_64(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=IMG_Header.Largeur; + Principal_Hauteur_image=IMG_Header.Hauteur; + + for (Pos_Y=0;(Pos_Yst_size; + + if (read(Fichier,&Head,sizeof(struct Header))==sizeof(struct Header)) + { + Principal_Commentaire[0]='\0'; // On efface le commentaire + if (Head.Jump) + { + Indice=0; + while ( (IndiceTAILLE_COMMENTAIRE) + { + Couleur=Octet; // On se sert de Couleur comme + Octet=TAILLE_COMMENTAIRE; // variable temporaire + Couleur-=TAILLE_COMMENTAIRE; + } + else + Couleur=0; + + if (read(Fichier,Principal_Commentaire,Octet)==Octet) + { + Indice+=Octet; + Principal_Commentaire[Octet]='\0'; + if (Couleur) + if (lseek(Fichier,Couleur,SEEK_CUR)==-1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + case 1 : // Dimensions de l'écran d'origine + if (read(Fichier,&Octet,1)==1) + { + if (Octet==4) + { + Indice+=4; + if ( (read(Fichier,&Ecran_original_X,2)!=2) + || (read(Fichier,&Ecran_original_Y,2)!=2) ) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + case 2 : // Couleur de transparence + if (read(Fichier,&Octet,1)==1) + { + if (Octet==1) + { + Indice++; + if (read(Fichier,&Back_color,1)!=1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + else + Erreur_fichier=2; + break; + + default: + if (read(Fichier,&Octet,1)==1) + { + Indice+=Octet; + if (lseek(Fichier,Octet,SEEK_CUR)==-1) + Erreur_fichier=2; + } + else + Erreur_fichier=2; + } + } + else + Erreur_fichier=2; + } + if ( (!Erreur_fichier) && (Indice!=Head.Jump) ) + Erreur_fichier=2; + } + + Init_lecture(); + + if (!Erreur_fichier) + { + Initialiser_preview(Head.Largeur,Head.Hauteur,Taille_du_fichier,FORMAT_PKM); + if (Erreur_fichier==0) + { + Principal_Largeur_image=Head.Largeur; + Principal_Hauteur_image=Head.Hauteur; + Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); + + memcpy(Principal_Palette,Head.Palette,sizeof(T_Palette)); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Compteur_de_donnees_packees=0; + Compteur_de_pixels=0; + Taille_pack=(Informations_Fichier->st_size)-sizeof(struct Header)-Head.Jump; + + // Boucle de décompression: + while ( (Compteur_de_pixels>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_pixels2) && (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; + close(Fichier); + } + else + { + Erreur_fichier=1; + close(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); +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// LBM //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format LBM -------------------------------- + + int LBM_Fichier; + + // ------------ Lire et traduire une valeur au format Motorola ------------ + dword Lire_long(void) + { + dword Temp; + dword Valeur; + + if (read(LBM_Fichier,&Valeur,4)!=4) + Erreur_fichier=1; + swab((char *)&Valeur,(char *)&Temp,4); + return ((Temp>>16)+(Temp<<16)); + } + + +void Test_LBM(void) +{ + char Nom_du_fichier[256]; + char Format[4]; + char Section[4]; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(LBM_Fichier,Section,4)!=4) + Erreur_fichier=1; + else + if (memcmp(Section,"FORM",4)) + Erreur_fichier=1; + else + { + Lire_long(); // On aurait pu vérifier que ce long est égal à la taille + // du fichier - 8, mais ‡a aurait interdit de charger des + // fichiers tronqués (et déjà que c'est chiant de perdre + // une partie du fichier il faut quand mˆme pouvoir en + // garder un peu... Sinon, moi je pleure :'( !!! ) + if (read(LBM_Fichier,Format,4)!=4) + Erreur_fichier=1; + else + if ( (memcmp(Format,"ILBM",4)) && (memcmp(Format,"PBM ",4)) ) + Erreur_fichier=1; + } + close(LBM_Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format LBM ----------------------------------------- + + byte * LBM_Buffer; + byte Image_HAM; + byte HBPm1; // Header.BitPlanes-1 + + // ---------------- Adapter la palette pour les images HAM ---------------- + void Adapter_Palette_HAM(void) + { + short I,J,Temp; + byte Couleur; + + if (Image_HAM==6) + { + for (I=1; I<=14; I++) + { + // On recopie a palette de base + memcpy(Principal_Palette+(I<<4),Principal_Palette,48); + // On modifie les teintes de cette palette + for (J=0; J<16; J++) + { + Couleur=(I<<4)+J; + if (I<=7) + { + if (I&1) + { + Temp=Principal_Palette[J].R+16; + Principal_Palette[Couleur].R=(Temp<63)?Temp:63; + } + if (I&2) + { + Temp=Principal_Palette[J].V+16; + Principal_Palette[Couleur].V=(Temp<63)?Temp:63; + } + if (I&4) + { + Temp=Principal_Palette[J].B+16; + Principal_Palette[Couleur].B=(Temp<63)?Temp:63; + } + } + else + { + if ((I-7)&1) + { + Temp=Principal_Palette[J].R-16; + Principal_Palette[Couleur].R=(Temp>=0)?Temp:0; + } + if ((I-7)&2) + { + Temp=Principal_Palette[J].V-16; + Principal_Palette[Couleur].V=(Temp>=0)?Temp:0; + } + if ((I-7)&4) + { + Temp=Principal_Palette[J].B-16; + Principal_Palette[Couleur].B=(Temp>=0)?Temp:0; + } + } + } + } + // Ici, il reste les 16 derniŠres couleurs à modifier + for (I=240,J=0; J<16; I++,J++) + { + Temp=Principal_Palette[J].R+8; + Principal_Palette[I].R=(Temp<63)?Temp:63; + Temp=Principal_Palette[J].V+8; + Principal_Palette[I].V=(Temp<63)?Temp:63; + Temp=Principal_Palette[J].B+8; + Principal_Palette[I].B=(Temp<63)?Temp:63; + } + } + else if (Image_HAM==8) + { + for (I=1; I<=3; I++) + { + // On recopie la palette de base + memcpy(Principal_Palette+(I<<6),Principal_Palette,192); + // On modifie les teintes de cette palette + for (J=0; J<64; J++) + { + Couleur=(I<<6)+J; + switch (I) + { + case 1 : + Temp=Principal_Palette[J].R+16; + Principal_Palette[Couleur].R=(Temp<63)?Temp:63; + break; + case 2 : + Temp=Principal_Palette[J].V+16; + Principal_Palette[Couleur].V=(Temp<63)?Temp:63; + break; + default: + Temp=Principal_Palette[J].B+16; + Principal_Palette[Couleur].B=(Temp<63)?Temp:63; + } + } + } + } + else // Image 64 couleurs sauvée en 32. + { + for (I=0; I<32; I++) + { + J=I+32; + Principal_Palette[J].R=Principal_Palette[I].R>>1; + Principal_Palette[J].V=Principal_Palette[I].V>>1; + Principal_Palette[J].B=Principal_Palette[I].B>>1; + } + } + } + + // ------------------------- Attendre une section ------------------------- + byte Wait_for(byte * Section_attendue) + { + // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur) + dword Taille_section; + byte Section_lue[4]; + + if (read(LBM_Fichier,Section_lue,4)!=4) + return 0; + while (memcmp(Section_lue,Section_attendue,4)) // Sect. pas encore trouvée + { + Taille_section=Lire_long(); + if (Erreur_fichier) + return 0; + if (Taille_section&1) + Taille_section++; + if (lseek(LBM_Fichier,Taille_section,SEEK_CUR)==-1) + return 0; + if (read(LBM_Fichier,Section_lue,4)!=4) + return 0; + } + return 1; + } + + // ----------------------- Afficher une ligne ILBM ------------------------ + void Draw_ILBM_line(short Pos_Y, short Vraie_taille_ligne) + { + byte Couleur; + byte Rouge,Vert,Bleu; + byte Temp; + short Pos_X; + + if (Image_HAM<=1) // ILBM + { + for (Pos_X=0; Pos_X>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + case 0x02: // Rouge + Rouge=Temp>>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + case 0x03: // Vert + Vert=Temp>>2; + Couleur=Meilleure_couleur(Rouge,Vert,Bleu); + break; + default: // Nouvelle couleur + Couleur=Temp; + Rouge=Principal_Palette[Couleur].R; + Vert =Principal_Palette[Couleur].V; + Bleu =Principal_Palette[Couleur].B; + } + Pixel_de_chargement(Pos_X,Pos_Y,Couleur); + } + } + } + + +void Load_LBM(void) +{ + char Nom_du_fichier[256]; + //int Fichier; + struct Header_LBM + { + word Width; + word Height; + short Xorg; // Inutile + short Yorg; // Inutile + byte Bit_planes; + byte Mask; + byte Compression; + byte Pad1; // Inutile + word Transp_col; + byte Xaspect; // Inutile + byte Yaspect; // Inutile + short Xscreen; + short Yscreen; + } Header; + char Format[4]; + char Section[4]; + byte Octet; + short B256; + dword Nb_couleurs; + dword Taille_image; + short Pos_X; + short Pos_Y; + short Compteur; + short Taille_ligne; // Taille d'une ligne en octets + short Vraie_taille_ligne; // Taille d'une ligne en pixels + byte Couleur; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((LBM_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + // On avance dans le fichier (pas besoin de tester ce qui l'a déjà été) + read(LBM_Fichier,Section,4); + Lire_long(); + read(LBM_Fichier,Format,4); + if (!Wait_for((byte *)"BMHD")) + Erreur_fichier=1; + Lire_long(); + + // Maintenant on lit le header pour pouvoir commencer le chargement de l'image + if ( (read(LBM_Fichier,&Header,sizeof(struct Header_LBM))==sizeof(struct Header_LBM)) + && Header.Width && Header.Height) + { + if ( (Header.Bit_planes) && (Wait_for((byte *)"CMAP")) ) + { + Nb_couleurs=Lire_long()/3; + + if (((int)1< il faut copier les 32 coul. + } // sur les 32 suivantes et assombrir ces derniŠres. + else + { + if ((Header.Bit_planes==6) || (Header.Bit_planes==8)) + Image_HAM=Header.Bit_planes; + else + // Erreur_fichier=1; /* C'est censé ˆtre incorrect mais j'ai */ + Image_HAM=0; /* trouvé un fichier comme ‡a, alors... */ + } + } + else + Image_HAM=0; + + if ( (!Erreur_fichier) && (Nb_couleurs>=2) && (Nb_couleurs<=256) ) + { + HBPm1=Header.Bit_planes-1; + if (Header.Mask==1) + Header.Bit_planes++; + + // Deluxe paint le fait... alors on le fait... + Back_color=Header.Transp_col; + + // On commence par passer la palette en 256 comme ‡a, si la nouvelle + // palette a moins de 256 coul, la précédente ne souffrira pas d'un + // assombrissement préjudiciable. + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + // On peut maintenant charger la nouvelle palette + if (read(LBM_Fichier,Principal_Palette,3*Nb_couleurs)==(3*Nb_couleurs)) + { + Palette_256_to_64(Principal_Palette); + if (Image_HAM) + Adapter_Palette_HAM(); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // On lit l'octet de padding du CMAP si la taille est impaire + if (Nb_couleurs&1) + if (read(LBM_Fichier,&Octet,1)==1) + Erreur_fichier=2; + + if ( (Wait_for((byte *)"BODY")) && (!Erreur_fichier) ) + { + Taille_image=Lire_long(); + swab((char *)&Header.Width ,(char *)&Principal_Largeur_image,2); + swab((char *)&Header.Height,(char *)&Principal_Hauteur_image,2); + + swab((char *)&Header.Xscreen,(char *)&Ecran_original_X,2); + swab((char *)&Header.Yscreen,(char *)&Ecran_original_Y,2); + + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_LBM); + if (Erreur_fichier==0) + { + if (!memcmp(Format,"ILBM",4)) // "ILBM": InterLeaved BitMap + { + // Calcul de la taille d'une ligne ILBM (pour les images ayant des dimensions exotiques) + if (Principal_Largeur_image & 15) + { + Vraie_taille_ligne=( (Principal_Largeur_image+16) >> 4 ) << 4; + Taille_ligne=( (Principal_Largeur_image+16) >> 4 )*(Header.Bit_planes<<1); + } + else + { + Vraie_taille_ligne=Principal_Largeur_image; + Taille_ligne=(Principal_Largeur_image>>3)*Header.Bit_planes; + } + + if (!Header.Compression) + { // non compressé + LBM_Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=0; ((Pos_Y127) + { + Couleur=Lire_octet(LBM_Fichier); + B256=(short)(256-Octet); + for (Compteur=0; Compteur<=B256; Compteur++) + if (Pos_X127) + { + Couleur=Lire_octet(LBM_Fichier); + B256=256-Octet; + for (Compteur=0; Compteur<=B256; Compteur++) + Pixel_de_chargement(Pos_X++,Pos_Y,Couleur); + } + else + for (Compteur=0; Compteur<=Octet; Compteur++) + Pixel_de_chargement(Pos_X++,Pos_Y,Lire_octet(LBM_Fichier)); + } + } + Close_lecture(); + } + } + } + } + else + Modif_Erreur_fichier(2); + } + else + { + // On restore l'ancienne palette en cas d'erreur... + Palette_256_to_64(Principal_Palette); + // ... ce qui permet de ne renvoyer qu'une erreur 1 (pas de modif) + Erreur_fichier=1; + } + } + else + Modif_Erreur_fichier(1); + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + + close(LBM_Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format LBM --------------------------------------- + + byte LBM_File_de_couleurs[129]; + word LBM_Taille_de_file; + byte LBM_Mode_repetition; + + // ----------- Traduire et écrire une valeur au format Motorola ----------- + void Ecrire_long(dword Valeur) + { + dword Temp; + + swab((char *)&Valeur,(char *)&Temp,4); + Valeur=(Temp>>16)+(Temp<<16); + if (write(LBM_Fichier,&Valeur,4)==-1) + Erreur_fichier=1; + } + + // ------------- Ecrire les couleurs que l'on vient de traiter ------------ + void Transferer_couleurs(void) + { + byte Indice; + + if (LBM_Taille_de_file>0) + { + if (LBM_Mode_repetition) + { + Ecrire_octet(LBM_Fichier,257-LBM_Taille_de_file); + Ecrire_octet(LBM_Fichier,LBM_File_de_couleurs[0]); + } + else + { + Ecrire_octet(LBM_Fichier,LBM_Taille_de_file-1); + for (Indice=0; Indice et on a 3 couleurs qui se suivent + { + LBM_Taille_de_file-=2; + Transferer_couleurs(); + LBM_File_de_couleurs[0]=Couleur; + LBM_File_de_couleurs[1]=Couleur; + LBM_File_de_couleurs[2]=Couleur; + LBM_Taille_de_file=3; + LBM_Mode_repetition=1; + } + } + else // La couleur n'est pas la mˆme que la précédente + { + if (!LBM_Mode_repetition) // On conserve le mode... + { + LBM_File_de_couleurs[LBM_Taille_de_file++]=Couleur; + if (LBM_Taille_de_file==128) + Transferer_couleurs(); + } + else // On change de mode... + { + Transferer_couleurs(); + LBM_File_de_couleurs[LBM_Taille_de_file]=Couleur; + LBM_Taille_de_file++; + } + } + } + } + + +void Save_LBM(void) +{ + char Nom_du_fichier[256]; + struct Header_LBM + { + word Width; + word Height; + short Xorg; // Inutile + short Yorg; // Inutile + byte BitPlanes; + byte Mask; + byte Compression; + byte Pad1; // Inutile + word Transp_col; // Inutile + byte Xaspect; // Inutile + byte Yaspect; // Inutile + short Xscreen; + short Yscreen; + } Header; + word Pos_X; + word Pos_Y; + byte Octet; + word Vraie_largeur; + struct stat* Informations_Fichier=NULL; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + + // Ouverture du fichier + LBM_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (LBM_Fichier!=-1) + { + write(LBM_Fichier,"FORM",4); + Ecrire_long(0); // On mettra la taille à jour à la fin + + write(LBM_Fichier,"PBM BMHD",8); + Ecrire_long(20); + + // On corrige la largeur de l'image pour qu'elle soit multiple de 2 + Vraie_largeur=Principal_Largeur_image+(Principal_Largeur_image&1); + + //swab((byte *)&Vraie_largeur,(byte *)&Header.Width,2); + swab((byte *)&Principal_Largeur_image,(byte *)&Header.Width,2); + swab((byte *)&Principal_Hauteur_image,(byte *)&Header.Height,2); + Header.Xorg=0; + Header.Yorg=0; + Header.BitPlanes=8; + Header.Mask=0; + Header.Compression=1; + Header.Pad1=0; + Header.Transp_col=Back_color; + Header.Xaspect=1; + Header.Yaspect=1; + swab((byte *)&Largeur_ecran,(byte *)&Header.Xscreen,2); + swab((byte *)&Hauteur_ecran,(byte *)&Header.Yscreen,2); + + write(LBM_Fichier,&Header,sizeof(struct Header_LBM)); + + write(LBM_Fichier,"CMAP",4); + Ecrire_long(sizeof(T_Palette)); + + Palette_64_to_256(Principal_Palette); + write(LBM_Fichier,Principal_Palette,sizeof(T_Palette)); + Palette_256_to_64(Principal_Palette); + + write(LBM_Fichier,"BODY",4); + Ecrire_long(0); // On mettra la taille à jour à la fin + + Init_ecriture(); + + LBM_Taille_de_file=0; + + for (Pos_Y=0; ((Pos_Yst_size)-824); + + if (!Erreur_fichier) + { + lseek(LBM_Fichier,4,SEEK_SET); + + // Si la taille de la section de l'image (taille fichier-8) est + // impaire, on rajoute un 0 (Padding) à la fin. + if ((Informations_Fichier->st_size) & 1) + { + Ecrire_long((Informations_Fichier->st_size)-7); + lseek(LBM_Fichier,0,SEEK_END); + Octet=0; + if (write(LBM_Fichier,&Octet,1)==-1) + Erreur_fichier=1; + } + else + Ecrire_long((Informations_Fichier->st_size)-8); + + close(LBM_Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + } + else + { + Erreur_fichier=1; + close(LBM_Fichier); + remove(Nom_du_fichier); + } + } + else // Il y a eu une erreur lors du compactage => on efface le fichier + remove(Nom_du_fichier); + } + else + Erreur_fichier=1; +} + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// BMP //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format BMP -------------------------------- +void Test_BMP(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct BMP_Header + { + word Signature; // ='BM' = 0x4D42 + long Taille_1; // =Taille du fichier + word Reserv_1; // =0 + word Reserv_2; // =0 + long Decalage; // Nb octets avant les données bitmap + + long Taille_2; // =40 + long Largeur; + long Hauteur; + word Plans; // =1 + word Nb_bits; // =1,4,8 ou 24 + long Compression; + long Taille_3; + long XPM; + long YPM; + long Nb_Clr; + long Clr_Imprt; + } Header; + + + Erreur_fichier=1; + Nom_fichier_complet(Nom_du_fichier,0); + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) + if ( (Header.Signature==0x4D42) && (Header.Taille_2==40) + && Header.Largeur && Header.Hauteur ) + Erreur_fichier=0; + close(Fichier); + } +} + + +// -- Charger un fichier au format BMP -------------------------------------- +void Load_BMP(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct BMP_Header + { + word Signature; // ='BM' = 0x4D42 + long Taille_1; // =Taille du fichier + word Reserv_1; // =0 + word Reserv_2; // =0 + long Decalage; // Nb octets avant les données bitmap + + long Taille_2; // =40 + long Largeur; + long Hauteur; + word Plans; // =1 + word Nb_bits; // =1,4,8 ou 24 + long Compression; + long Taille_3; + long XPM; + long YPM; + long Nb_Clr; + long Clr_Imprt; + } Header; + byte * Buffer; + word Indice; + byte Palette_locale[256][4]; // R,V,B,0 + word Nb_Couleurs; + short Pos_X; + short Pos_Y; + word Taille_ligne; + byte A,B,C=0; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&Header,sizeof(struct BMP_Header))==sizeof(struct BMP_Header)) + { + switch (Header.Nb_bits) + { + case 1 : + case 4 : + case 8 : + if (Header.Nb_Clr) + Nb_Couleurs=Header.Nb_Clr; + else + Nb_Couleurs=1<>3; + + Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + { + if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) + for (Pos_X=0; Pos_X>1] & 0xF); + else + Pixel_de_chargement(Pos_X,Pos_Y,Buffer[Pos_X>>1] >> 4 ); + break; + case 1 : + if ( Buffer[Pos_X>>3] & (0x80>>(Pos_X&7)) ) + Pixel_de_chargement(Pos_X,Pos_Y,1); + else + Pixel_de_chargement(Pos_X,Pos_Y,0); + } + else + Erreur_fichier=2; + } + free(Buffer); + break; + + case 1 : // Compression RLE 8 bits + Pos_X=0; + Pos_Y=Principal_Hauteur_image-1; + + Init_lecture(); + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + while ( (!Erreur_fichier) && ((A)||(B!=1)) ) + { + if (A) // Encoded mode + for (Indice=1; Indice<=A; Indice++) + Pixel_de_chargement(Pos_X++,Pos_Y,B); + else // Absolute mode + switch (B) + { + case 0 : // End of line + Pos_X=0; + Pos_Y--; + break; + case 1 : // End of bitmap + break; + case 2 : // Delta + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + Pos_X+=A; + Pos_Y-=B; + break; + default: // Nouvelle série + while (B) + { + A=Lire_octet(Fichier); + C=Lire_octet(Fichier); + Pixel_de_chargement(Pos_X++,Pos_Y,A); + if (--B) + { + Pixel_de_chargement(Pos_X++,Pos_Y,C); + B--; + } + } + } + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + } + Close_lecture(); + break; + + case 2 : // Compression RLE 4 bits + Pos_X=0; + Pos_Y=Principal_Hauteur_image-1; + + Init_lecture(); + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + while ( (!Erreur_fichier) && ((A)||(B!=1)) ) + { + if (A) // Encoded mode (A fois les 1/2 pixels de B) + for (Indice=1; Indice<=A; Indice++) + { + if (Indice & 1) + Pixel_de_chargement(Pos_X,Pos_Y,B>>4); + else + Pixel_de_chargement(Pos_X,Pos_Y,B&0xF); + Pos_X++; + } + else // Absolute mode + switch (B) + { + case 0 : //End of line + Pos_X=0; + Pos_Y--; + break; + case 1 : // End of bitmap + break; + case 2 : // Delta + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + Pos_X+=A; + Pos_Y-=B; + break; + default: // Nouvelle série (B 1/2 pixels bruts) + for (Indice=1; ((Indice<=B) && (!Erreur_fichier)); Indice++,Pos_X++) + { + if (Indice&1) + { + C=Lire_octet(Fichier); + Pixel_de_chargement(Pos_X,Pos_Y,C>>4); + } + else + Pixel_de_chargement(Pos_X,Pos_Y,C&0xF); + } + // On lit l'octet rendant le nombre d'octets pair, si + // nécessaire. Encore un truc de crétin "made in MS". + if ( ((B&3)==1) || ((B&3)==2) ) + Lire_octet(Fichier); + } + A=Lire_octet(Fichier); + B=Lire_octet(Fichier); + } + Close_lecture(); + } + close(Fichier); + } + else + { + close(Fichier); + Erreur_fichier=1; + } + } + } + else + { + // Image 24 bits!!! + Erreur_fichier=0; + + Principal_Largeur_image=Header.Largeur; + Principal_Hauteur_image=Header.Hauteur; + Initialiser_preview(Header.Largeur,Header.Hauteur,Taille_du_fichier,FORMAT_BMP | FORMAT_24B); + + if (Erreur_fichier==0) + { + Taille_ligne=Principal_Largeur_image*3; + Pos_X=(Taille_ligne % 4); // Pos_X sert de variable temporaire + if (Pos_X>0) + Taille_ligne+=(4-Pos_X); + + Buffer=(byte *)malloc(Taille_ligne); + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + { + if (read(Fichier,Buffer,Taille_ligne)==Taille_ligne) + for (Pos_X=0,Indice=0; Pos_X> 3)+1) << 3; + else + Taille_ligne=Principal_Largeur_image; + + Header.Signature =0x4D42; + Header.Taille_1 =(Taille_ligne*Principal_Hauteur_image)+1078; + Header.Reserv_1 =0; + Header.Reserv_2 =0; + Header.Decalage =1078; + Header.Taille_2 =40; + Header.Largeur =Taille_ligne; + Header.Hauteur =Principal_Hauteur_image; + Header.Plans =1; + Header.Nb_bits =8; + Header.Compression=0; + Header.Taille_3 =0; + Header.XPM =0; + Header.YPM =0; + Header.Nb_Clr =0; + Header.Clr_Imprt =0; + + if (write(Fichier,&Header,sizeof(struct BMP_Header))!=-1) + { + // Chez Bill, ils ont dit: "On va mettre les couleur dans l'ordre + // inverse, et pour faire chier, on va les mettre sur une échelle de + // 0 à 255 parce que le standard VGA c'est de 0 à 63 (logique!). Et + // puis comme c'est pas assez débile, on va aussi y rajouter un octet + // toujours à 0 pour forcer les gens à s'acheter des gros disques + // durs... Comme ‡a, ‡a fera passer la pillule lorsqu'on sortira + // Windows 95." ... + Palette_64_to_256(Principal_Palette); + for (Indice=0; Indice<256; Indice++) + { + Palette_locale[Indice][0]=Principal_Palette[Indice].B; + Palette_locale[Indice][1]=Principal_Palette[Indice].V; + Palette_locale[Indice][2]=Principal_Palette[Indice].R; + Palette_locale[Indice][3]=0; + } + Palette_256_to_64(Principal_Palette); + + if (write(Fichier,Palette_locale,1024)!=-1) + { + Init_ecriture(); + + // ... Et Bill, il a dit: "OK les gars! Mais seulement si vous rangez + // les pixels dans l'ordre inverse, mais que sur les Y quand-mˆme + // parce que faut pas pousser." + for (Pos_Y=Principal_Hauteur_image-1; ((Pos_Y>=0) && (!Erreur_fichier)); Pos_Y--) + for (Pos_X=0; Pos_X>=Nb_bits_en_cours; + Nb_bits_traites +=Nb_bits_en_cours; + Nb_bits_a_traiter-=Nb_bits_en_cours; + GIF_Rest_bits -=Nb_bits_en_cours; + } + + return GIF_Code_actuel; + } + + // -- Affiche un nouveau pixel -- + + void GIF_Nouveau_pixel(byte Couleur) + { + Pixel_de_chargement(GIF_Pos_X,GIF_Pos_Y,Couleur); + + GIF_Pos_X++; + + if (GIF_Pos_X>=Principal_Largeur_image) + { + GIF_Pos_X=0; + + if (!GIF_Entrelacee) + GIF_Pos_Y++; + else + { + switch (GIF_Passe) + { + case 0 : GIF_Pos_Y+=8; + break; + case 1 : GIF_Pos_Y+=8; + break; + case 2 : GIF_Pos_Y+=4; + break; + default: GIF_Pos_Y+=2; + } + + if (GIF_Pos_Y>=Principal_Hauteur_image) + { + switch(++GIF_Passe) + { + case 1 : GIF_Pos_Y=4; + break; + case 2 : GIF_Pos_Y=2; + break; + case 3 : GIF_Pos_Y=1; + break; + case 4 : GIF_Image_entrelacee_terminee=1; + } + } + } + } + } + + +void Load_GIF(void) +{ + char Nom_du_fichier[256]; + char Signature[6]; + + word * Alphabet_Pile; // Pile de décodage d'une chaŒne + word * Alphabet_Prefixe; // Table des préfixes des codes + word * Alphabet_Suffixe; // Table des suffixes des codes + word Alphabet_Free; // Position libre dans l'alphabet + word Alphabet_Max; // Nombre d'entrées possibles dans l'alphabet + word Alphabet_Pos_pile; // Position dans la pile de décodage d'un chaŒne + + struct Type_LSDB + { + word Largeur; // Largeur de l'écran virtuel + word Hauteur; // Hauteur de l'écran virtuel + byte Resol; // Informations sur la résolution (et autres) + byte Backcol; // Couleur de fond + byte Aspect; // Informations sur l'aspect ratio (et autres) + } LSDB; // Logical Screen Descriptor Block + + struct Type_IDB + { + word Pos_X; // Abscisse o— devrait ˆtre affichée l'image + word Pos_Y; // Ordonnée o— devrait ˆtre affichée l'image + word Largeur_image; // Largeur de l'image + word Hauteur_image; // Hauteur de l'image + byte Indicateur; // Informations diverses sur l'image + byte Nb_bits_pixel; // Nb de bits par pixel + } IDB; // Image Descriptor Block + + word Nb_couleurs; // Nombre de couleurs dans l'image + word Indice_de_couleur; // Indice de traitement d'une couleur + word Taille_de_lecture; // Nombre de données à lire (divers) + //word Indice_de_lecture; // Indice de lecture des données (divers) + byte Block_indicateur; // Code indicateur du type de bloc en cours + word Nb_bits_initial; // Nb de bits au début du traitement LZW + word Cas_special=0; // Mémoire pour le cas spécial + word Code_ancien=0; // Code précédent + word Read_byte; // Sauvegarde du code en cours de lecture + word Valeur_Clr; // Valeur <=> Clear tables + word Valeur_Eof; // Valeur <=> Fin d'image + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + /////////////////////////////////////////////////// FIN DES DECLARATIONS // + + + GIF_Pos_X=0; + GIF_Pos_Y=0; + GIF_Last_byte=0; + GIF_Rest_bits=0; + GIF_Rest_byte=0; + + Nom_fichier_complet(Nom_du_fichier,0); + + if ((GIF_Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if ( (read(GIF_Fichier,Signature,6)==6) && + ( (memcmp(Signature,"GIF87a",6)==0) || + (memcmp(Signature,"GIF89a",6)==0) ) ) + { + // Allocation de mémoire pour les tables & piles de traitement: + Alphabet_Pile =(word *)malloc(4096*sizeof(word)); + Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); + + if (read(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) + { + // Lecture du Logical Screen Descriptor Block réussie: + + Ecran_original_X=LSDB.Largeur; + Ecran_original_Y=LSDB.Hauteur; + + // Palette globale dispo = (LSDB.Resol and $80) + // Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1 + // Nombre de bits/pixel = (LSDB.Resol and $07)+1 + // Ordre de Classement = (LSDB.Aspect and $80) + + Alphabet_Pos_pile=0; + GIF_Last_byte =0; + GIF_Rest_bits =0; + GIF_Rest_byte =0; + + Nb_couleurs=(1 << ((LSDB.Resol & 0x07)+1)); + Nb_bits_initial=(LSDB.Resol & 0x07)+2; + + if (LSDB.Resol & 0x80) + { + // Palette globale dispo: + + // On commence par passer la palette en 256 comme ‡a, si la + // nouvelle palette a moins de 256 coul, la précédente ne souffrira + // pas d'un assombrissement préjudiciable. + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + + // On peut maintenant charger la nouvelle palette: + if (!(LSDB.Aspect & 0x80)) + // Palette dans l'ordre: + read(GIF_Fichier,Principal_Palette,Nb_couleurs*3); + else + { + // Palette triée par composantes: + for (Indice_de_couleur=0;Indice_de_couleurValeur_Clr) + { + Alphabet_Pile[Alphabet_Pos_pile++]=Alphabet_Suffixe[GIF_Code_actuel]; + GIF_Code_actuel=Alphabet_Prefixe[GIF_Code_actuel]; + } + + Cas_special=Alphabet_Pile[Alphabet_Pos_pile++]=GIF_Code_actuel; + + do + GIF_Nouveau_pixel(Alphabet_Pile[--Alphabet_Pos_pile]); + while (Alphabet_Pos_pile!=0); + + Alphabet_Prefixe[Alphabet_Free ]=Code_ancien; + Alphabet_Suffixe[Alphabet_Free++]=GIF_Code_actuel; + Code_ancien=Read_byte; + + if (Alphabet_Free>Alphabet_Max) + { + if (GIF_Nb_bits<12) + Alphabet_Max =((1 << (++GIF_Nb_bits))-1); + } + } + else // Code Clear rencontré + { + GIF_Nb_bits =Nb_bits_initial; + Alphabet_Max =((1 << GIF_Nb_bits)-1); + Alphabet_Free =Nb_couleurs+2; + Cas_special =GIF_Get_next_code(); + Code_ancien =GIF_Code_actuel; + GIF_Nouveau_pixel(GIF_Code_actuel); + } + } + else + Erreur_fichier=2; + } // Code End-Of-Information ou erreur de fichier rencontré + + Close_lecture(); + + if (Erreur_fichier>=0) + if ( /* (GIF_Pos_X!=0) || */ + ( ( (!GIF_Entrelacee) && (GIF_Pos_Y!=Principal_Hauteur_image) ) || + ( (GIF_Entrelacee) && (!GIF_Image_entrelacee_terminee) ) + ) ) + Erreur_fichier=2; + } // Le fichier contenait un IDB + else + Erreur_fichier=2; + + } // Le fichier contenait une image + else + Erreur_fichier=2; + + } // Le fichier contenait un LSDB + else + Erreur_fichier=1; + + // Libération de la mémoire utilisée par les tables & piles de traitement: + free(Alphabet_Suffixe); + free(Alphabet_Prefixe); + free(Alphabet_Pile); + } // Le fichier contenait au moins la signature GIF87a ou GIF89a + else + Erreur_fichier=1; + + close(GIF_Fichier); + + } // Le fichier était ouvrable + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format GIF --------------------------------------- + + int GIF_Arret; // "On peut arrˆter la sauvegarde du fichier" + byte GIF_Buffer[256]; // Buffer d'écriture de bloc de données compilées + + // -- Vider le buffer GIF dans le buffer KM -- + + void GIF_Vider_le_buffer(void) + { + word Indice; + + if (GIF_Rest_byte) + { + GIF_Buffer[0]=GIF_Rest_byte; + + for (Indice=0;Indice<=GIF_Rest_byte;Indice++) + Ecrire_octet(GIF_Fichier,GIF_Buffer[Indice]); + + GIF_Rest_byte=0; + } + } + + // -- Ecrit un code à GIF_Nb_bits -- + + void GIF_Set_code(word Code) + { + word Nb_bits_a_traiter=GIF_Nb_bits; + word Nb_bits_traites =0; + word Nb_bits_en_cours; + + while (Nb_bits_a_traiter) + { + Nb_bits_en_cours=(Nb_bits_a_traiter<=(8-GIF_Rest_bits))?Nb_bits_a_traiter:(8-GIF_Rest_bits); + + GIF_Last_byte|=(Code & ((1<>=Nb_bits_en_cours; + GIF_Rest_bits +=Nb_bits_en_cours; + Nb_bits_traites +=Nb_bits_en_cours; + Nb_bits_a_traiter-=Nb_bits_en_cours; + + if (GIF_Rest_bits==8) // Il ne reste plus de bits à coder sur l'octet courant + { + // Ecrire l'octet à balancer: + GIF_Buffer[++GIF_Rest_byte]=GIF_Last_byte; + + // Si on a atteint la fin du bloc de Raster Data + if (GIF_Rest_byte==255) + // On doit vider le buffer qui est maintenant plein + GIF_Vider_le_buffer(); + + GIF_Last_byte=0; + GIF_Rest_bits=0; + } + } + } + + + // -- Lire le pixel suivant -- + + byte GIF_Pixel_suivant(void) + { + byte Temp; + + Temp=Lit_pixel_de_sauvegarde(GIF_Pos_X,GIF_Pos_Y); + + if (++GIF_Pos_X>=Principal_Largeur_image) + { + GIF_Pos_X=0; + if (++GIF_Pos_Y>=Principal_Hauteur_image) + GIF_Arret=1; + } + + return Temp; + } + + + +void Save_GIF(void) +{ + char Nom_du_fichier[256]; + + word * Alphabet_Prefixe; // Table des préfixes des codes + word * Alphabet_Suffixe; // Table des suffixes des codes + word * Alphabet_Fille; // Table des chaŒnes filles (plus longues) + word * Alphabet_Soeur; // 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 Depart; // Code précédent (sert au linkage des chaŒnes) + int Descente; // Booléen "On vient de descendre" + + struct Type_LSDB + { + word Largeur; // Largeur de l'écran virtuel |_ Dimensions de l'image si 1 + word Hauteur; // Hauteur de l'écran virtuel | seule image dans le fichier (ce qui est notre cas) + byte Resol; // Informations sur la résolution (et autres) + byte Backcol; // Couleur de fond + byte Aspect; // Informations sur l'aspect ratio (et autres) + } LSDB; // Logical Screen Descriptor Block + + struct Type_IDB + { + word Pos_X; // Abscisse o— devrait ˆtre affichée l'image + word Pos_Y; // Ordonnée o— devrait ˆtre affichée l'image + word Largeur_image; // Largeur de l'image + word Hauteur_image; // Hauteur de l'image + byte Indicateur; // Informations diverses sur l'image + byte Nb_bits_pixel; // Nb de bits par pixel + } IDB; // Image Descriptor Block + + byte Block_indicateur; // Code indicateur du type de bloc en cours + word Chaine_en_cours; // Code de la chaŒne en cours de traitement + byte Caractere; // CaractŠre à coder + word Indice; // Indice de recherche de chaŒne + + + /////////////////////////////////////////////////// FIN DES DECLARATIONS // + + + GIF_Pos_X=0; + GIF_Pos_Y=0; + GIF_Last_byte=0; + GIF_Rest_bits=0; + GIF_Rest_byte=0; + + Nom_fichier_complet(Nom_du_fichier,0); + + GIF_Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (GIF_Fichier!=-1) + { + // On écrit la signature du fichier + if (write(GIF_Fichier,"GIF87a",6)==6) + { + // La signature du fichier a été correctement écrite. + + // Allocation de mémoire pour les tables + Alphabet_Prefixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Suffixe=(word *)malloc(4096*sizeof(word)); + Alphabet_Fille =(word *)malloc(4096*sizeof(word)); + Alphabet_Soeur =(word *)malloc(4096*sizeof(word)); + + // On initialise le LSDB du fichier + if (Config.Taille_ecran_dans_GIF) + { + LSDB.Largeur=Largeur_ecran; + LSDB.Hauteur=Hauteur_ecran; + } + else + { + LSDB.Largeur=Principal_Largeur_image; + LSDB.Hauteur=Principal_Hauteur_image; + } + LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette + LSDB.Backcol=0; + LSDB.Aspect =0; // Palette normale + + // On sauve le LSDB dans le fichier + + if (write(GIF_Fichier,&LSDB,sizeof(struct Type_LSDB))==sizeof(struct Type_LSDB)) + { + // Le LSDB a été correctement écrit. + + // On sauve la palette + + Palette_64_to_256(Principal_Palette); + if (write(GIF_Fichier,Principal_Palette,768)==768) + { + // La palette a été correctement écrite. + + // Le jour o— on se servira des blocks d'extensions pour placer + // des commentaires, on le fera ici. + + // On va écrire un block indicateur d'IDB et l'IDB du fichier + + Block_indicateur=0x2C; + IDB.Pos_X=0; + IDB.Pos_Y=0; + IDB.Largeur_image=Principal_Largeur_image; + IDB.Hauteur_image=Principal_Hauteur_image; + IDB.Indicateur=0x07; // Image non entrelacée, pas de palette locale. + IDB.Nb_bits_pixel=8; // Image 256 couleurs; + + if ( (write(GIF_Fichier,&Block_indicateur,1)==1) && + (write(GIF_Fichier,&IDB,sizeof(struct Type_IDB))==sizeof(struct Type_IDB)) ) + { + // Le block indicateur d'IDB et l'IDB ont étés correctements + // écrits. + + Init_ecriture(); + + Indice=4096; + Erreur_fichier=0; + GIF_Arret=0; + + // Réintialisation de la table: + Alphabet_Free=258; + GIF_Nb_bits =9; + Alphabet_Max =511; + GIF_Set_code(256); + for (Depart=0;Depart<4096;Depart++) + { + Alphabet_Fille[Depart]=4096; + Alphabet_Soeur[Depart]=4096; + } + + ////////////////////////////////////////////// COMPRESSION LZW // + + Depart=Chaine_en_cours=GIF_Pixel_suivant(); + Descente=1; + + do + { + Caractere=GIF_Pixel_suivant(); + + // On regarde si dans la table on aurait pas une chaŒne + // équivalente à Chaine_en_cours+Caractere + + while ( (Indice0xFFF) + { + // Réintialisation de la table: + GIF_Set_code(256); + Alphabet_Free=258; + GIF_Nb_bits =9; + Alphabet_Max =511; + for (Depart=0;Depart<4096;Depart++) + { + Alphabet_Fille[Depart]=4096; + Alphabet_Soeur[Depart]=4096; + } + } + else if (Alphabet_Free>Alphabet_Max+1) + { + // On augmente le nb de bits + + GIF_Nb_bits++; + Alphabet_Max=(1< 16c , 1 => 256c + word Bytes_per_plane_line;// Doit toujours ˆtre pair + word Palette_info; // 1 => Couleur , 2 => Gris (ignoré à partir de la version 4) + word Screen_X; // |_ Dimensions de + word Screen_Y; // | l'écran d'origine + byte Filler[54]; // Ca... J'adore! + } Header; // Je hais ce header! + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) + { + // 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 ( (Header.Manufacturer!=10) + || (Header.Compression>1) + || ( (Header.Depth!=1) && (Header.Depth!=2) && (Header.Depth!=4) && (Header.Depth!=8) ) + || ( (Header.Plane!=1) && (Header.Plane!=2) && (Header.Plane!=4) && (Header.Plane!=8) && (Header.Plane!=3) ) + || (Header.X_max>((Reduction_moins_1-(Pos_X%Reduction))*Depth)) & Masque; + Pixel_de_chargement(Pos_X,Pos_Y,Couleur); + } + } + +void Load_PCX(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct PCX_Header + { + byte Manufacturer; // |_ Il font chier ces cons! Ils auraient pu + byte Version; // | mettre une vraie signature! + byte Compression; // L'image est-elle compressée? + byte Depth; // Nombre de bits pour coder un pixel (inutile puisqu'on se sert de Plane) + word X_min; // |_ Coin haut-gauche | + word Y_min; // | de l'image |_ (Crétin!) + word X_max; // |_ Coin bas-droit | + word Y_max; // | de l'image | + word X_dpi; // |_ Densité de |_ (Presque inutile parce que + word Y_dpi; // | l'image | aucun moniteur n'est pareil!) + byte Palette_16c[48]; // Palette 16 coul (inutile pour 256c) (débile!) + byte Reserved; // Ca me plait ‡a aussi! + byte Plane; // 4 => 16c , 1 => 256c , ... + word Bytes_per_plane_line;// Doit toujours ˆtre pair + word Palette_info; // 1 => Couleur , 2 => Gris (ignoré à partir de la version 4) + word Screen_X; // |_ Dimensions de + word Screen_Y; // | l'écran d'origine + byte Filler[54]; // Ca... J'adore! + } Header; // Je hais ce header! + short Taille_ligne; + short Vraie_taille_ligne; // Largeur de l'image corrigée + short Largeur_lue; + short Pos_X; + short Pos_Y; + byte Octet1; + byte Octet2; + byte Indice; + dword Nb_couleurs; + long Taille_du_fichier; + byte Palette_CGA[9]={ 84,252,252, 252, 84,252, 252,252,252}; + + long Position; + long Taille_image; + byte * Buffer; + struct stat* Informations_Fichier =NULL; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + + if (read(Fichier,&Header,sizeof(struct PCX_Header))==sizeof(struct PCX_Header)) + { + Principal_Largeur_image=Header.X_max-Header.X_min+1; + Principal_Hauteur_image=Header.Y_max-Header.Y_min+1; + + Ecran_original_X=Header.Screen_X; + Ecran_original_Y=Header.Screen_Y; + + if (Header.Plane!=3) + { + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_PCX); + if (Erreur_fichier==0) + { + // On prépare la palette à accueillir les valeurs du fichier PCX + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + else + Palette_64_to_256(Principal_Palette); + Nb_couleurs=(dword)(1<4) + memcpy(Principal_Palette,Header.Palette_16c,48); + else + { + Principal_Palette[1].R=0; + Principal_Palette[1].V=0; + Principal_Palette[1].B=0; + Octet1=Header.Palette_16c[3]>>5; + if (Nb_couleurs==4) + { // Pal. CGA "alakon" (du Turc Allahkoum qui signifie "à la con" :)) + memcpy(Principal_Palette+1,Palette_CGA,9); + if (!(Octet1&2)) + { + Principal_Palette[1].B=84; + Principal_Palette[2].B=84; + Principal_Palette[3].B=84; + } + } // Palette monochrome (on va dire que c'est du N&B) + else + { + Principal_Palette[1].R=252; + Principal_Palette[1].V=252; + Principal_Palette[1].B=252; + } + } + + // On se positionne à la fin du fichier - 769 octets pour voir s'il y + // a une palette. + if ( (Header.Depth==8) && (Header.Version>=5) && (Taille_du_fichier>sizeof(T_Palette)) ) + { + lseek(Fichier,Taille_du_fichier-(sizeof(T_Palette)+1),SEEK_SET); + // On regarde s'il y a une palette aprŠs les données de l'image + if (read(Fichier,&Octet1,1)==1) + if (Octet1==12) // Lire la palette si c'est une image en 256 couleurs + { + // On lit la palette 256c que ces crétins ont foutue à la fin du fichier + if (read(Fichier,Principal_Palette,sizeof(T_Palette))!=sizeof(T_Palette)) + Erreur_fichier=2; + } + } + Palette_256_to_64(Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + // Maintenant qu'on a lu la palette que ces crétins sont allés foutre + // à la fin, on retourne juste aprŠs le header pour lire l'image. + lseek(Fichier,sizeof(struct PCX_Header),SEEK_SET); + + if (!Erreur_fichier) + { + Taille_ligne=Header.Bytes_per_plane_line*Header.Plane; + Vraie_taille_ligne=(short)Header.Bytes_per_plane_line<<3; + // On se sert de données LBM car le dessin de ligne en moins de 256 + // couleurs se fait comme avec la structure ILBM. + Image_HAM=0; + HBPm1=Header.Plane-1; + LBM_Buffer=(byte *)malloc(Taille_ligne); + + // Chargement de l'image + if (Header.Compression) // Image compressée + { + Init_lecture(); + + Taille_image=(long)Header.Bytes_per_plane_line*Principal_Hauteur_image; + + if (Header.Depth==8) // 256 couleurs (1 plan) + { + for (Position=0; ((Position=Taille_ligne) + { + for (Pos_X=0; Pos_X=Taille_ligne) + { + for (Pos_X=0; Pos_X1) || (Last_pixel>=0xC0) ) + Ecrire_octet(Fichier,Compteur|0xC0); + Ecrire_octet(Fichier,Last_pixel); + + } + } + + // Ecriture de l'octet (12) indiquant que la palette arrive + if (!Erreur_fichier) + Ecrire_octet(Fichier,12); + + Close_ecriture(Fichier); + + // Ecriture de la palette + if (!Erreur_fichier) + { + if (write(Fichier,Principal_Palette,sizeof(T_Palette))==-1) + Erreur_fichier=1; + } + } + else + Erreur_fichier=1; + + close(Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + + // On remet la palette à son état normal + Palette_256_to_64(Principal_Palette); + } + else + Erreur_fichier=1; +} + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// CEL //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format CEL -------------------------------- + +void Test_CEL(void) +{ + char Nom_du_fichier[256]; + int Taille; + int Fichier; + struct CEL_Header1 + { + word Width; // Largeur de l'image + word Height; // Hauteur de l'image + } Header1; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image + word Hauteur; // Hauteur de l'image + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + struct stat* Informations_Fichier =NULL; + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) + { + // Vu que ce header n'a pas de signature, il va falloir tester la + // cohérence de la dimension de l'image avec celle du fichier. + stat(Nom_du_fichier,Informations_Fichier); + Taille=(Informations_Fichier->st_size)-sizeof(struct CEL_Header1); + if ( (!Taille) || ( (((Header1.Width+1)>>1)*Header1.Height)!=Taille ) ) + { + // Tentative de reconnaissance de la signature des nouveaux fichiers + + lseek(Fichier,0,SEEK_SET); + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + if (memcmp(Header2.Signa,"KiSS",4)==0) + { + if (Header2.Kind!=0x20) + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + } + else + Erreur_fichier=1; + + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format CEL ----------------------------------------- + +void Load_CEL(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct CEL_Header1 + { + word Width; // Largeur de l'image + word Height; // Hauteur de l'image + } Header1; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image + word Hauteur; // Hauteur de l'image + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + short Pos_X; + short Pos_Y; + byte Dernier_octet=0; + long Taille_du_fichier; + struct stat* Informations_Fichier=NULL; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + if (read(Fichier,&Header1,sizeof(struct CEL_Header1))==sizeof(struct CEL_Header1)) + { + stat(Nom_du_fichier,Informations_Fichier); + Taille_du_fichier=Informations_Fichier->st_size; + if ( (Taille_du_fichier>sizeof(struct CEL_Header1)) + && ( (((Header1.Width+1)>>1)*Header1.Height)==(Taille_du_fichier-sizeof(struct CEL_Header1)) ) ) + { + // Chargement d'un fichier CEL sans signature (vieux fichiers) + Principal_Largeur_image=Header1.Width; + Principal_Hauteur_image=Header1.Height; + Ecran_original_X=Principal_Largeur_image; + Ecran_original_Y=Principal_Hauteur_image; + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); + if (Erreur_fichier==0) + { + // Chargement de l'image + Init_lecture(); + for (Pos_Y=0;((Pos_Y> 4)); + } + else + Pixel_de_chargement(Pos_X,Pos_Y,(Dernier_octet & 15)); + Close_lecture(); + } + } + else + { + // On réessaye avec le nouveau format + + lseek(Fichier,0,SEEK_SET); + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + // Chargement d'un fichier CEL avec signature (nouveaux fichiers) + + Principal_Largeur_image=Header2.Largeur+Header2.Decalage_X; + Principal_Hauteur_image=Header2.Hauteur+Header2.Decalage_Y; + Ecran_original_X=Principal_Largeur_image; + Ecran_original_Y=Principal_Hauteur_image; + Initialiser_preview(Principal_Largeur_image,Principal_Hauteur_image,Taille_du_fichier,FORMAT_CEL); + if (Erreur_fichier==0) + { + // Chargement de l'image + Init_lecture(); + + if (!Erreur_fichier) + { + // Effacement du décalage + for (Pos_Y=0;Pos_Y> 4)); + } + else + Pixel_de_chargement(Pos_X+Header2.Decalage_X,Pos_Y+Header2.Decalage_Y,(Dernier_octet & 15)); + break; + + case 8: + for (Pos_Y=0;((Pos_Y16 sont utilisées dans l'image + for (Pos_X=16;((Pos_X<256) && (!Utilisation[Pos_X]));Pos_X++); + + if (Pos_X==256) + { + // Cas d'une image 16 couleurs (écriture à l'ancien format) + + Header1.Width =Principal_Largeur_image; + Header1.Height=Principal_Hauteur_image; + + if (write(Fichier,&Header1,sizeof(struct CEL_Header1))!=-1) + { + // Sauvegarde de l'image + Init_ecriture(); + for (Pos_Y=0;((Pos_Y>4)!=0) + Erreur_fichier=1; + } + else + { + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + if (memcmp(Header2.Signa,"KiSS",4)==0) + { + if (Header2.Kind!=0x10) + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + else + Erreur_fichier=1; + } + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Lire un fichier au format KCF ----------------------------------------- + +void Load_KCF(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct KCF_Header + { + struct + { + struct + { + byte Octet1; + byte Octet2; + } Couleur[16]; + } Palette[10]; + } Buffer; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image ou nb de couleurs définies + word Hauteur; // Hauteur de l'image ou nb de palettes définies + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + byte Octet[3]; + int Indice_palette; + int Indice_couleur; + int Indice; + long Taille_du_fichier; + + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille_du_fichier=filelength(Fichier); + if (Taille_du_fichier==sizeof(struct KCF_Header)) + { + // Fichier KCF à l'ancien format + + if (read(Fichier,&Buffer,sizeof(struct KCF_Header))==sizeof(struct KCF_Header)) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + + // Chargement de la palette + for (Indice_palette=0;Indice_palette<10;Indice_palette++) + for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) + { + Indice=16+(Indice_palette*16)+Indice_couleur; + Principal_Palette[Indice].R=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 >> 4) << 2); + Principal_Palette[Indice].B=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1 & 15) << 2); + Principal_Palette[Indice].V=((Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2 & 15) << 2); + } + + for (Indice=0;Indice<16;Indice++) + { + Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; + Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; + Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; + } + + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + Erreur_fichier=1; + } + else + { + // Fichier KCF au nouveau format + + if (read(Fichier,&Header2,sizeof(struct CEL_Header2))==sizeof(struct CEL_Header2)) + { + // Initialiser_preview(???); // Pas possible... pas d'image... + + Indice=(Header2.Nbbits==12)?16:0; + for (Indice_palette=0;Indice_palette> 4) << 2; + Principal_Palette[Indice].B=(Octet[0] & 15) << 2; + Principal_Palette[Indice].V=(Octet[1] & 15) << 2; + break; + + case 24: // RRRR RRRR | VVVV VVVV | BBBB BBBB + read(Fichier,Octet,3); + Principal_Palette[Indice].R=Octet[0]>>2; + Principal_Palette[Indice].V=Octet[1]>>2; + Principal_Palette[Indice].B=Octet[2]>>2; + } + + Indice++; + } + } + + if (Header2.Nbbits==12) + for (Indice=0;Indice<16;Indice++) + { + Principal_Palette[Indice].R=Principal_Palette[Indice+16].R; + Principal_Palette[Indice].V=Principal_Palette[Indice+16].V; + Principal_Palette[Indice].B=Principal_Palette[Indice+16].B; + } + + Set_palette(Principal_Palette); + Remapper_fileselect(); + } + else + Erreur_fichier=1; + } + close(Fichier); + } + else + Erreur_fichier=1; + + if (!Erreur_fichier) Dessiner_preview_palette(); +} + + +// -- Ecrire un fichier au format KCF --------------------------------------- + +void Save_KCF(void) +{ + char Nom_du_fichier[256]; + int Fichier; + struct KCF_Header + { + struct + { + struct + { + byte Octet1; + byte Octet2; + } Couleur[16]; + } Palette[10]; + } Buffer; + struct CEL_Header2 + { + byte Signa[4]; // Signature du format + byte Kind; // Type de fichier ($10=PALette $20=BitMaP) + byte Nbbits; // Nombre de bits + word Filler1; // ??? + word Largeur; // Largeur de l'image ou nb de couleurs définies + word Hauteur; // Hauteur de l'image ou nb de palettes définies + word Decalage_X; // Decalage en X de l'image + word Decalage_Y; // Decalage en Y de l'image + byte Filler2[16]; // ??? + } Header2; + byte Octet[3]; + int Indice_palette; + int Indice_couleur; + int Indice; + dword Utilisation[256]; // Table d'utilisation de couleurs + + // On commence par compter l'utilisation de chaque couleurs + Palette_Compter_nb_couleurs_utilisees(Utilisation); + + Erreur_fichier=0; + Nom_fichier_complet(Nom_du_fichier,0); + if ((Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP))!=-1) + { + // Sauvegarde de la palette + + // On regarde si des couleurs >16 sont utilisées dans l'image + for (Indice=16;((Indice<256) && (!Utilisation[Indice]));Indice++); + + if (Indice==256) + { + // Cas d'une image 16 couleurs (écriture à l'ancien format) + + for (Indice_palette=0;Indice_palette<10;Indice_palette++) + for (Indice_couleur=0;Indice_couleur<16;Indice_couleur++) + { + Indice=16+(Indice_palette*16)+Indice_couleur; + Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet1=((Principal_Palette[Indice].R>>2)<<4) | (Principal_Palette[Indice].B>>2); + Buffer.Palette[Indice_palette].Couleur[Indice_couleur].Octet2=Principal_Palette[Indice].V>>2; + } + + if (write(Fichier,&Buffer,sizeof(struct KCF_Header))!=sizeof(struct KCF_Header)) + Erreur_fichier=1; + } + else + { + // Cas d'une image 256 couleurs (écriture au nouveau format) + + memcpy(Header2.Signa,"KiSS",4); // Initialisation de la signature + Header2.Kind=0x10; // Initialisation du type (PALette) + Header2.Nbbits=24; // Initialisation du nombre de bits + Header2.Filler1=0; // Initialisation du filler 1 (???) + Header2.Largeur=256; // Initialisation du nombre de couleurs + Header2.Hauteur=1; // Initialisation du nombre de palettes + Header2.Decalage_X=0; // Initialisation du décalage X + Header2.Decalage_Y=0; // Initialisation du décalage Y + for (Indice=0;Indice<16;Indice++) // Initialisation du filler 2 (???) + Header2.Filler2[Indice]=0; + + if (write(Fichier,&Header2,sizeof(struct CEL_Header2))!=sizeof(struct CEL_Header2)) + Erreur_fichier=1; + + for (Indice=0;(Indice<256) && (!Erreur_fichier);Indice++) + { + Octet[0]=Principal_Palette[Indice].R<<2; + Octet[1]=Principal_Palette[Indice].V<<2; + Octet[2]=Principal_Palette[Indice].B<<2; + if (write(Fichier,Octet,3)!=3) + Erreur_fichier=1; + } + } + + close(Fichier); + + if (Erreur_fichier) + remove(Nom_du_fichier); + } + else + Erreur_fichier=1; +} + + + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// SCx //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +// -- Tester si un fichier est au format SCx -------------------------------- +void Test_SCx(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + //byte Signature[3]; + struct Header + { + byte Filler1[4]; + word Largeur; + word Hauteur; + byte Filler2; + byte Plans; + } SCx_Header; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Lecture et vérification de la signature + if ((read(Handle,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + if ( (!memcmp(SCx_Header.Filler1,"RIX",3)) + && SCx_Header.Largeur && SCx_Header.Hauteur) + Erreur_fichier=0; + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format SCx ----------------------------------------- +void Load_SCx(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + word Pos_X,Pos_Y; + long Taille,Vraie_taille; + long Taille_du_fichier; + struct Header + { + byte Filler1[4]; + word Largeur; + word Hauteur; + byte Filler2; + byte Plans; + } SCx_Header; + T_Palette SCx_Palette; + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille_du_fichier=filelength(Fichier); + + if ((read(Fichier,&SCx_Header,sizeof(struct Header)))==sizeof(struct Header)) + { + Initialiser_preview(SCx_Header.Largeur,SCx_Header.Hauteur,Taille_du_fichier,FORMAT_SCx); + if (Erreur_fichier==0) + { + if (!SCx_Header.Plans) + Taille=sizeof(T_Palette); + else + Taille=sizeof(struct Composantes)*(1<>3)*SCx_Header.Plans; + Vraie_taille=(Taille/SCx_Header.Plans)<<3; + LBM_Buffer=(byte *)malloc(Taille); + HBPm1=SCx_Header.Plans-1; + Image_HAM=0; + + for (Pos_Y=0;(Pos_Y>=1; + } +} + +//// CODAGE d'une partie d'IMAGE //// + +void PI1_16p_to_8b(byte * Src,byte * Dst) +{ + int i; // Indice du pixel à calculer + word masque; // Masque de codage + word w0,w1,w2,w3; // Les 4 words bien ordonnés de la destination + + masque=0x8000; + w0=w1=w2=w3=0; + for (i=0;i<16;i++) + { + // Pour coder le pixel nøi, il faut modifier les 4 words sur leur bit + // correspondant à celui du masque + + w0|=(Src[i] & 0x01)?masque:0x00; + w1|=(Src[i] & 0x02)?masque:0x00; + w2|=(Src[i] & 0x04)?masque:0x00; + w3|=(Src[i] & 0x08)?masque:0x00; + masque>>=1; + } + Dst[0]=w0 >> 8; + Dst[1]=w0 & 0x00FF; + Dst[2]=w1 >> 8; + Dst[3]=w1 & 0x00FF; + Dst[4]=w2 >> 8; + Dst[5]=w2 & 0x00FF; + Dst[6]=w3 >> 8; + Dst[7]=w3 & 0x00FF; +} + +//// DECODAGE de la PALETTE //// + +void PI1_Decoder_palette(byte * Src,byte * Pal) +{ + int i; // Numéro de la couleur traitée + int ip; // Indice dans la palette + word w; // Word contenant le code + + // Schéma d'un word = + // + // Low High + // VVVV RRRR | 0000 BBBB + // 0321 0321 | 0321 + + ip=0; + for (i=0;i<16;i++) + { + w=((word)Src[(i*2)+1]<<8) | Src[(i*2)+0]; + + // Traitement des couleurs rouge, verte et bleue: + Pal[ip++]=(((w & 0x0007) << 1) | ((w & 0x0008) >> 3)) << 2; + Pal[ip++]=(((w & 0x7000) >> 11) | ((w & 0x8000) >> 15)) << 2; + Pal[ip++]=(((w & 0x0700) >> 7) | ((w & 0x0800) >> 11)) << 2; + } +} + +//// CODAGE de la PALETTE //// + +void PI1_Coder_palette(byte * Pal,byte * Dst) +{ + int i; // Numéro de la couleur traitée + int ip; // Indice dans la palette + word w; // Word contenant le code + + // Schéma d'un word = + // + // Low High + // VVVV RRRR | 0000 BBBB + // 0321 0321 | 0321 + + ip=0; + for (i=0;i<16;i++) + { + // Traitement des couleurs rouge, verte et bleue: + w =(((word)Pal[ip] & 0x38) >> 3) | (((word)Pal[ip] & 0x04) << 1); ip++; + w|=(((word)Pal[ip] & 0x38) << 9) | (((word)Pal[ip] & 0x04) << 13); ip++; + w|=(((word)Pal[ip] & 0x38) << 5) | (((word)Pal[ip] & 0x04) << 9); ip++; + + Dst[(i*2)+0]=w & 0x00FF; + Dst[(i*2)+1]=(w>>8); + } +} + + +// -- Tester si un fichier est au format PI1 -------------------------------- +void Test_PI1(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + int Taille; // Taille du fichier + word Res; // Résolution de l'image + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Vérification de la taille + Taille=filelength(Handle); + if ((Taille==32034) || (Taille==32066)) + { + // Lecture et vérification de la résolution + if ((read(Handle,&Res,2))==2) + { + if (Res==0x0000) + Erreur_fichier=0; + } + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format PI1 ----------------------------------------- +void Load_PI1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + word Pos_X,Pos_Y; + byte * buffer; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + // allocation d'un buffer mémoire + buffer=(byte *)malloc(32034); + if (buffer!=NULL) + { + // Lecture du fichier dans le buffer + if (read(Fichier,buffer,32034)==32034) + { + // Initialisation de la preview + Initialiser_preview(320,200,filelength(Fichier),FORMAT_PI1); + if (Erreur_fichier==0) + { + // Initialisation de la palette + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + PI1_Decoder_palette(buffer+2,(byte *)Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=320; + Principal_Hauteur_image=200; + + // Chargement/décompression de l'image + ptr=buffer+34; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + for (Pos_X=0;Pos_X<(320>>4);Pos_X++) + { + PI1_8b_to_16p(ptr,pixels+(Pos_X<<4)); + ptr+=8; + } + for (Pos_X=0;Pos_X<320;Pos_X++) + Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); + } + } + } + else + Erreur_fichier=1; + free(buffer); + } + else + Erreur_fichier=1; + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PI1 --------------------------------------- +void Save_PI1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + short Pos_X,Pos_Y; + byte * buffer; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // allocation d'un buffer mémoire + buffer=(byte *)malloc(32034); + // Codage de la résolution + buffer[0]=0x00; + buffer[1]=0x00; + // Codage de la palette + PI1_Coder_palette((byte *)Principal_Palette,buffer+2); + // Codage de l'image + ptr=buffer+34; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // Codage de la ligne + memset(pixels,0,320); + if (Pos_Y>4);Pos_X++) + { + PI1_16p_to_8b(pixels+(Pos_X<<4),ptr); + ptr+=8; + } + } + + if (write(Fichier,buffer,32034)==32034) + { + close(Fichier); + } + else // Erreur d'écriture (disque plein ou protégé) + { + close(Fichier); + remove(Nom_du_fichier); + Erreur_fichier=1; + } + // Libération du buffer mémoire + free(buffer); + } + else + { + close(Fichier); + remove(Nom_du_fichier); + Erreur_fichier=1; + } +} + + + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////// PC1 //////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +//// DECOMPRESSION d'un buffer selon la méthode PACKBITS //// + +void PC1_Decompresser_PackBits(byte * Src,byte * Dst) +{ + int is,id; // Les indices de parcour des buffers + int n; // Octet de contr“le + + for (is=id=0;id<32000;) + { + n=Src[is++]; + + if (n & 0x80) + { + // Recopier Src[is] -n+1 fois + n=257-n; + for (;(n>0) && (id<32000);n--) + Dst[id++]=Src[is]; + is++; + } + else + { + // Recopier n+1 octets littéralement + n=n+1; + for (;(n>0) && (id<32000);n--) + Dst[id++]=Src[is++]; + } + + // Contr“le des erreurs + if (n>0) + Erreur_fichier=1; + } +} + +//// COMPRESSION d'un buffer selon la méthode PACKBITS //// + +void PC1_Compresser_PackBits(byte * Src,byte * Dst,int TailleS,int * TailleD) +{ + int is; // Indice dans la source + int id; // Indice dans la destination + int ir; // Indice de la répétition + int n; // Taille des séquences + int repet; // "Il y a répétition" + + for (is=id=0;is0;n--) + Dst[id++]=Src[is++]; + } + + // On code la partie sans répétitions + if (repet) + { + // On compte la quantité de fois qu'il faut répéter la valeur + for (ir+=3;ir>=1; + } + } +} + +//// CODAGE d'une partie d'IMAGE //// + +// Transformation d'1 ligne de pixels en 4 plans de bits + +void PC1_1lp_to_4pb(byte * Src,byte * Dst0,byte * Dst1,byte * Dst2,byte * Dst3) +{ + int i,j; // Compteurs + int ip; // Indice du pixel à calculer + byte masque; // Masque de decodage + byte b0,b1,b2,b3; // Les 4 octets des plans bits sources + + ip=0; + // Pour chacun des 40 octets des plans de bits + for (i=0;i<40;i++) + { + // Pour chacun des 8 bits des octets + masque=0x80; + b0=b1=b2=b3=0; + for (j=0;j<8;j++) + { + b0|=(Src[ip] & 0x01)?masque:0x00; + b1|=(Src[ip] & 0x02)?masque:0x00; + b2|=(Src[ip] & 0x04)?masque:0x00; + b3|=(Src[ip] & 0x08)?masque:0x00; + ip++; + masque>>=1; + } + Dst0[i]=b0; + Dst1[i]=b1; + Dst2[i]=b2; + Dst3[i]=b3; + } +} + + +// -- Tester si un fichier est au format PC1 -------------------------------- +void Test_PC1(void) +{ + int Handle; // Handle du fichier + char Nom_du_fichier[256]; // Nom complet du fichier + int Taille; // Taille du fichier + word Res; // Résolution de l'image + + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=1; + + // Ouverture du fichier + Handle=open(Nom_du_fichier,O_RDONLY); + if (Handle!=-1) + { + // Vérification de la taille + Taille=filelength(Handle); + if ((Taille<=32066)) + { + // Lecture et vérification de la résolution + if ((read(Handle,&Res,2))==2) + { + if (Res==0x0080) + Erreur_fichier=0; + } + } + // Fermeture du fichier + close(Handle); + } +} + + +// -- Lire un fichier au format PC1 ----------------------------------------- +void Load_PC1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + int Taille; + word Pos_X,Pos_Y; + byte * buffercomp; + byte * bufferdecomp; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + if ((Fichier=open(Nom_du_fichier,O_RDONLY))!=-1) + { + Taille=filelength(Fichier); + // allocation des buffers mémoire + buffercomp=(byte *)malloc(Taille); + bufferdecomp=(byte *)malloc(32000); + if ( (buffercomp!=NULL) && (bufferdecomp!=NULL) ) + { + // Lecture du fichier dans le buffer + if (read(Fichier,buffercomp,Taille)==Taille) + { + // Initialisation de la preview + Initialiser_preview(320,200,filelength(Fichier),FORMAT_PC1); + if (Erreur_fichier==0) + { + // Initialisation de la palette + if (Config.Clear_palette) + memset(Principal_Palette,0,sizeof(T_Palette)); + PI1_Decoder_palette(buffercomp+2,(byte *)Principal_Palette); + Set_palette(Principal_Palette); + Remapper_fileselect(); + + Principal_Largeur_image=320; + Principal_Hauteur_image=200; + + // Décompression du buffer + PC1_Decompresser_PackBits(buffercomp+34,bufferdecomp); + + // Décodage de l'image + ptr=bufferdecomp; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // Décodage de la scanline + PC1_4pb_to_1lp(ptr,ptr+40,ptr+80,ptr+120,pixels); + ptr+=160; + // Chargement de la ligne + for (Pos_X=0;Pos_X<320;Pos_X++) + Pixel_de_chargement(Pos_X,Pos_Y,pixels[Pos_X]); + } + } + } + else + Erreur_fichier=1; + free(bufferdecomp); + free(buffercomp); + } + else + { + Erreur_fichier=1; + if (bufferdecomp) free(bufferdecomp); + if (buffercomp) free(buffercomp); + } + close(Fichier); + } + else + Erreur_fichier=1; +} + + +// -- Sauver un fichier au format PC1 --------------------------------------- +void Save_PC1(void) +{ + char Nom_du_fichier[256]; // Nom complet du fichier + int Fichier; + int Taille; + short Pos_X,Pos_Y; + byte * buffercomp; + byte * bufferdecomp; + byte * ptr; + byte pixels[320]; + + Nom_fichier_complet(Nom_du_fichier,0); + + Erreur_fichier=0; + // Ouverture du fichier + Fichier=open(Nom_du_fichier,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP); + if (Fichier!=-1) + { + // Allocation des buffers mémoire + bufferdecomp=(byte *)malloc(32000); + buffercomp =(byte *)malloc(64066); + // Codage de la résolution + buffercomp[0]=0x80; + buffercomp[1]=0x00; + // Codage de la palette + PI1_Coder_palette((byte *)Principal_Palette,buffercomp+2); + // Codage de l'image + ptr=bufferdecomp; + for (Pos_Y=0;Pos_Y<200;Pos_Y++) + { + // Codage de la ligne + memset(pixels,0,320); + if (Pos_Ypixels;