2017年1月29日 星期日

JPEG 編碼解碼流程

網路串流影像的主流格式是 H.264, H.265 以及 VP9,不過針對特殊應用,仍有使用 JPEG的地方。本篇參考WIKI 說明,整理 JPEG 編解碼流程,以及 JFIF 格式封裝方法,方便自己遇到問題時可以當作參考。

JPEG 編碼流程

  1. 將 RGB 轉換為 YUV。
  2. 將 YUV444 轉換為 YUV422 或 YUV420。
  3. 將 Y 區域劃分成多個 8x8 子區域,每個區域使用 DCT 轉換到頻率空間。轉換之後,每個子區域的左上角會使用差分編碼,其他欄位會使用行程編碼
  4. 量化,把人眼不容易辨別的差異移除。其實現方式就是把很多更高頻率的成份捨位成為接近0,且剩下很多會變成小的正或負數。這是整個壓縮過程中的主要失真運算。
  5. entropy coding:將影像成份以Z字型(zigzag)排列,把相似頻率群組在一起(矩陣中往左上方向是越低頻率之係數,往右下較方向是較高頻率之係數),插入長度編碼的零,且接著對剩下的使用霍夫曼編碼


JPEG 解碼流程
將上述編碼流程反向即可。
JPEG 用到的各種編碼方式
差分編碼(Delta encoding)
  • 原理:儲存序列式資料之間的差異(而不是儲存資料本身)
  • 舉例說明:若原本資料為 「2, 4, 6, 9, 7」,不儲存原始資料,只儲存差異值,結果會儲存「2, 2, 2, 3, -2」 
行程編碼(RLE,run-length encoding)
  • 原理:「使用變動長度的碼來取代連續重複出現的原始資料」的壓縮技術。
  • 舉例說明:"AAAABBBCCDEEEE",經過 RLE 可將資料壓縮為 4A3B2C1D4E(由14個單位轉成10個單位) 
霍夫曼編碼(Huffman Coding)

JFIF(JPEG File Interchange Format)
JFIF 是一種封裝 JPEG 資料的方式。通常使用者所稱的 JPEG 檔案,就是指一個 JFIF 檔案。 JFIF 固定格式是 FF xx s1 s2 data bytes,其中各個欄位說明如下: 
FF xx
此處表示各種可能的標記(Marker)組合,幾個常見的標記如下:
FF D8 (SOI) Start of Image
FF D9 (EOI) End of Image
FF E0      APP0 marker
FF DB  (DQT) Define Quantization Table
FF DA     (SOS)Start of Scan 
s1,s2
這兩個位元用來表示長度,實際表示的長度值為  256 * s1 + s2 - 2, 
"data bytes"
根據每個不同的 Marker,後面可能會接續不同的資料。可以參考 http://www.baike.com/wiki/jfif