Sunday, August 26, 2007

Marker Code Assignment in JPEG files


規格書 P. 32 的 Table B.1 列出了所有的 JPEG 可能使用到的 Marker。JPEG 的 Marker Segments 就是由一個 Marker 後面連接著一串相關的參數。

Restart Interval in JPEG files


這個圖是出現在規格書 P.43, Figure B.9 - Restart interval definition syntax。

DRI: Define restart interval marker
 從規格書 Table B.1 中可以查到 DRI marker 的 code assignments 是 X'FFDD', 在 Rex.pdf 文件中, DRI marker 是出現在 P.23, address 00003586h。

Lr: Define restart interval segment length
 從規格書 Table B.8 可以看到 Lr 的值永遠為 4 , 表示 DRI segment 的長度是固定為 4。

Ri: Restart interval - Specifies the number of MCU in the restart interval.
 Ri 指出在這個 Restart interval 中, Entropy-coded segment (ECS) 包含多少個 MCUs。

  

 在 Rex.pdf 文件中, P.23 的 Ri 為 X'000F', 表示 ECS 包含了 15 個 MCUs。
 

Thursday, August 23, 2007

Frame Header in JPEG files

Frame header 出現在 frame 資料的最前端, 主要指明:
1. the source image characteristics,
 來源影像的一些特性, 如長、寬等。
2. the components in the frame,
 來源影像由多少個 components 組成。
3. the sampling factors for each component,
 每一個 component 的取樣因數。
4. the destination from which the quantized tables to be used with each component are retrieved.
 每一個 quantization table 都有一個 destination identifier, 當我們要指明某個 component 要使用哪一個 quantization table 來作量化處理時, 就是在 frame header 中指明該 table 的 destination identifier。
 

這個圖是出現在規格書 P. 35 的 Figure B.3 Frame header syntax。

SOFn: Start of Frame marker,
利用 n 來指明屬於哪一種模式的壓縮方式, 詳細列表在規格書 P. 32 Table B.1 。
Rex.pdf 文件中, 你可以在 P. 23 , Address 00003573h 找到 X'FFC0', 換句話說, Rex.jpg 這張影像是屬於 Baseline DCT 的壓縮模式。



Lf: Frame Header Length
 Frame header 的長度。在 Rex.pdf 中, Lf = 0011h, 因此共 17 Bytes。

P: Sample Precision

 每一個 sample 用多少個 bits 來記錄其值。
 P = 0008h, 表示每個 sample 用 8 bits 存。

Y: Number of lines

 影像的高, Y = 0078h, Rex.jpg 影像高 120 pixels。

X: Number of samples per line

 影像的寬, X = 0078h, Rex.jpg 影像寬 120 pixels。

Nf: Number of image component in frame
 影像是由 Nf 個 components 所組成,
 Rex.jpg 就是由 3 個 components 所組成的彩色影像。

在 Nf 參數之後的是 Nf 組 Component-specification parameters, 每一個 component 都有一組對應的參數來描述:

Ci: Component identifier
 每一個 component 都有一個 identifier 來做識別代碼。
 第 i 個 component 的 identifier 就是 Ci。

Hi: Horizontal sampling factor
 第 i 個 component 的水平取樣參數。
 
Vi: Vertical sampling factor
 第 i 個 component 的垂直取樣參數。
 
Tqi: Quantization table destination selector
 指明第 i 個 component 是用哪一個 quantization table 來做量化處理。

Rex.jpg 這張影像中, 一共有 3 個 components, 因此共有 3 組的 Component-specification parameters, 分別如下:
C1 = 01, H1 = 1, V1 = 1, Tq1 = 00;
C2 = 02, H2 = 1, V2 = 1, Tq2 = 01;
C3 = 03, H3 = 1, V3 = 1, Tq3 = 01。
 

Sunday, August 19, 2007

JPEG High-level Syntax


這是 JPEG 規格書 P. 34 所提供的語法圖(Figure B.2), 如果想看懂 JPEG 儲存格式, 然後寫一個 JPEG Decoder, 可以從看懂這個圖開始著手。

由上而下的第一層告訴我們: JPEG Compressed image data 最前面必須有一個 SOI marker, 最後面則是 EOI marker, 中間的資料則是 Frame, 一張影像其實就是一個 Frame。所謂的 SOI, 就是 Start of image 的縮寫, 在規格書 P. 32 Table B.1 中, 可以查到 SOI 的 Code Assignment 是 X'FFD8'。同樣地, EOI 就是 End of Image 的縮寫, Code Assignment 則是 X'FFD9'。

將左圖 Rex.jpg 用 UltraEdit 開啟, 就可以看到 Rex.pdf 這份文件中的資料。資料的最前與最後, 分別就是 X'FFD8' 與 X'FFD9'。

