青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-4  評論-40  文章-117  trackbacks-0


這份資料的格式很不錯,收了!謝謝整理者。

  GIF文件的圖象數據使用了可變長度編碼的LZW壓縮算法(Variable-Length_Code LZW Compression),這是從LZW(Lempel Ziv Compression)壓縮算法演變過來的,通過壓縮原始數據的重復部分來達到減少文件大小的目的。

標準的LZW壓縮原理
先來解釋一下幾個基本概念:
  LZW壓縮有三個重要的對象:數據流(CharStream)、編碼流(CodeStream)和編譯表(String Table)。在編碼時,數據流是輸入對象(圖象的光柵數據序列),編碼流就是輸出對象(經過壓縮運算的編碼數據);在解碼時,編碼流則是輸入對象,數據流是輸出對象;而編譯表是在編碼和解碼時都須要用借助的對象。

字符(Character):最基礎的數據元素,在文本文件中就是一個字節,在光柵數據中就是一個像素的顏色在指定的顏色列表中的索引值
字符串(String):由幾個連續的字符組成;
前綴(Prefix):也是一個字符串,不過通常用在另一個字符的前面,而且它的長度可以為0;
(Root):單個長度的字符串;
編碼(Code):一個數字,按照固定長度(編碼長度)從編碼流中取出,編譯表的映射值;
圖案:一個字符串,按不定長度從數據流中讀出,映射到編譯表條目.

  LZW壓縮的原理:提取原始圖象數據中的不同圖案,基于這些圖案創建一個編譯表,然后用編譯表中的圖案索引來替代原始光柵數據中的相應圖案,減少原始數據大小。看起來和調色板圖象的實現原理差不多,但是應該注意到的是,我們這里的編譯表不是事先創建好的,而是根據原始圖象數據動態創建的,解碼時還要從已編碼的數據中還原出原來的編譯表(GIF文件中是不攜帶編譯表信息的),為了更好理解編解碼原理,我們來看看具體的處理過程:

編碼器(Compressor)

  編碼數據,第一步,初始化一個編譯表,假設這個編譯表的大小是12位的,也就是最多有4096個單位,另外假設我們有32個不同的字符(也可以認為圖象的每個像素最多有32種顏色),表示為a,b,c,d,e...,初始化編譯表:第0項為a,第1項為b,第2項為c...一直到第31項,我們把這32項就稱為根。
  開始編譯,先定義一個前綴對象Current Prefix,記為[.c.],現在它是空的,然后定義一個當前字符串Current String,標記為[.c.]k,[.c.]就為Current Prefix,k就為當前讀取字符。現在來讀取數據流的第一個字符,假如為p,那么Current String就等于[.c.]p(由于[.c.]為空,實際上值就等于p),現在在編譯表中查找有沒有Current String的值,由于p就是一個根字符,我們已經初始了32個根索引,當然可以找到,把p設為Current Prefix的值,不做任何事繼續讀取下一個字符,假設為q,Current String就等于[.c.]q(也就是pq),看看在編譯表中有沒有該值,當然。沒有,這時我們要做下面的事情:將Current String的值(也就是pq)添加到編譯表的第32項,把Current Prefix的值(也就是p)在編譯表中的索引輸出到編碼流,修改Current Prefix為當前讀取的字符(也就是q)。繼續往下讀,如果在編譯表中可以查找到Current String的值([.c.]k),則把Current String的值([.c.]k)賦予Current Prefix;如果查找不到,則添加Current String的值([.c.]k)到編譯表,把Current Prefix的值([.c.])在編譯表中所對應的索引輸出到編碼流,同時修改Current Prefix為k ,這樣一直循環下去直到數據流結束。偽代碼看起來就像下面這樣:

 

Initialize String Table;
[.c.] = Empty;
[.c.]k = First Character in CharStream;
while ([.c.]k != EOF )
{
  if ( [.c.]k is in the StringTable)
  {
    [.c.] = [.c.]k;
  }
  else
  {
    add [.c.]k to the StringTable;
    Output the Index of [.c.] in the StringTable to the CodeStream;
    [.c.] = k;
  }
  [.c.]k = Next Character in CharStream;
}

Output the Index of [.c.] in the StringTable to the CodeStream;


