/*************************************************************************************************************************************/ /* */ /* C O M P R E S S I O N / D E C O M P R E S S I O N " R U N - L E N G T H E N C O D I N G 11 " */ /* E N L O N G U E U R V A R I A B L E : */ /* */ /* */ /* Nota : */ /* */ /* Ce programme est inspire de 'v $xtc/CompressionDecompression_RLE_1D.01$c'. */ /* Il y a une petite difference au sujet du compte des repetitions : */ /* */ /* */ /* $xtc/CompressionDecompression_RLE_1D.01$c */ /* */ /* Kc --> K */ /* - */ /* */ /* KKc --> KK */ /* -- */ /* */ /* KKKc --> KKK */ /* --- */ /* */ /* KKKKc --> KKKK[4] */ /* ---- */ /* */ /* KKKKKc --> KKKK[5] */ /* ---- */ /* */ /* KKKKKKc --> KKKK[6] */ /* ---- */ /* */ /* (...) */ /* */ /* KKKKK(...)K --> KKKK[255] */ /* ---- */ /* ----------- */ /* /|\ */ /* | */ /* | */ /* ------------- il n'y a que 255 caracteres 'K'. */ /* */ /* */ /* alors que : */ /* */ /* $KrC/CompressionDeCompressionRunLengthEncoding.11$vv$I */ /* */ /* Kc --> K */ /* - */ /* */ /* KKc --> KK */ /* -- */ /* */ /* KKKc --> KKK */ /* --- */ /* */ /* KKKKc --> KKKK[0] */ /* ---- */ /* */ /* KKKKKc --> KKKK[1] */ /* ---- */ /* */ /* KKKKKKc --> KKKK[2] */ /* */ /* (...) */ /* */ /* KKKKK(...)K --> KKKK[255] */ /* ---- */ /* ----------- */ /* /|\ */ /* | */ /* | */ /* ------------- il y a au total 4+255=259 caracteres 'K'. */ /* */ /* */ /* (ou [n] represente un octet contenant en binaire */ /* la valeur n comprise entre 0 et 255) ce qui est donc */ /* plus optimise. Enfin, 'c' represente un caractere */ /* different de 'K' (on notera au passage que ce caractere */ /* 'c' n'apparait pas apres une chaine de 'K's de longueur */ /* maximale car, en effet, le caractere suivant le dernier */ /* 'K' peut etre un autre caractere 'K'...). */ /* */ /* */ /* Author of '$xrC/CompressionDeCompressionRunLengthEncoding.11$vv$I' : */ /* */ /* Jean-Francois Colonna (LACTAMME, 20141216113529). */ /* */ /*************************************************************************************************************************************/ #include "CompressionDeCompressionRunLengthEncodingGeneral.01.vv.I" #define QUE_FAIRE(x) \ (0) #define NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS \ (1) #define BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS \ (256) #define BORNE_INFERIEURE_DE_REPETITIONS \ ((4)+QUE_FAIRE(NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS)) #if ((1 == 0) && (NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS == (1))) /* L'optimisation suivante est provisoirement inhibee (via le "1 == 0") car, en effet, tres */ /* paradoxalement, la decompression de l'image 'v $xiirC/OBJC.21_22.11' demande 13170953 */ /* avec cette optimisation et 13170288 sans (c'est-a-dire moins). Des tests laborieux ont */ /* montre que c'etait en fait la seule presence de la fonction 'borne_superieure(...)' qui */ /* faisait gagner 13170953-13170288=665 instructions ! */ /* */ /* Ces tests consistent a forcer : */ /* */ /* #define BORNE_SUPERIEURE_DE_REPETITIONS 255 */ /* */ /* avec (ce qui a de l'importance apparemment...) : */ /* */ /* #define LONGUEUR_MAXIMALE_DES_BUFFERS (3*longueur) */ /* */ /* Voici les resultats de la commande 'testE' suivant le test '#if' ci-dessus : */ /* */ /* #if ((1 == 0) && (...)) 'borne_superieure(...)' EST definie */ /* */ /* 13170288 */ /* 173495 */ /* 1085937 */ /* */ /* */ /* #if ((0 == 0) && (...)) 'borne_superieure(...)' N'EST PAS definie */ /* */ /* 13170953 */ /* 173468 */ /* 1085937 */ /* */ /* Via un 'DIFF' sur les deux '$c's correspondants on verifie que seule la presence ou */ /* ou l'absence de la fonction 'borne_superieure(...)' fait la difference ! */ # define BORNE_SUPERIEURE_DE_REPETITIONS \ (BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS-1) #else int borne_superieure() { int cumul=1; int compteur; for (compteur=1 ; compteur<=NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS ; compteur++) { cumul = BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS*cumul; } return(cumul-1); } # define BORNE_SUPERIEURE_DE_REPETITIONS \ borne_superieure() #endif /* Definitions des bornes : */ /* */ /* INFERIEUR a partir de laquelle on compacte, */ /* SUPERIEUR limite superieure du compactage a cause de la capacite d'un octet. */ /* */ /* On notera que si l'on utilise plus d'un octet pour stocker les nombres de repetitions, */ /* la borne inferieure doit etre augmentee, mais comment et de combien ? */ #define LONGUEUR_MAXIMALE_DES_BUFFERS \ (2*longueur) #define STORE_COMPRESSION_11(valeur) \ { \ ImageCompactee[JImageCompactee] = (valeur); \ \ if (JImageCompactee < NombreVersIndex(LONGUEUR_MAXIMALE_DES_BUFFERS)) \ { \ JImageCompactee++; \ } \ else \ { \ fprintf(stderr,"Erreur de compression/decompression (debordement de capacite) -1-\n"); \ } \ \ LImageCompactee++; \ } #define STORE_REPETITION_11(nombre) \ { \ int compteur; \ int quotient=(nombre); \ int reste; \ \ for (compteur=1 ; compteur<=NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS ; compteur++) \ { \ reste = quotient % BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS; \ quotient = quotient / BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS; \ STORE_COMPRESSION_11((TypeImage)reste); \ } \ \ if (quotient != 0) \ { \ fprintf(stderr,"Erreur de compression (debordement de capacite de repetition) -1-\n"); \ } \ else \ { \ } \ } #define COMPRESSION_RUN_LENGTH_ENCODING_11_DU_FICHIER_R \ { \ TypeImage *ImageACompacter=malloc(longueur); \ TypeImage *ImageCompactee=malloc(LONGUEUR_MAXIMALE_DES_BUFFERS); \ \ TypeImage CaracterePrecedent=0; \ int CaracterePrecedentExiste=FAUX; \ int CompteurDeRepetitions=1; \ int JImageACompacter; \ int JImageCompactee=INDEX0; \ int LImageCompactee = 0; \ \ LECTURE_FICHIER(ImageACompacter,longueur); \ \ for (JImageACompacter=INDEX0 ; JImageACompacter<=NombreVersIndex(NombreOctetsLus) ; JImageACompacter++) \ { \ TypeImage CaractereCourant=ImageACompacter[JImageACompacter]; \ \ if (CaracterePrecedentExiste == FAUX) \ { \ CaracterePrecedent = CaractereCourant; \ CaracterePrecedentExiste = VRAI; \ \ STORE_COMPRESSION_11(CaractereCourant); \ } \ else \ { \ if ( (CaractereCourant == CaracterePrecedent) \ && (CompteurDeRepetitions \ < (BORNE_SUPERIEURE_DE_REPETITIONS+BORNE_INFERIEURE_DE_REPETITIONS) \ ) \ ) \ { \ CompteurDeRepetitions++; \ \ if ( (CompteurDeRepetitions > 1) \ && (CompteurDeRepetitions <= BORNE_INFERIEURE_DE_REPETITIONS) \ ) \ { \ STORE_COMPRESSION_11(CaractereCourant); \ } \ else \ { \ } \ \ if ( (CompteurDeRepetitions >= BORNE_INFERIEURE_DE_REPETITIONS) \ && (JImageACompacter == NombreVersIndex(longueur)) \ ) \ { \ STORE_REPETITION_11(CompteurDeRepetitions-BORNE_INFERIEURE_DE_REPETITIONS); \ } \ else \ { \ } \ } \ else \ { \ if (CompteurDeRepetitions >= BORNE_INFERIEURE_DE_REPETITIONS) \ { \ STORE_REPETITION_11(CompteurDeRepetitions-BORNE_INFERIEURE_DE_REPETITIONS); \ } \ else \ { \ } \ \ STORE_COMPRESSION_11(CaractereCourant); \ \ CaracterePrecedent = CaractereCourant; \ CompteurDeRepetitions = 1; \ } \ } \ } \ \ ECRITURE_FICHIER(ImageCompactee,LImageCompactee); \ \ free(ImageCompactee); \ free(ImageACompacter); \ } #define STORE_DECOMPRESSION_11(valeur) \ { \ gSTORE_IMAGE_PLAN(ImageDecompactee,x,y,valeur); \ \ DimensionImageEffective++; \ /* Et ce afin de pouvoir traiter aussi bien des images '$TypeOctet' que '$TypeBit__' */ \ /* auquel la matrice 'ImageDecompactee' n'est pas entierement remplie et surtout n'est */ \ /* remplie pas comme on le croit, suivant un carre... */ \ \ PROGRESSION_DES_COORDONNEES; \ } #define GET_REPETITION_11(NombreDeCaracteres) \ { \ int compteur; \ int facteur=1; \ \ NombreDeCaracteres=0; \ \ for (compteur=1 ; compteur<=NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS ; compteur++) \ { \ TypeImage caractere=ImageCompactee[JImageADeCompacter]; \ NombreDeCaracteres = NombreDeCaracteres+(caractere*facteur); \ facteur = BASE_DE_NUMERATION_DES_NOMBRES_DE_REPETITIONS*facteur; \ \ if (compteur < NOMBRE_D_OCTETS_POUR_LES_NOMBRES_DE_REPETITIONS) \ { \ JImageADeCompacter++; \ } \ else \ { \ } \ } \ \ NombreDeCaracteres = NombreDeCaracteres; \ } #define REPEAT_STORE_DECOMPRESSION_11(valeur) \ { \ int nombre; \ \ int NombreDeCaracteres_ADupliquer; \ GET_REPETITION_11(NombreDeCaracteres_ADupliquer); \ \ for (nombre=1 ; nombre <= NombreDeCaracteres_ADupliquer ; nombre++) \ { \ STORE_DECOMPRESSION_11(valeur); \ } \ } #define CARACTERE_PRECEDENT_INDEFINI \ INFINI #define DECOMPRESSION_RUN_LENGTH_ENCODING_11_DU_FICHIER_R \ { \ TypeImage *ImageCompactee=malloc(longueur); \ TypeImage DEFINITION_IMAGE(ImageDecompactee,dimY,dimX); \ \ int iterer=VRAI; \ int CaracterePrecedent=CARACTERE_PRECEDENT_INDEFINI; \ /* ATTENTION : doit etre un 'int' et non pas un 'CHAR' a cause de la valeur 'INFINI'... */ \ int CompteurDeRepetitions=1; \ int DimensionImageEffective=0; \ int JImageADeCompacter=0; \ \ LECTURE_FICHIER(ImageCompactee,longueur); \ \ x=Xmin; \ y=Ymin; \ \ JImageADeCompacter = INDEX0; \ while (iterer == VRAI) \ { \ TypeImage CaractereCourant=ImageCompactee[JImageADeCompacter]; \ \ if (CompteurDeRepetitions <= BORNE_INFERIEURE_DE_REPETITIONS) \ { \ if (CompteurDeRepetitions == BORNE_INFERIEURE_DE_REPETITIONS) \ { \ REPEAT_STORE_DECOMPRESSION_11(CaracterePrecedent); \ CaracterePrecedent = CARACTERE_PRECEDENT_INDEFINI; \ CompteurDeRepetitions = 1; \ } \ else \ { \ if (CaractereCourant == CaracterePrecedent) \ { \ CompteurDeRepetitions++; \ } \ else \ { \ CaracterePrecedent = CaractereCourant; \ CompteurDeRepetitions = 1; \ } \ \ STORE_DECOMPRESSION_11(CaractereCourant); \ } \ } \ else \ { \ fprintf(stderr,"Erreur de decompression -1-\n"); \ } \ \ JImageADeCompacter++; \ if (JImageADeCompacter<=NombreVersIndex(NombreOctetsLus)) \ { \ } \ else \ { \ iterer = FAUX; \ } \ } \ \ ECRITURE_FICHIER(ImageDecompactee,DimensionImageEffective); \ \ free(ImageCompactee); \ }