LZW c'est cool... en francais, c'est mieux.

La compression LZW est utilisee notamment par ZIP, GZIP, ARJ etc
LZW provient des initiales des 3 auteurs Lempel, Ziv et Welch.

Par comparaison a RLE (Run Length Encoding), ou on code les
rptitions identiques, (RLE: aaaaabbbbccc => 5a4b3c), LZW permet
de coder des suites de caractres non identiques.



1) Compression


k est un caractere (peu importe le nombre de bits, bitchar,
par ex, 8) chaine est une chaine de caractere.

chaine = chaine + k signifie qu'on ajoute k a la fin de chaine, de
mme "chaine=k" initialise chaine a k. (Par exemple: chaine="LZ",
k='W', chaine+k="LZW")
Je dis ca pour que l'algo ressemble un peu au C, un peu au pascal,
un peu...

Le dictionnaire est un tableau de chaines de caractres, dont
l'indice est cod par un nombre de bits donne, ce nombre doit tre
connu lors de la dcompression, c'est gnralement 12 (bitindice).

nouveau est l'indice de la prochaine entre dans le dictionnaire.

   1. Initialisation du dictionnaire
      for(nouveau=0; nouveau<2^bitchar; nouveau++)
         dictionnaire[nouveau]=nouveau;
   /* pour bitinput = 8, dictionnaire = 0,1,2,3,4,...,254,255 */
		
   2. Lecture du premier caractere: k
      Initialisation de chaine a ce caractere, chaine = k
		
   3. Tant que (Lecture caractere suivant: k) <---+
       |                                          |
       |   4. Si (chaine+k  dictionnaire) alors  |
       |       |   chaine = chaine + k            |
       |       |   GOTO 3  /* bourk */ -----------+
       |      Fsi
       |
       |   5. ecriture du code correspondant a chaine
       |   cad du rang de chaine dans le dictionnaire
       |   sur le nombre de bits voulu (bintindice)
       |   ex: chaine="pipo", tableau[359]="pipo" => ecr de 359
       |
       |   6. dictionnaire[nouveau++] = chaine+k
       |
       |   7. chaine = k
       |
      Ftque

   8. criture du code correspondant a chaine cad du rang de
      chaine dans le dictionnaire sur le nombre de bits voulu
      (bintindice)



1.1) Exemple:


Fichier entree            Chaine reconnue            Dictionnaire
                        

LZWLZ78LZ77LZCLZMWLZAP            L                   LZ   (=256)
 ZWLZ78LZ77LZCLZMWLZAP            Z                   ZW   (=257)
  WLZ78LZ77LZCLZMWLZAP            W                   WL   (=258)
   LZ78LZ77LZCLZMWLZAP            LZ                  LZ7  (=259)
     78LZ77LZCLZMWLZAP            7                   78   (=260)
      8LZ77LZCLZMWLZAP            8                   8L   (=261)
       LZ77LZCLZMWLZAP            LZ7                 LZ77 (=262)
          7LZCLZMWLZAP            7                   7L   (=263)
           LZCLZMWLZAP            LZ                  LZC  (=264)
             CLZMWLZAP            C                   CL   (=265)
              LZMWLZAP            LZ                  LZM  (=266)
                MWLZAP            M                   MW   (=267)
                 WLZAP            WL                  WLZ  (=268)
                   ZAP            Z                   ZA   (=269)
                    AP            A                   AP   (=270)
                     P            P

     Sortie: L Z W <256> 78 <259> 7 <256> C <256> M <258> Z A P



1.2) Remarques


 * si chaine+k  dictionnaire alors chaine  dictionnaire

 * la recherche de l'appartenance de chaine au dictionnaire est
   lourde (4.)

 * on peut depasser le nombre d'entree du dictionnaire => boum
   GIF implemente une variante pour corriger ca, on reserve les
   deux premieres entrees du dictionnaires apres l'initialisation
   pour deux codes speciaux: fin de fichier, et RAZ ( on
   rinitialise le dictionnaire et on recommence )



2) Decompression


old et code sont deux indices, sur bitindice bits (cf compression)
Donc les lectures se font sur bitindice bits (generalement 12),
c'est  dire qu'il faut gerer soit meme le flux des des donnes en
entre.


   1. Initialisation de la table
      for(nouveau=0; nouveau<2^bitchar; nouveau++)
         dictionnaire[nouveau]=nouveau;

   2. Lecture ( code )

   3. Ecriture de dictionnaire[code]

   4. old = code
	
   5. Tant que (lecture code suivant)
      |
      |    6. Si (code < nouveau) /* code  dictionnaire ? */
      |       |
      |       |    ecriture(dictionnaire[code]);
      |       |    chaine = dictionnaire[old];
      |       |    k = dictionnaire[code][0];
      |       |    dictionnaire[max++] = chaine+k;
	   |       |
      |       Sinon /* cas ennuyeux voir 3.3 */
	   |       |
      |       |    chaine = dictionnaire[old];
      |       |    k = chaine[0];
      |       |    ecriture(chaine+k);
      |       |    dictionnaire[nouveau++] = chaine+k;
      |       |
      |       Fsi
      |
      |    7. old = code
      |
      Ftque



2.2) Exemple:


C = premier caractere du code (suivant).

Code suivant        C       Dictionnaire         Ecriture
        -                
     L                                              L
     Z              Z        LZ   (=256)            Z
     W              W        ZW   (=257)            W
   <256>            L        WL   (=258)            LZ
     7              7        LZ7  (=259)            7
     8              8        78   (=260)            8
   <259>            L        8L   (=261)            LZ7
     7              7        LZ77 (=262)            7
   <256>            L        7L   (=263)            LZ
     C              C        LZC  (=264)            C
   <256>            L        CL   (=265)            LZ
     M              M        LZM  (=266)            M
   <258>            W        MW   (=267)            WL
     Z              Z        WLZ  (=268)            Z
     A              A        ZA   (=269)            A
     P              P        AP   (=270)            P

       Sortie: L Z W LZ 7 8 LZ7 7 LZ C LZ M WL W A P



2.3) Cas ennuyeux


Ce cas se produit lors de la compression de chaines de type
k[...]k[...]k.

Exemple la chaine: APAPAPAPAP

Compression:

Entree                 Chaine reconnue               Dictionnaire
                                
APAPAPAPAPAP                   A                     AP    (=256)
 PAPAPAPAPAP                   P                     PA    (=257)
  APAPAPAPAP                   AP                    APA   (=258)
    APAPAPAP                   APA                   APAP  (=259)
       PAPAP                   PA                    PAP   (=260)
         PAP                   PAP

                    Sortie: A P <256> <258> <257> <260>


Decompression:

Entree              C            Dictionnaire    Ecriture
              -                
     A                                              A
     P              P            AP   (=256)        P
   <256>            A            PA   (=257)        AP
   <258>           ???

                    A            APA  (=258)        APA
   <257>            P            APAP (=259)        PA
   <260>           ???

                    P            PAP  (=260)        PAP

                    Sortie: A P AP APA PA PAP



                                         aLgoL / Psykotrope PC


Il y a pas mal de textes qui traitent de ce sujet sur le Net, mais
pas trop en francais...

