在上一部份處理完MCU的DCT及量化,這篇要介紹如何進行對係數進行編碼。
一個8x8 MCU經過量化後可分為
從2-D DCT可發現DC coefficient代表區塊內像素平均值,由於鄰近區塊的DC coefficient有相似性,以DPCM方式編碼使值縮小,可以在之後的壓縮取得不錯成效。
例如
代表
AC coefficient藉由zig-zag順序來將低頻率的係數放在前面,有助於entropy coding。又因區塊小,跨區塊變化也小,高頻部份趨近於0,適合以RLE方式編碼。
接者編碼AC/DC coefficient成Bit-stream。
DC/AC coefficient在檔案中的存放方式
DC/AC coefficient需經過Huffman encoding才寫入。
下表範例是經過Huffman encoding的資料集以及其codeword
Symbol | a | b | c | d | e |
---|---|---|---|---|---|
weights | 0.10 | 0.15 | 0.30 | 0.16 | 0.29 |
codeword | 0b010 | 0b011 | 0b11 | 0b00 | 0b10 |
JPEG分兩部份存Huffman table,第一個部份存codeword length,第二個存decoded value,實作上可使用兩個迴圈建出Huffman tree。Expansion of DHT Table into binary bit strings敘述如何利用codeword length及decoded value重建code word:
步驟如下:
了解上述流程才能理解Huffman table在JPEG內所佔空間為何是16+n
bytes
In JPEG all Huffman code tables are defined in the image header. Each table requires 16 + n bytes, where n is the number of codewords in the table. The first 16 bytes list the number of codewords of each length from 1 to 16 bits (codewords longer than 16 bits are forbidden). The remaining n bytes list the decoded output values of the n codewords in ascending codeword order (n < 256).
以下方HEX Code為例,嘗試解出Huffman table:
Codeword length (bits) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | … | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|
Decoded value | - | 0x00 | 0x01, 0x02, 0x03, 0x04, 0x05 | 0x06 | 0x07 | 0x08 | 0x09 | 0x0A | 0x0B | - | - |
Symbol | Codeword | Bit-length |
---|---|---|
0x00 | 00 | 2 |
0x01 | 010 | 3 |
0x02 | 011 | 3 |
0x03 | 100 | 3 |
0x04 | 101 | 3 |
0x05 | 110 | 3 |
0x06 | 1110 | 4 |
0x07 | 11110 | 5 |
0x08 | 111110 | 6 |
0x09 | 1111110 | 7 |
0x0A | 11111110 | 8 |
0x0B | 111111110 | 9 |
當採用Optimized
Luminance/Chrominance的DC/AC coefficient分別個一張表,共4張表
一般來說,JPEG不會對各種係數各建一張表,除非儲存時選擇Optimized
。
Optimized JPEG指的是對Y(Luminance), CbCr(Chrominance)不同DC/AC係數各算一張Huffman table,雖然在檔案中需額外定義,但整體空間省下2.4~6.8%。現代高階相機具有輸出Optimized JPEG的能力,但考慮到耗時與節省的空間不成比例,多採用JPEG ITU-T81D standard, 149-157提供的Huffman table。
計算Optimized JPEG的Huffman table方式不只一種,最簡單的方式是採用先前提到的作法:將係數化成Size
和Additional bits
,再對Size
進行編碼。也有的軟體有自家處理的方法,例如Photoshop CS2限制DC chrominance table不得有0xA-0xB
、EOB
為在DC luminance table內為5位元長度的codeword。
由於JPEG對於Huffman table的限制,DC table的Size
為0x0-0xB
,也就是最多12個code word;AC table的Run
與Size
分別為0x0-0xF
、0x1-0xA
,再加上EOB (0x00)
與ZRL (0xF0)
共162個code word。Standard huffman tables必須涵蓋所有code word。
使用方式如下,拿Table K3的category對應到Luminance的DC係數的Size。例如Size = 3, 對應的code word就是0b100
。
但即使存儲影像時選擇Standard
也未必採用Standard huffman table,例如Photoshop CS2輸出的檔案,其Huffman table會依據quaility而定。
DC coeffiecient並非直接經過Huffman encoding直接寫入檔案,先前提過由於相鄰的區塊DC coefficient有所關係,使用DPCM可降低entropy。
但經過DPCM轉換有著Difference過大的問題,想像一下原始圖片數值介於[0,255]
,假設經過DCT放大8倍,Difference同樣擴大8倍,這會造成code table非常巨大。因此進一步採用floating-point representation。
Decode
Huffman table解碼出的值,對應到下方表格的Size
、。Size=5
代表要讀取5 bits的Additional bits
,再對應到實際的值。在給定Size
下,每個Additional bits
出現的機率相近,使得entropy coding效率高。
DC Value (Size) | Additional bits | Value (DC Coef Difference) |
---|---|---|
0x05 | 0b00101 | -26 |
Size = 0
具有特殊意義,代表該MCU結束(End of block)Encode
Example
以一小段hex作為範例,MCU 1, 2的DC Coef分別是 -512、+508
Run-length encoding(RLE)具有以下特性:
影像經過DCT及Quantization,數值集中在左上角,AC coefficient以zig-zag順序排成一維陣列,進行 (RLE)可以得到不錯的效果。
觀察zig-zag matrix
我們可以拿zigzag matrix生成函式的一部份,窮舉所有座標對應的值,依照這些值進行遞增排序即為zig-zag order。
預先生成8x8 zig-zag matrix:
The codeword represents the run-length of zeros before a non-zero coef and the Size of that coef. This is then followed by the Additional Bits which define the coef amplitude and sign precisely. Size and Additional Bits are defined just as for DC coefs.
編碼方式:
步驟如下:
(Run, Size)
組合而成的位元組進行Huffman encoding得到codeword,例如 Run=0x0A, Size=0x03, (Run, Size)=0xA3
Additional bit
之所以將Run
和Size
放在一起進行編碼,是因為Run
和Size
關聯性高(較小的係數通常前面0多,較大的係數前面0較少)。
有些特殊的組合:
EOB=(0,0)
ZRL=(15,0)
The procedure “Append EHUFSI(X’F0’) bits of EHUFCO(X’F0’)” codes a run of 16 zero coefficients (ZRL code of Figure F.1). The procedure “Code EHUFSI(0) bits of EHUFCO(0)” codes the end-of-block (EOB code). If the last coefficient (K = 63) is not zero, the EOB code is bypassed. - ISO/IEC 10918-1:19, 90-91
EOB
代表後續無係數,ZRL
用來與其他(Run, Size)
使用表示更長的run,例如:
等同
如果不想對(Run, Size)
進行Huffman encoding,可以使用上方的Table K.3。
Example
這篇弄清了係數如何進行編碼AC/DC coeffieient,下篇介紹如何將這些東西塞進檔案。此外,我們並未進行down-sampling,但後續仍需處理這部份的JPEG header。