來看一個具體的例子,我們有一個字母表a,b,c,d.有一個輸入的字符流abacaba。現在來初始化編譯表:#0=a,#1=b,#2=c,#3=d.現在開始讀取第一個字符a,[.c.]a=a,可以在在編譯表中找到,修改[.c.]=a;不做任何事繼續讀取第二個字符b,[.c.]b=ab,在編譯表中不能找,那么添加[.c.]b到編譯表:#4=ab,同時輸出[.c.](也就是a)的索引#0到編碼流,修改[.c.]=b;讀下一個字符a,[.c.]a=ba,在編譯表中不能找到:添加編譯表#5=ba,輸出[.c.]的索引#1到編碼流,修改[.c.]=a;讀下一個字符c,[.c.]c=ac,在編譯表中不能找到:添加編譯表#6=ac,輸出[.c.]的索引#0到編碼流,修改[.c.]=c;讀下一個字符a,[.c.]c=ca,在編譯表中不能找到:添加編譯表#7=ca,輸出[.c.]的索引#2到編碼流,修改[.c.]=a;讀下一個字符b,[.c.]b=ab,編譯表的#4=ab,修改[.c.]=ab;讀取最后一個字符a,[.c.]a=aba,在編譯表中不能找到:添加編譯表#8=aba,輸出[.c.]的索引#4到編碼流,修改[.c.]=a;好了,現在沒有數據了,輸出[.c.]的值a的索引#0到編碼流,這樣最后的輸出結果就是:#0#1#0#2#4#0.



來看一個具體的例子,我們有一個字母表a,b,c,d.有一個輸入的字符流abacaba。現在來初始化編譯表:#0=a,#1=b,#2=c,#3=d.現在開始讀取第一個字符a,[.c.]a=a,可以在在編譯表中找到,修改[.c.]=a;不做任何事繼續讀取第二個字符b,[.c.]b=ab,在編譯表中不能找,那么添加[.c.]b到編譯表:#4=ab,同時輸出[.c.](也就是a)的索引#0到編碼流,修改[.c.]=b;讀下一個字符a,[.c.]a=ba,在編譯表中不能找到:添加編譯表#5=ba,輸出[.c.]的索引#1到編碼流,修改[.c.]=a;讀下一個字符c,[.c.]c=ac,在編譯表中不能找到:添加編譯表#6=ac,輸出[.c.]的索引#0到編碼流,修改[.c.]=c;讀下一個字符a,[.c.]c=ca,在編譯表中不能找到:添加編譯表#7=ca,輸出[.c.]的索引#2到編碼流,修改[.c.]=a;讀下一個字符b,[.c.]b=ab,編譯表的#4=ab,修改[.c.]=ab;讀取最后一個字符a,[.c.]a=aba,在編譯表中不能找到:添加編譯表#8=aba,輸出[.c.]的索引#4到編碼流,修改[.c.]=a;好了,現在沒有數據了,輸出[.c.]的值a的索引#0到編碼流,這樣最后的輸出結果就是:#0#1#0#2#4#0.

解碼器(Decompressor)

  好了,現在來看看解碼數據。數據的解碼,其實就是數據編碼的逆向過程,要從已經編譯的數據(編碼流)中找出編譯表,然后對照編譯表還原圖象的光柵數據。
  首先,還是要初始化編譯表。GIF文件的圖象數據的第一個字節存儲的就是LZW編碼的編碼大小(一般等于圖象的位數),根據編碼大小,初始化編譯表的根條目(從0到2的編碼大小次方),然后定義一個當前編碼Current Code,記作[code],定義一個Old Code,記作[old]。讀取第一個編碼到[code],這是一個根編碼,在編譯表中可以找到,把該編碼所對應的字符輸出到數據流,[old]=[code];讀取下一個編碼到[code],這就有兩種情況:在編譯表中有或沒有該編碼,我們先來看第一種情況:先輸出當前編碼[code]所對應的字符串到數據流,然后把[old]所對應的字符(串)當成前綴prefix [...],當前編碼[code]所對應的字符串的第一個字符當成k,組合起來當前字符串Current String就為[...]k,把[...]k添加到編譯表,修改[old]=[code],讀下一個編碼;我們來看看在編譯表中找不到該編碼的情況,回想一下編碼情況:如果數據流中有一個p[...]p[...]pq這樣的字符串,p[...]在編譯表中而p[...]p不在,編譯器將輸出p[...]的索引而添加p[...]p到編譯表,下一個字符串p[...]p就可以在編譯表中找到了,而p[...]pq不在編譯表中,同樣將輸出p[...]p的索引值而添加p[...]pq到編譯表,這樣看來,解碼器總比編碼器慢一步』,當我們遇到p[...]p所對應的索引時,我們不知到該索引對應的字符串(在解碼器的編譯表中還沒有該索引,事實上,這個索引將在下一步添加),這時需要用猜測法:現在假設上面的p[...]所對應的索引值是#58,那么上面的字符串經過編譯之后是#58#59,我們在解碼器中讀到#59時,編譯表的最大索引只有#58,#59所對應的字符串就等于#58所對應的字符串(也就是p[...])加上這個字符串的第一個字符(也就是p),也就是p[...]p。事實上,這種猜測法是很準確(有點不好理解,仔細想一想吧)。上面的解碼過程用偽代碼表示就像下面這樣:


