Jernej Golja, 2008
Jun 30, 2015
Jernej Golja, 2008
Kompresija podatkov
Je postopek, kako enake podatke zapisati z manj zlogi.
Dve vrsti kompresije: lossless (brez izgube) in lossy (z izgubo) kompresija.
Kompresija z izgubo
Primerna za datoteke, kjer vsaka informacija, ki predstavlja podatke, ni ključnega pomena (slika, zvok, govor …).
Kodiramo tako, da je končni rezultat še vedno dovolj dober za prejemnika.
Primeri: JPEG, MPEG, MP3, WMA …
Kompresija brez izgube (1/2) Vse kar zakodiramo, moramo
odkodirati v prvotno obliko. Kje uporabljamo: tekstovne datoteke
(.txt), zagonske datoteke (.exe), tam kjer so prvotni podatki ključnega pomena.
V principu bi vsak lossless algoritem lahko deloval nad vsemi vrstami podatkov. Vendar?
Kompresija brez izgube (2/2) Za različne vrste datotek različni
algoritmi kodiranja: Bolj smo specifični, bolj smo učinkoviti. Tekst, slika, zvok – vsak ima svoje lastnosti.
Uporabno tudi pri kriptiranju (odstranimo logične vzorce v datoteki).
Ne moremo garantirati kompresije za vsako datoteko (posebej, če je že bila kodirana).
Huffmanovo kodiranje (1/6) Uporablja entropičen algoritem:
Vsak znak lahko zapišemo z drugačnim zapisom (različno število zlogov).
Uporabimo statistiko za izračun verjetnosti in frekvence.
Ustvari se prefix binarno drevo. Nobena vrednost lista v drevesu ne
predstavlja začetka vrednosti v drugem listu.
Huffmanovo kodiranje (2/6) Koraki pri izdelavi drevesa:
Korake ponavljamo, dokler obstajata vsaj dva elementa za primerjat: 1. najdi dva najmanjša elementa (z
najmanjšo frekvenco) 2. seštej njuni frekvenci in jih združi v
vozlišče 3. odstrani elementa iz prejšnjega
seznama in upoštevaj vozlišče pri naslednjem iskanju
Huffmanovo kodiranje (3/6) Primer: “ospo je ospo.”:
“o” (4)0.308
“j” (1)0.077
“e” (1)0.077
“.” (1)0.077
“s” (2)0.154
“p” (2)0.154
“ ” (2)0.154
0.154 0.308
0.385 0.615
1
0.231
Huffmanovo kodiranje (4/6) Koraki pri izdelavi drevesa:
Vsem listom v drevesu dodamo primerno bitno kodo, glede na to kje se nahajajo.
Huffmanovo kodiranje (5/6) Primer: “ospo je ospo.”:
“o” (4)0.30811
“j” (1)0.077000
“e” (1)0.077001
“.” (1)0.077010
“s” (2)0.154011
“p” (2)0.154100
“ ” (2)0.154101
0.154 0.308
0.385 0.615
1
0.231
0
0
00 0
0
1
1
111
1
Huffmanovo kodiranje (6/6) Kaj smo dobili?
Binarno drevo listov z unikatnim bitnim zapisom svoje “kode”.
Večjo kot ima znak v izvorni datoteki frekvenco, manjšo bitno kodo mu dodelimo in obratno.
Zapis kodirane datoteke (1/5) Drevo je za vsako datoteko unikatno, zato ga
moramo zapisati zraven. Zapisati moramo zgolj znak in binarno kodo Zraven pa zapišemo tudi št. izvornih znakov in odmik
glave, za lažje dekodiranje
Primer:
000|j001|e010|.|18|3
itn…
Zapis kodirane datoteke (2/5) Manipulacija bitov
združujemo bitne kode naših znakov v zloge in le-te zapisujemo
Zapis kodirane datoteke (3/5) Primer zapisa:
“o” (4)0.30811
“j” (1)0.077000
“e” (1)0.077001
“.” (1)0.077010
“s” (2)0.154011
“p” (2)0.154100
“ ” (2)0.154101
ospo je ospo.
11 011 100
1 byte
Zapis kodirane datoteke (4/5) Manipulacija bitov
ponavljamo do konca pazimo na zadnji zlog, ker ponavadi ni
vseh 8 bitov zapisanih, zato mu dodamo lastne bite, kar s štetjem znakov upoštevamo pri dekodiranju.
Zapis kodirane datoteke (5/5) Rezultat?
Odvisen od datoteke. najboljši v primeru velike količine enakih
znakov. najslabši ko je malo znakov in so vsi različni.
V povprečju vsaj 50% učinkovit pri naključnih podatkih (pri mojih lastnih testiranjih).
Dekodiranje(1/2)
Iz glave ustvarimo enosmerno povezan seznam znakov z njihovimi bitnimi kodami.
Potem pa relativno enak način kot kodiranje: bite sestavljamo v vzorce, ki jih potem
primerjamo v našem seznamu. v kolikor najdemo vzorec, v datoteko
zapišemo njegov pravi znak.
Slabosti & izboljšave
Moja implementacija: Zagotovo dela samo z znakovnim kodiranjem,
kjer je en znak predstavljen z enim zlogom (ANSI – ASCII).
Rešitev? Uporaba drugega tipa kot char, npr. int (4 zlogi – dovolj za UTF-8), itn.
Boljši zapis drevesa v “glavo” kodirane datoteke. Buffer za pisanje v datoteke (za hitrejše
delovanje)
Huffmanov algoritem: Ni primeren za real-time kompresijo, saj moramo
vsaj 2x skozi datoteko, da jo zakodiramo.
Vprašanja?