第二層指出 Frame 的主要組成是由 frame header 和 scan 資料, frame header 之前也可以放置一些會使用到的相關表格, 如 Quantization tables, Huffman tables 或是其他相關資料, 規格書的 Figure B.5 有詳細列表。

至於一個 frame 包含多少個 scans, 則要視對影像資料的編碼次序(encoding order)而定, 編碼次序分成 interleaved 或 non-interleaved 兩種, 在規格書 P. 20 的 Figure 12 及 Figure 13 可以很清楚地看出什麼是一個 scan。

第三層指出 scan 的組成為何? 最前端同樣可以存放相關表格與資料, 接著存放的是 scan header, 然後就是一個接著一個, 中間夾著 Restart marker (RSTm) 的 Entropy-coded segments (ECS)。

第四層則是說明 Entropy-coded segment 是由多個 minimum coded unit (MCU)所組成。每一個 ECS 至少包含 Ri 個 MCU。注意: Ri 是在前面的 Define restart interval (DRI) segment 中被定義的。( Rex.jpg 影像中的 Entropy-coded segment )
 

Monday, August 13, 2007

Huffman Table Generating Procedures



在了解 JPEG 影像檔如何儲存 Huffman tables 之後, 接下來就是要將儲存在檔頭 (header) 的參數(paremeters) 轉換成解壓縮時能用的 Huffman tables。
JPEG 規格書 的 Annex C , 提供了一套完整的作法。

整個演算法包含三個程序:

1. Figure C.1 : generates a table of Huffman code sizes.

Goal: 讀取儲存在 JPEG 檔頭中的 BITS list, 將其轉換成儲存每個 Huffman code 的長度。

input: BITS list
output: HUFFSIZE table

Rex.jpg 的第 1 個 Huffman table 為例,
BITS 為 0, 0, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
HUFFSIZE 應該為 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8

Figure C.1 的對應程式碼如下:

k=0;
for (i=1 ; i<17 ; i++)
{
for (j=0 ; j<iBITS[iTc][iTh][i]; j++)
{
iHUFFSIZE[iTc][iTh][k] = i;
k++;  
}
}
iHUFFSIZE[iTc][iTh][k] = 0;
iLASTK[iTc][iTh] = k;

//由於一共有 4 個 tables 需要處理, 因此我宣告三維陣列來分別儲存這些資料

2. Figure C.2 : generates the Huffman codes from the table built in the Figure C.1.

Goal: 根據 HUFFSIZE 所記錄的長度, 產生相對應的 HUFFCODE

input: table HUFFSIZE
output: table HUFFCODE

同樣以 Rex.jpg 的第 1 個 Huffman table 為例,
HUFFSIZE 為 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8
HUFFCODE 應該為 0, 1, 2, 3, 4, 5, 6, 14, 30, 62, 126, 254

Figure C.2 的對應程式碼如下:

k=0;
iCODE = 0;
iSI = iHUFFSIZE[iTc][iTh][0];
do {
do {
iHUFFCODE[iTc][iTh][k] = iCODE;
iCODE++;
k++;
}
while (iHUFFSIZE[iTc][iTh][k] == iSI);
if (iHUFFSIZE[iTc][iTh][k]!=0)
{
do {
iCODE = iCODE << 1;
iSI++;
}
while (iHUFFSIZE[iTc][iTh][k]! = iSI);
}
}
while (iHUFFSIZE[iTc][iTh][k] != 0);

3. Figure C.3 : generates the Huffman codes in symbol value order.

Goal: 將 C.2 Procedure 所產生的 HUFFCODE 依照 HUFFVAL 的次序排列。

input: HUFFCODE, HUFFSIZE, HUFFVAL
output: ordered HUFFCODE, ordered HUFFSIZE

Rex.jpg 的第 1 個 Huffman table,
HUFFCODE 為 0, 1, 2, 3, 4, 5, 6, 14, 30, 62, 126, 254
HUFFVAL 為 04, 05, 03, 02, 06, 01, 00, 07, 08, 09, 0A, 0B
因此, 排序過的 HUFFCODE 為 6, 5, 3, 2, 0, 1, 4, 14, 30, 62, 126, 254

Figure C.3 的對應程式碼如下:

for (k=0;k<iLASTK[iTc][iTh];k++) 
{
i = ucHUFFVAL[k];
iEHUFCO[iTc][iTh][i]=iHUFFCODE[iTc][iTh][k];
iEHUFSI[iTc][iTh][i]=iHUFFSIZE[iTc][iTh][k];
}


