先ほど学習したjpegデコードの知識をもとに、jpegデコードコードを記述します ここでは、実際のデコード処理を用いてjpegについて説明します。
図1に示すように、実際のjpg画像データは、JPEG形式に従って、対応する識別子と対応するデータ情報が解析されます。
FF D8 : SOI ファイルヘッダー
FF E0 : APP0画像情報認識
FF DB : DQT量子化テーブル
FF C0 : SOF0 フレーム開始
FF C4:DHT Huffman表
FF DA : SOS スキャンラインの開始
データをエンコードする
FF D9 : SOI ファイルの終わり
図 1 に示すように、ファイル ヘッダーをスキャンして有効な DQT 量子化テーブル情報を取得します。
図 2 に示すように、SOF は画像の基本情報を認識します。
画像解像度: 1920*1080、4:1:1 画像をデコード、y 成分は Cb および Cr の 4 倍。
MCU サイズは 8*8 です。4:1:1 モードでは、1920/(8*2)=120、1080/(2*8)=67.5 になります。このとき、整数個の MCU を補償する必要があります。したがって、実際の幅は 68*16 = 1088、合計 120 行、68 列の MCU になります。
したがって、実際に処理される画像サイズは 1920*1088、120*68 MCU、各 MCU サイズは 8*8、Y コンポーネントは 2*2 MCU に従ってデコードされます。
DHT ハフマン テーブル情報、およびJPEG のハフマン デコード例に基づいて 、図 3 に示すように、ハフマン ツリーを再構築し、ハフマン コードとサイズ テーブルを取得します。00 -> Y-DC、tablenum=0:
図4,10 -> Y-AC,tablenum=1:
図 5、01 -> CbCr-DC、tablenum=2:
図 6、11 -> CbCr-AC、tablenum=3:
SOS の後、3 バイトのデータは省略され (他の目的に使用され)、有効な 32 ビット データは後で読み取ることができます。
32 ビット データの取得: 0xe2e8a28a --> 1110 0010 1110 1000 1010 0010 1000 1010
ハフマンはテーブルを検索し、DHT コードワード 0x06 を取得しました。上位 4 ビットはゼロの予約桁を表し、下位 4 ビットはデータ ビット長を表します。つまり、データの次の 6 ビットが取得されます。
6ビットデータを取得: 0010 11 ==>0xb
実際のデータ値を計算します: (0xb+1)-(1<<6) = -52、使用される累積ビット数は 10 ビットです
DC データは DPCM エンコードされます。現在の DC 値から前回の DC 値を引いた結果です MCU の最初の DC 値は 0 でなければなりませんので、DC 値は取得データ + DC データになります このとき、DC 量子化後の実際の値は -52; (AC データは DPCM エンコードが必要ではありません)
量子化: ピクセル値を使用して得られた結果 ÷ 量子化テーブルの対応する値
したがって、逆量子化データ値 = DQT*(-52)、この時点では -416 になります。
逆量子化データに対してアンチジグザグを実行すると、-416 が得られます。
アンチジグザグテーブル:
0 | 1 | 8 | 16 | 9 | 2 | 3 | 10 |
17 | 24 | 32 | 25 | 18 | 11 | 4 | 5 |
12 | 19 | 26 | 33 | 40 | 48 | 41 | 34 |
27 | 20 | 13 | 6 | 7 | 14 | 21 | 28 |
35 | 42 | 49 | 56 | 57 | 50 | 43 | 36 |
29 | 22 | 15 | 23 | 30 | 37 | 44 | 51 |
58 | 59 | 52 | 45 | 38 | 31 | 39 | 46 |
53 | 60 | 61 | 54 | 47 | 55 | 62 |
元の画像は 8*8 MCU ブロックに分割されて個別にエンコードされるため、デコードも 1 つの MCU に従ってデコードされます。
MCU がデコードするとき:
1. DC コンポーネントがデータ ビット長 0 に遭遇すると、データも 0 になります。
2. AC コンポーネントが EOB 終了シンボルに遭遇すると、MCU デコードは終了します。予約されたゼロの数は 0 で、データ ビット長も 0 です。
3. AC コンポーネントが ZRL コードに遭遇すると、それは 15 個のゼロ データです。予約されたゼロの数は 0xF、データ ビット長は 0 です。
MCU の最終的にデコードされた DCT データは次のとおりです。
DCT データに対して逆 DCT 変更を実行して、実際の YUV ピクセル データを取得します。
YUV データを RGB 形式に変換し、ビジュアル bmp 形式で保存します。
R = (u8_t)(Y+ 1.4075*(Cr - 128));
G = (u8_t)(Y-0.7169*(Cr - 128)-0.3455*(Cb - 128));
B = (u8_t)(Y+1.779*(Cb-128));