程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> JPEG圖像密寫研究(一) JPEG圖像文件結構

JPEG圖像密寫研究(一) JPEG圖像文件結構

編輯:關於C語言

【轉載】轉載自http://www.cnblogs.com/leaven/archive/2010/04/06/1705846.html

 

JPEG壓縮編碼算法的主要計算步驟如下:

(0) 8*8分塊。

(1) 正向離散余弦變換(FDCT)。

(2) 量化(quantization)。

(3) Z字形編碼(zigzag scan)。

(4) 使用差分脈沖編碼調制(DPCM)對直流系數(DC)進行編碼。

(5) 使用行程長度編碼(RLE)對交流系數(AC)進行編碼。

(6) 熵編碼。

 

一、JPEG文件格式介紹

JPEG文件使用的數據存儲方式有多種。最常用的格式稱為JPEG文件交換格式(JPEG File Interchange Format,JFIF)。而JPEG文件大體上可以分成兩個部分:標記碼(Tag)和壓縮數據。

標記碼由兩個字節構成,其前一個字節是固定值0xFF,後一個字節則根據不同意義有不同數值。在每個標記碼之前還可以添加數目不限的無意義的0xFF填充,也就說連續的多個0xFF可以被理解為一個0xFF,並表示一個標記碼的開始。而在一個完整的兩字節的標記碼後,就是該標記碼對應的壓縮數據流,記錄了關於文件的諸種信息。

常用的標記有SOI、APP0、DQT、SOF0、DHT、DRI、SOS、EOI。

注意,SOI等都是標記的名稱。在文件中,標記碼是以標記代碼形式出現。例如SOI的標記代碼為0xFFD8,即在JPEG文件中的如果出現數據0xFFD8,則表示此處為一個SOI標記。

 

SOI,Start of Image,圖像開始

標記代碼                                 2字節     固定值0xFFD8

 

APP0,Application,應用程序保留標記0

標記代碼                                 2字節     固定值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。

 

APPn,Application,應用程序保留標記n,其中n=1~15(任選)

標記代碼                                 2字節     固定值0xFFE1~0xFFF

包含2個具體字段:
 ① 數據長度                         2字節     ①~②2個字段的總長度
                                                            即不包括標記代碼,但包括本字段
 ② 詳細信息            數據長度-2字節   內容不定
                                                    

例如,Adobe Photoshop生成的JPEG圖像中就用了APP1和APP13兩個標記段分別存儲了一幅圖像的副本。

 

DQT,Define Quantization Table,定義量化表

標記代碼                          2字節            固定值0xFFDB

包含9個具體字段:
 ① 數據長度                  2字節            字段①和多個字段②的總長度
                                                            即不包括標記代碼,但包括本字段
 ② 量化表        數據長度-2字節

a)精度及量化表ID   1字節            高4位:精度,只有兩個可選值
                                                              0:8位;1:16位
                                                低4位:量化表ID,取值范圍為0~3

b)表項       (64×(精度+1))字節              例如8位精度的量化表
                                                其表項長度為64×(0+1)=64字節

 

本標記段中,字段②可以重復出現,表示多個量化表,但最多只能出現4次。

 

SOF0,Start of Frame,幀圖像開始

標記代碼                   2字節     固定值0xFFC0

包含9個具體字段:
 ① 數據長度           2字節     ①~⑥六個字段的總長度
                                              即不包括標記代碼,但包括本字段
 ② 精度                 1字節     每個數據樣本的位數
                                              通常是8位,一般軟件都不支持 12位和16位
 ③ 圖像高度           2字節     圖像高度(單位:像素),如果不支持 DNL 就必須 >0
  ④ 圖像寬度           2字節     圖像寬度(單位:像素),如果不支持 DNL 就必須 >0
  ⑤ 顏色分量數        1字節     只有3個數值可選
                                              1:灰度圖;3:YCrCb或YIQ;4:CMYK
                                              而JFIF中使用YCrCb,故這裡顏色分量數恆為3
  ⑥顏色分量信息      顏色分量數×3字節(通常為9字節)

a)顏色分量ID                 1字節    

b)水平/垂直采樣因子      1字節            高4位:水平采樣因子
                                                       低4位:垂直采樣因子
                                                       (曾經看到某資料把這兩者調轉了)