除此之外, 由於在解壓縮時, 我們所接收的 input 是 binary data,
因此, 光有 HUFFCODE 是無法進行解碼的,
必須配合 HUFFSIZE 進一步將 HUFFCODE 變成二進位模式,
如同規格書 K.3.1 (P.149) 的 Code word一般。

將 HUFFCODE 轉換成二進位形式之對應程式碼如下:

for (k=0;k<256;k++)
{
iCodeLength = iEHUFSI[iTc][iTh][k];
iCodeValue = iEHUFCO[iTc][iTh][k];
for (i=iCodeLength-1;i>=0;i--)
{
iEHUFCOB[iTc][iTh][k][i] = iCodeValue % 2;
iCodeValue = iCodeValue / 2;
}
}

Rex.jpg 的第 1 個 Huffman table 為

Category Length HUFFCODE Code word
0     3    6    110
1     3    5    101
2     3    3    011
3     3    2    010
4     3    0    000
5     3    1    001
6     3    4    100
7     4    14     1110
8     5    30    11110
9     6    62    111110
10     7    126   1111110
11     8    254   11111110

Saturday, August 11, 2007

Huffman Tables in JPEG Files

在 JPEG 影像壓縮標準中, DCT係數經過量化( quantization )後, 會使用熵編碼( entropy coding )來做更進一步的資料壓縮處理。在JPEG壓縮中, 熵編碼最常使用的技術就是霍夫曼編碼技術(Huffman coding)。因此, 在每一個 JPEG 影像壓縮檔 ( *.jpg ) 的檔頭中, 都會定義 Huffman table, 而 X'FFC4' 就是 Define Huffman table(s) - DHT 的 marker。當我們在 JPEG 影像檔頭中搜尋到 X'FFC4', 這表示接下來的資料就是在解壓縮時, 會用到的 Huffman table。

Huffman Table 的儲存語法在規格書 B.2.4.2 有完整說明, 這邊我們則再進一步解釋, 讓大家更容易看懂規格書。

Lh: Huffman table definition length.
 用 16 bits 來記錄整個規格書中, 所有 Huffman table 的總長度。

Tc: Table class - 0 = DC table or lossless table, 1 = AC table.
 有些 table 是給 DC 係數壓縮用的, 有些則是用來壓縮 AC 係數, 因此用 4 bits 來區分。

Th: Huffman table destination identifier
 影像中不同的 component 通常會使用不同的 table 來處理, 因此這邊用 4 bits 來讓這些 tables 有所區分。

Li: Number of Huffman codes of length i - Specifies the number of Huffman codes for each of the 16 possible lengths allowed by this Specification. Li’s are the elements of the list BITS.
 由於 Huffman coding 所編出來的碼, 並不是固定長度的(fixed-length), JPEG 壓縮標準所使用的最長編碼為 16, 因此, L1 就是紀錄長度為 1 的碼有幾個, L2 就是紀錄長度為 2 的碼有幾個,... 每個 Li 使用 8 bits 來記錄, 一共有 16 bytes。在規格書 Annex C 中, 用一個 list BITS 來儲存 Li。將 16 個 Li 值加總起來, 就是所有 Huffman codes 的總數。

Vi,j: Value associated with each Huffman code – Specifies, for each i, the value associated with each Huffman code of length i. The meaning of each value is determined by the Huffman coding model. The Vi,j’s are the elements of the list HUFFVAL.
 每一個 Huffman code 都有一個 Symbol Value 相對應, 利用這些 Value 就可以將所產生 Huffman Codes 用 Figure C.3 的演算法 做正確的排序。在 Annex C 中, 用一個 list HUFFVAL 來儲存這些 Symbol Value。

實例:



上圖是一張大小為 120*120 的 JPEG 影像, Rex.pdf 是將檔案內容以16進位的方式列印出來的結果。

我們如果在 Rex.pdf 中搜尋 "FF C4" 字串, 會分別在 address 00000215h (Page 1), 0000153ah (Page 9), 0000358ch (Page 23) 等三處找到 "FF C4" 字串。根據規格書中的 Table B.1 Marker Code Assignment 所列出來的 Marker 研判, 前面二個 FFC4 是屬於 Application Segments 的範圍, 只有第三個 "FFAC" 才是用來壓縮影像本身的 Huffman table。在這個例子中, Lh = 01A2, 一共有 418 bytes, 一共包含 4 個 Huffman tables, 前 2 個 tables 的 Tc = 0, 屬於 DC tables, 後 2 個 tables 的 Tc = 1, 屬於 AC tables。

第 1 個 table 的 Tc = 0, Th = 0,
L1 = 0, L2 = 0, L3 = 7, L4 = 1, L5 = 1, L6 = 1, L7 = 1, L8 = 1,
L9 = 0, L10 = 0, L11 = 0, L12 = 0, L13 = 0, L14 = 0, L15 = 0, L16 = 0。
一共有 7 + 1 + 1 + 1 + 1 + 1 = 12 個 codes。
每一個 code 所對應的 HUFFVAL 依序分別為 04, 05, 03, 02, 06, 01, 00, 07, 08, 09, 0A, 0B。

