/*************************************************************************************************************************************/ /* */ /* C O M P R E S S I O N / D E C O M P R E S S I O N : */ /* */ /* */ /* Author of '$xrC/CompressionDeCompression.01$vv$I' : */ /* */ /* Jean-Francois Colonna (LACTAMME, 20130926073743). */ /* */ /*************************************************************************************************************************************/ #ifndef define_dimX_dimY /* Introduit le 20141024150620... */ # undef dimX # define nodefine_dimX int dimX; # undef dimY # define nodefine_dimY int dimY; /* Introduit le 20131122152913 apres l'introduction de 'v $xrCMesures_CDC_seules.01$vv$Z'. */ /* */ /* Le 20131212103838 {dimX,dimY} sont passes de '#define" a 'int' afin d'accelerer */ /* considerablement le processus... */ #else /* Introduit le 20131122152913 pour accelerer la decompression utilisant le programme */ /* 'v .xrC.EffectuerCompilations.01.vv.Z DeCompressionRunLengthEncoding.02$vv'... */ #endif #include "images.01.vv.I" extern int system(); extern char *getenv(); char *Fgetenv(char *variable) /* Acces a une variable d'environnement... */ { char *valeur=getenv(variable); if (valeur == 0) { fprintf(stderr,"Il manque un 'source $xrC/Definitions.01$vv$Y' (pour la variable '%s').\n",variable); exit(NOK); /* C'est beaucoup plus prudent... */ } else { } return(valeur); } #define cat \ "cat" #define CP \ "cp" #define MV \ "mv" #define DELETE \ "rm -f" #define ESPACE \ " " #define PIPE \ " | " #define REDIRECTION \ " > " #define IGNORER \ " > /dev/null 2>&1" /* Quelques commandes utiles... */ /* */ /* On notera le 20141009144749 l'espace indispensable ci-dessus devant les">"s et ce a */ /* cause du fichier 'v $xiMd/xrC_____CompressionDeCompression.01$vv$I.$m4' qui reference */ /* ce fichier d'includes... */ int EditerCommande=FAUX; int status; int CommandeSysteme(char *commande) /* Execution d'une commande systeme (fonction introduite le 20141011092502). */ { if (EditerCommande == VRAI) { fprintf(stderr,"commande : '%s'\n",commande); } else { } status=system(commande); return(status); } #define FORCAGE___COMMANDE(commande) \ CommandeSysteme(commande) #define EXECUTION_COMMANDE(commande) \ { \ if (FORCAGE___COMMANDE(commande) == OK) \ { \ } \ else \ { \ fprintf(stderr,"Erreur d'execution (%d) de la commande '%s'.\n",status,commande); \ exit(NOK); \ } \ } \ /* Execution d'une commande quelconque sous '$SH'. */ #define NOM_DU_FICHIER \ argv[1] #define DECOMPRESSEUR_ABSENT \ "" #ifdef Genere_CDC_00 /* Introduit le 20151123103407 pour plus de generalite... */ # define Compresseur___00 \ Fgetenv("SCompresseur___00") # define DeCompresseur___00 \ Fgetenv("SDeCompresseur_00") # define PostFixe_CDC__00 \ Fgetenv("PostFixe_CDC__00") /* Definition du couple {compresseur,decompresseur} 0. */ #else #endif #ifdef Genere_CDC_01 # define Compresseur___01 \ Fgetenv("SCompresseur___01") # define DeCompresseur___01 \ Fgetenv("SDeCompresseur_01") # define PostFixe_CDC__01 \ Fgetenv("PostFixe_CDC__01") /* Definition du couple {compresseur,decompresseur} 1. */ #else #endif #ifdef Genere_CDC_02 # define Compresseur___02 \ Fgetenv("SCompresseur___02") # define DeCompresseur___02 \ Fgetenv("SDeCompresseur_02") # define PostFixe_CDC__02 \ Fgetenv("PostFixe_CDC__02") /* Definition du couple {compresseur,decompresseur} 2. */ #else #endif #ifdef Genere_CDC_03 # define BCompresseur___03 \ Fgetenv("BCompresseur___03") # define BDeCompresseur___03 \ Fgetenv("BDeCompresseur_03") /* Definition du couple {compresseur,decompresseur} "Basique" 3. */ # define Compresseur___03 \ Fgetenv("SCompresseur___03") # define DeCompresseur___03 \ Fgetenv("SDeCompresseur_03") # define PostFixe_CDC__03 \ Fgetenv("PostFixe_CDC__03") /* Definition du couple {compresseur,decompresseur} 3 (introduit le 20130919212714). */ #else # define DeCompresseur___03 \ DECOMPRESSEUR_ABSENT /* Introduit le 20151123110447 a cause de la definition de 'DECOMPRESSION_2(...)' ci-apres. */ #endif #ifdef Genere_CDC_04 # define BCompresseur___04 \ Fgetenv("BCompresseur___04") # define BDeCompresseur___04 \ Fgetenv("BDeCompresseur_04") /* Definition du couple {compresseur,decompresseur} "Basique" 4. Ces definitions ont ete */ /* introduites le 20140123165006... */ # define Compresseur___04 \ Fgetenv("SCompresseur___04") # define DeCompresseur___04 \ Fgetenv("SDeCompresseur_04") # define PostFixe_CDC__04 \ Fgetenv("PostFixe_CDC__04") /* Definition du couple {compresseur,decompresseur} 4 (introduit le 20130920121800). */ #else # define DeCompresseur___04 \ DECOMPRESSEUR_ABSENT /* Introduit le 20151123110447 a cause de la definition de 'DECOMPRESSION_2(...)' ci-apres. */ #endif #ifdef Genere_CDC_05 # define Compresseur___05 \ Fgetenv("SCompresseur___05") # define DeCompresseur___05 \ Fgetenv("SDeCompresseur_05") # define PostFixe_CDC__05 \ Fgetenv("PostFixe_CDC__05") /* Definition du couple {compresseur,decompresseur} 5 (introduit le 20130925103907). */ #else #endif #ifdef Genere_CDC_06 # define Compresseur___06 \ Fgetenv("SCompresseur___06") # define DeCompresseur___06 \ Fgetenv("SDeCompresseur_06") # define PostFixe_CDC__06 \ Fgetenv("PostFixe_CDC__06") /* Definition du couple {compresseur,decompresseur} 6 (introduit le 20130925103907). */ #else #endif #ifdef Genere_CDC_07 # define Compresseur___07 \ Fgetenv("SCompresseur___07") # define DeCompresseur___07 \ Fgetenv("SDeCompresseur_07") # define PostFixe_CDC__07 \ Fgetenv("PostFixe_CDC__07") /* Definition du couple {compresseur,decompresseur} 7 (introduit le 20130925103907). */ #else #endif #ifdef Genere_CDC_08 # define Compresseur___08 \ Fgetenv("SCompresseur___08") # define DeCompresseur___08 \ Fgetenv("SDeCompresseur_08") # define PostFixe_CDC__08 \ Fgetenv("PostFixe_CDC__08") /* Definition du couple {compresseur,decompresseur} 8 (introduit le 20130925103907). */ #else #endif #ifdef Genere_CDC_09 # define Compresseur___09 \ Fgetenv("SCompresseur___09") # define DeCompresseur___09 \ Fgetenv("SDeCompresseur_09") # define PostFixe_CDC__09 \ Fgetenv("PostFixe_CDC__09") /* Definition du couple {compresseur,decompresseur} 9 (introduit le 20130925103907). */ #else #endif #ifdef Genere_CDC_0A # define Compresseur___0A \ Fgetenv("SCompresseur___0A") # define DeCompresseur___0A \ Fgetenv("SDeCompresseur_0A") # define PostFixe_CDC__0A \ Fgetenv("PostFixe_CDC__0A") /* Definition du couple {compresseur,decompresseur} A (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0B # define Compresseur___0B \ Fgetenv("SCompresseur___0B") # define DeCompresseur___0B \ Fgetenv("SDeCompresseur_0B") # define PostFixe_CDC__0B \ Fgetenv("PostFixe_CDC__0B") /* Definition du couple {compresseur,decompresseur} B (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0C # define Compresseur___0C \ Fgetenv("SCompresseur___0C") # define DeCompresseur___0C \ Fgetenv("SDeCompresseur_0C") # define PostFixe_CDC__0C \ Fgetenv("PostFixe_CDC__0C") /* Definition du couple {compresseur,decompresseur} C (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0D # define Compresseur___0D \ Fgetenv("SCompresseur___0D") # define DeCompresseur___0D \ Fgetenv("SDeCompresseur_0D") # define PostFixe_CDC__0D \ Fgetenv("PostFixe_CDC__0D") /* Definition du couple {compresseur,decompresseur} D (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0E # define Compresseur___0E \ Fgetenv("SCompresseur___0E") # define DeCompresseur___0E \ Fgetenv("SDeCompresseur_0E") # define PostFixe_CDC__0E \ Fgetenv("PostFixe_CDC__0E") /* Definition du couple {compresseur,decompresseur} E (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0F # define Compresseur___0F \ Fgetenv("SCompresseur___0F") # define DeCompresseur___0F \ Fgetenv("SDeCompresseur_0F") # define PostFixe_CDC__0F \ Fgetenv("PostFixe_CDC__0F") /* Definition du couple {compresseur,decompresseur} F (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0G # define Compresseur___0G \ Fgetenv("SCompresseur___0G") # define DeCompresseur___0G \ Fgetenv("SDeCompresseur_0G") # define PostFixe_CDC__0G \ Fgetenv("PostFixe_CDC__0G") /* Definition du couple {compresseur,decompresseur} G (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0H # define Compresseur___0H \ Fgetenv("SCompresseur___0H") # define DeCompresseur___0H \ Fgetenv("SDeCompresseur_0H") # define PostFixe_CDC__0H \ Fgetenv("PostFixe_CDC__0H") /* Definition du couple {compresseur,decompresseur} H (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0I # define Compresseur___0I \ Fgetenv("SCompresseur___0I") # define DeCompresseur___0I \ Fgetenv("SDeCompresseur_0I") # define PostFixe_CDC__0I \ Fgetenv("PostFixe_CDC__0I") /* Definition du couple {compresseur,decompresseur} I (introduit le 20140424155328). */ #else #endif #ifdef Genere_CDC_0J # define Compresseur___0J \ Fgetenv("SCompresseur___0J") # define DeCompresseur___0J \ Fgetenv("SDeCompresseur_0J") # define PostFixe_CDC__0J \ Fgetenv("PostFixe_CDC__0J") /* Definition du couple {compresseur,decompresseur} J (introduit le 20140424155328). */ #else #endif #define PostFixe_CDC__0TMP \ Fgetenv("PostFixe_CDC__0TMP") \ /* Postfixe temporaire (introduit le 20131003151635). En effet, a cause de */ \ /* 'v $xrC/CompressionPNG.01$vv$c' et de 'v $xrC/DeCompressionPNG.01$vv$c' qui ne */ \ /* savent pas gerer 'STDIN' et 'STDOUT', il n'est plus possible de programmer */ \ /* 'COMPRESSION(...)' selon : */ \ /* */ \ /* $CA FICHIER | COMPRESSION > FICHIER.POSTFIXE */ \ /* */ \ /* La solution est donc de sauvegarder le fichier avant la compression et de le */ \ /* restaurer ensuite. Il en est de meme avec 'DECOMPRESSION(...)'. */ #define COMPRESSION(Compresseur,PostFixe) \ { \ char *SPostFixe=SuppressionPostFixe(PostFixe); \ /* Ceci est du a la possibilite qu'un meme Compresseur/DeCompresseur soit utilise plusieurs */ \ /* fois sous plusieurs noms differents. Ainsi, par exemple : */ \ /* */ \ /* Compresseur___01 "bzip2 --best" */ \ /* Compresseur___08 "$Compresseur___01 ; $xrC/TransformationRotation_pPIs2.0@$vv$X" */ \ /* */ \ /* Or dans les deux cas, 'bzip2' va creer des fichiers compresses de postfixes ".bz2". Il */ \ /* est donc necessaire de distinguer les deux fichiers compresses par un deuxieme postfixe */ \ /* (par exemple '$PrePost_Neutre' et '$PrePost_Rotation_PIs2') inclus dans '$PostFixe' et */ \ /* que l'on doit eliminer provisoirement pour acceder au resultat de la compresion... */ \ EXECUTION_COMMANDE(CONCATENE_CHAINE_04(DELETE,ESPACE,NOM_DU_FICHIER,SPostFixe)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_04(DELETE,ESPACE,NOM_DU_FICHIER,PostFixe)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_06(CP,ESPACE,NOM_DU_FICHIER,ESPACE,NOM_DU_FICHIER,PostFixe_CDC__0TMP)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_03(Compresseur,ESPACE,NOM_DU_FICHIER)); \ FORCAGE___COMMANDE(CONCATENE_CHAINE_08(MV,ESPACE,NOM_DU_FICHIER,SPostFixe,ESPACE,NOM_DU_FICHIER,PostFixe,IGNORER)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_06(MV,ESPACE,NOM_DU_FICHIER,PostFixe_CDC__0TMP,ESPACE,NOM_DU_FICHIER)); \ \ if (FAUX) \ /* Ce ce qui suit a ete inhibe le 20140509074827... */ \ { \ if (LongueurFichier(CONCATENE_CHAINE_02(NOM_DU_FICHIER,PostFixe),FAUX) \ == TailleFichierCompresseLePlusCourt \ ) \ { \ fprintf(stderr,"Plusieurs compresseurs donnent la meme longueur de fichier compresse.\n"); \ /* Je note le 20140125134512 que cette situation, si elle se rencontre, pose un probleme */ \ /* dans 'v $xrC/CompressionDeCompressionOptimale.01$vv$I NETTOYAGE' qui risque de conserver */ \ /* plusieurs fichiers compresses, alors qu'il n'en faut qu'un seul... */ \ } \ else \ { \ } \ } \ else \ { \ } \ \ TailleFichierCompresseLePlusCourt=MIN2(TailleFichierCompresseLePlusCourt \ ,LongueurFichier(CONCATENE_CHAINE_02(NOM_DU_FICHIER,PostFixe),FAUX) \ ); \ } \ /* Compresssion d'un fichier... */ #define DECOMPRESSION_1(DeCompresseur,PostFixe) \ { \ if (LongueurFichier(CONCATENE_CHAINE_02(NOM_DU_FICHIER_sans_postfixe,PostFixe),FAUX) > 0) \ { \ EXECUTION_COMMANDE(CONCATENE_CHAINE_03(DELETE,ESPACE,NOM_DU_FICHIER_sans_postfixe)); \ FORCAGE___COMMANDE(CONCATENE_CHAINE_05(DeCompresseur,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,PostFixe \ ,IGNORER \ ) \ ); \ \ if (status != OK) \ { \ /* Cas des commandes telles 'bzip2', 'gzip' ou encore 'lzma' qui n'acceptent pas d'autres */ \ /* postfixes que les leurs... */ \ char *SPostFixe=SuppressionPostFixe(PostFixe); \ /* Voir le commentaire de 'COMPRESSION(...)' ci-dessus. */ \ EXECUTION_COMMANDE(CONCATENE_CHAINE_04(DELETE,ESPACE,NOM_DU_FICHIER_sans_postfixe,SPostFixe)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_07(MV,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,PostFixe,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,SPostFixe \ ) \ ); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_03(DELETE,ESPACE,NOM_DU_FICHIER_sans_postfixe)); \ EXECUTION_COMMANDE(CONCATENE_CHAINE_04(DeCompresseur,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,SPostFixe \ ) \ ); \ /* Je note le 20141009142630 que pour ces commandes l'execution de 'DeCompresseur' se */ \ /* fait donc deux fois. La consequence de cela se situe au niveau de la mesure du nombre */ \ /* d'instructions de decompression ('v $xrCD/CheckNIDC.01$vv$Y 20141009132226') qui sera */ \ /* donc pour ces commandes deux fois trop importante... */ \ } \ else \ { \ /* Cas des commandes de '$xrC'... */ \ FORCAGE___COMMANDE(CONCATENE_CHAINE_08(MV,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,PostFixe,".out",ESPACE \ ,NOM_DU_FICHIER_sans_postfixe \ ,IGNORER \ ) \ ); \ /* Mais en fait, il peut s'agir de 'bunzip2' sur '$CMAP28 -ex "picpus"-' qui alors */ \ /* accepte des fichiers de postfixe quelconque "FICHIER.POSTFIXE" et qui les decompresse */ \ /* en leur donnant le nom "FICHIER.POSTFIXE.out", d'ou ce 'MV' a priori qui s'il echoue */ \ /* ne peut pas faire de mal... */ \ } \ \ NombreDeFichiersDecompresses++; \ } \ else \ { \ } \ } \ /* DeCompresssion d'un fichier (methode 1)... */ #define DECOMPRESSION_2(DeCompresseur,PostFixe) \ { \ if (LongueurFichier(CONCATENE_CHAINE_02(NOM_DU_FICHIER_sans_postfixe,PostFixe),FAUX) > 0) \ { \ EXECUTION_COMMANDE(CONCATENE_CHAINE_03(DELETE,ESPACE,NOM_DU_FICHIER_sans_postfixe)); \ \ if ( (CompareChaines(DeCompresseur,DeCompresseur___03) == FAUX) \ && (CompareChaines(DeCompresseur,DeCompresseur___04) == FAUX) \ ) \ { \ EXECUTION_COMMANDE(CONCATENE_CHAINE_08(cat,ESPACE,NOM_DU_FICHIER_sans_postfixe,PostFixe \ ,PIPE \ ,DeCompresseur \ ,REDIRECTION,NOM_DU_FICHIER_sans_postfixe \ ) \ ); \ FORCAGE___COMMANDE(CONCATENE_CHAINE_04(DELETE,ESPACE,NOM_DU_FICHIER_sans_postfixe,PostFixe)); \ \ FORCAGE___COMMANDE(CONCATENE_CHAINE_08(MV,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,PostFixe,".out",ESPACE \ ,NOM_DU_FICHIER_sans_postfixe \ ,IGNORER \ ) \ ); \ } \ else \ { \ FORCAGE___COMMANDE(CONCATENE_CHAINE_05(DeCompresseur,ESPACE \ ,NOM_DU_FICHIER_sans_postfixe,PostFixe \ ,IGNORER \ ) \ ); \ } \ \ NombreDeFichiersDecompresses++; \ } \ else \ { \ } \ } \ /* DeCompresssion d'un fichier (methode 2)... */ #define DECOMPRESSION(DeCompresseur,PostFixe) \ { \ DECOMPRESSION_2(DeCompresseur,PostFixe); \ } \ /* DeCompresssion d'un fichier suivant la methode choisie (introduit le 20141011102105). */ extern int atoi(); #define LECTURE_FICHIER(Fichier,NombreOctets) \ { \ TypeImage *FichierV; \ int NombreOctetsALire=NombreOctets; \ int NombreOctetsCourants=INFINI; \ int NombreOctetsLus=0; \ \ FichierV=Fichier; \ \ while ((NombreOctetsALire > 0) && (NombreOctetsCourants > 0)) \ { \ NombreOctetsCourants=read(DescripteurFichierA,FichierV,NombreOctetsALire); \ /* On notera que 'NombreOctetsCourants' peut etre nul avant que 'NombreOctetsALire' soit */ \ /* lui-meme nul : c'est le cas en particulier des images "format bit" ou il y a huit */ \ /* fois moins d'octets a lire que pour les images "format octet"... */ \ NombreOctetsALire = NombreOctetsALire-NombreOctetsCourants; \ NombreOctetsLus = NombreOctetsLus+NombreOctetsCourants; \ FichierV = FichierV+NombreOctetsCourants; \ } \ /* ATTENTION : il n'y a pas de '}' afin que la variable 'NombreOctetsALire' puisse se */ \ /* propager jusqu'a 'ECRITURE_FICHIER(...)' si necessaire (comme c'est d'ailleurs le cas */ \ /* pour 'v $xrC/CompressionDeCompressionNeutre.01$vv$I NombreOctetsALire'). */ #define ECRITURE_FICHIER(Fichier,NombreOctets) \ /* ATTENTION : il n'y a pas de '{' afin que la variable 'NombreOctetsALire' puisse se */ \ /* propager jusqu'a 'ECRITURE_FICHIER(...)' si necessaire (comme c'est d'ailleurs le cas */ \ /* pour 'v $xrC/CompressionDeCompressionNeutre.01$vv$I NombreOctetsALire'). */ \ { \ int NombreOctetsAEcrire=NombreOctets; \ write(DescripteurFichierR,Fichier,NombreOctetsAEcrire); \ } \ } int LongueurChaine(char chaine[]) /* Longueur d'une chaine de caracteres non compris l'octet nul de fin de chaine... */ { int index=0; int longueur=0; while (chaine[index] != EndOfChain) { index++; longueur++; } return(longueur); } int CompareChaines(char chaine1[],char chaine2[]) /* Comparaison de deux chaines (introduit le 20141011102105). */ { int identiques=VRAI; int longueur1=LongueurChaine(chaine1); int longueur2=LongueurChaine(chaine2); if (longueur1 == longueur2) { int index=0; while (index < MIN2(longueur1,longueur2)) { if (chaine1[index] != chaine2[index]) { identiques=FAUX; } else { } index++; } } else { identiques=FAUX; } return(identiques); } #define CONCATENE_CHAINE_02(chaine1,chaine2) \ ChaineConcatene(chaine1,chaine2) #define CONCATENE_CHAINE_03(chaine1,chaine2,chaine3) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_02(chaine2,chaine3)) #define CONCATENE_CHAINE_04(chaine1,chaine2,chaine3,chaine4) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_03(chaine2,chaine3,chaine4)) #define CONCATENE_CHAINE_05(chaine1,chaine2,chaine3,chaine4,chaine5) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_04(chaine2,chaine3,chaine4,chaine5)) #define CONCATENE_CHAINE_06(chaine1,chaine2,chaine3,chaine4,chaine5,chaine6) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_05(chaine2,chaine3,chaine4,chaine5,chaine6)) #define CONCATENE_CHAINE_07(chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,chaine7) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_06(chaine2,chaine3,chaine4,chaine5,chaine6,chaine7)) #define CONCATENE_CHAINE_08(chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,chaine8) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_07(chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,chaine8)) #define CONCATENE_CHAINE_09(chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,chaine8,chaine9) \ CONCATENE_CHAINE_02(chaine1,CONCATENE_CHAINE_08(chaine2,chaine3,chaine4,chaine5,chaine6,chaine7,chaine8,chaine9)) char *ChaineConcatene(char chaine1[],char chaine2[]) /* Concatenation de deux chaines. */ { char *chaine; int Lchaine1=LongueurChaine(chaine1); int Lchaine2=LongueurChaine(chaine2); int index=0; int index1=0; int index2=0; chaine=malloc(Lchaine1+Lchaine2+1); /* On notera que le 'free(...)' correspondant est inexistant, mais cela n'est pas trop */ /* grave... */ while (chaine1[index1] != EndOfChain) { *(chaine+index)=chaine1[index1]; index++; index1++; } while (chaine2[index2] != EndOfChain) { *(chaine+index)=chaine2[index2]; index++; index2++; } *(chaine+index)=EndOfChain; return(chaine); } char *SuppressionPostFixe(char chaine1[]) /* Suppression d'un postfixe en bout de chaine. */ { char *chaine; int index; int index1=LongueurChaine(chaine1)-1; while ((chaine1[index1] != '.') && (index1 > 0)) { index1--; } chaine=malloc(index1+1); /* On notera que le 'free(...)' correspondant est inexistant, mais cela n'est pas trop */ /* grave... */ for (index=0 ; index < index1 ; index++) { *(chaine+index)=chaine1[index]; } *(chaine+index)=EndOfChain; return(chaine); } char *SuppressionPostFixes2(char chaine1[]) /* Suppression de deux postfixes en bout de chaine. */ { return(SuppressionPostFixe(SuppressionPostFixe(chaine1))); } #include <fcntl.h> #include <sys/stat.h> #define INFINI \ 2000000000 int LongueurFichier(char nom[],int message) /* Longueur (en octets) d'un fichier. */ { int DescripteurFichier=-1; int etat_fichier; struct stat file_status; int longueur=0; DescripteurFichier=open(nom,O_RDONLY); if (DescripteurFichier == -1) { if (message == VRAI) { fprintf(stderr,"Probleme avec le fichier '%s' -1-.\n",nom); } else { } } else { etat_fichier=fstat(DescripteurFichier,&file_status); if (etat_fichier != OK) { fprintf(stderr,"Probleme avec le fichier '%s' -2-.\n",nom); } else { longueur=file_status.st_size; } close(DescripteurFichier); } return(longueur); } #ifndef define_dimX_dimY /* Introduit le 20141024150620... */ # define COMPRESSION_DECOMPRESSION_DIMENSIONS_IMAGES \ { \ dimX=atoi(getenv("dimX")); \ dimY=atoi(getenv("dimY")); \ \ if (FAUX) \ /* Le 20140506161845 la validation suivante de {dimX,dimY} est (provisoirement) inhibee. */ \ /* On notera qu'elle est difficile a justifier puisque {dimX,dimY} sont variables et */ \ /* viennent de '$dimX' et de '$dimY'... */ \ /* */ \ /* En fait l'explication est dans 'v $xrC/CompressionDeCompression.01$vv$I 20131212103838'. */ \ { \ if ((dimX != dimXY) || (dimY != dimXY)) \ { \ fprintf(stderr,"Les dimensions (Dx=%d ou Dy=%d) different de %d" \ ,dimX,dimY \ ,dimXY \ ); \ fprintf(stderr," ce qui peut poser probleme -1-"); \ fprintf(stderr," (peut-etre manque-t-il un 'Sdu').\n"); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ } \ } \ else \ { \ } \ } \ /* Introduit le 20140115174921... */ #else # define COMPRESSION_DECOMPRESSION_DIMENSIONS_IMAGES \ { \ } \ /* Introduit le 20141024150620 pour accelerer la decompression utilisant le programme */ \ /* 'v .xrC.EffectuerCompilations.01.vv.Z DeCompressionRunLengthEncoding.02$vv'... */ #endif #define COMPRESSION_DECOMPRESSION_FILES(GENERATION_DU_FICHIER_R,DetruireFichierA) \ /* Avant le 20131003091513, le nom etait 'COMPRESSION_DECOMPRESSION(...)'. */ \ /* */ \ /* L'argument 'DetruireFichierA' a ete introduit le 20140115171628 a cause de l'utilisation */ \ /* de 'COMPRESSION_DECOMPRESSION_FILES(...)' pour les transformations... */ \ { \ COMPRESSION_DECOMPRESSION_DIMENSIONS_IMAGES; \ \ if (argc > 2) \ { \ fprintf(stderr,"Il y a trop d'arguments.\n"); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ int DescripteurFichierA=-1; \ int DescripteurFichierR=-1; \ \ if (argc == 2) \ /* Cas de la lecture d'un fichier : */ \ { \ int etat_fichierA; \ struct stat file_statusA; \ int detruire_fichierA=FAUX; \ \ DescripteurFichierA=open(NOM_DU_FICHIER_A,O_RDONLY); \ \ if (DescripteurFichierA == -1) \ { \ fprintf(stderr,"Probleme avec le fichierA '%s' -3-.\n",NOM_DU_FICHIER_A); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ etat_fichierA=fstat(DescripteurFichierA,&file_statusA); \ \ if (etat_fichierA != OK) \ { \ fprintf(stderr,"Probleme avec le fichierA '%s' -4-.\n",NOM_DU_FICHIER_A); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ int etat_fichierR; \ struct stat file_statusR; \ \ DescripteurFichierR=open(NOM_DU_FICHIER_R \ ,O_WRONLY|O_CREAT \ ,S_IRUSR|S_IWUSR \ ); \ \ if (DescripteurFichierR == -1) \ { \ fprintf(stderr,"Probleme avec le fichierR '%s' -5-.\n" \ ,NOM_DU_FICHIER_R \ ); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ etat_fichierR=fstat(DescripteurFichierR,&file_statusR); \ \ if (etat_fichierR != OK) \ { \ fprintf(stderr,"Probleme avec le fichierR '%s' -6-.\n" \ ,NOM_DU_FICHIER_R \ ); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ int longueur=file_statusA.st_size; \ \ GENERATION_DU_FICHIER_R; \ \ detruire_fichierA=VRAI; \ } \ \ close(DescripteurFichierR); \ } \ } \ \ close(DescripteurFichierA); \ \ if (DetruireFichierA == VRAI) \ { \ if (detruire_fichierA == VRAI) \ { \ unlink(NOM_DU_FICHIER_A); \ } \ else \ { \ } \ } \ else \ { \ } \ } \ } \ else \ { \ /* Cas de l'entree standard : */ \ int longueur=atoi(getenv("tailleI")); \ /* On notera que 'longueur' sera bien le nombre d'octets a transferer pour les images */ \ /* "format octet". Par contre, pour les images "format bit", cela sera 'longueur/8', */ \ /* mais ce fait n'est pas utilise. En effet, on 's'arrete des que 'read(...)' ne renvoie */ \ /* plus d'octets... */ \ \ DescripteurFichierA=fileno(stdin); \ DescripteurFichierR=fileno(stdout); \ \ GENERATION_DU_FICHIER_R; \ } \ } \ \ return(OK); \ /* A cause de 'v $xrC/CompressionDeCompressionOptimale.01$vv$I EXECUTION_COMMANDE' */ \ /* ce 'OK' est essentiel... */ \ } #define COMPRESSION_DECOMPRESSION_STREAMS(GENERATION_DU_FICHIER_R) \ /* Introduit le 20131003094437... */ \ { \ COMPRESSION_DECOMPRESSION_DIMENSIONS_IMAGES; \ \ if (argc != 2) \ { \ fprintf(stderr,"Il y a %d arguments, alors qu'il en faut un et un seul (le nom d'un fichier).\n",argc-1); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ FILE *DescripteurFichierA; \ FILE *DescripteurFichierR; \ \ int etat_fichierA; \ struct stat file_statusA; \ int detruire_fichierA=FAUX; \ \ DescripteurFichierA=fopen(NOM_DU_FICHIER_A,"r"); \ \ if (DescripteurFichierA == PointeurNULL) \ { \ fprintf(stderr,"Probleme avec le fichierA '%s' -7-.\n",NOM_DU_FICHIER_A); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ etat_fichierA=fstat(fileno(DescripteurFichierA),&file_statusA); \ \ if (etat_fichierA != OK) \ { \ fprintf(stderr,"Probleme avec le fichierA '%s' -8-.\n",NOM_DU_FICHIER_A); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ int etat_fichierR; \ struct stat file_statusR; \ \ DescripteurFichierR=fopen(NOM_DU_FICHIER_R,"w+"); \ \ if (DescripteurFichierR == PointeurNULL) \ { \ fprintf(stderr,"Probleme avec le fichierR '%s' -9-.\n" \ ,NOM_DU_FICHIER_R \ ); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ etat_fichierR=fstat(fileno(DescripteurFichierR),&file_statusR); \ \ if (etat_fichierR != OK) \ { \ fprintf(stderr,"Probleme avec le fichierR '%s' -10-.\n" \ ,NOM_DU_FICHIER_R \ ); \ exit(NOK); \ /* Plus prudent... */ \ } \ else \ { \ int longueur=file_statusA.st_size; \ \ GENERATION_DU_FICHIER_R; \ \ detruire_fichierA=VRAI; \ } \ \ fclose(DescripteurFichierR); \ } \ } \ \ fclose(DescripteurFichierA); \ \ if (detruire_fichierA == VRAI) \ { \ unlink(NOM_DU_FICHIER_A); \ } \ else \ { \ } \ } \ } \ \ return(OK); \ }