Initialize String Table;
[code] = First Code in the CodeStream;
Output the String for [code] to the CharStream;

[old] = [code];
[code] = Next Code in the CodeStream;
while ([code] != EOF )
{
  if ( [code] is in the StringTable)
  {
    Output the String for [code] to the CharStream;
// 輸出[code]所對應的字符串
    [...] = translation for [old]; // [old]所對應的字符串
    k = first character of translation for [code]; // [code]所對應的字符串的第一個字符
    add [...]k to the StringTable;
    [old] = [code];

  }
  else
  {
    [...] = translation for [old];
    k = first character of [...];
    Output [...]k to CharStream;
    add [...]k to the StringTable;
    [old] = [code];

  }
  [code] = Next Code in the CodeStream;
}



 

posted on 2009-10-30 17:34 李陽 閱讀(1494) 評論(1)  編輯 收藏 引用 所屬分類: 圖形圖像

評論:
# re: LZW算法和GIF數據壓縮 2012-12-01 09:31 | baozhi1992@gmail.com
在decompression那講的太好了!
我翻了幾十個blog/帖子,
就你講的我看明白了!!!!!!!!!  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久丁香综合五月国产三级网站| 欧美亚洲色图校园春色| 欧美激情一区二区三区全黄| 亚洲精品视频在线| 卡一卡二国产精品| 国模精品一区二区三区色天香| 一区二区三区视频在线| 麻豆91精品| 午夜视频久久久| 国产精品欧美在线| 亚洲一区三区在线观看| 亚洲精品女av网站| 亚洲网站视频| 欧美亚洲成人精品| 亚洲视屏一区| 一区二区三区波多野结衣在线观看| 欧美老女人xx| 亚洲视频你懂的| 一区二区三区高清在线| 欧美天堂亚洲电影院在线观看| 亚洲性线免费观看视频成熟| 一区二区日韩免费看| 国产精品美女久久久久久2018 | 日韩网站在线看片你懂的| 欧美gay视频激情| 亚洲精品国产精品乱码不99| 亚洲国产三级| 欧美日韩国产综合网| 亚洲小说区图片区| 亚洲欧美日韩天堂| 亚洲理论在线| 久久久精品视频成人| 玉米视频成人免费看| 欧美国产精品日韩| 欧美黑人多人双交| 一本色道久久88综合日韩精品| 亚洲欧洲另类国产综合| 欧美日韩妖精视频| 亚洲自拍偷拍一区| 午夜视频在线观看一区二区| 亚洲第一色在线| 欧美激情中文字幕乱码免费| 艳女tv在线观看国产一区| 国产精品99久久久久久久女警| 国产精品日韩欧美| 欧美电影在线观看| 国产精品激情av在线播放| 久久久视频精品| 欧美精品免费观看二区| 欧美在线精品免播放器视频| 久久久久久亚洲精品杨幂换脸| 99精品视频免费| 新狼窝色av性久久久久久| 亚洲国产一区二区三区在线播| 亚洲美女免费视频| 激情欧美一区二区三区| 亚洲精选视频在线| 黑人巨大精品欧美一区二区| 亚洲国产精品久久久久秋霞影院| 国产精品免费一区二区三区观看| 男女激情视频一区| 国产精品久久久久久模特| 欧美成人精品激情在线观看| 国产精品久久久久久久免费软件| 欧美国产日韩一区二区三区| 国产精品theporn88| 久久三级福利| 国产精品夫妻自拍| 亚洲国产成人在线播放| 国产日韩成人精品| 亚洲精品视频中文字幕| 伊人久久噜噜噜躁狠狠躁| 亚洲理论在线| 亚洲第一页在线| 午夜日韩视频| 亚洲欧美日本在线| 欧美激情精品久久久久久久变态| 久久www成人_看片免费不卡 | 国产午夜久久| 99热免费精品| 亚洲乱码精品一二三四区日韩在线 | 国产精品日韩在线| 亚洲精品色图| 欧美精品激情在线观看| 午夜精品久久久久99热蜜桃导演| 欧美精品在线视频观看| 亚洲视频1区| 欧美国产日本高清在线| 亚洲一区二区三区在线| 韩国精品一区二区三区| 国产精品一区二区久久久久| 欧美一级成年大片在线观看| 欧美国产日韩视频| 久久国产日韩欧美| 欧美性猛交视频| 亚洲国产精品悠悠久久琪琪 | 欧美视频日韩视频| 亚洲精品综合精品自拍| 亚洲美女视频在线观看| 久久国产精品一区二区三区| 国产精品乱码人人做人人爱| 99re成人精品视频| 亚洲在线观看免费视频| 国产精品v亚洲精品v日韩精品| 一区二区三区精品久久久| 一区二区三区产品免费精品久久75| 欧美成人免费全部| 亚洲黄色精品| 一区二区日韩伦理片| 欧美日韩在线三级| 国产精品99久久99久久久二8| 亚洲综合日韩中文字幕v在线| 国产精品成人一区二区艾草| 国产精品99久久久久久宅男| 午夜一区二区三区在线观看| 国产亚洲永久域名| 久久久另类综合| 亚洲欧洲一区二区三区久久| 一区二区三区成人精品| 国产美女精品免费电影| 久久精品免费观看| 91久久久久久久久久久久久| 一区二区三区精品在线| 国产精品一区一区三区| 久久国内精品自在自线400部| 欧美成人国产va精品日本一级| 亚洲精品欧美日韩专区| 欧美四级剧情无删版影片| 午夜在线a亚洲v天堂网2018| 久久夜色精品国产| 亚洲精品人人| 国产精品久久久久久久浪潮网站| 久久av资源网站| 亚洲国产网站| 久久精品亚洲国产奇米99| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲美女av电影| 国产日韩欧美精品综合| 国产精品一区在线观看| 影音先锋中文字幕一区| 亚洲一区中文| 亚洲精品国产精品国自产在线| 欧美一区亚洲| 国产精品综合久久久| 中文精品一区二区三区| 久久夜色精品国产噜噜av| 美乳少妇欧美精品| 免费不卡在线视频| 在线视频欧美日韩| 免费成人av在线看| 欧美在线啊v| 99re66热这里只有精品3直播| 国产在线精品一区二区中文| 免费h精品视频在线播放| 亚洲已满18点击进入久久| 欧美/亚洲一区| 亚洲欧美经典视频| 亚洲日本成人| 国一区二区在线观看| 欧美视频中文一区二区三区在线观看| 久久精品在线观看| 亚洲午夜激情| 亚洲久久一区| 亚洲国产欧美日韩精品| 看片网站欧美日韩| 亚洲欧美日韩人成在线播放| 99精品国产高清一区二区| 在线观看三级视频欧美| 国产伦精品免费视频| 国产精品国产三级国产普通话99 | 亚洲精品久久嫩草网站秘色| 国产一区二区三区四区五区美女| 国产精品video| 欧美成人中文| 欧美成人午夜| 麻豆久久久9性大片| 久久蜜臀精品av| 久久不射2019中文字幕| 午夜精品一区二区三区四区| 一区二区三区国产在线| av成人激情| 亚洲精品一区久久久久久 | 欧美日韩一区二区三区免费 | 亚洲日本中文字幕区| 在线日韩欧美视频| 亚洲高清中文字幕| 狠色狠色综合久久| 免费av成人在线| 欧美+日本+国产+在线a∨观看| 亚洲欧洲久久| 一本一本大道香蕉久在线精品| 亚洲欧洲另类国产综合| aa成人免费视频| 亚洲一区二区三区免费观看| 在线一区二区日韩| 午夜在线视频一区二区区别| 午夜久久久久久| 久久久精品一区| 欧美a级片网站| 亚洲一区二区3|