LZW-Kompressor


Eine Einheit, LZW-Dateien komprimieren

Autor: IAN HUNTER

(*
Von: IAN HUNTER
Betr.: LZW-Komprimierung-Einheit
*)

Einheit IHLZW;
{-Einheit, Datenkomprimierung behandeln}
Schnittstelle
Const
StackOverFlow = 1;
DeniedWrite = 2;
Typ
GetCharFunc = Function (Var Ch: Char): Boolean;
PutCharProc = Prozedur (Ch: Char);
LZW = Object
GetChar: GetCharFunc;
PutChar: PutCharProc;
LastError: Word;
Konstruktor Init;
Funktion Get_Hash_Code (PrevC, FollC: Integer): Integer;
Prozedur Make_Table_Entry (PrevC, FollC: Integer);
Prozedur Initialize_String_Table;
Prozedur Initialize;
Funktion Lookup_String (PrevC, FollC: Integer): Integer;
Procedure Get_Char (Var C: Integer);
Prozedur Put_Char (C: Integer);
Verfahren komprimieren;
Verfahren dekomprimieren;
Ende;

Umsetzung
Const
MaxTab = 4095;
No_Prev = $7FFF;
EOF_Char =-2;
End_List =-1;
Leer =-3;

Typ
AnyStr = String;
String_Table_Entry = Datensatz
Verwendet: Boolean;
PrevChar: Integer;
FollChar: Integer;
Weiter: Integer;
Ende;

Var
String_Table: Array [0..MaxTab] von String_Table_Entry;
Table_Used: Integer;
Output_Code: Integer;
Input_Code: Integer;
If_Compressing: Boolean;

Konstruktor LZW. Init;
BEGIN
LastError: = 0;
Ende;

LZW-Funktion. Get_Hash_Code (PrevC, FollC: Integer): Integer;
Var
Index: Integer;
Index2: Integer;
BEGIN
Index: = ((PrevC SHL 5) XOR FollC) und MaxTab;
Wenn (nicht String_Table [Index]. Verwendet)
Dann
Get_Hash_Code: = Index
Sonst
BEGIN
Während (String_Table [Index]. Nächste <> End_List) zu tun
Index: = String_Table [Index]. Weiter;
Index2: = (Index + 101) und MaxTab;
Während (String_Table [Index2]. Verwendet) zu tun
Index2: = Succ (Index2) und MaxTab;
String_Table [Index]. Nächste: = Index2;
Get_Hash_Code: = Index2;
Ende;
Ende;

LZW Verfahren. Make_Table_Entry (PrevC, FollC: Integer);
BEGIN
Wenn (Table_Used < = MaxTab)
Dann
BEGIN
Mit String_Table [Get_Hash_Code (PrevC, FollC)] Do
BEGIN
Verwendet: = True;
Nächste: = End_List;
PrevChar: = PrevC;
FollChar: = FollC;
Ende;
Inc (Table_Used);
(*
IF (Table_Used > (MaxTab + 1)) dann
BEGIN
WRITELN ('Hash-Tabelle voll.');
ENDE;
*)
Ende;
Ende;

LZW Verfahren. Initialize_String_Table;
Var
Ich: Integer;
BEGIN
Table_Used: = 0;
For I: = 0 to MaxTab-Do
Mit String_Table [I] Do
BEGIN
PrevChar: = No_Prev;
FollChar: = No_Prev;
Nächste: =-1;
Verwendet: = False;
Ende;
For I: = 0 bis 255 tun
Make_Table_Entry (No_Prev, ich);
Ende;

LZW Verfahren. Initialisieren;
BEGIN
Output_Code: = leer;
Input_Code: = leer;
Initialize_String_Table;
Ende;

LZW-Funktion. Lookup_String (PrevC, FollC: Integer): Integer;
Var
Index: Integer;
Index2: Integer;
Gefunden: Boolean;
BEGIN
Index: = ((PrevC Shl 5) Xor FollC) und MaxTab;
Lookup_String: = End_List;
Wiederholen Sie die
Gefunden: = (String_Table [Index]. PrevChar = PrevC) und
(String_Table [Index]. FollChar = FollC);
Wenn (nicht gefunden)
Dann
Index: = String_Table [Index]. Weiter;
Erst gefunden oder (Index = End_List);
Wenn gefunden
Dann
Lookup_String: = Index;
Ende;

LZW Verfahren. Get_Char (Var C: Integer);
Var
Ch: Char;
BEGIN
Wenn nicht GetChar (Ch)
Dann
C: = EOF_Char
Sonst
C: = Ord (Ch);
Ende;