第 2 個 table 的 Tc = 0, Th = 1,
L1 = 0, L2 = 2, L3 = 2, L4 = 3, L5 = 1, L6 = 1, L7 = 1, L8 = 1,
L9 = 1, L10 = 0, L11 = 0, L12 = 0, L13 = 0, L14 = 0, L15 = 0, L16 = 0。
一共有 2 + 2 + 3 +1 + 1 + 1 + 1 + 1 = 12 個 codes。
每一個 code 所對應的 HUFFVAL 依序分別為 01, 00, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B。

第 3 個 table 的 Tc = 1, Th = 0,
L1 = 0, L2 = 2, L3 = 1, L4 = 3, L5 = 3, L6 = 2, L7 = 4, L8 = 2,
L9 = 6, L10 = 7, L11 = 3, L12 = 4, L13 = 2, L14 = 6, L15 = 2, L16 = 73。
注意: L16 = 73, 是 16 進位值, 所以實際應該為 7 * 16 + 3 = 115
一共有 2 + 1 + 3 + 3 + 2 + 4 + 2 + 6 + 7 + 3 + 4 + 2 + 6 + 2 + 115 = 162 個 codes。
每一個 code 所對應的 HUFFVAL 依序分別為:
01, 02, 03, 11, 04, 00, 05, 21, 12, 31, 41, 51, 06, 13, 61, 22,
71, 81, 14, 32, 91, A1, 07, 15, B1, 42, 23, C1, 52, D1, E1, 33,
16, 62, F0, 24, 72, 82, F1, 25, 43, 34, 53, 92, A2, B2, 63, 73,
C2, 35, 44, 27, 93, A3, B3, 36, 17, 54, 64, 74, C3, D2, E2, 08,
26, 83, 09, 0A, 18, 19, 84, 94, 45, 46, A4, B4, 56, D3, 55, 28,
1A, F2, E3, F3, C4, D4, E4, F4, 65, 75, 85, 95, A5, B5, C5, D5,
E5, F5, 66, 76, 86, 96, A6, B6, C6, D6, E6, F6, 37, 47, 57, 67,
77, 87, 97, A7, B7, C7, D7, E7, F7, 38, 48, 58, 68, 78, 88, 98,
A8, B8, C8, D8, E8, F8, 29, 39, 49, 59, 69, 79, 89, 99, A9, B9,
C9, D9, E9, F9, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A, AA, BA, CA, DA,
EA, FA。

第 4 個 table 的 Tc = 1, Th = 1,
L1 = 0, L2 = 2, L3 = 2, L4 = 1, L5 = 2, L6 = 3, L7 = 5, L8 = 5,
L9 = 4, L10 = 5, L11 = 6, L12 = 4, L13 = 8, L14 = 3, L15 = 3, L16 = 6D。
注意: L16 = 6D, 是 16 進位值, 所以實際應該為 6 * 16 + 13 = 109
一共有 2 + 2 + 1 + 2 + 3 + 4 + 5 + 4 + 5 + 6 + 4 + 8 + 3 + 3 + 109 = 162 個 codes。
每一個 code 所對應的 HUFFVAL 依序分別為:
01, 00, 02, 11, 03, 04, 21, 12, 31, 41, 05, 51, 13, 61, 22, 06,
71, 81, 91, 32, A1, B1, F0, 14, C1, D1, E1, 23, 42, 15, 52, 62,
72, F1, 33, 24, 34, 43, 82, 16, 92, 53, 25, A2, 63, B2, C2, 07,
73, D2, 35, E2, 44, 83, 17, 54, 93, 08, 09, 0A, 18, 19, 26, 36,
45, 1A, 27, 64, 74, 55, 37, F2, A3, B3, C3, 28, 29, D3, E3, F3,
84, 94, A4, B4, C4, D4, E4, F4, 65, 75, 85, 95, A5, B5, C5, D5,
E5, F5, 46, 56, 66, 76, 86, 96, A6, B6, C6, D6, E6, F6, 47, 57,
67, 77, 87, 97, A7, B7, C7, D7, E7, F7, 38, 48, 58, 68, 78, 88,
98, A8, B8, C8, D8, E8, F8, 39, 49, 59, 69, 79, 89, 99, A9, B9,
C9, D9, E9, F9, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A, AA, BA, CA, DA,
EA, FA。

延伸閱讀:
1. Huffman Table Generating Procedures
2. Huffman Tables in the Rex.jpg