c) 量化表                         1字節            當前分量使用的量化表的ID

本標記段中,字段⑥應該重復出現,有多少個顏色分量(字段⑤),就出現多少次(一般為3次)。

 

DHT,Difine Huffman Table,定義哈夫曼表

標記代碼                                 2字節            固定值0xFFC4

包含2個具體字段:
 ①數據長度                             2字節            字段①和多個字段②的總長度
                                                                   即不包括標記代碼,但包括本字段
 ② 哈夫曼表              數據長度-2字節

a)表ID和表類型            1字節            高4位:類型,只有兩個值可選
                                                                     0:DC直流;1:AC交流
                                                        低4位:哈夫曼表ID,
                                                                     注意,DC表和AC表分開編碼

b)不同位數的碼字數量    16字節

c)編碼內容       16個不同位數的碼字數量之和(字節)

本標記段中,字段②可以重復出現(一般4次),也可以致出現1次。例如,Adobe Photoshop 生成的JPEG圖片文件中只有1個DHT標記段,裡邊包含了4個哈夫曼表;而Macromedia Fireworks生成的JPEG圖片文件則有4個DHT標記段,每個DHT標記段只有一個哈夫曼表。

 

DRI,Define Restart Interval,定義差分編碼累計復位的間隔

標記代碼                                 2字節     固定值0xFFDD

包含2個具體字段:
 ①數據長度                             2字節     固定值0x0004,①~②兩個字段的總長度
                                                            即不包括標記代碼,但包括本字段
 ②MCU塊的單元中的重新開始間隔
                                              2字節     設其值為n,則表示每n個MCU塊就有一個
                                                           RSTn標記。第一個標記是RST0,第二個是
                                                            RST1等,RST7後再從RST0重復。

 

如果沒有本標記段,或間隔值為0時,就表示不存在重開始間隔和標記RST

 

SOS,Start of Scan,掃描開始 12字節

標記代碼                          2字節     固定值0xFFDA

包含2個具體字段:
 ①數據長度                      2字節     ①~④兩個字段的總長度
                                                     即不包括標記代碼,但包括本字段
 ②顏色分量數                 1字節     應該和SOF中的字段⑤的值相同,即:
                                                     1:灰度圖是;3: YCrCb或YIQ;4:CMYK。

                                                         而JFIF中使用YCrCb,故這裡顏色分量數恆為3
   ③顏色分量信息
        a) 顏色分量ID           1字節
        b) 直流/交流系數表號 1字節     高4位:直流分量使用的哈夫曼樹編號
                                                        低4位:交流分量使用的哈夫曼樹編號

 ④ 壓縮圖像數據
        a)譜選擇開始                     1字節     固定值0x00
        b)譜選擇結束                     1字節     固定值0x3F
        c)譜選擇                            1字節     在基本JPEG中總為00

 

本標記段中,字段③應該重復出現,有多少個顏色分量(字段②),就出現多少次(一般為3次)。本段結束後,緊接著就是真正的圖像信息了。圖像信息直至遇到一個標記代碼就自動結束,一般就是以EOI標記表示結束。

 

EOI,End of Image,圖像結束 2字節

標記代碼                   2字節     固定值0xFFD9

 

這裡補充說明一下,由於在JPEG文件中0xFF具有標志性的意思,所以在壓縮數據流(真正的圖像信息)中出現0xFF,就需要作特別處理。具體方法是,在數據0xFF後添加一個沒有意義的0x00。換句話說,如果在圖像數據流中遇到0xFF,應該檢測其緊接著的字符,如果是

1)0x00,則表示0xFF是圖像流的組成部分,需要進行譯碼;

2)0xD9,則與0xFF組成標記EOI,則圖像流結束,同時圖像文件結束;

3)0xD0~0xD7,則組成RSTn標記,則要忽視整個RSTn標記,即不對當前0xFF和緊接的0xDn兩個字節進行譯碼,並按RST標記的規則調整譯碼變量;

3)0xFF,則忽視當前0xFF,對後一個0xFF再作判斷;

4)其他數值,則忽視當前0xFF,並保留緊接的此數值用於譯碼。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved