JPEG 文件格式解析
JPEG 文件使用的數據存儲方式有多種。最常用的格式稱爲 JPEG 文件交換格式(JPEG File Interchange Format,JFIF)。而 JPEG 文件大體上可以分成兩個部分:標記碼(Tag)和壓縮數據。
標記碼由兩個字節構成,其前一個字節是固定值 0xFF
,後一個字節則根據不同意義有不同數值。在每個標記碼之前還可以添加數目不限的無意義的 0xFF
填充,也就說連續的多個 0xFF
可以被理解爲一個 0xFF
,並表示一個標記碼的開始。而在一個完整的兩字節的標記碼後,就是該標記碼對應的壓縮數據流,記錄了關於文件的諸種信息。
常用的標記有 SOI
、APP0
、APPn
、DQT
、SOF0
、DHT
、DRI
、SOS
、EOI
。
注意,SOI
等都是標記的名稱。在文件中,標記碼是以標記代碼形式出現。例如 SOI
的標記代碼爲 0xFFD8
,即在 JPEG 文件中的如果出現數據 0xFFD8
,則表示此處爲一個 SOI
標記。
標記 | 標記代碼 | 描述 |
---|---|---|
SOI |
0xD8 | 圖像開始 |
APP0 | 0xE0 | JFIF應用數據塊 |
APPn | 0xE1 - 0xEF | 其他的應用數據塊(n, 1~15) |
DQT |
0xDB | 量化表 |
SOF0 | 0xC0 | 幀開始 |
DHT |
0xC4 | 霍夫曼(Huffman)表 |
DRI |
0xDD | 差分編碼累計復位的間隔 |
SOS |
0xDA | 掃描線開始 |
EOI |
0xD9 | 圖像結束 |
用來分析的樣例圖片:libpng-rgb-rainbow.jpg。
(1) SOI (Start of Image)圖像開始標記
0xFFD8
(2) APP0 (Application) 應用程序保留標記0
0xFFE0
包含9個具體字段:
序號 | 名稱 | 長度 | 描述 |
---|---|---|---|
① |
數據長度 | 2 字節 | ①~⑨ 9個字段的總長度,即不包括標記代碼,但包括本字段 |
② |
標識符 | 5 字節 | 固定值 0x4A46494600,即字符串“JFIF0” |
③ |
版本號 | 2 字節 | 一般是 0x0102,表示 JFIF 的版本號 1.2,可能會有其他數值代表其他版本 |
④ |
X 和 Y 的密度單位 | 1 字節 | 只有三個值可選 0:無單位;1:點數/英寸;2:點數/釐米 |
⑤ |
X 方向像素密度 | 2 字節 | 取值範圍未知 |
⑥ |
Y 方向像素密度 | 2 字節 | 取值範圍未知 |
⑦ |
縮略圖水平像素數目 | 1 字節 | 取值範圍未知 |
⑧ |
縮略圖垂直像素數目 | 1 字節 | 取值範圍未知 |
⑨ |
縮略圖 RGB 位圖 | 長度可能是 3 的倍數 | 縮略圖 RGB 位圖數據 |
本標記段可以包含圖像的一個微縮版本,存爲 24 位的 RGB 像素。如果沒有微縮圖像(這種情況更常見),則字段 ⑦“ 縮略圖水平像素數目”和字段 ⑧“ 縮略圖垂直像素數目”的值均爲 0 。
(3) APPn (Application) 應用程序保留標記 n,其中 n=1~15(任選)
0xFFE1~0xFFF
包含 2 個具體字段:
序號 | 名稱 | 長度 | 描述 |
---|---|---|---|
① | 數據長度 | 2 字節 | ①~② 2 個字段的總長度,即不包括標記代碼,但包括本字段 |
② | 詳細信息 | 數據長度-2 字節 | 內容不定 |
例如,Adobe Photoshop 生成的 JPEG 圖像中就用了 APP1 和 APP13 兩個標記段分別存儲了一幅圖像的副本。
(4) DQT (Define Quantization Table) 定義量化表
0xFFDB
包含 2 個具體字段:
序號 | 名稱 | 長度 | 描述 |
---|---|---|---|
① | 數據長度 | 2 字節 | 字段 ① 和多個字段 ② 的總長度 ,即不包括標記代碼,但包括本字段 |
② | 量化表 | 數據長度-2 字節 | 《量化表表格》 |
量化表表格:
名稱 | 長度 | 描述 |
---|---|---|
精度及量化表 ID | 1 字節 | 高 4 位:精度,只有兩個可選值 0:8位;1:16位; 低 4 位:量化表 ID,取值範圍爲 0~3 |
表項 | (64×(精度 1)) 字節 | 例如 8 位精度的量化表,其表項長度爲 64×(0 1)=64 字節 |
本標記段中,字段 ② 可以重複出現,表示多個量化表,但最多隻能出現 4 次。
(5) SOF0 (Start of Frame) 幀圖像開始
0xFFC0
包含 6 個具體字段:
顏色分量信息:
名稱 | 長度 | 描述 |
---|---|---|
顏色分量 ID | 1 字節 | |
水平/垂直採樣因子 | 1 字節 | 高 4 位:水平採樣因子,低 4 位:垂直採樣因子 |
量化表 | 1 字節 | 當前分量使用的量化表的 ID |
本標記段中,字段 ⑥ 應該重複出現,有多少個顏色分量(字段 ⑤),就出現多少次(一般爲 3 次)。
(6) DHT (Define Huffman Table) 定義哈夫曼表
0xFFC4
包含 2 個具體字段:
序號 | 名稱 | 長度 | 描述 |
---|---|---|---|
① | 數據長度 | 2 字節 | 字段 ① 和多個字段 ② 的總長度,即不包括標記代碼,但包括本字段 |
② | 哈夫曼表 | 數據長度-2 字節 | 《哈夫曼表表格》 |
哈夫曼表表格:
名稱 | 長度 | 描述 |
---|---|---|
表 ID 和表類型 | 1 字節 | 高 4 位:類型,只有兩個值可選 0:DC 直流;1:AC 交流; 低 4 位:哈夫曼表 ID,注意,DC 表和 AC 表分開編碼 |
不同位數的碼字數量 | 16 字節 | 編碼內容 16 個不同位數的碼字數量之和(字節) |
本標記段中,字段 ② 可以重複出現(一般 4 次),也可以只出現1次。例如,Adobe Photoshop 生成的 JPEG 圖片文件中只有 1 個 DHT 標記段,裏邊包含了 4 個哈夫曼表;而 Macromedia Fireworks 生成的 JPEG 圖片文件則有 4 個 DHT 標記段,每個 DHT 標記段只有一個哈夫曼表。
(7) DRI (Define Restart Interval) 定義差分編碼累計復位的間隔
0xFFDD
包含 2 個具體字段:
序號 | 名稱 | 長度 | 描述 |
---|---|---|---|
① | 數據長度 | 2 字節 | 固定值 0x0004,①~② 兩個字段的總長度,即不包括標記代碼,但包括本字段 |
② | MCU 塊的單元中的重新開始間隔 | 2字節 | 設其值爲 n,則表示每 n 個 MCU 塊就有一個 RSTn 標記。第一個標記是 RST0,第二個是 RST1 等,RST7 後再從 RST0 重複。 |
如果沒有本標記段,或間隔值爲 0 時,就表示不存在重開始間隔和標記 RST。
(8) SOS (Start of Scan) 掃描開始 12字節
0xFFDA
包含 4 個具體字段:
本標記段中,字段 ③ 應該重複出現,有多少個顏色分量(字段 ②),就出現多少次(一般爲 3 次)。本段結束後,緊接着就是真正的圖像信息了。圖像信息直至遇到一個標記代碼就自動結束,一般就是以 EOI 標記表示結束。
(9) EOI (End of Image) 圖像結束標記
0xFFD9
JPEG 標記總覽
More
下一步,將用代碼手動生成一張 JPEG 圖片,文章目錄: 音視頻入門文章目錄 。
參考資料:
[Jpg文件格式[參考]](https://www.cnblogs.com/robottech/archive/2008/07/21/1247721.html)
內容有誤?聯繫作者:
本文由博客一文多發平臺 OpenWrite 發佈!