/*************************************************************************************************************************************/
/* */
/* 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); \
}