Mein Format Codieren

Die Umwandlung eines BMP-Bildes in ein DSO/TRN (Abklatsch des JPG-Formates) 


1.0 Einleitung

Eine genaue Ausprogrammierung des JPG- Formates war leider nicht möglich, da eine gute Beschreibung des Formates nicht aufzutreiben war. Ich hatte zwar eine C-Version, doch erstens war diese Version wieder an DOS angepasst. Und wer C kennt, versteht, daß eine 600KB Ausprogrammierung eine Lesezeit von etwa einem Monat erwartet. Die Programmierung eines Formates kann so nicht erfolgen. Das Verständnis des Formates erfordert jede Einzelheit, da eine Optimierung sonst nicht möglich wird. So kam es jedenfall zu einem eigenständigem Format. Dieses Format wurde vom Algorithmus ähnlich dem JPG aufgebaut, jedoch mit folgenden Unterschieden: Es sei zu sagen, daß die Kompressionsrate im Vergleich zur Qualität dem  JPG leider nachsteht, da eine Einarbeitung in die Huffmancodierung zeitlich nicht mehr möglich war. Ich glaube hier (Huffmancodierung) liegt auch noch ein anderes großes
Manko, denn die Huffman- Tabellen sind nicht im File gespeichert. So wird dieses Format eigentlich schwer änderbar und nur in sich kompatibel sein


2.0 Die schrittweise Umwandlung von BMP nach DSO bzw. TRN

Die Umwandlung eines 24bit Bildes in ein DSO bzw TRN- Format erfolgt schrittweise. Die Unterteilung der Schritte ist hier kurz dargestellt.

2.1  Der 1. Schritt, Umwandlung eines RGB- Bildes in ein YUV(4:1:1)- Bild

Die Vorlage zum Packen ist ein ganz normales 24bit BMP-Bild. Dieses Bild wird blockweise gelesen. Ein Bildblock besteht aus 16 Zeilen. Falls der letzte Block kleiner als 16 Zeilen ist, werden die restlichen Zeilen mit der zuletzt gelesenen Zeile aufgefüllt. Damit wird der Fehler am kleinsten gehalten, und eine höhere Packrate wird erzielt, weil wahrscheinlich somit die geringste Änderungen vorhanden ist. Der gelesene 16 Zeilenblock wird nun in kleinere Blöcke unterteilt. Diese kleineren Blöcke nenne ich MCU-Block Eine MCU besteht aus 16 * 16 Pixeln. Sollte die letzte MCU nicht vollständig gefüllt sein (Zeilenlänge mod 16 <> 0), so wird die MCU mit der letzten Pixelspalte gefüllt, um den geringsten Fehler herzustellen. Zusammengefaßt kann man sagen: "Ein Bild wird in 16 * 16 Pixel- Matrizen aufgeteilt". Diese MCU wird wiederum in vier 8 * 8- Matrizen zerlegt. (Die 8 * 8 Matrizen sind für die Cosinustransformation. Wir brauchen vier 8 * 8 RGB-Matrizen. Da aus vier
8 * 8 RGB-Matrizen vier 8 * 8 Y-Matrizen werden und je eine 8 * 8 U-Matrix und eine 8 * 8 V-Matrix. Also kann damit immer eine vollständige 8 * 8 Matrix bei der Umwandlung entstehen.) Jede 8 * 8 RGB-Matrize wird dann als sechzehn je
2 * 2 Pixel- Matrizen betrachtet. Nun warum das Ganze zerlegen? Eine schrittweise Erklärung erfolgt.