LZW Verfahren. Put_Char (C: Integer);
Var
Ch: Char;
BEGIN
Ch: = Chr (C);
PutChar (Ch);
Ende;

LZW.Compress des Verfahrens;
Prozedur Put_Code (Hash_Code: Integer);
BEGIN
Wenn (Output_Code = leer)
Dann
BEGIN
Put_Char ((Hash_Code Shr 4) und $FF);
Output_Code: = Hash_Code und $0F;
Ende
Sonst
BEGIN
Put_Char (((Output_Code Shl 4) und $FF0) +
((Hash_Code SHR 8) und $00F));
Put_Char (Hash_Code und $FF);
Output_Code: = leer;
Ende;
Ende;

Prozedur Do_Compression;
Var
C: Integer;
WC: Integer;
W: Integer;
BEGIN
Get_Char (C);
W: = Lookup_String (No_Prev, C);
Get_Char (C);
(C <> EOF_Char), während
BEGIN
WC: = Lookup_String (B, C);
Wenn (WC = End_List)
Dann
BEGIN
Make_Table_Entry (B, C);
Put_Code (W);
W: = Lookup_String (No_Prev, C);
Ende
Sonst
W: = WC;
Get_Char (C);
Ende;
Put_Cod e (W);
Ende;

BEGIN
If_Compressing: = True;
Initialisieren;
Do_Compression;
Ende;

LZW Verfahren. Dekomprimieren;
Const
MaxStack = 4096;
Var
Stack: Array [1..MaxStack] von Integer;
Stack_Pointer: Integer;

Verfahren-Push (C: Integer);
BEGIN
Inc (Stack_Pointer);
Stapel [Stack_Pointer]: = C;
Wenn (Stack_Pointer > = MaxStack)
Dann
BEGIN
LastError: = 1;
Ausfahrt;
Ende;
Ende;

Verfahren-Pop (Var C: Integer);
Beginnen;
Wenn (Stack_Pointer > 0)
Dann
BEGIN
C: = Stapel [Stack_Pointer];
Dec (Stack_Pointer);
Ende
Sonst
C: = leer;
Ende;

