Zum Hauptinhalt springen

10. Dekodierungsalgorithmus (Decoding Algorithm)

10. Dekodierungsalgorithmus (Decoding Algorithm)​

Der Dekodierungsalgorithmus (Decoding Algorithm), der die unkomprimierten Daten erzeugt, ist wie folgt:

Fenstergröße lesen
do
   ISLAST-Bit lesen
   if ISLAST
      ISLASTEMPTY-Bit lesen
      if ISLASTEMPTY
         aus der Schleife ausbrechen
   MNIBBLES lesen
   if MNIBBLES ist Null
      überprüfen, dass das reservierte Bit Null ist
      MSKIPLEN lesen
      alle Bits bis zur nächsten Byte-Grenze überspringen
      MSKIPLEN Bytes überspringen
      zum nächsten Meta-Block fortfahren
   else
      MLEN lesen
   if not ISLAST
      ISUNCOMPRESSED-Bit lesen
      if ISUNCOMPRESSED
         alle Bits bis zur nächsten Byte-Grenze überspringen
         MLEN Bytes komprimierter Daten als Literale kopieren
         zum nächsten Meta-Block fortfahren

   Schleife für jede drei Blockkategorien (i = L, I, D)
      NBLTYPESi lesen
      if NBLTYPESi >= 2
         Präfixcode für Blocktypen lesen, HTREE_BTYPE_i
         Präfixcode für Blockzählungen lesen, HTREE_BLEN_i
         Blockzählung lesen, BLEN_i
         Blocktyp setzen, BTYPE_i auf 0
         vorletzten und letzten Blocktyp auf 0 und 1 initialisieren
      else
         Blocktyp setzen, BTYPE_i auf 0
         Blockzählung setzen, BLEN_i auf 16777216
   NPOSTFIX und NDIRECT lesen
   Array von Literal-Kontextmodi lesen, CMODE[]
   NTREESL lesen
   if NTREESL >= 2
      Literal-Kontextkarte lesen, CMAPL[]
   else
      CMAPL[] mit Nullen füllen
   NTREESD lesen
   if NTREESD >= 2
      Distanz-Kontextkarte lesen, CMAPD[]
   else
      CMAPD[] mit Nullen füllen
   Array von Literal-Präfixcodes lesen, HTREEL[]
   Array von Insert-and-Copy-Längenpräfixcodes lesen, HTREEI[]
   Array von Distanz-Präfixcodes lesen, HTREED[]
   do
      if BLEN_I ist Null
         Blocktyp mit HTREE_BTYPE_I lesen und BTYPE_I setzen
            vorherigen Blocktyp speichern
         Blockzählung mit HTREE_BLEN_I lesen und BLEN_I setzen
      BLEN_I dekrementieren
      Insert-and-Copy-Längensymbol mit HTREEI[BTYPE_I] lesen
      Einfügelänge ILEN und Kopierlänge CLEN berechnen
      Schleife für ILEN
         if BLEN_L ist Null
            Blocktyp mit HTREE_BTYPE_L lesen und BTYPE_L setzen
               vorherigen Blocktyp speichern
            Blockzählung mit HTREE_BLEN_L lesen und BLEN_L setzen
         BLEN_L dekrementieren
         Kontextmodus CMODE[BTYPE_L] nachschlagen
         Kontext-ID CIDL aus den letzten zwei unkomprimierten Bytes berechnen
         Literal mit HTREEL[CMAPL[64*BTYPE_L + CIDL]] lesen
         Literal in unkomprimierten Stream schreiben
      if Anzahl der in der Schleife für diesen Meta-Block erzeugten
         unkomprimierten Bytes gleich MLEN ist, dann aus der Schleife
         ausbrechen (in diesem Fall wird die Kopierlänge ignoriert und
         kann einen beliebigen Wert haben)

      if Distanzcode ein implizites Null aus Insert-and-Copy-Code ist
         Rückwärtsdistanz auf letzte Distanz setzen
      else
         if BLEN_D ist Null
            Blocktyp mit HTREE_BTYPE_D lesen und BTYPE_D setzen
               vorherigen Blocktyp speichern
            Blockzählung mit HTREE_BLEN_D lesen und BLEN_D setzen
         BLEN_D dekrementieren
         Kontext-ID CIDD aus CLEN berechnen
         Distanzcode mit HTREED[CMAPD[4*BTYPE_D + CIDD]] lesen
         Distanz durch Distanz-Kurzcode-Substitution berechnen
         if Distanzcode nicht Null ist,
            und Distanz keine statische Wörterbuchreferenz ist,
            Distanz in den Ringpuffer der letzten Distanzen schieben
      if Distanz kleiner als die maximal zulässige Distanz plus eins ist
         Distanz Bytes rückwärts in den unkomprimierten Daten bewegen,
         und CLEN Bytes von dieser Position in den
         unkomprimierten Stream kopieren
      else
         statisches Wörterbuch-Wort nachschlagen, Wort wie angewiesen
         transformieren und Ergebnis in den unkomprimierten Stream kopieren
   while Anzahl unkomprimierter Bytes für diesen Meta-Block < MLEN
while not ISLAST

Wenn der Stream vor Abschluss des letzten Meta-Blocks endet, sollte der Stream als ungültig abgelehnt werden.

Beachten Sie, dass eine duplizierte Zeichenkettenreferenz auf eine Zeichenkette in einem vorherigen Meta-Block verweisen kann, d.h. die Rückwärtsdistanz kann eine oder mehrere Meta-Block-Grenzen überschreiten. Eine Rückwärtskopierdistanz wird jedoch nicht über den Anfang des unkomprimierten Streams oder die Fenstergröße hinaus verweisen; jede solche Distanz wird als Referenz auf ein statisches Wörterbuch-Wort interpretiert. Beachten Sie auch, dass die referenzierte Zeichenkette die aktuelle Position überlappen kann, zum Beispiel, wenn die letzten 2 dekodierten Bytes die Werte X und Y haben, fügt eine Zeichenkettenreferenz mit <length = 5, distance = 2> X,Y,X,Y,X zum unkomprimierten Stream hinzu.


Quelle (Source): RFC 7932, Section 10
Offizieller Text (Official Text): https://www.rfc-editor.org/rfc/rfc7932.txt