Der erste Umwandlungsschritt ist die YUV-Zerlegung. YUV ist ein Farbmodell, das wie das RGB-Modell aus drei Komponenten besteht. Das RGB-Modell geht von der Intensität der 3 Komponenten Rot,Grün und Blau aus. Ein Pixel, der z.B. voll Rot ist, hat somit  Rot=255, Grün=O, Blau=O. Die Farbe Weiß ist ein Gemisch mit Rot=255, Blau=255 und Grün=255. Bei Schwarz sind die drei Komponenten auf Null usw. Das YUV-Modell legt Wert auf die Helligkeit eines Pixels,den Rot und den Blauanteil. (Y=Helligkeit, U=Blaukomponente und V ist die Rotkomponente). Worin liegt der Sinn des Ganzen? Das rnenschlich Auge ist 10mal empfinlicher auf Helligkeitsunterschiede als auf Farbunterschiede. Außerdem wird die Farbe Grün am stärksten wahrgenommen. (Das Auge ist am empfindlichsten auf Frequenzen im Grünbereich). Eine Umwandlung von RGB nach YUV wird formelmäßig später beschrieben. Durch diese Umwandlung wir nichts verändert, außer die Wertebedeutung. Jedoch kann man die Farbinformationen ein wenig "ausdünnen". Wir nehmen 4 beieinanderliegende Pixel, und wandeln die Pixel ins YUV. So entstehen 4 Y,4 U, 4 V Werte. Aus den 4 U-Werten bilde ich den Mittelwert und reduziere ihn auf eine Blaukomponente je 4Pixel. Das gleiche wird mit der Rotkomponente durchgeführt. Damit wäre der 1.Schritt getan. Aus je 4 RGB-Werten werden 4Y- ein U- und ein V Wert. Dieses Format nennt sich YUV 4:1:1. Das ungeübte Auge erkennt nach einer Rückwandlung bzw.Darstellung keinen Unterschied. Bei genauer Betrachtung fällt es aber doch auf und zwar bei harten Farbübergängen.
 

Vollständige MCU in einem RGB-Bild-Ausschnitt
 
EE EF
FE FF
 
 
E0 E1
F0 F1
E2 E3
F2 F3
E4 E5
F4 F5
E6 E7
F6 F7
 
 
E8 E9
F8 F9
EA EB
FA FB
EC ED
FC FD
EE EF
FE FF
 
 
E0 E1
F0 F1
 
 
0E 0F
1E 1F
2E 2F
3E 3F
4E 4F
5E 5F
6E 6F
7E 7F
 
 
00 11
10 11
02 03
12 13
04 05 14 15
06 07
16 17
20 21
30 31
22 23
32 33
24 25
34 35
26 27
36 37
40 41
50 51
42 43
52 53
44 45
54 55
46 47
56 57
60 61
70 71
62 63
72 73
64 65
74 75
66 67
76 77
 
 
08 19
18 19
0A 0B
1A 1B
0C 0D 1C 1D
0E 0F
1E 1F
28 29
38 39
2A 2B
3A 3B
2C 2D
3C 3D
2E 2F
3E 3F
48 49
58 59
4A 4B
5A 5B
4C 4D
5C 5D
4E 4F
5E 5F
68 69
78 79
6A 6B
7A 7B
6C 6D
7C 7D
6E 6F
7E 7F
 
 
00 11
10 11
20 21
30 31
40 41
50 51
60 61
70 71
 
 
8E 8F
9E 9F
AE AF
BE BF
CE CF
DE DF
EE EF
FE FF
 
 
80 81
90 91
82 83
92 93
84 85 94 95
86 87
96 97
A0 A1
B0 B1
A2 A3
B2 B3
A4 A5
B4 B5
A6 A7
B6 B7
C0 C1
D0 D1
C2 C3
D2 D3
C4 C5
D4 D5
C6 C7
D6 D7
E0 E1
F0 71
E2 E3
F2 F3
E4 E5
F4 F5
E6 E7
F6 F7
 
 
88 89
98 99
8A 8B
9A 9B
8C 8D 9C 9D
8E 8F
9E 9F
A8 A9
B8 B9
AA AB
BA BB
AC AD
BC BD
AE AF
BE BF
C8 C9
D8 D9
CA CB
DA DB
CC CD
DC DD
CE CF
DE DF
E8 E9
F8 F9
EA EB
FA FB
EC ED
FC FD
EE EF
FE FF
 
 
80 81
90 91
A0 A1
B0 B1
C0 C1
D0 D1
E0 E1
F0 F1
 
 
0E 0F
1E 1F
 
 
00 01
10 11
02 03
12 13
04 05
14 15
06 07
16 17
 
 
08 09
18 19
0A 0B
1A 1B
0C 0D
1C 1D
0E 0F
1E 1F
 
 
00 01
10 11
 


2.1.1 Programmtechnische Umsetzung

