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



Copyright © Jean-François Colonna, 2014-2021.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / Ecole Polytechnique, 2014-2021.