<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-65  評論-68  文章-4  trackbacks-0

    JPEG文件格式簡單分析

    作者:小爽

    摘要:

    這篇文章大體上介紹了JPEG文件的結構信息以及它的壓縮算法和編碼方式。使讀者能夠對JPEG文件格式有大體上的了解。為讀者進一步進行學習JPEG文件壓縮做好準備

     

    關鍵字:十六進制,段格式,編碼

     

    一、    JPEG文件格式概述:

    圖像和動畫的存儲方式是一個很重要的問題。幸好我們有了數據壓縮,有了JPEG等多種壓縮存儲圖像的文件格式,我們今天才能夠拿著小小的一個存儲器,卻存上許多張色彩鮮艷的圖片。如果沒有圖像壓縮算法,也許我們的多媒體時代就會晚到來許多年。

    JPEG圖像存儲格式一個比較成熟的圖像有損壓縮格式,雖然一個圖片經過轉化為JPEG圖像后,一些數據會丟失,但是,人眼是很不容易分辨出來這種差別的。也就是說,JPEG圖像存儲格式既滿足了人眼對色彩和分辨率的要求,又適當的去除了圖像中很難被人眼所分辨出的色彩,在圖像的清晰與大小中JPEG找到了一個很好的平衡點。

    雖然圖像轉化為JPEG格式會減小很多,但是并不是文件就變得簡單了,相反,JPEG文件的格式是比較復雜的。不經過認真地分析,是不容易弄懂它的。

     

    二、    JPEG文件的存儲方式:

    JPEG文件的格式是分為一個一個的段來存儲的(但并不是全部都是段),段的多少和長度并不是一定的。只要包含了足夠的信息,該JPEG文件就能夠被打開,呈現給人們。JPEG文件的每個段都一定包含兩部分一個是段的標識,它由兩個字節構成:第一個字節是十六進制0xFF,第二個字節對于不同的段,這個值是不同的。緊接著的兩個字節存放的是這個段的長度(除了前面的兩個字節0xFF0xXXX表示不確定。他們是不算到段的長度中的)。注意:這個長度的表示方法是按照高位在前,低位在后的,與Intel的表示方法不同。比方說一個段的長度是0x12AB,那么它會按照0x120xAB的順序存儲。但是如果按照Intel的方式:高位在后,低位在前的方式會存儲成0xAB0x12,而這樣的存儲方法對于JPEG是不對的。這樣的話如果一個程序不認識JPEG文件某個段,它就可以讀取后兩個字節,得到這個段的長度,并跳過忽略它。

    本人曾經編寫過一個讀取JPEG文件信息的程序,該程序能夠讀取JPEG文件中包含的段的信息并顯示出來。下面是一個JPEG圖片的信息片斷:

     

    SOI

            APP0    Length: 0x10

            DQT

                    DQT [0]:

            8       6       5       8       12      20      26      31

            6       6       7       10      13      29      30      28

            7       7       8       12      20      29      35      60

            7       9       11      15      26      44      50      31

            9       11      19      28      34      56      52      0

            12      18      28      32      61      52      0       46

            25      32      39      57      52      0       60      0

            36      46      39      49      253     50      0       50

            Length: 0x43

            DQT

                    DQT [1]:

            9       9       12      24      50      50      50      50

            9       11      13      33      50      50      50      50

            12      13      28      50      50      50      50      50

            24      33      50      50      50      50      50      50

            50      50      50      50      50      50      50      0

            50      50      50      50      50      50      0       50

            50      50      50      50      50      0       50      0

            50      50      50      50      253     50      0       50

            Length: 0x43

            SOF0

                    Image Height: 173

                    Image Width: 401

                    Number of Frame(s): 3

                    ****************

                    Content ID: 1

                    H Factor: 2

                    V Factor: 2

                    QT ID: 0

                    ****************

                    Content ID: 2

                    H Factor: 1

                    V Factor: 1

                    QT ID: 1

                    ****************

                    Content ID: 3

                    H Factor: 1

                    V Factor: 1

                    QT ID: 1

            Length: 0x11

            DHT

                    Type: DC TABLE

                    ID: 0

            Length: 0x1f

            DHT

                    Type: AC TABLE

                    ID: 0

            Length: 0xb5

            DHT

                    Type: DC TABLE

                    ID: 1

            Length: 0x1f

            DHT

                    Type: AC TABLE

                    ID: 1

            Length: 0xb5

            SOS     Length: 0xc     <-Will Not Process This Seg.

    FATAL ERROR: File Structure Does NOT Support.

     

    你首先會想到為什么最后會出現一個錯誤的信息呢?這是因為,在SOSStart Of Scan)段的后面,就是編碼后的一行一行的圖像信息。不再是段的結構了。在開始的SOIStart Of Image)不是一個段,它是文件的開始,它的值也是類似于0xFF0xXX的結構(SOI的具體數值清自己察看相關書籍,本文章中將不作重點介紹),但是后面沒有段的長度。在文件的最后,有一個EOIEnd Of Image)的標識,它的結構和SOI是類似的。它標志著文件的結束。

    在這中間,包含了APP0段,DQT段,SOF0段,DHT段,SOS段。有的段的個數是不唯一的,比方說DQT段。我們現在重點地介紹各個段的作用。

     

    三、    JPEG文件中段的介紹:

    APP0段中主要存儲的是圖片的識別信息(字符串”JFIF\0”)、一些分辨率的信息以及縮略圖的信息。在我的實際測試中,發現并不是所有的JPEG文件都有APP0段的,有的僅是有APP2之類的其他段,但是每個文件中肯定是包含APPX的段(X可以取得的值可以查閱相關文檔)。我個人估計,這些APPX的段的信息應該是大同小異。這個的驗證還有待本人進一步的學習,目前只能說到這里。

    DQT段的內容是量化表的信息。眾所周知,一個顏色可以分為RGB(紅、綠、蘭)三個分量,這三色光組成了我們可以見到的所有色彩。但是,在JPEG文件中,RGB色彩格式需要先轉化為YUV的格式。Y分量代表了亮度信息,UV分量代表了色差信息。相比之下,人眼對于Y分量更為敏感。量化表的作用就是對于一些不需要的量進行去除,這也是JPEG有損壓縮損失數據的關鍵。上面的輸出可以看到兩個量化表,一個給Y分量,另一個給UV分量。其實,他們也可以共用一個量化表。一個量化的結果如下所示(摘自《JPEG壓縮編碼標準》):

    15    0     -1    0     0     0     0     0

    -2    -1    0     0     0     0     0     0

    -1    -1    0     0     0     0     0     0

    0     0     0     0     0     0     0     0

    0     0     0     0     0     0     0     0

    0     0     0     0     0     0     0     0

    0     0     0     0     0     0     0     0

    0     0     0     0     0     0     0     0

    我們可以看到,量化后出現了大量的0,這種結果很有利于我們進行下一步的數據壓縮的。至于為什么是8x8的大小,待會你就知道了。

    SOF0段的內容是圖像的大小信息,每個像素的位數信息,以及YUV每個分量分別得的采樣信息(這部分如果讀者想要進一步學習,請參考相應書籍和文檔)。JPEG文件圖像的編碼是一個方塊一個方塊進行的,每塊的大小為8x8大小(如果圖像不是整數個方塊的大小那么就對圖像補齊為整數個大小)。簡略地說采樣信息,就是如何按組記錄YUV的信息,即若干個Y方塊,若干個U方塊,若干個V方塊經過量化的數據再次經過編碼后組成一組記錄,保存在SOS段結束后。

    DHT段的內容是一個重頭戲,如果沒有它,JPEG壓縮效率就不會那么高了。它內部定義的是一個Huffman表,不同的DHT段定義不同的Huffman表,有的是直流量的表,有的是交流量的表。什么是直流量,什么是交流量呢?待會我再作介紹。最多的Huffman表示幾個呢?YUV各一個,直流交流各一個,因為YUV每個分量都有直流和交流,所以最多時,Huffman表有3x2個,也就是可以有6DHT段。該文件中有4DHT表,您可以大概猜出來是哪幾個表么?Y的直流和交流各一個Huffman表,UV和起來直流和交流各一個Huffman表。這樣說應該比較合理吧。

    好了,現在我們應該弄明白什么是交流量,什么是直流量了。還舉上面那個有許多個08x8的表的例子說,所謂交流量,是經過量化后的塊內部除了左上角15那個值的其余值。實際上,塊與塊之間左上角那個值是用直流Huffman表來單獨編碼的。不與塊內部一同編碼。雖然不同的編碼,但是要注意的事,不同的編碼方式并不意味著它們是不在一起的,具體的存儲編碼后的數據的時候,還是按照若干個Y方塊,若干個U方塊,若干個V方塊經過量化的數據再次經過編碼后組成一組記錄來存儲的。

    SOS段的內容是關于YUV每個分量的直流和交流各使用那個Huffman表來編碼的。

          

    四、    JPEG文件十六進制代碼解析

    我覺得,如果想要的了解JPEG,對十六進制代碼的觀察是必不可少的。不要認為這樣有多難,我會讓你知道這是很簡單的。目前我們只需要了解我們能夠了解的東西就可以了。要記住,每個段的開始是0xFF0xXX,緊接著兩個字節是長度信息。

    可以看到,上圖被選定的標記是SOI標記。

    上圖被選定的段是APP0段。

     

    緊接著的段是DQT段,這個JPEG文件有兩個DQT段。這里需要強調一點的是,包括量化表在內8x8的塊的值是按照Z形來保存量化表8x8的數據的。而不是按照一行一行的保存的。這樣做的好處是,能夠讓實際上相鄰的像素點保存后也排列得比較近,便于壓縮和編碼。如下圖所示:

    (摘自《JPEG壓縮編碼標準》)

     

     

    上圖標記的段是DHT段,一共有4DHT段。

     

    這個段是SOS段,在這個段的后面就是所有壓縮后的數據。

    每段的具體信息在這里我就不詳細介紹了,網上有很多相關的文章,如果有興趣的話,可以去查找閱讀。

     

    五、    圖像數據塊內的編碼方式

    其實,圖像數據塊的編碼是比較麻煩的,它涉及到了行程編碼,Huffman編碼等編碼方式。這部分很多文檔說得都不是很清楚,我力求去除內部比較麻煩的部分,再通過簡單的語言讓大家明白原理,這樣大家如果有興趣進行下一步的研究,也會比較容易上手的。

    我們還是使用那剛才那個包含很多0的量化后的8x8的數據塊來說明。我們把塊內剩余的63個數據用行程編碼來編碼。經過行程編碼后的數據的格式是:(x,y)。x表示的是從當前位置開始有多少個連續的零,y表示這些連續的0的后面的第一個非零的數是多少。但是為了解決存儲的問題和進行進一步的壓縮。最后的壓縮格式變為:(x,yzxy占有一個字節的長度。z的長度不固定,需要根據y的值來判斷。x仍代表從當前位置開始有幾個連續的零,但是因為x只能占有四位的長度,也就是它的最大值是15,所以,當多于16個連續的零的時候。會用一個字節的(15,0)來代替前面的160,然后繼續編碼(注意:這時候沒有z部分)。當塊結束或者當前塊后面剩余的都是零的時候,就用(0,0)即EOB代替(同樣也是沒有z部分)。前面說到z的長度不固定,需要根據y的值來判斷,這是為什么呢?簡單的來說,z的長度是不一定的,在1~15的范圍內。Y的作用簡單的來說表示的是z的二進制位數(1~15),也正好是4位二進制的值能夠表示的。然后,把xy合成的一個字節單獨提取出來,利用DHT里面的Huffman表來進行編碼。這樣,編碼的長度又能夠被壓縮了。

     

    六、    總結

    敘述了這么多,相信大家對于JPEG已經有了一個大概的了解了吧,如果你通過閱讀這篇文章,對JPEG文件的結構和算法有了一個大體上的認識,那么這篇文章的目的也就達到了。下一步進行具體研究就不會有太大問題了。祝愿大家能夠在數據壓縮的路上走好。

     

    參考文獻:

    1.             JPEG壓縮編碼標準》

    2.             JPEG格式》

    3.             JPEG簡易文檔》        作者:風云

    posted on 2005-07-01 15:09 小爽 閱讀(48414) 評論(19)  編輯  收藏 所屬分類: 我的經驗

    評論:
    # re: JPEG文件格式簡單分析 2006-12-28 14:14 | 李運博
    基本對該編碼有一定的認識了,謝謝  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2007-01-15 14:41 | ysm
    有沒有JPEG文件格式解析編碼給一個,yangsm318@126.com 謝謝!  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2007-07-26 14:09 | wyz

    謝謝你的文章

    如何從網絡上讀取jpeg信息,并實時的顯示出來?(即不能全部讀到本地之后再顯示), 能告知嗎? 謝謝,

    wangyuanzhenghf@163.com  回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2007-08-03 17:20 | 過客
    不錯的文章,謝謝你,辛苦了!  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2007-08-06 20:22 | 暢達
    通俗易懂!謝謝你的文章!  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2007-08-06 20:24 | 暢達
    作者是否編寫過c++程序來處理JPEG圖像?
    我的郵箱xuzhengnan@163.com
    期待您的指導!  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2007-10-30 02:34 | Wilson
    我編寫過,但是因為現在在美國學習,所以沒有辦法給你發送一份拷貝,不好意思了@暢達
      回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2008-01-05 11:55 | xiaoxin
    首先非常感謝你的文章,辛苦了!
    不好意思我是新手,我想知道通過什么軟件或編輯器能知道一圖像的格式信息的?像你上面顯示出的圖片那樣,謝謝!
    還有請問你知道如何讀取jp2格式文件信息嗎?知道的話能方便告知嗎?不勝感激!
    我的郵箱是chenmo1013@126.com  回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2008-03-29 19:31 | 學習者
    謝謝你
    你的圖我覺得是比較好地
    十分感謝  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2008-04-07 09:38 | t
    很有收獲
    順便問一下jp2和漸進式jpeg怎么分辨?  回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2008-04-23 22:32 | xiaoxiao
    很急 樓主有沒有將接受到的數據轉換成JPEG的VC軟件程序或C軟件方面的資料,cxml84@163.com 謝謝  回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2008-05-15 13:39 | wolf
    good  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2008-08-05 10:02 | Sandwi
    非常好,感謝分享。  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2008-09-23 16:44 | 年建杰
    HI,小爽你好
    能把你那個讀取并顯示JPEG文件的程序發給我嗎? 我現在正在做這個文件的解析和顯示,比較迷茫。謝謝了  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2008-09-23 16:49 | 年建杰
    HI,小爽你好
    能把你那個讀取并顯示JPEG文件的程序發給我嗎? 我現在正在做這個文件的解析和顯示,比較迷茫。謝謝了
    我的MSN:nianjianjie@hotmail.com  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2009-01-16 08:51 | 理標電子
    詳細  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2009-03-24 08:35 | 小陳
    非常感謝你的文章!  回復  更多評論
      
    # re: JPEG文件格式簡單分析 2009-08-24 08:50 | 敏敏
    不錯,多謝分享!

    文中提到“JPEG文件圖像的編碼是一個方塊一個方塊進行的,每塊的大小為8x8大小(如果圖像不是整數個方塊的大小那么就對圖像補齊為整數個大小)”,很疑惑當圖像不是整數個方塊的大小如何將圖像補齊為整數個大小,例如一個大小為10(行)×7(列)像素大小的圖像(記為A11、A12、…A17,A21、A22、…,A71、A72、A73、…A77)該如何補成8x8的塊呢?  回復  更多評論
      
    # re: JPEG文件格式簡單分析[未登錄] 2010-01-17 00:07 | dboy
    不錯,學習了  回復  更多評論
      
    主站蜘蛛池模板: 国产午夜免费福利红片| 小日子的在线观看免费| 亚洲成年人电影网站| 国产亚洲情侣一区二区无| 中文字幕成人免费高清在线视频| 亚洲日本va午夜中文字幕久久 | 国产三级免费电影| 国产香蕉免费精品视频| 国产无遮挡无码视频免费软件| 久久久亚洲欧洲日产国码二区| 啦啦啦完整版免费视频在线观看| www在线观看免费视频| 久久精品国产亚洲av瑜伽| 亚洲男人的天堂一区二区| 免费观看男人免费桶女人视频| 91成人免费在线视频| 91精品国产免费入口| 美女免费视频一区二区| 亚洲精品自产拍在线观看动漫| 最近最新MV在线观看免费高清| 人与动性xxxxx免费| 亚洲最大的视频网站| 亚洲AV福利天堂一区二区三 | 曰批免费视频播放免费| 亚洲国产成人无码AV在线影院| 国产精品亚洲片夜色在线| 久久精品亚洲乱码伦伦中文| 免费国产成人午夜私人影视 | 亚洲免费日韩无码系列| 亚洲国产精品嫩草影院久久 | 国产精品免费αv视频| 深夜福利在线免费观看| 免费国产在线精品一区| 成人福利在线观看免费视频| 一级免费黄色大片| 特级毛片爽www免费版| 国产成人精品免费视频大全| 久久er国产精品免费观看8| 免费无码又爽又刺激一高潮| 亚洲av无码有乱码在线观看| 亚洲av中文无码乱人伦在线观看|