Professional Documents
Culture Documents
Lempel - Ziv Vizualizacija
Lempel - Ziv Vizualizacija
Lempel - Ziv Vizualizacija
Tekst je namjenjen svima koji ele nauiti neto vie o Lempel-Ziv metodama LZ77, LZ78 i LZW metode Metode pomou rjenika Sliding window metoda
7. veljaa 2009
Saetak
Od pojave prvih raunala susreemo se sa problemom komprimiranja podataka koji nas prati do danas. Do kraja 70-tih godina prolog stoljea istraivanja na polju kompresije podataka bila su usmjerena uglavnom na poboljavanje Huffman algoritma kodiranja podataka. Kako se taj algoritam temelji na odreivanju frekvencije ponavljanja odreenih simbola bilo je potrebno te simbole predvidjeti ili unaprijed proitati podatke. Dva Izraelska teoretiara informacije Abraham Lempel i Jacob Ziv 1977. godine predstavljaju radikalno drukiji pristup komprimiranju podataka. Kompresiju kod koje nije potrebno predviati frekvenciju ponavljanja simbola i bespotrebno unaprijed itati podatke. Lempel Ziv vizualizacija predstavlja jedinstven nain kompresije podataka. U predstojeem tekstu, biti e objanjena osnovna ideja komprimiranja podataka pomou Lempel - Ziv kodiranja.
Sadraj
1. 2. 3. 4. UVOD ............................................................................................................ 3 OPIS I VRSTE KODIRANJA ............................................................................... 4 LZ77 ............................................................................................................. 5 3.1. 4.1. 4.2. 5. 6. Primjer LZ77 kodiranja ............................................................................. 7 Primjer LZ78 kodiranja ............................................................................11 LZW ......................................................................................................12 LZ78 ............................................................................................................10
Ovaj seminarski rad je izraen u okviru predmeta Sustavi za praenje i voenje procesa na Zavodu za elektronike sustave i obradbu informacija, Fakulteta elektrotehnike i raunarstva, Sveuilita u Zagrebu. Sadraj ovog rada moe se slobodno koristiti, umnoavati i distribuirati djelomino ili u cijelosti, uz uvjet da je uvijek naveden izvor dokumenta i autor, te da se time ne ostvaruje materijalna korist, a rezultirajue djelo daje na koritenje pod istim ili slinim ovakvim uvjetima.
1. Uvod
Problem ograniene memorije koji nas prati od pojave prvih raunala pa sve do danas je jo uvijek jedna od injenica koje korisnik raunala treba uvijek imati na umu. Sa vremenom koliina memorije u raunalima se poveava, ali ostaje injenica da je ona uvijek ograniena. Korisnici raunala i programeri moraju omoguiti da sa tim ogranienim resursima raunala obrauju velike koliine podataka. Sasvim prirodno je da su se poele javljati razne ideje kako to uinkovitije smjestiti podatke u memoriju i jedna od njih je kompresija podataka. Kompresiju podataka moemo podijeliti u dvije kategorije. Prva kategorija je ona gdje dolazi do gubitka izvornih informacija, ali je uteda u memorijskom prostoru tolika da su ti gubici prihvatljivi. U engleskoj terminologiji to se naziva lossy data compression. Takvu kompresiju primjenjujemo kod podataka gdje moemo dozvoliti odreeni gubitak informacija, kao zvuk, video i slike. Dio informacija mijenjamo za memorijsku utedu koja nam je znatno vanija nego sami podaci. Naravno, postoje i podaci kod kojih gubitak informacija nije prihvatljiv i gdje nakon dekompresije moramo imati identine podatke poetnima. U engleskoj terminologiji takva vrsta kompresije se naziva lossless data compression. Razvijanjem uinkovitih vrsta kompresije zadovoljavamo rastue potrebe za memorijskim prostorom bez potrebe za razvijanjem novih tehnologija za izradu same memorije. Razvoj industrija kao to su filmska ili glazbena bio bi nezamisliv bez upotrebe neke vrste kompresije. Potreba za memorijskim kapacitetima uvijek e postojati, a kompresija podataka je tu potrebu uinila znatno manjom.
3. LZ77
LZ77 algoritam postie kompresiju zamjenom niza podataka sa odgovarajuim simbolom koji u rjeniku sadri upravo te podatke. Kad govorimo o rjeniku mi zapravo zamiljamo rjenik kao strukutru podataka koja se puni podacima prilikom kodiranja i nakon to se proces kodiranja zavri taj rjenik sauvamo da bi prilikom dekodiranja imali odakle povratiti izvorne podatke. Kod LZ77 algoritma nije takav sluaj. Pogledajmo najprije kako naelno taj algoritam radi:
Slika 2
Recimo da se niz podataka na slici 1 sastoji od dva niza: niz E='abcbbacde' i niz S='bbadeaa'. I recimo da je niz E ve bio prethodno kodiran a niz S jo uvijek nije. LZ77 algoritam prvo trai najdui odgovarajui niz podataka iz niza S u nizu E. U ovom sluaju najdui niz podataka je 'bba' koji je na treoj poziciji od poetka niza (brojei od nule). Dakle mogue je kodirati prva tri podatka u nizu S kao referencu na ta ista tri podatka u nizu E poevi od tree pozicije. Referenca je kodni znak koji u sebi sadri tri elementa: poziciju od poetka niza, duljinu kodiranog niza i prvi sljedei podatak koji se nalazi nakon kodiranog niza. U naem sluaju referenca je '33d'. Time smo niz od etiri znaka zamijenili jednom referencom i zapravo komprimirali podatke. Kada odgovarajui nizovi postani vei tada kompresija dolazi sve vie do izraaja.
to se dogaa ako je odgovarajui niz vrlo dug i referenca u sebi sadri velike brojeve? LZ77 algoritam zato koristi stukturu prikazivanja podataka koja se zove klizni prozor. Klizni prozor slui tome da kod kodiranja podataka i odabiranja pogodnih podataka za kodiranje koder gleda samo podatke koji se nalaze unutar tog prozora. Klizni prozor se sastoji od dva dijela: spremnik za usporedbu (search buffer) gdje su se podaci ve kodirali i spremnik s novim podacima (lookahead buffer) koji sadri podatke koji se jos nisu kodirali.
Iz koda vidimo ukoliko nema odgovarajueg niza u spremniku za usporedbu algoritam jednostavno upie u referencu 0 0 i pomakne se za jedan znak. Prilikom zapoinjanja procesa kodiranja u spremnik s novim podacima postavimo poetak eljenog dokumenta koji elimo kodirati, a spremnik za usporedbu napunimo sa unaprijed definiranim znakovima, u naem primjeru koristili smo nule.
3.1.
U sljedeem primjeru proi emo LZ77 algoritam korak po korak. Neka ulazni niz bude niz S = 001010210210212021021200... i neka su oba spremnika veliine 9 znakova. Proces zapoinjemo tako da spremnik za usporedbu napunimo nulama a u spremnik s novim podacima unesemo prvih 9 znakova niza S. Algoritam trai najdui odgovarajui niz. U ovom sluaju to je niz '00' i budui da spremnik za usporedbu ima same nule moe se uzeti bilo koji podniz kao odgovarajui. U primjeru smo uzeli zadnji znak kao poetak odgovarajueg podniza.
Kao to smo ve ranije spomenuli odgovarajui nizovi su kodirani kao referenca koja u sebi sadri poziciju niza, njegovu duinu i prvi sljedei znak koji se pojavljuje nakon niza. Prvi niz je kodiran kao C 1 = 22021. 22 je pozicija niza u spremniku za usporedbu u bazi tri (810 = 223), 02 predstavlja duljinu niza (210 = 23) a 1 je prvi sljedei znak koji se pojavljuje nakon odgovarajueg niza. Nakon toga prozor se pomie udesno za duljinu niza i jedan znak dakle u ovom sluaju pomie se za 3 i proces pronalaska odgovarajueg niza poinje ponovo. Algoritam je pronaao niz '010' kao najdulji odgovarajui i to na sedmom mjestu u spremniku za usporedbu te je taj niz kodiran kao C2 = 21102. Prozor se ponovno pomie, ali ovaj put za 4 znaka udesno. Postupak ponavljamo i dobivamo C3 = 20212 i C4 = 02220. Time smo niz S = 001010210210212021021200... zamijenili nizom kodiranih rijei C1C2C3C4 i time obavili znaajnu kompresiju. Kod dekodiranja se lako uoava zato ne trebamo prenositi ili sauvati rjenik. Na poetku dekodiranja kao i kod kodiranja prvo napunimo
7
spremnik za usporedbu nulama i spremnik s novim podacima ostavimo prazan. Dekodiranje se obavalja jednostavno itajui kodirane rijei i radei tono ono to pie. Pogledajmo sliku pa emo proi korake dekodiranja zajedno:
Slika 5: Dekodiranje
Nakon to smo napunili spremnik za usporedbu nulama itamo prvu kodnu rije: C1 = 22021. Ona nam govori: pozicioniraj se na osmo mjesto (223 = 810) spremnika za pretraivanje proitaj znak i upii u prvo mjesto spremnika s novim podacima, zatim se pomakni u oba spremnika za jedno mjesto udesno i ponovo uini isto. Postupak nastavi initi sve dok se broj tih postupaka ne izjednai sa brojem koji se nalazi na drugom mjestu kodne rijei. Nakon toga upii znak koji se nalazi na treem, ujedno i zadnjem mjestu kodne rijei. Nakon toga prozor se pomie udesno za jedan broj vei od drugog broja u kodnoj rijei, odnosno pomak udesno za jedan broj vei od niza koji smo upravo dekodirali. Uzimamo sljedeu kodnu rije i ponovimo postupak. Cijeli postupak se ponavlja sve dok ne dodemo do zadnje kodne rijei, nju na isti nain dekodiramo i dekodirali smo cijeli dokument koji je identian izvornome. Uoimo da nije vano ukoliko se iz spremnika za usporedbu pomaknemo u spremnik s novim podacima prilikom pomicanja udesno za jedan znak i itanja sljedeeg znaka. Vratimo se na na primjer i pokuajmo ga dekodirati: prvi dio kodne rijei C1 = 22021 nam govori da se pozicioniramo na osmo mjesto u spreminku za pretraivanje. Kopiramo znak sa osmog mjesta na prvo mjesto u spremniku s novim podacima, provjerimo jesmo li doli do kraja niza znakova koji trebamo kopirati. Nismo, tako da se pomjeramo za jedno mjesto udesno u oba spremnika. Primjeujemo da smo iz spremnika za usporedbu preli u spremnik sa novim podacima, to je doputeno tako da ponavljamo postupak. Kopiramo znak sa tog mjesta na sljedee mjesto u spremniku sa novim podacima. Provjerimo jesmo li doli do kraja niza, jesmo, pomiemo se za jedno mjesto u spremniku sa novim podacima i
8
upisujemo znak sa zadnjeg mjesta u kodnoj rijei i pomiemo prozor za 3 mjesta udesno tako da je spremnik sa novim podacima ponovo prazan. Uzimamo sljedeu kodnu rije i ponavljamo postupak. Nakon to dekodiramo sve kodne rijei dekodirali smo cijeli dokument.
4. LZ78
LZ78 je algoritam koji za kopmresiju koristi rjenik koji se na vrlo jednostavan nain gradi kod kodiranja i kasnije kod dekodiranja takoer na vrlo jednostavan nain ponovo se izgradi i vraa izvorne dijelove dokumenta. Prilikom kodiranja i spremanja odgovarajuih podataka u rjenik algoritam generira kodne rijei koje se sastoje od dva elementa: indeks koji upuuje na najdui odgovarajui podatak u rjeniku i sljedei znak koji se pojavljuje nakon tog podatka. U poetku rjenik je prazan i puni se podacima koji se iitavaju iz dokumenta. Teoretski veliina rjenika bi mogla biti beskonana, meutim u praksi se ona ograniava i kada se dostigne maksimalna veliina rjenika on se vie ne proiruje sa novim zapisima. Pogledajmo sada pojednostavljenu pseudokod verziju LZ78 algoritma da bismo ju mogli prodiskutirati i pomou nje pokuati rijeiti primjer:
w := NIL; while (there is input){ K := next symbol from input; if (wK exists in the dictionary) { w := wK; } else { output (index(w), K); add wK to the dictionary; w := NIL; } }
Algoritam uzima iz niza podatak, provjerava postoji li taj podatak u rjeniku. Ukoliko ne postoji kreira ga u rjeniku i na izlaz generira kodnu rije i provjerava dalje sljedei podatak iz niza. Ukoliko postoji u rjeniku sauva odgovarajui podatak i provjerava sljedei podatak. Ukoliko i sljedei podatak postoji u rjeniku algoritam dodaje u niz prethodnom i tako nastavlja sve dok ne dode do znaka koji se sa prethodnim nizom jo ne nalazi u rjeniku. Tada ponovo na izlaz generira kodnu rije koja se sastoji od indeksa niza koji se ve nalazi u rjeniku i novog znaka i kreira tu kodnu rije takoer i u rjeniku.
10
4.1.
Uzmimo znakovni niz S = 001212121021012101221011 kao niz za kodiranje. Promotrimo sliku i pogledajmo kako je LZ78 algoritam kodirao niz S.
U prvom koraku prvi znak koji zasigurno jo nije u rjeniku se u isti dodaje i pridodaje mu se kodna rije (0 0). Prva nula ukazuje na to da u rjeniku nema odgovarajueg niza ili znaka, a druga nula je upravo taj znak koji smo proitali i dodali u rjenik. Pomiemo se za jedno mjesto i uitavamo sljedei znak, primjeujemo da taj znak ve postoji u rjeniku te uitavamo dalje sljedei znak. Tog znaka nema u rjeniku te se generira sljedea kodna rije (1 1). Prva jedinica ukazuje na to da postoji taj znak u rjeniku i to na prvom mjestu (gdje se nalazi znak 0), a druga jedinica je sljedei znak koji se pojavio a nije u rjeniku. Time se niz '01' dodao u rjenik. Proces se ponavlja dok se ne doe do kraja niza. Nakon zavretka procesa kodiranja niz S = 001212121021012101221011 se zamjenjuje nizom kodnih rijei '001102013150617271' koji je krai i zauzima manje prostora. Proces dekodiranja obavlja se na vrlo lagan i intuitivan nain: dekoder dekodira kodne rijei na nain da iz njih ponovo izgradi rjenik koji e biti identian onome kod kodiranja te iz njega proita izvorne podatke. Tako e ako krenemo dekodirati na primjer dekoder prvo uzeti kodnu rije (0 0) i dekodirati ju na nain analogan kodiranju: prvu nulu shvatit e kao znak da se taj znak jo ne nalazi u rjeniku pa e sljedei znak u kodnoj rijei koji je takoer nula zapisati kao prvi znak u nizu i kao prvi dekodirani znak koji e postaviti u rjeniku. Sljedea kodna rije je (1 1) i
11
ona oznaava da kod prvog znaka kodne rijei da se dio ovog kodiranog niza nalazi u rjeniku i to pod rednim brojem jedan, drugi znak oznaava zadnji znak ovog kodiranog niza koji je u ovom sluaju znak jedan. Dekodirani niz koji je u ovom sluaju '01' pridodaje se prethodno dekodiranom nizu i postavlja se u rjeniku kao drugi dekodirani niz. Proces se nastavlja sve dok se ne doe do kraja niza koji treba dekodirati. Kao rezultat dekodiranja dobili smo izvorni niz S=001212121021012101221011 to moemo provjeriti na slici sedam koja nam prikazuje rjenik koji se izgradio od kodnih rijei i konaan dekodirani niz.
Slika 7: Dekodiranje
LZ78 ima nekoliko slabosti, jedna od njih je ta da rjenik moe unedogled rasti. Postoje razne metode koje se koriste da se to sprijei, neka od rjeenja su da rjenik nakon to se napuni do neke odreene mjere postane statine veliine ili da se postojei rjenik odbaci i pone se stvarati iznova. Kod procesa izgradnje rjenika due podnizove koje elimo kodirati a koji nam uvelike pridonose veoj kompresiji najee kodiramo tek pri kraju izgradnje rjenika i time ne ostvarujemo kompresiju koju bismo inae mogli ostvariti. Ipak, u praksi LZ78 algoritam kodiranja radi vrlo dobro i dovodi do vrlo velike kompresije podataka pod uvjetom da su ulazni podaci dovoljno veliki i da imaju odreeni stupanj ponavljanja.
4.2.
LZW
1984. godine Terry Welch je modificirao LZ78 algoritam kodiranja kako bi ga implementirao u vrlo brze diskovne kontrolere, to je rezultiralo nastajanjem Lempel-Ziv-Welch algoritma (poznatijeg kao LZW algoritam).
12
Ova poboljana verzija LZ78 algoritma je najpoznatija inaica i vrlo je esto pogreno nazivana kao izvorni Lempel Ziv algoritam. Razlika u odnosu na izvorni LZ78 algoritam je u tome to prije nego to se zapone proces kodiranja dokumenta prvo se u rjenik unesu svi znakovi, i to na prvih 256 mjesta u rjeniku (naravno taj unos svih znakova se radi automatski, nije ih potrebno runo unositi) i nakon toga se kree kodirati dokument. Sada vie nije potrebno svaki novi znak zasebno kodirati u rjenik jer su svi znakovi ve na samom poetku uneseni nego se poinje sa nizom od dva znaka i proces kodiranja se nastavlja jednako kao to se to inilo kod LZ78 algoritma. Algoritam za LZW metodu izgleda ovako:
w := NIL;
Kod je gotovo identian LZ78 kodu osim to se u poetku u rjenik unesu svi mogui znakovi. Dekodiranje se vri identino kao kod LZ78 dekodiranja osim to se naravno ponovno najprije u rjenik uitaju svi znakovi. LZW algoritam kompresije koristi se meu ostalima i kod GIF fromata koji je 1987 godine razvila tvrtka CompuServe za pohranu i slanje slikovnih datoteka. GIF format je bio slobodan medij za koritenje i s vremenom postajao sve popularniji i koriteniji koliko u tvrtkama koje bi ga koristile za oglaavanje toliko i meu korisnicima koji su GIF format koristili u privatne svrhe. Do 1994 godine GIF format je zamijenio PCX kao format koji se najee koristio za pohranu osmobitnih grafikih datoteka. Te je godine tvrtka Unisys kao vlasnik patenta LZW algoritma zatraila od tvrtke CompuServe da plaa licencu za koritenje to je izazvalo snano negodovanje u javnosti, posebice ako uzmemo u obzir da je tih godina internet industrija doivila veliki boom u razvoju a GIF je bio vodei medij za prijenos grafikih datoteka slabije rezolucije na internetu. Patent je istekao u SAD-u u lipnju 2003. godine a do srpnja 2004. godine i drugdje u svijetu.
13
5. Zakljuak
Lempel i Ziv su razvili vrlo jednostavan algoritam, a vrijeme je pokazalo da je to jedan od najuinkovitijih naina komprimiranja podataka koji poznajemo. Njegova primjena je vrlo rairena i danas je gotovo nemogue nai osobu koja nije barem jednom koristila kompresiju podataka temeljenu na Lempel-Ziv algoritmu. Cijeli niz algoritama i metoda temelji se na osnovnim principima koje je postavio Lempel-Ziv algoritam, a njegov razvoj ne prestaje i svakim danom se nadograuje sa novim mogunostima i modifikacijama. Snaga Lempel-Ziv algoritma nalazi se u njegovoj jednostavnosti i brzini izvoenja to su jedni od glavnih preduvijeta da neka tehnologija postane prihvaena od strane korisnika. Na jednostavan nain ovaj algoritam dokazuje u kojem pravcu treba razvijati nove tehnologije i kako je uz pomo osnovnih matematikih operacija mogue razvijati velike stvari.
14
6. Literatura
[1] [2] [3] [4] [5] [6] [7] Zeeh, Cristina: The Lempel Ziv Algorithm, 2003. URL: http://tuxtina.de/files/seminar/LempelZivReport.pdf Grubii, Ivor; Juro, Petar; Srbi, Mario: Lempel Ziv vizualizacija URL: http://diana.zesoi.fer.hr/pvprm/igrubisi/lempel-ziv_vizualizacija.htm Wikipedia URL: http://en.wikipedia.org/wiki/LZW Wikipedia URL: http://en.wikipedia.org/wiki/LZ77_and_LZ78 Interactive Data Compression Tutor URL: http://www.eee.bham.ac.uk/WoolleySI/All7/ziv_1.htm Nelson, Mark LZW Data Compression 1989. URL: http://marknelson.us/1989/10/01/lzw-data-compression/ Lempel Ziv Welch (LZW) Compression URL: http://netghost.narod.ru/gff/graphics/book/ch09_04.htm
15