事實上,在LZW中使用hash的具體方式有很多,開發者會基於時間/空間上的不同考慮選擇不同的解決方案。
在LZW算法中,首先建立壹個字符串表,將每個第壹次出現的字符串放入字符串表中,用壹個數字表示,這個數字與字符串在字符串表中的位置有關,這個數字存儲在壹個壓縮文件中。如果該字符串再次出現,它可以被代表它的數字替換,這個數字存儲在文件中。壓縮後丟棄字符串表。例如,如果“print”字符串在壓縮時用266表示,那麽每當它再次出現時就用266表示,“print”字符串將存儲在字符串表中。當圖像解碼過程中遇到數字266時,可以從字符串表中找出用266表示的字符串“print”,解壓時可以根據壓縮數據重新生成字符串表。
壓縮算法的壹個簡單例子不是完全實現lzw算法,而是從最直觀的角度來看LZW算法的思想。
LZW壓縮的原始數據ABCCAABCDDAACCDB。
原始數據中只包含四個字符(A,B,C,D),這四個字符可以用壹個2-2位數來表示,0-A,1-B,2-C,3-D,從最直觀的角度來看,原始字符串中有重復的字符:ABCCAABCDDAACCDB,4表示AB,4。
-
LZW數據壓縮算法原理分析
希望通過本文的介紹,能給目前對lzw算法及其在gif圖像中的應用不太了解,但又渴望了解的人壹些啟發和幫助。只是為了引玉,希望園裏的兄弟們提出寶貴意見。
1的全稱是什麽?LZW?
倫佩爾-齊夫-韋爾奇(LZW)。
2.LZW的引入和壓縮原理是什麽?
LZW壓縮算法是壹種新穎的壓縮方法,由萊姆普爾-齊夫-韋爾奇創立,並以他們的名字命名。它采用了高級的字符串表壓縮,將每個第壹個字符串放在壹個字符串表中,並使用壹個數字來表示該字符串。壓縮後的文件只存儲數字,不存儲字符串,大大提高了圖像文件的壓縮效率。神奇的是,這個字符串表在壓縮或解壓縮時都能正確建立,壓縮或解壓縮後又被丟棄。
在LZW算法中,首先建立壹個字符串表,將每個第壹次出現的字符串放入字符串表中,用壹個數字表示,這個數字與字符串在字符串表中的位置有關,這個數字存儲在壹個壓縮文件中。如果該字符串再次出現,它可以被代表它的數字替換,這個數字存儲在文件中。壓縮後丟棄字符串表。例如,如果“print”字符串在壓縮時用266表示,那麽每當它再次出現時就用266表示,“print”字符串將存儲在字符串表中。當圖像解碼過程中遇到數字266時,可以從字符串表中找出用266表示的字符串“print”,解壓時可以根據壓縮數據重新生成字符串表。
3.在詳細介紹算法之前,先列出壹些與算法相關的概念和詞匯。
1)'字符':壹個字符,壹個基本的數據元素,在壹個普通的文本文件中占據1個單獨的字節,但是在壹個圖像中,它是壹個表示給定像素的顏色的索引值。
2)“CharStream”:數據文件中的字符流。
3)“前綴”:前綴。和這個詞的意思壹樣,代表壹個字符之前最直接的字符。前綴字符的長度可以是0,前綴和字符可以組成壹個字符串。
4)‘後綴’:後綴,是壹個字符。壹個字符串可以由(A,B)組成。a是前綴,b是後綴。當A的長度為0時,它代表根,Root。
5)‘Code:代碼,用來表示壹個字符串的位置編碼。
6)“條目”,壹個代碼和它所代表的字符串。
4.壓縮算法的簡單例子並不是要完全實現lzw算法,而是從最直觀的角度來看LZW算法的思想。
LZW壓縮的原始數據ABCCAABCDDAACCDB。
原始數據中只包含四個字符(A,B,C,D),這四個字符可以用壹個2-2位數來表示,0-A,1-B,2-C,3-D,從最直觀的角度來看,原始字符串中有重復的字符:ABCCAABCDDAACCDB,4表示AB,4。
5.5的適用範圍。LZW算法
為了區分代表壹個字符串的值(代碼)和原來的單個數據值(字符串),需要使它們的數值域不重合,用0-3來代表A-D,所以AB必須用大於3的數值來代替。再比如,原來的數值範圍可以用8位表示,所以認為原來的數值範圍是0 ~ 255,壓縮程序生成的標簽範圍不能是0 ~。我們只能從256開始,但這樣會超出8位表示的範圍,所以我們必須至少擴展壹位的數據位數,但這不是增加了1個字符所占用的空間嗎?但是,壹個字符可以代表幾個字符。比如255以前是8位,現在用256來表示254和255這兩個數字是值得的。從這個原理可以看出,LZW算法的適用範圍是原始數據串要有大量重復多次的子串,重復次數越多,壓縮效果越好。相反,越是糟糕,實際上可能越是增加而不是減少。
6.6中的特殊標記。LZW算法
隨著新字符串的發現,標簽將繼續增長。如果原始數據過大,生成的標簽表會越來越大。這時候操作這壹套會造成效率問題。如何避免這個問題?Gif使用lzw算法的方式是,當標簽集足夠大時,它顯然不會增加,所以只需從頭開始。在這個位置,插入了壹個標簽,意味著我重新開始構造字典,之前的標簽全部無效,開始使用新的。
這時,另壹個問題出現了。它有多大?這個標簽集的合適大小是多少?理論上,標簽集越大,壓縮比越高,但開銷也越高。壹般根據處理速度和內存空間來選擇。GIF規範規定12位,如果表達式範圍超過12位,就要推倒重來。為了提高壓縮比,GIF使用了可變字長。比如原來的數據是8位,那麽開始的時候先加1位,初始字長變成9位,然後開始加標簽。當標簽加到512時,也就是大於9是能表示的最大數據量時,意味著後面的標簽只能用10比特表示,所以從這裏開始,後面的字長就是10。以此類推,到2 12,也就是4096的時候,在這裏插壹個清號,從後面開始,從9位數開始。
GIF指定的CLEAR標誌的值是原始數據字長的最大值加上1。如果原始數據字長是8,那麽清零標誌是256,如果原始數據字長是4,那麽就是16。此外,GIF還指定了壹個結束標誌END,其值為CLEAR標誌加1。因為GIF中規定的位數是1(單色圖像)、4 (16彩色)和8 (256彩色),如果在1比特的情況下只擴展1比特來表示4個狀態,那麽加上壹個清除標誌和壹個結束標誌就會用完,所以1比特就會用完。在另外兩種情況下,初始字長分別為5位和9位。/whycadi/
7.lzw算法壓縮原始數據的實例分析
輸入流,即原始數據為:255,24,54,255,24,255,255,24,5,123,45,255,24,5,24,54。..................
這只是gif文件中像素數組的壹部分。怎麽壓縮?
因為原始數據可以用8位表示,所以清零標誌為Clear=255+1 =256,結束標誌為End=256+1=257,當前標簽集為
0 1 2 3 .................................................................................255清除結束
第壹步是將第壹個字符讀為255,並在標記表中查找它。255已經存在,我們也已經知道了255,就不處理了。
第二步,取第二個字符,此時前綴為a,當前條目為(255,24),標簽集中不存在。我們不知道255,24。這次妳小子來了,我會記住妳,在標簽集中標記為258,然後輸出前綴A,保留後綴24,作為下壹個前綴(後綴變前綴)。
第三步,取第三個字符為54,當前條目(24,54),我不知道,記錄(24,54)為數字259,輸出24,後綴改為前綴。
第四部分:取第四個字符255,Entry=(54,255),我不知道,記(54,255)為參考數260,輸出54,後綴改為前綴。
第五步取第五個字符24,entry=(255,24),啊,我認識妳,這不是舊的258嗎,所以字符串指定為258,作為前綴。
第六步:取第六個字符255,entry=(258,255),不知道,記(258,255)為261,輸出258,後綴改為前綴。
.......
直到最後壹個字符。