跳到內容

JPEG - 想法與實踐/頭部部分

來自華夏公益教科書,開放的書籍,為開放的世界

JPEG 檔案的頭部部分被劃分為,每個段以一個標記開始,標識該段。 通常,JPEG 檔案包含 7 個不同的標記。標記是一個位元組對,第一個位元組是 255,第二個位元組不同於 0 和 255。我們透過第二個位元組來標識一個標記。有兩個標記是獨立的(因此不開啟一個段):開啟檔案的標記 SOI(開始影像)= 216 和關閉檔案的標記 EOI(結束影像)= 217。(還有另一種獨立的標記,但它不在我們這裡討論的順序 DCT 模式中使用:它標誌著掃描的重啟,並由 0、1、...、7 中的一個數字索引:RST0、...、RST7(重啟)= 208、...、215)。其他標記開啟一個段,在這種情況下,接下來的兩個位元組(b1,b2)表示段的長度(包括這兩個位元組):l = b1 * 256 + b2。接下來的 l - 2 個位元組序列是該段的內容。以下是段的型別(用它們的標記標識)

APP0、APP1、...、APP15(應用) 224-239
COM(註釋) 254
SOF(開始幀) 192-207,除了 196、200 和 204
DHT(定義霍夫曼表) 196
DQT(定義量化表) 219
SOS(開始掃描) 218

(以及其他幾個在此處未使用的標記:DNL(定義行數 = 220)、DRI(定義重啟間隔 = 221)、DHP(定義分層漸進 = 222)、EXP(擴充套件參考分量 = 223)、DAC(定義算術編碼條件 = 204)、TEM(用於算術編碼中的 TEMporary 使用 = 1)以及一些保留標記:JPG(保留用於 JPeG 擴充套件 = 200、240、241、...、253)和 RES(REServed = 2、...、191))

前兩個 - APP 和 COM - 指定了在 JPEG 程式之外的內容。通常只存在一個 APP 段(即 APP0),它指定了實現。APP 段還可以包含有關相機型別和拍攝圖片時間的資訊。COM 可以說明用於建立檔案的程式、選擇的質量百分比等。

幀段 SOF

[編輯 | 編輯原始碼]

JPEG 程式的出發點是“圖片”,圖片可以定義為數字、數字對、數字三元組或數字四元組的(矩形)矩陣。也就是說,圖片是具有 1-4 之間的一個數字的長度的陣列的矩陣。灰度圖片是位元組矩陣。彩色圖片是 RGB 三元組(位元組)矩陣或 YCbCr 三元組(有符號位元組)矩陣。因此,圖片可以被認為是由一個或多個(最多四個)整數矩陣組成的,這樣的矩陣被稱為圖片的分量。每個分量都分配一個分量識別符號(位元組):例如,灰度圖片的(一個)分量為 0,彩色圖片的三個分量為 0、1 和 2。

圖片的尺寸、分量識別符號和分量的順序在幀段 SOF 中指定,以及如何處理分量之間的關係。由於顏色通常只在位置之間緩慢變化(而且我們不太擅長區分顏色的微小變化),對於兩個顏色分量,我們可以例如將圖片分成 2x2 畫素的方塊並取平均值,這樣我們就可以將這個方塊看作是一個畫素,從而處理四倍小的彩色圖片。我們也可以只限於兩個畫素,要麼水平排列,要麼垂直排列。每個分量的數字對 (Hi, Vi) 決定了如何掃描分量之間的關係。Hi 和 Vi 可以從 1 到 4(Hi 和 Vi 必須比較小:它們的乘積之和不能超過 10)。分別設 H 和 V 為最大的 Hi 和 Vi 值。這些最大值通常與 Y 分量相關聯,而 ((Hi, Vi) = (H, V)) 意味著畫素按原樣取值:水平樣本數與圖片的寬度相同,水平行數與圖片的高度相同。如果一個(顏色)分量的對為 (Hi, Vi),則水平線上的樣本數是 (Hi/H) 乘以寬度,取樣線的數量是 (Vi/V) 乘以高度,也就是說,收集了 (H/Hi)x(V/Vi) 畫素的小矩形(並被認為是一個畫素)。通常情況下,顏色分量的 (Hi, Vi) = (1, 1),而 Y 分量的 (Hi, Vi) = (1, 1) 或 (2, 1) 或 (1, 2) 或 (2, 2)。(Hi, Vi) = (2, 2) 意味著收集了四個顏色畫素,並且“這個”畫素與四個 Y 畫素組合在一起。由於圖片被劃分為 8x8 的方塊,這意味著 Y 分量的四個 8x8 方塊與顏色分量的一個 8x8 方塊組合在一起。四個 Y 方塊的編碼資料(編碼的 64 陣列)按通常的掃描順序寫入檔案:從左到右沿行,從上到下。接下來是兩個顏色分量的編碼資料(編碼的 64 陣列)。當只收集兩個畫素(水平或垂直)時,類似的過程。由所有分量和收集的 8x8 方塊產生的資料流的這一部分被稱為最小編碼單元(MCU)。

這張圖片展示了當收集四個 Y 分量 8x8 方塊時的繪製方式(畫素對畫素 - 並且按放大的比例) - 你要想象中間的四個 8x8 方塊,兩個(最上面的)已經繪製了,第三個正在繪製

