由於懶和人的忘性,以前做的一些筆記再回過頭看時又有些生疏了,我決定把一些內容整理出來,以供有需要的來參考。
了解的人知道其價值所在,不知道的人就棄之如廢物吧。
本篇是JPEG解碼系列的第一篇——JPEG文件格式概覽。
1. 圖片文件的數據是什么?
這是一幅人眼可視的圖片:
這是其對應的二進制數據:(由於二進制數據量浩如煙海,只截取頭部的一些數據,使用的工具是WinHex)
2. 為什么需要文件格式來表達圖像?
這就凸顯了規范的重要性,使用同一套標准,各廠商都按照這個標准進行文件格式封裝,那么你拿到別人的照片后就知道
了如何進行(文件格式)解析和(jpeg)解碼了。
這也好理解,不同國家不同語言的人們如何交流?使用通用的標准——英語。
jpeg文件格式也自有其標准,文件格式標准參考電聯的JFIF,編解碼標准參考電聯的ITU-T81。
3. 標准文檔太長,沒耐心讀下去,怎么辦?
標准規范的頁碼都是很長的,用於照顧到各個角落和細節。
但是,各個廠商實現時,肯定不會實現規范的全部內容,只需滿足標准中最重要的一部分即可。
4. jpeg二進制數據解讀
一般情況下,是按照這個順序排列的:
TAG類型 | 數值 | 名稱 | 其他備注 |
SOI | 0xFFD8 | Start of Image | 必帶 |
APP0 | 0xFFE0 | application0 | 必帶 |
APPn | 0xFFEn | applicationn | 可選帶(APP1一般為Exif信息) |
DQT | 0xFFDB | Define Quantization Table | 必帶 |
SOF | 0xFFC0 | Start of Frame | 必帶 |
DHT | 0xFFC4 | Define Huffman Table | 必帶 |
SOS | 0xFFDA | Start of Scan | 必帶 |
compress data | 。。。 | 。。。 | 必帶 |
EOI | 0xFFD9 | End of Image | 必帶 |
如下為標注各種類型TAG,其中EOI在文件末尾未貼出來:
5. 關於各TAG的一些說明
5.1) 文件名末尾.jpg不代表真的是一個jpeg圖片,因為你可以隨意更改一個文件的后綴名。
5.2)JPEG文件必須以0xFF DB開頭和以0xFF D9結尾。
5.3)DQT為量化表,該類型表有兩個表,一個表示Y分量的量化表,另外一個為UV分量共用的量化表。
其中,TAG后面的0x 00 43表示這個TAG組中除去TAG兩個字節外,共有多少個字節組成,后面的0x00為第幾張表。
量化表為DCT變換系數,由於是8x8的二維DCT變換,故系數個數為64,這也即是:0x43 - 3 = 0x40 = 64。
5.4)SOF為幀圖像開始,記錄了采樣精度、圖形寬/高、分量個數、水平/垂直采樣因子、量化表號等信息。
例如,摘抄下SOF下的這幾個字節:0x00 11 08 02 D0 03 E0 03 01 22 00 02 11 01 03 11 01
其中,0x00 11代表SOF下共有17字節;
0x08代表采樣精度,幾乎都是用8位進行采樣精度,即一個像素點可以有2^8=256級過渡;
0x02 D0代表圖像高,即0x02d0=720像素高;
0x03 E0代表圖像寬,即0x03E0=992像素寬;
0x03代表分量表數,為3,分別代表Y、U和V的表;
0x01 22 00中第一個字節01代表量化表序號(從1開始),第二個22代表水平/垂直采樣因子(高四位為水平采樣因子,第四位為垂直采樣因子),第三個00代表量化表id=0;
0x02 11 01中第一個字節01代表量化表序號為2,第二個11代表水平/垂直采樣因子都為1,第三個00代表量化表id=1;
0x03 11 01中第一個字節01代表量化表序號為3,第二個11代表水平/垂直采樣因子都為1,第三個00代表量化表id=2;
需要補充說明一下,采樣因子和量化表的問題。
采樣因子:該圖象的Y分量的寬/高采樣因子都為2,而UV分量的采樣因子都為1,則在同一個方向上(水平或垂直方向),Y分量采樣點是UV分量采樣點的2倍,
如果圖像Y分量寬高分別W和H,那么U和V分量只采樣了W/2和H/2個點,這也代表原始圖象的size=1.5*W*H。
有些圖像的第一張表可能是2和1或1和2,再或都是1,但是第二和第三張表的采樣因子都是1。
量化表:Y分量使用一張量化表,UV分量使用另外一張表,因為DQT表一般就兩張。
5.5)DHT為霍夫曼表,由四個表組成,分表代表:
[0][0]——直流霍夫曼表0,Y分量直流部分解碼時使用
[0][1]——直流霍夫曼表0,UV分量直流部分解碼時使用
[1][0]——交流霍夫曼表0,Y分量交流部分解碼時使用
[1][1]——交流霍夫曼表1,UV分量交流部分解碼時使用
5.6)SOS為掃描開始,其代表霍夫曼表關系進行映射。
5.7)SOS后面就為真正的編碼數據,這是數據的大頭,相比於此,文件頭的size其實是非常之少。
5.8)EOI為圖像結束的標志,圖像必須以此結束。