kodowanie słownikowe
Transkrypt
kodowanie słownikowe
Algorytmy kodowania słownikowego • • Kodowanie ze słownikiem dynamicznym (LZ77, LZ78, LZSS, LZW) Zastosowania Kodowanie słownikowe - zasada Chcemy zakodować zdanie angielskie: A good example of how dictionary based compression works Słownik: Longman Dictionary of Contemporary English Kodowanie: wskaźnik do słowa to x/y, x – nr strony, y – nr słowa na stronie. Wynik: 1/1 489/7 377/19 755/36 548/13 303/7 73/3 223/1 1270/25 Liczba stron w słowniku: 1280 – x kodujemy przez 11 bitów Liczba słów na stronie < 128 – y kodujemy przez 7 bitów Wskaźnik x/y – 18 bitów. Całkowita ilość bitów: 9*18 = 162 Normalne kodowanie ASCII – 48 bajtów, czyli 384 bity Stopień kompresji – 2.37 : 1 Słownik dynamiczny Największe znaczenie – metody ze słownikiem dynamicznym Przełomowe znaczenie – prace Jacoba Ziva i Abrahama Lempela z końca lat siedemdziesiątych Słownik budowany dynamicznie na podstawie przetworzonej części danych – równy fragmentowi przetworzonej części danych lub wytworzony ze wszystkich fraz przetworzonych do tej pory NajwaŜniejsze algorytmy: LZ77, LZ78, LZW Algorytm LZ77 Słownik – fragment wcześniej zakodowanej części danych Przeglądamy dane przez przesuwające się okno o rozmiarze W Okno dzieli się na: bufor słownikowy – zawiera ostatnio zakodowany fragment ciągu danych bufor kodowania – zawiera fragment ciągu, który właśnie mamy kodować Praktyczne implementacje – rozmiar bufora słownikowego: 8 – 16 kB, rozmiar bufora kodowania ~ 100 bajtów Algorytm LZ77 – c.d. Zasada działania: Umieszczamy wskaźnik przeszukiwania na końcu bufora słownikowego Przesuwamy wskaźnik w lewo (liczba miejsc – o) aŜ do napotkania symbolu równego pierwszemu symbolowi w buforze kodowania Sprawdzamy, czy następne symbole w obu buforach nie są sobie równe. Liczba równych sobie symboli – długość dopasowania l Przeglądamy w ten sposób cały bufor słownikowy tak, by zmaksymalizować dopasowanie Optymalne dopasowanie kodujemy jako (o, l, c), gdzie c – kod symbolu w buforze kodowania występujący jako pierwszy niedopasowany symbol k a b r a k a d a 7 b r 4 a r r a (7, 4, C(r)) Algorytm LZ77 – c.d. Ostatni element trójki – na wypadek zerowego dopasowania Po wysłaniu kodu (o, l , c) przesuwamy okno o l + 1 w prawo i powtarzamy procedurę Długość zapisu kodującego dla kodowania o stałej długości niech rozmiar okna = W, rozmiar bufora słownikowego = S, rozmiar alfabetu = A wtedy długość zapisu = log2 S + log2 W + log2 A Uwaga: dopasowanie moŜe przekroczyć rozmiar bufora słownikowego Algorytm LZ77 – kodowanie Kodujemy ciąg: . k a b r a k a d a b r a r r a r r a d . Zakładamy, Ŝe podciąg k a b r a k a jest juŜ zakodowany. Parametry okna: W=13, S=7 Kolejne kroki kodowania: k a b r a k a d a b r a r (0,0,C(d)) a b r a k a d a b r a r r (7,4,C(r)) a d a b r a r r a r r a d (3,5,C(d)) Algorytm LZ77 – dekodowanie Startujemy z odkodowanego podciągu k a b r a k a Odkodowujemy (0,0,C(d)) – czyli C(d) k a b r a k a d Kopiowanie 1 znaku Odkodowujemy (7,4,C(r)) k a b r a k a d k a b r a k a d a Przesunięcie o 7 Kopiowanie 2 znaku k a b r Kopiowanie 3 znaku a k a d a b k a b r r a k a d a b r r Odkodowanie C(r) Kopiowanie 4 znaku k a b a k a d a b a k a b r a k a d a b r a r Algorytm LZ77 – dekodowanie – c.d. Odkodowanie (3,5,C(d)) a b a b r a r 1 znak a b a b r a r o 3 pozycje 2 znak a b a b r a r r r 3 znak a b a b a r a r r a r 4 znak a b a b r a r r a r 5 znak a b a b r Odkodowanie C(d) a b a b r a r r a r r a d r a r r a r r a Algorytm LZ77 – własności Prosta metoda adaptacyjna, nie wymaga wcześniejszej wiedzy o charakterze źródła Kodowanie moŜe być czasochłonne (duŜo porównań); dekodowanie proste i szybkie NieduŜe wymagania dotyczące pamięci Asymptotycznie – wyniki najlepsze jakie moŜna uzyskać przy pełnej częstości pojawiania się znaków i korelacji między nimi MoŜna zastosować róŜne modyfikacje algorytmu poprawiające jego efektywność Odmiany LZ77 Algorytm LZSS – unika konieczności wysyłania (o,l,c) Redundancja – albo nie trzeba pointera (bo jest zerowy), albo kodu znaku (moŜe być przekazany w następnym wejściu) Działanie: • Znajdź dopasowanie (o,l) • JeŜeli l ≥ MIN_LENGTH to wysyłamy (o, l ) i przesuwamy okno o l • JeŜeli l < MIN_LENGTH to wysyłamy kod pierwszego znaku z bufora kodowania i przesuwamy okno o 1 • Aby rozróŜnić oba przypadki ich zapisy poprzedzamy odpowiednimi flagami bitowymi Inne modyfikacje – poprawa efektywności kodowania – kodowanie trójek (lub dwójek liczb) kodowaniem o zmiennej długości – pakiety Pkzip, Zip, gzip, ARJ, LHarc Zastosowanie efektywnych struktur danych do reprezentacji zawartości bufora słownikowego (TRIE) Algorytm LZ78 Wada algorytmu LZ77 – skończony czas, w jakim wzorzec jest pamiętany – wzorce odległe o bardziej niŜ szerokość bufora słownikowego nie „czują” swej obecności a b c d e f g h i a b c d e f g h i a b c d e f g i a b LZ78 – zastąpienie bufora słownikowego słownikiem tworzonym explicite – dynamicznie w trakcie kodowania i dekodowania Słowniki – tabela zawierająca indeks i odpowiadający mu wzorzec. Na początku kodowania (dekodowania) – słownik pusty. Potem – ostatnio dopasowany wzorze + niedopas. znak Kodowanie – para (i,c), gdzie i – indeks, c – kod pierwszego niedopasowanego znaku LZ78 – przykład Ciąg do zakodowania: aa_bbb_cccc_ddddd_e Słownik: Nr Wzorzec 0 ^ 1 a 2 a_ 3 b 4 bb 5 _ 6 c 7 cc 8 c_ 9 d 10 dd 11 dd_ 12 e Kodowanie: (0,a)(1,_)(0,b)(3,b)(0,_)(0,c) (6,c)(6,_)(0,d)(9,d)(10,_) (0,e) Do słownika wstawiane są coraz dłuŜsze wzorce. JeŜeli jakaś fraza się powtarza, to wkrótce znajdzie się w całości w słowniku. Odkodowanie – bardzo proste. Własności algorytmu LZ78 Szybsze kodowanie niŜ dla LZ77 (znacznie mniej porównań stringów) Łatwe dekodowanie (choć wolniejsze niŜ dla LZ77 – konieczność odbudowy słownika) Wzorce są stale dodawane do słownika (1 wzorzec na jeden proces kodowania) i nie zapominane – niebezpieczeństwo przepełnienia pamięci Jest punktem wyjścia dla algorytmów pochodnych – najbardziej znany algorytm LZW. Algorytm LZW Zaproponowany w 1984 przez Terry’ego Welcha Główna modyfikacja – koder nie wysyła kodu pierwszego niedopasowanego znaku (a tylko indeks słownika) Aby to było moŜliwe – słownik na starcie zawiera wszystkie litery wyjściowego alfabetu Procedura kodowania: Próbujemy dopasować kawałek łańcucha wejściowego Niech s – maksymalny podłańcuch który ma wzorzec w słowniku (indeks j) o długości d, c – pierwszy niedopasowany znak Na wyjście: j (indeks wzorca zgodnego z s) Do słownika dodajemy s+c Przesuwamy znacznik pozycji o d Algorytm LZW – kodowanie • Przykład: kodujemy ciąg a b c a b b c a b b a a w D, ab – nie, ab do D4, wyjście 1 Indeks Wzorzec 1 a b w D, bc – nie, bc do D5, wyjście 2 2 b c w D, ca – nie, ca do D6, wyjście 3 3 c ab w D, abb – nie, abb do D7, wyjście 4 4 ab bc w D, bca – nie, bca do D8, wyjście 5 5 bc abb w D, abba – nie, abba do D9, wyjście 7 6 ca 7 abb 8 bca 9 abba a w D, wyjście 1 Wynik: 1234571 Zastosowanie LZW Format GIF Podstawa – b = ilość bitów na piksel. Zaczynamy od słownika o rozmiarze 2b+1. Po wypełnieniu – zwiększamy o czynnik 2. Maksymalny rozmiar – 4096. Po jego osiągnięciu – słownik jest zamroŜony. Kompresja obrazów - zestawienie Huffman Obraz Huffman Dyn. Huff. róŜnice róŜnice GIF 1_ch 57 504 32 968 32 261 51 085 2_ch 61 430 38 541 37 896 60 649 Ziemia 40 543 33 880 39 501 34 276 Miasto 58 374 52 643 52 321 61 580