以下圖片(佔用 3.2 Kb)下面的兩張圖片是這張圖片,每隔一條垂直線都繪製為黑色,但以不同的方式掃描:對於顏色分量,分別在垂直和水平方向上收集兩個畫素(即顏色分量的 (Hi, Vi) = (1, 1),而 Y 分量的 (Hi, Vi) = (1, 2) 和 (2, 1))。在第一張圖片(佔用 5.9 Kb)中,顏色是正確的,在第二張圖片(佔用 4.7 Kb)中,顏色是褪色的,因為它們與線的黑色混合在一起

幀段 SOF 由以下位元組組成:標記 (255, b),其中位元組 b 指定掃描模式。我們假設這裡 b = 192,表示基線順序 DCT 模式;然後是表示段長度的位元組對(包括這兩個位元組),這對位元組為 (0, 8 + 3 * 分量數);然後是一個表示顏色值位數的位元組,這裡設定為 8(表示顏色值為位元組),但在擴充套件模式中為 12;然後是一對位元組 (b1, b2) 表示圖片的高度 (= b1 * 256 + b2) 和一對位元組表示寬度;最後是一個表示分量數(1-4)的位元組,以及每個分量的以下位元組:分量識別符號(位元組)、Hi(½ 位元組)和 Vi(½ 位元組)(位元組 = Hi * 16 + Vi)以及量化表目標選擇器(位元組)。

這裡,顏色分量的對 (Hi, Vi) 為 (1, 1),而 Y 分量的 (Hi, Vi) 為 (1, 1)、(1, 2)、(2, 1) 或 (2, 2)。量化表目標選擇器是 0-3 之間的數字之一,例如,Y 分量為 0,顏色分量為 1。

霍夫曼表段 DHT

[編輯 | 編輯原始碼]

通常,灰度圖片的檔案中會有兩個霍夫曼表段,彩色圖片中有四個:每個分量的 DC 和 AC 數字的編碼方式不同,Y 分量和兩個顏色分量的編碼方式也不同。在霍夫曼段中,資訊(在標記和表示長度的位元組對之後)以這種方式排列:如果霍夫曼表用於 DC 數字,則第一個半位元組為 0,如果用於 AC 數字,則為 1。下一個半位元組是霍夫曼表目標識別符號(0 或 1),例如,Y 分量為 0,顏色分量為 1(將在掃描段 SOS 中引用,在 SOS 中指定了霍夫曼表)。接下來的 16 個位元組序列是列表 BITS,它表示 i = 1、...、16 時長度為 i 的程式碼數量。然後是列表 HUFFVAL,它表示霍夫曼值:對於每個非零的程式碼長度,將有與該長度的程式碼數量相同的數值。如果我們將霍夫曼值的數量稱為 nhv,則段中的位元組數(包括表示長度的位元組對)為 19 + nhv。

量化表段 DQT

[編輯 | 編輯原始碼]

量化表是一個 8x8 位元組矩陣,按之字形原則排序。通常情況下,Y 分量和顏色分量有不同的量化表。在 T.81 的附錄“示例和指南”中,你可以分別找到 Y 分量和顏色分量的以下內容

16 11 10 16 24   40   51   61
12 12 14 19 26   58   60   55
14 13 16 24 40   57   69   56
14 17 22 29 51   87   80   62
18 22 37 56 68   109 103 77
24 35 55 64 81   104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
17 18 24 47 99 99 99 99
18 21 26 66 99 99 99 99
24 26 56 99 99 99 99 99
47 66 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99

它指出“如果將這些量化值除以 2,則生成的重建影像通常與源影像幾乎無法區分”。透過我們的程式“JPEG_File”,你可以看到一張圖片的表格(使用順序 DCT 程式,並且)指定了名稱“pict”。在我們生成(真實的)JPEG 檔案的程式中,我們為 Y 分量選擇了另一個表格,而不是上面的表格,即在影像編輯程式(IrfanView)中使用,將質量設定為 70% 時使用的表格

10 7   6   10 14 24 31 37
7   8   11 16 35 36 33
8   8   10 14 24 34 41 34
10 13 17 31 52 48 37
11 13 22 34 41 65 62 46
14 21 33 38 49 62 68 55
29 38 47 52 62 73 72 61
43 55 57 59 67 60 62 59

量化表在 DQT 段中指定。DQT 段以標記 DQT = 219 和長度開頭,長度為 (0, 67)。然後是一個位元組,其前半部分為 0,表示該表由位元組(8 位數字 - 對於擴充套件模式,為 1,表示該表由字,16 位數字)組成,後半部分為表的 *目標識別符號* (0-3),例如,Y 分量為 0,顏色分量為 1。接下來是表的 64 個數字(位元組)。

掃描段 SOS

[編輯 | 編輯原始碼]

緊接掃描段 SOS 之後是圖片的編碼資料,掃描段指定了用於分量的哈夫曼表。該段以標記 SOS = 218 和長度開頭,長度為 (0, 6 + 2 * 分量數)。然後是一個位元組,表示分量數 (1-4),然後是每個分量的兩個位元組,第一個是分量識別符號(在幀段中定義),第二個分為兩部分,第一部分表示 DC 哈夫曼表的目標選擇器,第二部分表示 AC 哈夫曼表的目標選擇器(例如,Y 分量為 0,顏色分量為 1)。該段以三個位元組結束,在我們的案例(順序 DCT)中,它們是 0、63 和 0(最後一個分為兩個半位元組)。

華夏公益教科書