From 03c0b0d20aed664372cfcfe0ff5a71de611fe5fa Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Thu, 29 Jan 2009 19:59:13 +0000 Subject: [PATCH] PNG saving. Text data are saved: 'Software'='GrafX2', 'Title'= git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@573 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- loadsave.c | 223 ++++++++++++++++++++++------------------------------- 1 file changed, 93 insertions(+), 130 deletions(-) diff --git a/loadsave.c b/loadsave.c index 7aa762b6..8f3f4689 100644 --- a/loadsave.c +++ b/loadsave.c @@ -125,7 +125,7 @@ T_Format FormatFichier[NB_FORMATS_CONNUS] = { {"cel", Test_CEL, Load_CEL, Save_CEL, 1, 0}, {"kcf", Test_KCF, Load_KCF, Save_KCF, 0, 0}, {"pal", Test_PAL, Load_PAL, Save_PAL, 0, 0}, - {"png", Test_PNG, Load_PNG, Save_PNG, 1, 0} + {"png", Test_PNG, Load_PNG, Save_PNG, 1, 1} }; // Taille de fichier, en octets @@ -5531,6 +5531,26 @@ void Load_PNG(void) if (bit_depth <= 8 && (color_type == PNG_COLOR_TYPE_PALETTE || PNG_COLOR_TYPE_GRAY)) { + int num_text; + png_text *text_ptr; + + // Commentaire + Principal_Commentaire[0]='\0'; // On efface le commentaire + if ((num_text=png_get_text(png_ptr, info_ptr, &text_ptr, NULL))) + { + while (num_text--) + { + if (!strcmp(text_ptr[num_text].key,"Title")) + { + int Taille; + Taille = Min(text_ptr[num_text].text_length, TAILLE_COMMENTAIRE); + strncpy(Principal_Commentaire, text_ptr[num_text].text, Taille); + Principal_Commentaire[Taille]='\0'; + break; // Pas besoin de vérifier les suivants + } + } + } + Initialiser_preview(info_ptr->width,info_ptr->height,Taille_du_fichier,FORMAT_PNG); if (Erreur_fichier==0) @@ -5538,7 +5558,7 @@ void Load_PNG(void) int x,y; png_colorp palette; int num_palette; - + if (color_type == PNG_COLOR_TYPE_GRAY) { if (bit_depth < 8) @@ -5553,7 +5573,7 @@ void Load_PNG(void) } else { - // conversion des fichiers de moins de 256 couleurs + // image couleurs if (bit_depth < 8) { png_set_packing(png_ptr); @@ -5577,7 +5597,6 @@ void Load_PNG(void) Principal_Largeur_image=info_ptr->width; Principal_Hauteur_image=info_ptr->height; Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); - Principal_Commentaire[0]='\0'; // On efface le commentaire png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); @@ -5630,153 +5649,97 @@ void Save_PNG(void) { char Nom_du_fichier[TAILLE_CHEMIN_FICHIER]; FILE *Fichier; - T_Header_PKM Head; - dword Compteur_de_pixels; - dword Taille_image; - word Compteur_de_repetitions; - byte Derniere_couleur; - byte Valeur_pixel; - byte Taille_commentaire; - - - - // Construction du header - memcpy(Head.Ident,"PKM",3); - Head.Methode=0; - Trouver_recon(&Head.Recon1,&Head.Recon2); - Head.Largeur=Principal_Largeur_image; - Head.Hauteur=Principal_Hauteur_image; - memcpy(Head.Palette,Principal_Palette,sizeof(T_Palette)); - Palette_256_to_64(Head.Palette); - - // Calcul de la taille du Post-Header - Head.Jump=9; // 6 pour les dimensions de l'ecran + 3 pour la back-color - Taille_commentaire=strlen(Principal_Commentaire); - if (Taille_commentaire) - Head.Jump+=Taille_commentaire+2; - - + int y; + byte * PixelPtr; + png_structp png_ptr; + png_infop info_ptr; + Nom_fichier_complet(Nom_du_fichier,0); - Erreur_fichier=0; - + row_pointers = NULL; + // Ouverture du fichier if ((Fichier=fopen(Nom_du_fichier,"wb"))) { - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - Head.Largeur = SDL_Swap16(Head.Largeur); - Head.Hauteur = SDL_Swap16(Head.Hauteur); - Head.Jump = SDL_Swap16(Head.Jump); -#endif - - // Ecriture du header - if (write_bytes(Fichier,&Head,sizeof(T_Header_PKM))) + /* initialisation */ + if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) + && (info_ptr = png_create_info_struct(png_ptr))) { - Init_ecriture(); - - // Ecriture du commentaire - // (Compteur_de_pixels est utilisé ici comme simple indice de comptage) - if (Taille_commentaire) - { - Ecrire_octet(Fichier,0); - Ecrire_octet(Fichier,Taille_commentaire); - for (Compteur_de_pixels=0; Compteur_de_pixels>8); - Ecrire_octet(Fichier,Hauteur_ecran&0xFF); - Ecrire_octet(Fichier,Hauteur_ecran>>8); - // Ecriture de la back-color - Ecrire_octet(Fichier,2); - Ecrire_octet(Fichier,1); - Ecrire_octet(Fichier,Back_color); - - // Routine de compression PKM de l'image - Taille_image=(dword)(Principal_Largeur_image*Principal_Hauteur_image); - Compteur_de_pixels=0; - Valeur_pixel=Lit_pixel_de_sauvegarde(0,0); - - while ( (Compteur_de_pixels=Taille_image) break; - Valeur_pixel=Lit_pixel_de_sauvegarde(Compteur_de_pixels % Principal_Largeur_image,Compteur_de_pixels / Principal_Largeur_image); - } + png_set_IHDR(png_ptr, info_ptr, Principal_Largeur_image, Principal_Hauteur_image, + 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - if ( (Derniere_couleur!=Head.Recon1) && (Derniere_couleur!=Head.Recon2) ) - { - if (Compteur_de_repetitions==1) - Ecrire_octet(Fichier,Derniere_couleur); - else - if (Compteur_de_repetitions==2) + png_set_PLTE(png_ptr, info_ptr, (png_colorp)Principal_Palette, 256); { - Ecrire_octet(Fichier,Derniere_couleur); - Ecrire_octet(Fichier,Derniere_couleur); + // Commentaires texte PNG + // Cette partie est optionnelle + png_text text_ptr[2] = { + {-1, "Software", "Grafx2", 6}, + {-1, "Title", NULL, 0} + }; + int Nb_texte=1; + if (Principal_Commentaire[0]) + { + text_ptr[1].text=Principal_Commentaire; + text_ptr[1].text_length=strlen(Principal_Commentaire); + Nb_texte=2; + } + png_set_text(png_ptr, info_ptr, text_ptr, Nb_texte); + } + png_write_info(png_ptr, info_ptr); + + /* ecriture des pixels de l'image */ + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * Principal_Hauteur_image); + PixelPtr = (Lit_pixel_de_sauvegarde==Lit_pixel_dans_ecran_courant)?Principal_Ecran:Brosse; + for (y=0; y2) && (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); - } + Erreur_fichier=1; } 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); - } - } + Erreur_fichier=1; } - - Close_ecriture(Fichier); + else + { + Erreur_fichier=1; + } + png_destroy_write_struct(&png_ptr, &info_ptr); } else Erreur_fichier=1; + // fermeture du fichier fclose(Fichier); } - else - { - Erreur_fichier=1; - fclose(Fichier); - } + // S'il y a eu une erreur de sauvegarde, on ne va tout de même pas laisser // ce fichier pourri traîner... Ca fait pas propre. if (Erreur_fichier) remove(Nom_du_fichier); + + if (row_pointers) + { + free(row_pointers); + row_pointers=NULL; + } }