Es werden mit einem Mal vier 4 * 4 RGB-Pixel in das YUV-Format umgerechnet, da sich das leichter rechnen läßt und einen
geringeren Proceduren- Overhead verursacht. Man könnte auch eine ganze 8 * 8 Matrix berechnen. Doch dann wird der Programmcode nur wesentlich größer und vielleicht nur geringfügig schneller.
 
Quelle ist das RGB- Bild
 
P00
P01
P02
P03
P04
P05
P06
P07
P10
P11
P12
P13
P14
P15
P16
P17
 
Punkt bestehen aus Rot Grün Blau Komponenten 
Pxy = Rxy + Gxy + Bxy = 3Bytes je Punkt 
¼ Ausschnitt aus der 
ersten 8 * 8 RGB- Matrix

nach der Umwandlung entsteht das YUV- Bild
 
Y00
Y01
Y02
Y03
Y04
Y05
Y06
Y07
Y10
Y11
Y12
Y13
Y14
Y15
Y16
Y17
 
¼- Ausschnitt aus der Y- Matrix = 1Bye je Punkt(Y)
 
U00
U01
U02
U03
 
Farbwert der Blaukomponenten (1/16- Ausschnitt der U- Matrix) 1Byte je 4Punkte
 
V00
V01
V02
V03
 
Farbwert der Rotkomponenten (1/16- Ausschnitt der V- Matrix) 1Byte je 4Punkte

2.1.2 Umwandlungformel von RGB > YUV

 
Y := 0.299 * R + 0.587 * G + 0.114 * B maxY= +255.000  minY=  0.000
U := B-Y maxU= +225.930  minU= -225.930
V := R-Y maxV= +178.755 minV= -178.755
U und V liegen im Integerbereich. Daraus folgt eine Skalierung der Größen in den Shortint- Bereich. Da Shortint im Bereich -128 bis 127 liegt, folgt eine Sklaierung mit dem kleinsten Skaler 127/???, da 128/??? aus dem shortint Maximum führen würde. So wird dann U mit 127/225.93 scaliert und V wird logischerweise mit 127/178.755 skaliert. Im Min- Bereich geht nach der Skalierung der Min-Wert bis minimal -127. Man verschenkt somit einen Wert,deshalb  könnte man mit ein wenig Aufwand diesen Wert retten, aber ich glaube, das lohnt sich nicht da ich so schon gegen das Zeitproblem ankämpfe. Die FPU wurde bei der Procedure auf die Strafbank gesetzt, da die Gleitkomma- Arithmetik wie immer zu langsam ist. Die Brüche z.B. 0.299 100/299 wurden auf Brüche mit 2^n im Nenner umgestellt, da mit der CPU das leichter zu rechnen ist. Mit allen Mühen und Statistischen Messungen, d.h ich habe die FPU-Werte und die Integer-Werte verglichen, habe ich minimale Abweichungen mit 16bit Befehlen erreicht. 9999 Werte von 10000 sind nach den Messungen zu folge richtig gerundet worden. Daraus folgt die maximale Abweichung von rund ±0.75 und im Durchschnitt bei rund ±0.2, das gilt für Y, U und V.Ich finde, daß dies eine beachtliche Leistung für Integeroperationen ist.


2.2 Aus einer 8 * 8 Y-Matrix wird eine 8 * 8 DCC-Matrix

Formel: Cosinus Transformation = F(u,v) =  c(u) * c(v) / 4*-(x=0-7)(y=0-7)f(x,y)cos(pi*u(2x+1)/16)cos(pi*v(2x+1)/16)
 für u,v=0,1,2,3,4,5,6,7;
c(?) = 1/2, wenn ?=0; sonst c(?) =0;