Procedure Get_Code (Var Hash_Code: Integer);
Var
Local_Buf: Integer;
BEGIN
Wenn (Input_Code = leer)
Dann
BEGIN
Get_Char (Local_Buf);
Wenn (Local_Buf = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Get_Char (Input_Code);
Wenn (Input_Code = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Hash_Code: = ((Local_Buf Shl 4) und $FF0) +
((Input_Code SHR 4) und $00F);
Input_Code: = Input_Code und $0F;
Ende
Sonst
BEGIN
Get_Char (Local_Buf);
Wenn (Local_Buf = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Hash_Code: = Local_Buf + ((Input_Code Shl 8) und $F00);
Input_Code: = leer;
Ende;
Ende;

Prozedur Do_Decompression;
Var
C: Integer;
Code: Integer;
Old_Code: Integer;
Fin_Char: Integer;
In_Code: Integer;
Last_Char: Integer;
Unbekannt: Boolean;
Temp_C: Integer;
BEGIN
Stack_Pointer: = 0;
Unbekannt: = False;
Get_Code (Old_Code);
Code: = Old_Code;
C: = String_Table [Code]. FollChar;
Put_Char (C);
Fin_Char: = C;
Get_Code (In_Code);
Während (In_Code <> EOF_Char)
BEGIN
Code: = In_Code;
Wenn (nicht String_Table [Code]. Verwendet)
Dann
BEGIN
Last_Char: = Fin_Char;
Code: = Old_Code;
Unbekannt: = TRUE;
Ende;
Während (String_Table [Code]. PrevChar <> No_Prev)
Mit Do String_Table [Code]
BEGIN
Drücken Sie (FollChar);
Wenn (LastError <> 0)
Dann
Ausfahrt;
Code: = PrevChar;
Ende;
Fin_Char: = String_Table [Code]. FollChar;
Put_Char (Fin_Char);
Pop (Temp_C);
Während (Temp_C <> leer)
BEGIN
Put_Char (Temp_C);
Pop (Temp_C);
Ende;
Wenn Unbekannte
Dann
BEGIN
Fin_Char: = Last_Char;
Put_Char (Fin_Char);
Unbekannt: = FALSE;
Ende;
Make_Table_Entry (Old_Code, Fin_Char);
Old_Code: = In_Code;
Get_Code (In_Code);
Ende;
Ende;

BEGIN
If_Compressing: = False;
Initialisieren;
Do_Decompression;
Ende;

Ende.

(* ***************************** TEST PROGRAM ****************** *)

Program LZWTest;
{Programm zum Demotest/das LZW-Objekt}
Verwendet
IHLZW; {Nur braucht das}
Var
C: LZW; {Der Star der Show; das Objekt Kompression}

{$F+} Funktion GetTheChar (Var Ch: Char): Boolean; {$F-}
{Machen Sie Ihre GetChar Routine-Erklärung, die genau so aussehen}

BEGIN
Wenn nicht Eof (Input) {Ende Eingabe?}
Dann
BEGIN
Read (Input, Ch); {Dann lesen Sie ein Zeichen in Ch und...}
GetTheChar: = True; { ... Die Rückgabe von True}
Ende
Sonst
GetTheChar: = False; {Zurück, ansonsten False}
Ende;

{$F+} Prozedur PutTheChar (Ch: Char); {$F-}
{Machen Sie Ihre PutChar Routine-Erklärung, die genau so aussehen}

BEGIN
Write (Ausgabe, Ch); {Schreiben Sie Ch in Ausgabedatei}
Ende;

BEGIN
{Open Datendateien}
Zuweisen (Eingang, ''); {Standardeingabe; erfordert Umleitung nützlich sein}
Zuweisen (Ausgang, ''); {Standardausgabe; erfordert Umleitung nützlich sein}
Zurücksetzen (Input);
Rewrite (Output);
{Nicht umhin noch--vielleicht ein Nachkomme könnte, obwohl...}
Wenn nicht C.Init
Dann
Halt;
{I/O Routinen zuweisen}
C.GetChar: = GetTheChar; {Set LZWs GetChar an Routine GetTheChar}
C.PutChar: = PutTheChar; {Set LZWs PutChar Routine PutTheChar}
{sind wir komprimiert dekomprimieren oder?}
Wenn (ParamCount = 0)
Dann
C.Compress. {Kompresse}
Sonst
C.Decompress; {Dekomprimieren}
{Alle getan!}
Ende.









LZW-Kompressor


LZW-Kompressor : Mehreren tausend Tipps, um Ihr Leben einfacher machen.


Eine Einheit, LZW-Dateien komprimieren

Autor: IAN HUNTER

(*
Von: IAN HUNTER
Betr.: LZW-Komprimierung-Einheit
*)

Einheit IHLZW;
{-Einheit, Datenkomprimierung behandeln}
Schnittstelle
Const
StackOverFlow = 1;
DeniedWrite = 2;
Typ
GetCharFunc = Function (Var Ch: Char): Boolean;
PutCharProc = Prozedur (Ch: Char);
LZW = Object
GetChar: GetCharFunc;
PutChar: PutCharProc;
LastError: Word;
Konstruktor Init;
Funktion Get_Hash_Code (PrevC, FollC: Integer): Integer;
Prozedur Make_Table_Entry (PrevC, FollC: Integer);
Prozedur Initialize_String_Table;
Prozedur Initialize;
Funktion Lookup_String (PrevC, FollC: Integer): Integer;
Procedure Get_Char (Var C: Integer);
Prozedur Put_Char (C: Integer);
Verfahren komprimieren;
Verfahren dekomprimieren;
Ende;

Umsetzung
Const
MaxTab = 4095;
No_Prev = $7FFF;
EOF_Char =-2;
End_List =-1;
Leer =-3;

Typ
AnyStr = String;
String_Table_Entry = Datensatz
Verwendet: Boolean;
PrevChar: Integer;
FollChar: Integer;
Weiter: Integer;
Ende;

Var
String_Table: Array [0..MaxTab] von String_Table_Entry;
Table_Used: Integer;
Output_Code: Integer;
Input_Code: Integer;
If_Compressing: Boolean;

Konstruktor LZW. Init;
BEGIN
LastError: = 0;
Ende;

LZW-Funktion. Get_Hash_Code (PrevC, FollC: Integer): Integer;
Var
Index: Integer;
Index2: Integer;
BEGIN
Index: = ((PrevC SHL 5) XOR FollC) und MaxTab;
Wenn (nicht String_Table [Index]. Verwendet)
Dann
Get_Hash_Code: = Index
Sonst
BEGIN
Während (String_Table [Index]. Nächste <> End_List) zu tun
Index: = String_Table [Index]. Weiter;
Index2: = (Index + 101) und MaxTab;
Während (String_Table [Index2]. Verwendet) zu tun
Index2: = Succ (Index2) und MaxTab;
String_Table [Index]. Nächste: = Index2;
Get_Hash_Code: = Index2;
Ende;
Ende;

LZW Verfahren. Make_Table_Entry (PrevC, FollC: Integer);
BEGIN
Wenn (Table_Used < = MaxTab)
Dann
BEGIN
Mit String_Table [Get_Hash_Code (PrevC, FollC)] Do
BEGIN
Verwendet: = True;
Nächste: = End_List;
PrevChar: = PrevC;
FollChar: = FollC;
Ende;
Inc (Table_Used);
(*
IF (Table_Used > (MaxTab + 1)) dann
BEGIN
WRITELN ('Hash-Tabelle voll.');
ENDE;
*)
Ende;
Ende;

LZW Verfahren. Initialize_String_Table;
Var
Ich: Integer;
BEGIN
Table_Used: = 0;
For I: = 0 to MaxTab-Do
Mit String_Table [I] Do
BEGIN
PrevChar: = No_Prev;
FollChar: = No_Prev;
Nächste: =-1;
Verwendet: = False;
Ende;
For I: = 0 bis 255 tun
Make_Table_Entry (No_Prev, ich);
Ende;

LZW Verfahren. Initialisieren;
BEGIN
Output_Code: = leer;
Input_Code: = leer;
Initialize_String_Table;
Ende;

LZW-Funktion. Lookup_String (PrevC, FollC: Integer): Integer;
Var
Index: Integer;
Index2: Integer;
Gefunden: Boolean;
BEGIN
Index: = ((PrevC Shl 5) Xor FollC) und MaxTab;
Lookup_String: = End_List;
Wiederholen Sie die
Gefunden: = (String_Table [Index]. PrevChar = PrevC) und
(String_Table [Index]. FollChar = FollC);
Wenn (nicht gefunden)
Dann
Index: = String_Table [Index]. Weiter;
Erst gefunden oder (Index = End_List);
Wenn gefunden
Dann
Lookup_String: = Index;
Ende;

LZW Verfahren. Get_Char (Var C: Integer);
Var
Ch: Char;
BEGIN
Wenn nicht GetChar (Ch)
Dann
C: = EOF_Char
Sonst
C: = Ord (Ch);
Ende;

LZW Verfahren. Put_Char (C: Integer);
Var
Ch: Char;
BEGIN
Ch: = Chr (C);
PutChar (Ch);
Ende;

LZW.Compress des Verfahrens;
Prozedur Put_Code (Hash_Code: Integer);
BEGIN
Wenn (Output_Code = leer)
Dann
BEGIN
Put_Char ((Hash_Code Shr 4) und $FF);
Output_Code: = Hash_Code und $0F;
Ende
Sonst
BEGIN
Put_Char (((Output_Code Shl 4) und $FF0) +
((Hash_Code SHR 8) und $00F));
Put_Char (Hash_Code und $FF);
Output_Code: = leer;
Ende;
Ende;

Prozedur Do_Compression;
Var
C: Integer;
WC: Integer;
W: Integer;
BEGIN
Get_Char (C);
W: = Lookup_String (No_Prev, C);
Get_Char (C);
(C <> EOF_Char), während
BEGIN
WC: = Lookup_String (B, C);
Wenn (WC = End_List)
Dann
BEGIN
Make_Table_Entry (B, C);
Put_Code (W);
W: = Lookup_String (No_Prev, C);
Ende
Sonst
W: = WC;
Get_Char (C);
Ende;
Put_Cod e (W);
Ende;

BEGIN
If_Compressing: = True;
Initialisieren;
Do_Compression;
Ende;

LZW Verfahren. Dekomprimieren;
Const
MaxStack = 4096;
Var
Stack: Array [1..MaxStack] von Integer;
Stack_Pointer: Integer;

Verfahren-Push (C: Integer);
BEGIN
Inc (Stack_Pointer);
Stapel [Stack_Pointer]: = C;
Wenn (Stack_Pointer > = MaxStack)
Dann
BEGIN
LastError: = 1;
Ausfahrt;
Ende;
Ende;

Verfahren-Pop (Var C: Integer);
Beginnen;
Wenn (Stack_Pointer > 0)
Dann
BEGIN
C: = Stapel [Stack_Pointer];
Dec (Stack_Pointer);
Ende
Sonst
C: = leer;
Ende;

Procedure Get_Code (Var Hash_Code: Integer);
Var
Local_Buf: Integer;
BEGIN
Wenn (Input_Code = leer)
Dann
BEGIN
Get_Char (Local_Buf);
Wenn (Local_Buf = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Get_Char (Input_Code);
Wenn (Input_Code = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Hash_Code: = ((Local_Buf Shl 4) und $FF0) +
((Input_Code SHR 4) und $00F);
Input_Code: = Input_Code und $0F;
Ende
Sonst
BEGIN
Get_Char (Local_Buf);
Wenn (Local_Buf = EOF_Char)
Dann
BEGIN
Hash_Code: = EOF_Char;
Ausfahrt;
Ende;
Hash_Code: = Local_Buf + ((Input_Code Shl 8) und $F00);
Input_Code: = leer;
Ende;
Ende;

Prozedur Do_Decompression;
Var
C: Integer;
Code: Integer;
Old_Code: Integer;
Fin_Char: Integer;
In_Code: Integer;
Last_Char: Integer;
Unbekannt: Boolean;
Temp_C: Integer;
BEGIN
Stack_Pointer: = 0;
Unbekannt: = False;
Get_Code (Old_Code);
Code: = Old_Code;
C: = String_Table [Code]. FollChar;
Put_Char (C);
Fin_Char: = C;
Get_Code (In_Code);
Während (In_Code <> EOF_Char)
BEGIN
Code: = In_Code;
Wenn (nicht String_Table [Code]. Verwendet)
Dann
BEGIN
Last_Char: = Fin_Char;
Code: = Old_Code;
Unbekannt: = TRUE;
Ende;
Während (String_Table [Code]. PrevChar <> No_Prev)
Mit Do String_Table [Code]
BEGIN
Drücken Sie (FollChar);
Wenn (LastError <> 0)
Dann
Ausfahrt;
Code: = PrevChar;
Ende;
Fin_Char: = String_Table [Code]. FollChar;
Put_Char (Fin_Char);
Pop (Temp_C);
Während (Temp_C <> leer)
BEGIN
Put_Char (Temp_C);
Pop (Temp_C);
Ende;
Wenn Unbekannte
Dann
BEGIN
Fin_Char: = Last_Char;
Put_Char (Fin_Char);
Unbekannt: = FALSE;
Ende;
Make_Table_Entry (Old_Code, Fin_Char);
Old_Code: = In_Code;
Get_Code (In_Code);
Ende;
Ende;

BEGIN
If_Compressing: = False;
Initialisieren;
Do_Decompression;
Ende;

Ende.

(* ***************************** TEST PROGRAM ****************** *)

Program LZWTest;
{Programm zum Demotest/das LZW-Objekt}
Verwendet
IHLZW; {Nur braucht das}
Var
C: LZW; {Der Star der Show; das Objekt Kompression}

{$F+} Funktion GetTheChar (Var Ch: Char): Boolean; {$F-}
{Machen Sie Ihre GetChar Routine-Erklärung, die genau so aussehen}

BEGIN
Wenn nicht Eof (Input) {Ende Eingabe?}
Dann
BEGIN
Read (Input, Ch); {Dann lesen Sie ein Zeichen in Ch und...}
GetTheChar: = True; { ... Die Rückgabe von True}
Ende
Sonst
GetTheChar: = False; {Zurück, ansonsten False}
Ende;

{$F+} Prozedur PutTheChar (Ch: Char); {$F-}
{Machen Sie Ihre PutChar Routine-Erklärung, die genau so aussehen}

BEGIN
Write (Ausgabe, Ch); {Schreiben Sie Ch in Ausgabedatei}
Ende;

BEGIN
{Open Datendateien}
Zuweisen (Eingang, ''); {Standardeingabe; erfordert Umleitung nützlich sein}
Zuweisen (Ausgang, ''); {Standardausgabe; erfordert Umleitung nützlich sein}
Zurücksetzen (Input);
Rewrite (Output);
{Nicht umhin noch--vielleicht ein Nachkomme könnte, obwohl...}
Wenn nicht C.Init
Dann
Halt;
{I/O Routinen zuweisen}
C.GetChar: = GetTheChar; {Set LZWs GetChar an Routine GetTheChar}
C.PutChar: = PutTheChar; {Set LZWs PutChar Routine PutTheChar}
{sind wir komprimiert dekomprimieren oder?}
Wenn (ParamCount = 0)
Dann
C.Compress. {Kompresse}
Sonst
C.Decompress; {Dekomprimieren}
{Alle getan!}
Ende.


LZW-Kompressor

LZW-Kompressor : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
LZW-Kompressor
Wiezutun
Freunden empfehlen
  • gplus
  • pinterest

Kommentar

Einen Kommentar hinterlassen

Wertung