国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
JPEG 簡易文檔 V2.14
云風(fēng)  2006-07-26 10:56:19  云風(fēng)工作室
寫在前面
1. 為什么寫這個文檔?
云風(fēng)想對 JPEG/MPEG 有一個系統(tǒng)的研究, 但是苦于找到好的資料. 而英文水平又不怎樣, 所以在學(xué)習(xí)的過程,    將已經(jīng)了解了的東西記錄下來. 方便自己在編寫代碼的時候查閱. 而且正式的 JPEG 文檔非常復(fù)雜, 打印出來也有厚厚一本, 就是英文底子比較好的朋友, 看起來也會頭痛的. 這里寫一份精簡版本, 僅僅對 JPEG Baseline 編碼的解碼算法做些介紹. 這樣對想了解下 JPEG 的朋友會有好處的.當(dāng)然需要深入研究 JPEG 的朋友請自己再去找書和資料. 希望 inet 上中文資料越來 越豐富.
2. 通過閱讀這份文檔期望達(dá)到的目的.
能夠?qū)?JPEG 圖形壓縮有一定感性的認(rèn)識, 但其數(shù)學(xué)原理不需要搞清. 能夠通過這, 開始寫自己的編碼/解碼程序. 或者看懂以有的代碼. 對有損圖形壓縮有進(jìn)一步了解. 自己能夠改良 JPEG, 比如增加透明色的支持, 加快 JPEG 的解碼速度.
3. 為什么用文本格式寫, 而不用 HTML?
個人喜好. 不喜歡有格式編排的電子文檔. 純文本能夠更廣泛的使用, 而不需要HTML 瀏覽器.
4. 讀者需要為這個文檔付出什么嗎?
您可以自由使用它. 但是由于您是無償使用, 所以作者不對可能出現(xiàn)的錯誤和問題擔(dān)負(fù)任何責(zé)任. 關(guān)于相關(guān)問題,可以來 email 探討, 但由于精力有限, 不保證回信. 如果你對這有不滿意的地方, 云風(fēng)不接受任何無理批評.
5. 能夠轉(zhuǎn)載這篇文檔嗎?
歡迎您隨意轉(zhuǎn)載, 但不得用它贏利. 而且轉(zhuǎn)載請保留其內(nèi)容完整. 如果您為它制作了諸如 HTML 等別的格式的版本, 也必須同時保留一份純文本版在一起.
6. 如何得到文檔的最新版本?
你看到的這份文檔很可能不是最新版本, 幾年來云風(fēng)總是能收到文檔的讀者對其中一些章節(jié)的質(zhì)疑, 詢問. 所以每隔一段時間, 一些被發(fā)現(xiàn)的 bug, 一些沒有寫清楚的細(xì)節(jié)會被修正和補(bǔ)充. 所以在有疑問時可以先http://www.codingnow.com/ 獲得最新版本.
文檔概貌
本文檔文字組織比較簡陋, 大體上分成 3 個部分.
壓縮算法簡介
1. 色彩模型
2. DCT (離散余弦變換)
3. 重排列 DCT 結(jié)果
4. 量化
5. 0 RLE 編碼
6. 范式 Huffman 編碼
7. DC 的編碼
解碼過程簡述
8. 一個數(shù)據(jù)單元 Y 的解碼
9. JPG 文件(Byte 級)里怎樣組織圖片信息
10. 關(guān)于標(biāo)記
11. JPG 文件中 Haffman 表的儲存
12. 采樣系數(shù)
13. JPG 文件的解碼簡述
JPEG 文件格式
[!--empirenews.page--]JPEG 簡易文檔 V2.14 (2)[/!--empirenews.page--]
一、JPEG 壓縮簡介
1. 色彩模型
JPEG 的圖片使用的是 YCrCb 顏色模型, 而不是計算機(jī)上最常用的 RGB. 關(guān)于色彩模型, 這里不多闡述. 只是說明, YCrCb 模型更適合圖形壓縮. 因?yàn)槿搜蹖D片上的亮度 Y 的變化遠(yuǎn)比色度 C 的變化敏感. 我們完全可以每個點(diǎn)保存一個 8bit 的亮度值, 每 2x2 個點(diǎn)保存一個 Cr Cb 值, 而圖象在肉眼中的感覺不會起太大的變化. 所以, 原來用 RGB 模型, 4 個點(diǎn)需要 4x3=12 字節(jié). 而現(xiàn)在僅需要 4+2=6 字節(jié); 平均每個點(diǎn)占 12bit. 當(dāng)然 JPEG 格式里允許每個點(diǎn)的 C 值都記錄下來; 不過 MPEG 里都是按 12bit 一個點(diǎn)來存放的, 我們簡寫為 YUV12.
[R G B] -> [Y Cb Cr] 轉(zhuǎn)換
-------------------------
(R,G,B 都是 8bit unsigned)
| Y  |     |  0.299       0.587       0.114 |   | R |     | 0 |
| Cb |  =  |- 0.1687    - 0.3313      0.5   | * | G |   + |128|
| Cr |     |  0.5       - 0.4187    - 0.0813|   | B |     |128|
Y = 0.299*R + 0.587*G + 0.114*B  (亮度)
Cb =  - 0.1687*R - 0.3313*G + 0.5   *B + 128
Cr =    0.5   *R - 0.4187*G - 0.0813*B + 128
[Y,Cb,Cr] -> [R,G,B] 轉(zhuǎn)換
-------------------------
R = Y                    + 1.402  *(Cr-128)
G = Y - 0.34414*(Cb-128) - 0.71414*(Cr-128)
B = Y + 1.772  *(Cb-128)
一般, C 值 (包括 Cb Cr) 應(yīng)該是一個有符號的數(shù)字, 但這里被處理過了, 方法
是加上了 128. JPEG 里的數(shù)據(jù)都是無符號 8bit 的.
2. DCT (離散余弦變換)
JPEG 里, 要對數(shù)據(jù)壓縮, 先要做一次 DCT 變換. DCT 變換的原理, 涉及到數(shù)學(xué)知識, 這里我們不必深究. 反正和傅立葉變換(學(xué)過高數(shù)的都知道) 是差不多了. 經(jīng)過這個變換, 就把圖片里點(diǎn)和點(diǎn)間的規(guī)律呈現(xiàn)出來了, 更方便壓縮.JPEG 里是對每 8x8 個點(diǎn)為一個單位處理的. 所以如果原始圖片的長寬不是 8 的倍數(shù), 都需要先補(bǔ)成 8 的倍數(shù), 好一塊塊的處理. 另外, 記得剛才我說的 Cr Cb 都是 2x2 記錄一次嗎? 所以大多數(shù)情況, 是要補(bǔ)成 16x16 的整數(shù)塊.按從左到右, 從上到下的次序排列 (和我們寫字的次序一樣). JPEG 里是對 Y Cr Cb 分別做 DCT 變換的. 這里進(jìn)行 DCT 變換的 Y, Cr, Cb 值的范圍都是 -128~127. (Y 被減去 128)
JPEG 編碼時使用的是 Forward DCT (FDCT) 解碼時使用的 Inverse DCT (IDCT)
下面給出公式:
FDCT:
7   7                 2*x+1                2*y+1
F(u,v) = alpha(u)*alpha(v)* sum sum f(x,y) * cos (------- *u*PI)* cos (------ *v*PI)
x=0 y=0                 16                   16
u,v = 0,1,...,7
{ 1/sqrt(8)  (u==0)
alpha(u) = {
{ 1/2        (u!=0)
IDCT:
7   7                                 2*x+1                2*y+1
f(x,y) = sum sum alpha(u)*alpha(v)*F(u,v)*cos (------- *u*PI)* cos (------ *v*PI)
u=0 v=0                                 16                   16
x,y=0,1...7
這個步驟很花時間, 另外有種 AA&N 優(yōu)化算法, 大家可以去 inet 自己找一下.  在Intel 主頁上可以找到 AA&N IDCT 的 MMX 優(yōu)化代碼. ( Intel 主頁上的代碼, 輸入數(shù)據(jù)為12.4 的定點(diǎn)數(shù), 輸入矩陣需要轉(zhuǎn)置 90 度)
3. 重排列 DCT 結(jié)果
DCT 將一個 8x8 的數(shù)組變換成另一個 8x8 的數(shù)組. 但是內(nèi)存里所有數(shù)據(jù)都是線形存放的, 如果我們一行行的存放這 64 個數(shù)字, 每行的結(jié)尾的點(diǎn)和下行開始的點(diǎn)就 沒有什么關(guān)系, 所以 JPEG 規(guī)定按如下次序整理 64 個數(shù)字.
0, 1, 5, 6,14,15,27,28,
2, 4, 7,13,16,26,29,42,
3, 8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
這樣數(shù)列里的相鄰點(diǎn)在圖片上也是相鄰的了.
4. 量化
對于前面得到的 64 個空間頻率振幅值, 我們將對它們作幅度分層量化操作.方法就是分別除以量化表里對應(yīng)值并四舍五入.
for (i = 0 ; i<=63; i++ )
vector[i] = (int) (vector[i] / quantization_table[i] + 0.5)
下面有張 JPEG 標(biāo)準(zhǔn)量化表. (按上面同樣的彎曲次序排列)
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
這張表依據(jù)心理視覺閥制作, 對 8bit 的亮度和色度的圖象的處理效果不錯.當(dāng)然我們可以使用任意的量化表. 量化表是定義在 jpeg 的 DQT 標(biāo)記后. 一般為 Y 值定義一個, 為 C 值定義一個.
量化表是控制 JPEG 壓縮比的關(guān)鍵. 這個步驟除掉了一些高頻量, 損失了很高細(xì)節(jié). 但事實(shí)上人眼對高空間頻率遠(yuǎn)沒有低頻敏感.所以處理后的視覺損失很小.另一個重要原因是所有的圖片的點(diǎn)與點(diǎn)之間會有一個色彩過渡的過程. 大量的圖象信息被包含在低空間頻率中. 經(jīng)過量化處理后, 在高空間頻率段, 將出現(xiàn)大量連續(xù)的零.
注意, 量化后的數(shù)據(jù)有可能超過 2 byte 有符號整數(shù)的處理范圍.
5. 0 RLE 編碼
現(xiàn)在我們矢量中有許多連續(xù)的 0. 我們可以使用 RLE 來壓縮掉這些 0. 這里我們將跳過第一個矢量 (后面將解釋為什么) 因?yàn)樗木幋a比較特別. 假設(shè)有一組矢量(64 個的后 63 個) 是
57,45,0,0,0,0,23,0,-30,-16,0,0,1,0,0,0, 0 , 0 ,0 , 0,..,0
經(jīng)過 RLE 壓縮后就是
(0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-16) ; (2,1) ; EOB
EOB 是一個結(jié)束標(biāo)記, 表示后面都是 0 了. 實(shí)際上, 我們用 (0,0) 表示 EOB,
但是, 如果這組數(shù)字不以 0 結(jié)束,  那么就不需要 EOB.
另外需要注意的是, 由于后面 huffman 編碼的要求, 每組數(shù)字前一個表示 0 的
數(shù)量的必須是 4 bit, 就是說, 只能是 0~15, 所以, 如果有這么一組數(shù)字:
57, 十八個0, 3, 0, 0, 0, 0, 2, 三十三個0, 895, EOB
我們實(shí)際這樣編碼:
(0,57) ; (15,0) (2,3) ; (4,2) ; (15,0) (15,0) (1,895) , (0,0)
注意 (15,0) 表示了 16 個連續(xù)的 0.
6. 范式 Huffman 編碼
為了提高儲存效率, JPEG 里并不直接保存數(shù)值, 而是將數(shù)值按位數(shù)分成 16 組:
數(shù)值                 組              實(shí)際保存值
0                   0                   -
-1,1                  1                  0,1
-3,-2,2,3                2              00,01,10,11
-7,-6,-5,-4,4,5,6,7            3    000,001,010,011,100,101,110,111
-15,..,-8,8,..,15            4       0000,..,0111,1000,..,1111
-31,..,-16,16,..,31           5     00000,..,01111,10000,..,11111
-63,..,-32,32,..,63           6                   .
-127,..,-64,64,..,127          7                   .
-255,..,-128,128,..,255         8                   .
-511,..,-256,256,..,511         9                   .
-1023,..,-512,512,..,1023       10                   .
-2047,..,-1024,1024,..,2047      11                   .
-4095,..,-2048,2048,..,4095      12                   .
-8191,..,-4096,4096,..,8191      13                   .
-16383,..,-8192,8192,..,16383     14                   .
-32767,..,-16384,16384,..,32767    15                   .
還是來看前面的例子:
(0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-8) ; (2,1) ; (0,0)
只處理每對數(shù)右邊的那個:
57 是第 6 組的, 實(shí)際保存值為 111001 , 所以被編碼為 (6,111001)
45 , 同樣的操作, 編碼為 (6,101101)
23  ->  (5,10111)
-30  ->  (5,00001)
-8  ->  (4,0111)
1  ->  (1,1)
前面的那串?dāng)?shù)字就變成了:
(0,6), 111001 ; (0,6), 101101 ; (4,5), 10111; (1,5), 00001; (0,4) , 0111 ;
(2,1), 1 ; (0,0)
括號里的數(shù)值正好合成一個字節(jié). 后面被編碼的數(shù)字表示范圍是  -32767..32767.合成的字節(jié)里, 高 4 位是前續(xù) 0 的個數(shù), 低 4 位描述了后面數(shù)字的位數(shù).
繼續(xù)剛才的例子, 如果 06 的 huffman 編碼為 111000 ( 06 對應(yīng) 111000 為查表所得. jpeg 文件里保存了壓縮時所產(chǎn)生的 huffman 表, 將 0~255 這 256 個 8 bits 定長數(shù)字, 對應(yīng)成 1~16 bits 的不定長數(shù)值. 出現(xiàn)頻率高的數(shù)字小于 8bits, 頻率低的大于8bits,從而使整個的數(shù)據(jù)長度降低, jpeg 實(shí)際使用的是范式 Huffman 編碼(Canonical Huffman Code)關(guān)于范式 huffman 編碼的詳細(xì)介紹, 請查閱相關(guān)資料 )
69 = (4,5)    --- 1111111110011001  ( 注: 69=4*16+5=0x45 )
21 = (1,5)    ---  11111110110
4  = (0,4)    ---  1011
33 = (2,1)    ---  11011
0 = EOB = (0,0) ---  1010
那么最后對于前面的例子表示的 63 個系數(shù) (記得我們將第一個跳過了嗎?) 按位流
寫入 JPG 文件中就是這樣的:
111000 111001  111000 101101  1111111110011001 10111   11111110110 00001
1011 0111   11011 1   1010
7. DC 的編碼
記得剛才我們跳過了每組 64 個數(shù)據(jù)的第一個吧, DC 就是指的這個數(shù)字 (后面 63 個簡稱 AC) 代入前面的 FDCT 公式可以得到
c(0,0)     7   7
DC = F(0,0) = --------- * sum sum f(x,y) * cos 0 * cos 0 其中 c(0,0) = 1/2
4       x=0 y=0
1     7   7
=  --- * sum sum f(x,y)
8    x=0 y=0
即一塊圖象樣本的平均值. 就是說, 它包含了原始 8x8 圖象塊里的很多能量. (通常會得到一個很大的數(shù)值)
JPEG 的作者指出連續(xù)塊的 DC 率之間有很緊密的聯(lián)系,  因此他們決定對 8x8 塊的DC 值的差別進(jìn)行編碼. (Y, Cb, Cr 分別有自己的 DC)
Diff = DC(i)  - DC(i-1)
所以這一塊的 DC(i) 就是:  DC(i)  = DC(i-1)  + Diff
JPG 從 0 開始對 DC 編碼, 所以 DC(0)=0. 然后再將當(dāng)前 Diff 值加在上一個值上得到當(dāng)前值.
下面再來看看上面那個例子: (記住我們保存的 DC 是和上一塊 DC 的差值 Diff)
例如上面例子中, Diff 是 -511, 就編碼成
(9, 000000000)
如果 9 的 Huffman 編碼是 1111110 (在 JPG 文件中, 一般有兩個 Huffman 表, 一個是 DC 用, 一個是 AC 用) 那么在 JPG 文件中, DC 的 2 進(jìn)制表示為
1111110 000000000
它將放在 63 個 AC 的前面, 上面上個例子的最終 BIT 流如下:
1111110 000000000 111000 111001  111000 101101  1111111110011001 10111
11111110110 00001 1011 0111   11011 1   1010
[!--empirenews.page--]JPEG 簡易文檔 V2.14 (3)[/!--empirenews.page--]
二、解碼過程簡述
8. 一個數(shù)據(jù)單元 Y 的解碼 (其余類同)
在整個圖片解碼的開始, 你需要先初始化 DC 值為 0.
1) 先解碼 DC:
a) 取得一個 Huffman 碼 (使用 Huffman DC 表)
b) Huffman解碼, 看看后面的數(shù)據(jù)位數(shù) N
c) 取得 N 位, 計算 Diff 值
d) DC + = Diff
e) 寫入 DC 值:      " vector[0]=DC "
2) 解碼 63 個 AC:
------- 循環(huán)處理每個 AC 直到 EOB 或者處理到 64 個 AC
a) 取得一個 Huffman 碼 (使用 Huffman AC 表)
b) Huffman 解碼, 得到 (前面 0 數(shù)量, 組號)
[記住: 如果是(0,0) 就是 EOB 了]
c) 取得 N 位(組號) 計算 AC
d) 寫入相應(yīng)數(shù)量的 0
e) 接下來寫入 AC
下一步的解碼:
上一步我們得到了 64 個矢量. 下面我們還需要做一些解碼工作:
1) 反量化 64 個矢量 : "for (i=0;i<=63;i++) vector[i]*=quant[i]" (注意防止溢出)
2) 重排列 64 個矢量到 8x8 的塊中
3) 對 8x8 的塊作 IDCT
對 8x8 塊的 (Y,Cb,Cr) 重復(fù)上面的操作 [Huffman 解碼, 步驟 1), 2), 3)]
4) 將所有的 8bit 數(shù)加上 128
5) 轉(zhuǎn)換 YCbCr 到 RGB
9. JPG 文件(Byte 級)里怎樣組織圖片信息
注意 JPEG/JFIF 文件格式使用 Motorola 格式, 而不是 Intel 格式, 就是說, 如果是一個字的話, 高字節(jié)在前, 低字節(jié)在后.
JPG 文件是由一個個段 (segments) 構(gòu)成的. 每個段長度 <=65535. 每個段從一個標(biāo)記字開始. 標(biāo)記字都是 0xff 打頭的, 以非 0 字節(jié)和 0xFF 結(jié)束. 例如 ‘FFDA‘ , ‘FFC4‘, ‘FFC0‘. 每個標(biāo)記有它特定意義, 這是由第2字節(jié)指明的. 例如, SOS (Start Of Scan = ‘FFDA‘) 指明了你應(yīng)該開始解碼. 另一個標(biāo)記 DQT (Define QuantizationTable = 0xFFDB) 就是說它后面有 64 字節(jié)的 quantization 表
在處理 JPG 文件時, 如果你碰到一個 0xFF, 而它后面的字節(jié)不是 0, 并且這個字節(jié)沒有意義. 那么你遇到的 0xFF 字節(jié)必須被忽略. (一些 JPG 里, 常用用 0xFF 做某些填充用途) 如果你在做 huffman 編碼時碰巧產(chǎn)生了一個 0xFF, 那么就用 0xFF0x00 代替. 就是說在 jpeg 圖形解碼時碰到 FF00 就把它當(dāng)作 FF 處理.
另外在 huffman 編碼區(qū)域結(jié)束時, 碰到幾個 bit 沒有用的時候, 應(yīng)該用 1 去填充.然后后面跟 FF.
下面是幾個重要的標(biāo)記:
SOI = Start Of Image = ‘FFD8‘
這個標(biāo)記只在文件開始出現(xiàn)一次
EOI = End Of Image = ‘FFD9‘
JPG 文件都以 FFD9 結(jié)束
RSTi = FFDi ( i =  0..7)  [ RST0 = FFD0, RST7=FFD7]
= 復(fù)位標(biāo)記
通常穿插在數(shù)據(jù)流里, 我想是擔(dān)心 JPG 解碼出問題吧(應(yīng)該配合 DRI 使用). RST 將Huffman 的解碼數(shù)據(jù)流復(fù)位. DC 也重新從 0 開始計
(SOS --- RST0 --- RST1 -- RST2 --...
...-- RST6 --- RST7 -- RST0 --...)
10. 標(biāo)記
下面是必須處理的標(biāo)記
SOF0 = Start Of Frame 0 = FFC0
SOS  = Start Of Scan    = FFDA
APP0 = it‘s the marker used to identify a JPG file which uses the JFIF
specification       = FFE0
COM  = Comment          = FFFE
DNL  = Define Number of Lines    = FFDC
DRI  = Define Restart Interval   = FFDD
DQT  = Define Quantization Table = FFDB
DHT  = Define Huffman Table      = FFC4
11. JPG 文件中 Haffman 表的儲存
JPEG 里定義了一張表來描述 Haffman 樹. 定義在 DHT 標(biāo)記后面. 注意: Haffman 代碼的長度限制在 16bit 內(nèi).
一般一個 JPG 文件里會有 2 類 Haffman 表: 一個用于 DC 一個用于 AC (實(shí)際有 4個表, 亮度的 DC,AC 兩個, 色度的 DC,AC 兩個)
這張表是這樣保存的:
1) 16 字節(jié):
第 i 字節(jié)表示了 i 位長的 Huffman 代碼的個數(shù) (i= 1 到 16)
2) 這表的長度 (字節(jié)數(shù)) = 這 16 個數(shù)字之和
現(xiàn)在你可以想象這張表怎么存放的吧? 對應(yīng)字節(jié)就是對應(yīng) Haffman 代碼等價數(shù)字. 我
不多解釋, 這需要你先了解 Canonical Huffman Code. 這里只舉一個例子:
Haffman 表的表頭是 0,2,3,1,1,1,0,1,0,0,0,0,0,0,0,0
就是說長度為 1 的代碼沒有
長度為 2 的代碼為 00
01
長度為 3 的代碼是 100
101
110
長度為 4 的代碼是 1110
長度為 5 的代碼是 11110
長度為 6 的代碼是 111110
長度為 7 的代碼沒有 (如果有一個的話應(yīng)該是 1111110)
長度為 8 的代碼是 11111100
.....
后面都沒有了.
如果表下面的數(shù)據(jù)是
45 57 29 17 23 25 34 28
就是說
45 = 00
57 = 01
29 = 100
17 = 101
23 = 110
等等...
使用 Canonical Huffman Code 的好處在于可以很簡潔的重建對應(yīng)關(guān)系表.
12. 采樣系數(shù)
下面講解的都是真彩 JPG 的解碼, 灰度 JPG 的解碼很簡單, 因?yàn)閳D形中只有亮度信息. 而彩色圖形由 (Y, Cr, Cb) 構(gòu)成, 前面提到過, Y 通常是每點(diǎn)采樣一次, 而 Cr,Cb 一般是 2x2 點(diǎn)采樣一次, 當(dāng)然也有的 JPG 是逐點(diǎn)采樣, 或者每兩點(diǎn)采樣 (橫向兩點(diǎn), 縱向一點(diǎn)) 采樣系數(shù)均被定義成對比最高采樣系數(shù)的相對值.
一般情況 (即: Y 逐點(diǎn)采樣, Cr Cb 每 2x2 點(diǎn)一次) 下: Y 有最高的采樣率, 橫向采樣系數(shù)HY=2 縱向采樣系數(shù) VY=2; Cb 的橫向采樣系數(shù) HCb=1, 縱向采樣系數(shù) VCb=1;同樣 HCr=1, VCr=1
在 Jpeg 里, 8x8 個原始數(shù)據(jù), 經(jīng)過 RLE, Huffman 編碼后的一串?dāng)?shù)據(jù)流稱為一個
Data Unit (DU) JPG 里按 DU 為單位的編碼次序如下:
1)      for  (counter_y=1;counter_y<=VY;counter_y++)
for (counter_x=1;counter_x<=HY;counter_x++)
{  對 Y 的 Data Unit 編碼 }
2)      for  (counter_y=1;counter_y<=VCb ;counter_y++)
for (counter_x=1;counter_x<=HCb;counter_x++)
{  對 Cb 的 Data Unit 編碼 }
3)      for  (counter_y=1;counter_y<=VCr;counter_y++)
for (counter_x=1;counter_x<=HCr;counter_x++)
{  對 Cr 的 Data Unit 編碼 }
按我上面的例子: (HY=2, VY=2 ; HCb=VCb =1, HCr,VCr=1) 就是這樣一個次序
YDU,YDU,YDU,YDU,CbDU,CrDU
這些就描述了一塊 16x16 的圖形. 16x16 = (Hmax*8 x Vmax*8) 這里 Hmax=HY=2 Vmax=VY=2
一個 (Hmax*8,Vmax*8) 的塊被稱作 MCU (Minimun Coded Unix) 前面例子中一個
MCU = YDU,YDU,YDU,YDU,CbDU,CrDU
如果  HY =1, VY=1
HCb=1, VCb=1
HCr=1, VCr=1
這樣 (Hmax=1,Vmax=1), MCU 只有 8x8 大, MCU = YDU,CbDU,CrDU
對于灰度 JPG, MCU 只有一個 DU (MCU = YDU)
JPG 文件里, 圖象的每個組成部分的采樣系數(shù)定義在 SOF0 (FFC0) 標(biāo)記后
13. 簡單說一下 JPG 文件的解碼
解碼程序先從 JPG 文件中讀出采樣系數(shù), 這樣就知道了 MCU 的大小, 算出整個圖象
有幾個 MCU. 解碼程序再循環(huán)逐個對 MCU 解碼, 一直到檢查到 EOI 標(biāo)記. 對于每個
MCU, 按正規(guī)的次序解出每個 DU, 然后組合, 轉(zhuǎn)換成 (R,G,B) 就 OK 了
[!--empirenews.page--]JPEG 簡易文檔 V2.14 (4)[/!--empirenews.page--]
三、附:JPEG 文件格式
- 文件頭 (2 bytes):  $ff, $d8 (SOI) (JPEG 文件標(biāo)識)
- 任意數(shù)量的段 , 見后面
- 文件結(jié)束 (2 bytes): $ff, $d9 (EOI)
段的格式:
- header (4 bytes):
$ff     段標(biāo)識
n      段的類型 (1 byte)
sh, sl  該段長度, 包括這兩個字節(jié), 但是不包括前面的 $ff 和 n.
注意: 長度不是 intel 次序, 而是 Motorola 的, 高字節(jié)在前,
低字節(jié)在后!
- 該段的內(nèi)容, 最多 65533 字節(jié)
注意:
- 有一些無參數(shù)的段 (下面那些前面注明星號的)
這些段沒有長度描述 (而且沒有內(nèi)容), 只有 $ff 和類型字節(jié).
- 段之間無論有多少 $ff 都是合法的, 必須被忽略掉.
段的類型:
*TEM   = $01   可以忽略掉
SOF0  = $c0   幀開始 (baseline JPEG), 細(xì)節(jié)附后
SOF1  = $c1   dito
SOF2  = $c2   通常不支持
SOF3  = $c3   通常不支持
SOF5  = $c5   通常不支持
SOF6  = $c6   通常不支持
SOF7  = $c7   通常不支持
SOF9  = $c9   arithmetic 編碼(Huffman 的一種擴(kuò)展算法), 通常不支持
SOF10 = $ca   通常不支持
SOF11 = $cb   通常不支持
SOF13 = $cd   通常不支持
SOF14 = $ce   通常不支持
SOF14 = $ce   通常不支持
SOF15 = $cf   通常不支持
DHT   = $c4   定義 Huffman Table,  細(xì)節(jié)附后
JPG   = $c8   未定義/保留 (引起解碼錯誤)
DAC   = $cc   定義 Arithmetic Table, 通常不支持
*RST0  = $d0   RSTn 用于 resync, 通常被忽略
*RST1  = $d1
*RST2  = $d2
*RST3  = $d3
*RST4  = $d4
*RST5  = $d5
*RST6  = $d6
*RST7  = $d7
SOI   = $d8   圖片開始
EOI   = $d9   圖片結(jié)束
SOS   = $da   掃描行開始, 細(xì)節(jié)附后
DQT   = $db   定義 Quantization Table, 細(xì)節(jié)附后
DNL   = $dc   通常不支持, 忽略
DRI   = $dd   定義重新開始間隔, 細(xì)節(jié)附后
DHP   = $de   忽略 (跳過)
EXP   = $df   忽略 (跳過)
APP0  = $e0   JFIF APP0 segment marker (細(xì)節(jié)略)
APP15 = $ef   忽略
JPG0  = $f0   忽略 (跳過)
JPG13 = $fd   忽略 (跳過)
COM   = $fe   注釋, 細(xì)節(jié)附后
其它的段類型都保留必須跳過
SOF0: Start Of Frame 0:
- $ff, $c0 (SOF0)
- 長度 (高字節(jié), 低字節(jié)), 8+components*3
- 數(shù)據(jù)精度 (1 byte) 每個樣本位數(shù), 通常是 8 (大多數(shù)軟件不支持 12 和 16)
- 圖片高度 (高字節(jié), 低字節(jié)), 如果不支持 DNL 就必須 >0
- 圖片寬度 (高字節(jié), 低字節(jié)), 如果不支持 DNL 就必須 >0
- components 數(shù)量(1 byte), 灰度圖是 1, YCbCr/YIQ 彩色圖是 3, CMYK 彩色圖
是 4
- 每個 component: 3 bytes
- component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
- 采樣系數(shù) (bit 0-3 vert., 4-7 hor.)
- quantization table 號
DRI: Define Restart Interval:
- $ff, $dd (DRI)
- 長度 (高字節(jié), 低字節(jié)), 必須是 4
- MCU 塊的單元中的重新開始間隔 (高字節(jié), 低字節(jié)),
意思是說, 每 n 個 MCU 塊就有一個 RSTn 標(biāo)記.
第一個標(biāo)記是 RST0, 然后是 RST1 等, RST7 后再從 RST0 重復(fù)
DQT: Define Quantization Table:
- $ff, $db (DQT)
- 長度 (高字節(jié), 低字節(jié))
- QT 信息 (1 byte):
bit 0..3: QT 號(0..3, 否則錯誤)
bit 4..7: QT 精度, 0 = 8 bit, 否則 16 bit
- n 字節(jié)的 QT, n = 64*(精度+1)
備注:
- 一個單獨(dú)的 DQT 段可以包含多個 QT, 每個都有自己的信息字節(jié)
- 當(dāng)精度=1 (16 bit), 每個字都是高位在前低位在后
DAC: Define Arithmetic Table:
法律原因, 現(xiàn)在的軟件不支持 arithmetic 編碼.
不能生產(chǎn)使用 arithmetic 編碼的 JPEG 文件
DHT: Define Huffman Table:
- $ff, $c4 (DHT)
- 長度 (高字節(jié), 低字節(jié))
- HT 信息 (1 byte):
bit 0..3: HT 號 (0..3, 否則錯誤)
bit 4   : HT 類型, 0 = DC table, 1 = AC table
bit 5..7: 必須是 0
- 16 bytes: 長度是 1..16 代碼的符號數(shù). 這 16 個數(shù)的和應(yīng)該 <=256
- n bytes: 一個包含了按遞增次序代碼長度排列的符號表
(n = 代碼總數(shù))
備注:
- 一個單獨(dú)的 DHT 段可以包含多個 HT, 每個都有自己的信息字節(jié)
COM: 注釋:
- $ff, $fe (COM)
- 注釋長度 (高字節(jié), 低字節(jié)) = L+2
- 注釋為長度為 L 的字符流
SOS: Start Of Scan:
- $ff, $da (SOS)
- 長度 (高字節(jié), 低字節(jié)), 必須是 6+2*(掃描行內(nèi)組件的數(shù)量)
- 掃描行內(nèi)組件的數(shù)量 (1 byte), 必須 >= 1 , <=4 (否則是錯的) 通常是 3
- 每個組件: 2 bytes
- component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q), 見 SOF0
- 使用的 Huffman 表:
- bit 0..3: AC table (0..3)
- bit 4..7: DC table (0..3)
- 忽略 3 bytes (???)
備注:
- 圖片數(shù)據(jù) (一個個掃描行) 緊接著 SOS 段.
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JPEG decoding algorithm
JPEG簡易文檔V2.11
Jpeg文件的格式和解碼
JPEG文件格式介紹
JPEG壓縮原理
JPEG編解碼過程詳解 - 海王 - 博客園
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服