Dies ist eine sehr umständliche Formel und erfordert eine Menge Berechnungszeit. Es kann aus der Formel durch genaues Hinsehen (mathematische Ironie "... und wie man leicht sieht ...") eine Matrizenmultiplikation hergeleitet werden, die das Ganze beschleunigt und übersichtlich macht. Wie folgt: F = DCT * Y * DCT ' (DCT ' ist die transponierte DCT, d.h. DCT=(DCT')'; DCT ist eine Koeffizienten- Matrix; eine Matrize mit vorberechneten Cosinuswerten). Die Punkte der 8 * 8 Y-Matrix werden durch eine "nur" zweifache Matrizenmultiplikation berechnet. Es werden dazu 2 Koeffizientenmatrizen erstellt, die wie folgt berechnet werden (allgemeine Formel für N * N-Matrix).
 DCT i,j = 1/N; wenn i (die Zeile) =0, sonst
 DCT i,j = 1/N* cos[(2j+1)* i * pi / 2N], wenn i>0;
 in unserem Fall ist N=8, dh: i, j laufen von 0..7
 
Dies ist ein Ausschnitt der DCT
DCT =   
.
   
.
|
+0.3535 +0.3535 ..... +0.3535 |
|
+0.4904 +0.4157 -0.4904 |
|
:
:
:
:
|
|
+0.0975 -0.2777 ..... -0.0975 |
'
   
´
 


Die Multiplikationen der Matrix habe ich in einer Assemblerlösung vollzogen, da eine FPU-Lösung zu langsam wäre..

Pascal- Programm mit FPU -Lösung
 var d:array[0..7,0..7] of real; --- Die DCT Matrix ---
     t:array[0..7,0..7] of real; --- Die DCT'- Matrix ---
     Y:array[0..7,0..7] of byte; --- Die Y Matrix ---
     e:array[0..7,0..7] of real; --- ein zwischen Ergebnis
     f:array[0..7,0..7] of real; --- Das Endergebnis
     1s,lz,tm:integer;           --- Ein paar Laufvariablen

 begin
 for ls:=0 to 7 do d[0][ls]:=1/sqrt(8);             --- 0. Zeile der DCT
 for 1z:=1 to 7 do for 1s:=0 to 7 do                --- 1-7. Zeile der DCT
  d[lz][ls]:=sgrt(2/8)*cos((2*ls+1)*lz*pi/(2*8));   --- Die Formel
 for 1z:=0 to 7 do for ls:=0 to 7 do                --- Die Transponierte
  t[lz][ls]:=d[ls][lz];                             --- Die DCT'
 for 1z:=0 to 7 do                                  --- << Y * DCT' >>
  for 1s:=0 to 7 do                                 --- ! Skale Y-Matrix
   for tm:=0 to 7 do                                --- !! Y-128
    e[lz][ls]:=e[lz][ls]+(i[lz][tm]-128)*t[tm][ls ];--  rechne
 for 1z:=0 to 7 do
  for 1s:=0 to 7 do
   for tm:=0 to 7 do
    f[lz][ls]:=f[lz][ls]+d[lz][trn]*e[tm][ls];
 end.



In meinem Assemblerprogramm wird mit Integerarithmetik die FPU emuliert. Die Realzahlen z.B. 1/8 = 0.35355 wurde mit Vielfachen von 2 multipliziet, so z.Bsp. mit 16384, dh. 1/8 > 5792. Bei einer zweifachen Matrixmultiplikation habe ich eine maximale Abweichung von ±0.75 erreicht und mit einer 92%-igen Sicherheit sind die Werte im richtigen Bereich gerundet. Nach der Quantisierung werden 100tige Ergebnisse erreicht.

Der 3. und 4. Schritt Quantisierung & ZigZag Scanning der DCC Matrix

Aus der 8 * 8 F- Matrix wird eine Quantisierte 8 * 8 F- Matrix. Jedes Element wird mit einem festen Faktor (hier die SAR- Matrizen), der über die Qualität entscheidet, dividiert. Danach wir die quantisierte F- Matrix in einem Zig-Zag-Scaning gespeichert. Es sind logischerweise 64 Elemente in der F-Matrix, die in ein einfaches Feld gespeichert werden. D.h. aus
8 * 8 M > 64iger Vektor die Elemente des ZigZag-Scan-Vektors werden wie folgt bestimmt. Nach dern unten folgendem Bild.  So wäre
 z.B. V[ 0] := M[0][0];
      V[ 2] := M[1][0];
      V[23] := M[4][2];
      V[64] := M[7][7];
 
Lage Vektorelemente in 8 * 8 Matrix
  xO x1 x2 x3 x4 x5 x6 x7
0x  
1x  
2x  
3x  
4x  
5x  
6x  
7x 
00 01 05 06 14 15 27 28 
02 04 07 13 16 26 29 42 
03 08 12 17 25 30 41 43 
09 11 18 24 31 40 44 53 
10 19 23 32 39 45 52 54 
20 22 33 38 46 51 55 60 
21 34 37 47 50 56 59 61 
35 36 48 49 57 58 62 63 
 
==>
64'iger Vektor mit Elementen aus 8 * 8 Matrix
 
x0
x1
x2
x3
x4
x5
x6
x7
x8
x9
0x
OO
01
10
20
11
02
03
12
21
30
1x
40
31
22
13
04
05
14
23
32
41
2x
50
60
51
42
33
24
15
06
07
16
3x
25
34
43
52
61
70
71
62
53
44
4x
35
26
17
27
36
45
54
63
72
73
5x
64
55
46
37
47
56
65
74
75
66
6x
57
67
76
77
 
 
 
 
 
 
 
In den folgenden Tabellen sind die Quantisierungstabellen aufgelistet, die von meinem Programm verwendet werden. Jede Division wird mit SAR (Assembler Shift Arithmetik Right) ausgedrückt. Das SAR-Effektiv ist deshalb aufgeführt, da mit der SAR-Bewegung in meinem Programm die Werte gleichzeitig normiert werden. Das heist, die Brüche (aus der FPU-Emulation)
bestehen aus Zahl/2^5 (Zahl/32'igstel). Mit diesem SAR werden also 2 Fliegen mit einer Klappe geschlagen, Quantisierung plus Normierung. SAR wird deswegen genommen, damit die negativen Zahlen erhalten bleiben.

1. Quantisierungstabelle 1-2%  sehr gute Qualität
Devisor Matrix
SAR-Matrix
SAR-Effektiv
01 02 02 02 04 08 08 08
02 02 02 08 08 08 08 08
02 04 04 08 08 08 08 08
02 04 08 08 08 08 08 08
04 08 08 08 08 08 08 08
08 08 08 08 08 08 08 08
08 08 08 08 08 08 08 08
08 08 08 08 08 08 08 08
0 1 1 1 2 3 3 3
1 1 1 3 3 3 3 3
1 2 2 3 3 3 3 3
1 2 3 3 3 3 3 3
2 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3
5 6 6 6 7 8 8 8
6 6 6 8 8 8 8 8
6 7 7 8 8 8 8 8
6 7 8 8 8 8 8 8
7 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8
8 8 8 8 8 8 8 8

2. Quantisierungstabelle 15% gute Qualität
Devisor Matrix
SAR-Matrix
SAR-Effektiv
01 02 02 04 08 16 16 16
02 04 04 16 16 16 16 16
04 08 08 16 16 16 16 16
04 08 16 16 16 16 16 16
08 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
0 1 1 2 3 4 4 4
1 2 2 4 4 4 4 4
2 3 3 4 4 4 4 4
2 3 4 4 4 4 4 4
3 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
5 6 6 7 8 9 9 9
6 7 7 9 9 9 9 9
7 8 8 9 9 9 9 9
7 8 9 9 9 9 9 9
8 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9

3. Quantisierungstabelle 40%  ausreichende Qualität
Devisor Matrix
SAR-Matrix
SAR-Effektiv
01 08 08 08 16 16 32 32
08 08 08 32 32 32 32 32
08 16 16 32 32 32 32 32
08 16 32 32 32 32 32 32
16 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
0 3 3 3 4 4 5 5
3 3 3 5 5 5 5 5
3 4 4 5 5 5 5 5
3 4 5 5 5 5 5 5
4 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5
5 8 8 8 9 9 A A
8 8 A A A A A A
8 9 9 A A A A A
8 9 A A A A A A
9 A A A A A A A
A A A A A A A A
A A A A A A A A
A A A A A A A A

4. Quantisierungstabelle 60% schlechte Qualität
Devisor Matrix
SAR-Matrix
SAR-Effektiv
01 16 16 16 32 32 64 64
16 16 16 64 64 64 64 64
16 32 32 64 64 64 64 64
16 32 64 64 64 64 64 64
32 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64
0 4 4 4 5 5 6 6
4 4 4 6 6 6 6 6
4 4 4 6 6 6 6 6
4 5 6 6 6 6 6 6
5 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6
5 9 9 9 A A B B
9 9 9 B B B B B
9 A A B B B B B
9 A B B B B B B
A B B B B B B B
B B B B B B B B
B B B B B B B B
B B B B B B B B

2.5  5. Schritt Eliminierung bzw. Zusammenfassung der Nullen in 6 Vektoren

Nach der Umsetzung der vier 8 * 8 RGB Matrizen sind nun 6 Quantisierte Vektoren entstanden. Davon sind die ersten 4 Vektoren Y-Informationen, der 5. Vektor ist die U-Information und der 6. Vektor ist die V-Information. So ist nun ein 64 * 6-Integervektor entstanden. Viele der Werte in dem Vektor sind NULL (Teilweise weit über 90%.). Durch die DCT wurden aus den Bytewerten Integerwerte. Durch langes Probieren (Zufallszahlen in den Matrizen) habe ich den Wertebereich abgesteckt. Ich fand keinen Wert der die ±1000 überschritt. Also habe ich den Wertebereich von 1023 bis -1023 festgelegt. Falls es Zahlen geben sollte, die diesen Wertebereich übertreffen, so werden sie mit dem Maximalwert 1023 bzw. -1023 festgelegt. Wie man sieht ist der Integerbereich nicht voll ausgeschöpft. Es werden 5 bits der 16-bit Zahl gar nicht genutzt. Da
das Signed- bit genau an der Stelle "F" des words steht, skaliere ich die Zahl. Ich addiere 1024 dazu. Somit liegt die Zahl im Wertebereich von 0..2047. Nun sind die oberen 5bits frei. Dann werden noch alle Nullen gezählt. Hier stehen mir 5 bits zur Verfügung, dh maximal 31 Nullen können mit gespeichert werden. Werden mehr als 31 Nullen gezählt, so wird der Null-Zähler auf 31 gelassen; die nächste Wertzahl wird auf 0 gesetzt (Aufgepasst! Nach der Skalierung entspricht eine Null der 1024), und erneut werden die Nullen gezählt.
Aufteilung der 16bit Zahl
 
Anzahl Null .------- ZAHL ------.
 F E D C B A 9 8 7 6 5 4 3 2 1 0
 n n n n n D D D D D D D D D D D
 
 
Bsp. 7 Vektorzahlen werden zusammengefaßt zu 2 Null-codierten Zahlen 
Vektorwert
Gespeicherter Wert
Bitfolge Codiert
12 
0
12 + 1 x Null
1xNull    12 
0000100000001100
FEDCBA9876543210
5
0
0
0
5 + 3 x Null
1xNull    12 
0001100000000101
FEDCBA9876543210
6 ganze Vektoren (6 * 64 Werte) werden Null-Codiert. Jeder nullcodierte Block wird in einern Puffer abgelegt. Sollte die Puffergröße beim nächsten Eintrag 4097 Werte übersteigen oder das Bild ist zu Ende, so wird der Block Huffmancodiert und auf Platte gespeichert.

6.Schritt Huffmann-Codierung von zusammengefaßten Vektor-Blöcken

Dieses Thema ist am dünnsten ausgefallen, hier kann noch viel rausgehohlt werden. Hier existiert als Ausgang ein Integerblock in der Größe von etwa 4000 Integerwerten. Diese Integerwerte werden aufgeteilt in High und Low- Bytes, da es Unterschiede in der Häufigkeitsverteilung gibt. Ich habe verschiedene "nullgepackte Bilder" gespeichert. Danach habe ich von einem Programm die auftretenden Bytes für High und Low- Bytes zählen lassen. Dann habe ich mehrere Tabelle per Hand erstellt, die die verschiedenen Bit-Kombinationen für jedes Byte festlegen. Für häufig auftretende Zeichen werden kurze (2-3bit) Bitkombinationen und für selten auftretende Zeichen werden lange (bis zu 15bit) Bitkombinationen verwandt. Vorgehen des Algorithmuses.  Ein sehr einfacher und schneller Algorithmus, spart aber relativ wenig ein (etwa 50%).

Blättern:
FLI und FLC Erläuterungen     Mein Format Decodieren

Praktikum