JPEG解碼——(4)霍夫曼解碼

本篇是該系列的第四篇,主要介紹霍夫曼解碼相關內容。編碼

承接上篇,文件頭解析完畢後,就進入了編碼數據區域,即SOS的tag後的區域,也是圖片數據量的大頭所在。spa

1. 解碼過程規則描述blog

a)今後顏色份量單元數據流的起點開始一位一位的讀入,直到讀入的編碼與該份量直流哈夫曼樹的某個碼字(葉子結點)一致,而後用直流哈夫曼樹圖片

      查得該碼字對應的權值。權值(共8位)表示該直流份量數值的二進制位數,也就是接下來須要讀入的位數。變量

b)繼續讀入位數據,直到讀入的編碼與該份量交流哈夫曼樹的某個碼字(葉子結點)一致,而後用交流哈夫曼樹查得該碼字對應的權值。權值的高4位二進制

      表示當前數值前面有多少個連續的零,低4 位表示該交流份量數值的二進制位數,也就是接下來須要讀入的位數。im

c)不斷重複步驟b,直到知足交流份量數據結束的條件。d3

      而結束條件有兩個,只要知足其中一個便可:數據

①當讀入碼字的權值爲零,表示日後的交流變量所有爲零;
②已經讀入63個交流份量。img

2. 待處理的數據區域

  上面的規則描述過於抽象,須要一個例子來實戰說明,仍使用那張animal_park.jpg的圖片。

  其二進制數據顯示以下(FFDA所表明的SOS以後深色標註區域):

  截取到的二進制數據爲:F9 96 8B FA 71 EA 5B 24 B5 ...

3. 準備好霍夫曼表

  先列出四張霍夫曼表——DC0,AC0, DC1,AC1,待後面查找使用。

  DC0——Y份量的直流部分

  AC0——Y份量的交流部分(表太長,沒列全)

 

   DC1——UV份量的直流部分

  AC1——UV份量的交流部分

4. 解碼步驟

  這是難點所在,解碼的過程其實就是霍夫曼樹的查找過程。mcu單元內部使用了RLE行程編碼和霍夫曼編碼來壓縮數據。

  例子:F9 96 8B FA 71 EA 5B 24 B5。。。

  對應的二進制位展開:1111 1001, 1001 0110, 1000 1011, 1111 1010, 0111 0001, 1110 1010, 0101 1011, 0010 0100, 1011 0101。。。

step1. 先讀入若干位與DC0表的Code進行匹配。

          讀取2位的11時,  無匹配的Code,由於2位寬的Code只有0b00和0b01

                 3位的111        無                              3                           0b100,0b101和0b110。

                 4位的1111      無                              4                            0b1110。

                 5位的11111    無                              5                            0b11110。

                 6位的111110  有                              6                            0b111110,剛好匹配!其對應的CodeVal爲0x7

step2. 利用上面獲得的CodeVal進行拆分,並讀取後面若干位。
  0x7=0x07,高四位爲0,低四位爲7,則再讀取後面的7位二進制,爲:01, 1001 0。
  後面讀取的值,這樣算:若是開頭爲1則爲正數,若是開頭爲0,則爲負數,而後對各位求反獲得數值,便可。

  01, 1001 0這個值,因爲開頭爲0,則爲負數,多少呢?取反獲得:10, 01101 = 0x4D = 77,最後獲得最終值爲:-77。

step3. 經過上面兩步驟的第一次掃描,獲得的爲Y份量的DC值,後面還需通過63次掃描獲得剩餘的AC值(通常掃描幾回就結束了)。

  上面DC值標記爲-77。

step4. 繼續經過相似step1和step2來取得AC值,注意要查找AC0表。

  讀取5位的110, 10時,有匹配的Code:0b11010=0x1a,其對應的CodeVal=0x04;
  取得後四位的值——4,表示還需讀取的二進制位數量,來表示真正的信源值——0b0010,經(step2中描述)變換後值爲-13;
  那麼能夠RLE標記爲(0,-13),其中0來自於CodeVal的高4位,-13爲另讀入的數據值。可也記爲key-val對。

step5. 重複step4的操做,直到獲得(0,0)(位置爲5B那個字節的最高四位)。

   後面的依次爲:

  Code                                CodeVal          RLE_val         RLE

 11, 1111 1010(0x3FA)         0x34            0111(-8)         (3, -8)

 00                                        0x1              0 (-1)              (0, -1)

 1, 1110 10(0x7A)                 0x71            1(1)                 (7, 1)

00                                          0x1             1(1)                 (0, 1)

01                                          0x0              --                    (0, 0)  -> 結束於5B的高4位

step6. 經過step1-step5的掃描,獲得數據:-77, (0, -13), (3, -8),(0, -1),(7, 1), (0, 1), (0, 0)

step7. step1到step6結束後,表示一個mcu的霍夫曼解碼結束。

  RLE中的(m,n),m表示前面填充0的個數,n表示實際值。

  其解碼結果以下:

相關文章
相關標籤/搜索