1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203:
| {$R-,G+} PROGRAM DATENKOMPRESSION_NACH_HUFFMANN; USES CRT;
TYPE STRING80=STRING[80]; ASTZEIGER=^AST; AST=RECORD ZEICHEN:BYTE; ZWEIG:ARRAY[0..1]OF ASTZEIGER END; CODE=ARRAY[0..37]OF BYTE;
VAR ANZAHL:ARRAY[0..255]OF LONGINT; STAMM:AST; CODES:ARRAY[0..255]OF CODE; START:CODE; J,K:BYTE; CH:CHAR; GESZEICHEN,AUSZEICHEN:LONGINT; DATEI1,DATEI2:STRING;
PROCEDURE AUSZAEHLEN(NAME:STRING); VAR F:FILE OF BYTE; I,WERT:BYTE; M:LONGINT; BEGIN ASSIGN(F,NAME);RESET(F); FOR I:=0 TO 255 DO ANZAHL[I]:=0; FOR M:=1 TO FILESIZE(F) DO BEGIN READ(F,WERT);INC(ANZAHL[WERT]) END; CLOSE(F) END;
PROCEDURE BINAERBAUM; VAR DUMMY:AST; I,MIN1,MIN2,GZEICHEN:BYTE; BAUM:ARRAY[0..255]OF ASTZEIGER;
PROCEDURE FINDMIN(VAR M1,M2:BYTE); VAR ANZ1,ANZ2:LONGINT; I:BYTE; BEGIN ANZ1:=MAXLONGINT;ANZ2:=ANZ1; FOR I:=0 TO 255 DO IF BAUM[I]<>NIL THEN BEGIN IF ANZ1>=ANZAHL[I] THEN BEGIN ANZ2:=ANZ1;ANZ1:=ANZAHL[I];M2:=M1;M1:=I END ELSE IF ANZ2>=ANZAHL[I] THEN BEGIN ANZ2:=ANZAHL[I];M2:=I END END END;
BEGIN GZEICHEN:=255; FOR I:=0 TO 255 DO IF ANZAHL[I]=0 THEN BEGIN BAUM[I]:=NIL;DEC(GZEICHEN) END ELSE BEGIN NEW(BAUM[I]);BAUM[I]^.ZEICHEN:=I;BAUM[I]^.ZWEIG[0]:=NIL; BAUM[I]^.ZWEIG[1]:=NIL END; FOR I:=1 TO GZEICHEN DO BEGIN FINDMIN(MIN1,MIN2); DUMMY.ZEICHEN:=MIN1;DUMMY.ZWEIG[0]:=BAUM[MIN1]; DUMMY.ZWEIG[1]:=BAUM[MIN2]; NEW(BAUM[MIN1]);BAUM[MIN1]^:=DUMMY; INC(ANZAHL[MIN1],ANZAHL[MIN2]); BAUM[MIN2]:=NIL END; I:=0; WHILE BAUM[I]=NIL DO INC(I); STAMM:=BAUM[I]^;GESZEICHEN:=ANZAHL[I] END;
PROCEDURE DEFCODE(GABEL:AST;STARTWERT:CODE); BEGIN IF (GABEL.ZWEIG[0]=NIL)AND(GABEL.ZWEIG[1]=NIL) THEN CODES[GABEL.ZEICHEN]:=STARTWERT ELSE BEGIN STARTWERT[STARTWERT[0]DIV 8+1]:=STARTWERT[STARTWERT[0]DIV 8+1] AND (255 - 1 SHL (STARTWERT[0]MOD 8)); INC(STARTWERT[0]); DEFCODE(GABEL.ZWEIG[0]^,STARTWERT); DISPOSE(GABEL.ZWEIG[0]);DEC(STARTWERT[0]); STARTWERT[STARTWERT[0]DIV 8+1]:=STARTWERT[STARTWERT[0]DIV 8+1] OR (1 SHL (STARTWERT[0]MOD 8)); INC(STARTWERT[0]); DEFCODE(GABEL.ZWEIG[1]^,STARTWERT); DISPOSE(GABEL.ZWEIG[1]); END END;
PROCEDURE CODEAUS(NAME1,NAME2:STRING); VAR WERT,BITZAEHL,I,AUSGABE:BYTE; M:INTEGER; VON,NACH:FILE OF BYTE; BEGIN BITZAEHL:=0;ASSIGN(VON,NAME1);ASSIGN(NACH,NAME2); RESET(VON);REWRITE(NACH); FOR I:=0 TO 3 DO BEGIN AUSGABE:=(GESZEICHEN SHR(24-8*I)) AND 255; WRITE(NACH,AUSGABE) END; FOR I:=0 TO 255 DO BEGIN FOR M:=0 TO CODES[I,0]-1 DO BEGIN AUSGABE:=AUSGABE SHL 2+(CODES[I,M DIV 8+1]SHR (M MOD 8)) AND 1; INC(BITZAEHL,2); IF BITZAEHL=8 THEN BEGIN WRITE(NACH,AUSGABE);BITZAEHL:=0 END END; AUSGABE:=AUSGABE SHL 2+3; INC(BITZAEHL,2); IF BITZAEHL=8 THEN BEGIN WRITE(NACH,AUSGABE);BITZAEHL:=0 END END; WHILE NOT(EOF(VON)) DO BEGIN READ(VON,WERT); FOR I:=0 TO CODES[WERT,0]-1 DO BEGIN AUSGABE:=AUSGABE SHL 1+(CODES[WERT,I DIV 8+1]SHR (I MOD 8)) AND 1; INC(BITZAEHL); IF BITZAEHL=8 THEN BEGIN WRITE(NACH,AUSGABE);BITZAEHL:=0;INC(AUSZEICHEN) END END END; IF BITZAEHL>0 THEN BEGIN FOR I:=BITZAEHL TO 7 DO AUSGABE:=AUSGABE SHL 1+1; WRITE(NACH,AUSGABE) END; AUSZEICHEN:=FILESIZE(NACH);CLOSE(VON);CLOSE(NACH); END;
PROCEDURE DEKOMPRESS(NAME1,NAME2:STRING); VAR WERT,BITZAEHL,I,AUSGABE,NP:BYTE; VON,NACH:FILE OF BYTE; DUMMY,DUMMYX:ASTZEIGER; BEGIN BITZAEHL:=8;STAMM.ZWEIG[0]:=NIL;STAMM.ZWEIG[1]:=NIL;DUMMY:=@STAMM; ASSIGN(VON,NAME1);ASSIGN(NACH,NAME2);RESET(VON);REWRITE(NACH); READ(VON,WERT);GESZEICHEN:=WERT; READ(VON,WERT);GESZEICHEN:=GESZEICHEN SHL 8+WERT; READ(VON,WERT);GESZEICHEN:=GESZEICHEN SHL 8+WERT; READ(VON,WERT);GESZEICHEN:=GESZEICHEN SHL 8+WERT; READ(VON,WERT); FOR I:=0 TO 255 DO BEGIN WHILE ((WERT SHR(BITZAEHL-1)) AND 1)=0 DO BEGIN NP:=(WERT SHR(BITZAEHL-2)) AND 1; IF DUMMY^.ZWEIG[NP]=NIL THEN BEGIN NEW(DUMMYX); DUMMY^.ZWEIG[NP]:=DUMMYX;DUMMYX^.ZWEIG[0]:=NIL; DUMMYX^.ZWEIG[1]:=NIL END; DUMMY:=DUMMY^.ZWEIG[NP]; DEC(BITZAEHL,2); IF BITZAEHL=0 THEN BEGIN READ(VON,WERT);BITZAEHL:=8 END END; DUMMY^.ZEICHEN:=I;DUMMY:=@STAMM; DEC(BITZAEHL,2); IF BITZAEHL=0 THEN BEGIN READ(VON,WERT);BITZAEHL:=8 END END; AUSZEICHEN:=0; WHILE AUSZEICHEN<GESZEICHEN DO BEGIN IF BITZAEHL=0 THEN BEGIN READ(VON,WERT);BITZAEHL:=8 END; DUMMY:=DUMMY^.ZWEIG[(WERT SHR(BITZAEHL-1))AND 1]; IF (DUMMY^.ZWEIG[0]=NIL) AND (DUMMY^.ZWEIG[1]=NIL) THEN BEGIN WRITE(NACH,DUMMY^.ZEICHEN);DUMMY:=@STAMM;INC(AUSZEICHEN) END; DEC(BITZAEHL) END; CLOSE(VON);CLOSE(NACH) END;
BEGIN CLRSCR;WRITE('Name der "Von" - Datei : ');READLN(DATEI1); WRITE('Name der "Nach" - Datei : ');READLN(DATEI2); WRITE('Soll (K)omprimiert oder (D)ekomprimiert werden : '); REPEAT CH:=UPCASE(READKEY) UNTIL CH IN['D','K'];WRITELN(CH); IF CH='K' THEN BEGIN AUSZAEHLEN(DATEI1);WRITELN('Ausgezählt...'); BINAERBAUM;WRITELN('Bin„rbaum steht...'); FOR J:=0 TO 32 DO START[J]:=0; FOR J:=0 TO 255 DO CODES[J]:=START; DEFCODE(STAMM,START); WRITELN('Codierungen zugeordnet...'); CODEAUS(DATEI1,DATEI2); WRITELN('Code auf Festplatte...'); WRITELN('Kompression : ',100-AUSZEICHEN/GESZEICHEN*100:0:2,'%'); END ELSE BEGIN DEKOMPRESS(DATEI1,DATEI2); WRITE('Dekompression erfolgt...') END; WRITE('Drücke eine Taste');CH:=READKEY END. |