BMP 画像を JPEG に変換する C++ プログラムを作成しています。
私が従おうとしている基本的なアルゴリズムは次のとおりです。
- RGB カラー スペースを Y、Cb、Cr に変換します。
- Cb と Cr を 2 ずつダウンサンプリングします (つまり、2*2 の正方形ブロックごとに 4 つの異なる Y 値がありますが、1 つの Cb と 1 つの Cr 値があります)。
- 各 8*8 ピクセルのデータ単位に DCT を適用します...
- 次に、Cb と Cr の標準量子化テーブルを使用して、DCT 係数に量子化を適用します。
- ジグザグに並べます。
- ハフマン符号化を使用して DC 係数と AC 係数を別々に符号化します。
- 適切なヘッダーを書き込み、ハフマンでエンコードされた値をファイルに書き込みます...
上記を正しく実行していることを確認しましたが、まだ次の問題があります。
- 生成中の JPEG が正しく表示されません。
- 色の値 R=10 B=10 および G=100 で完全に満たされた小さな 8*8 24 ビット (色深度) の bmp ファイルを作成しました... 64 ピクセルすべてが同じ色です..
- 私がすべてのステップで取得しているデータは次のとおりです...
- BMP ヘッダー サイズ 40
- ヘッダーのサイズ 40
- 幅8
- 高さ8
- 飛行機の数 1
- ピクセルあたりのビット数 24
- 画像サイズ 194
- x 解像度 1 メートルあたりのピクセル数 2834
- 1 メートルあたりの y 解像度ピクセル 2834
- 色数 0
- インプ色の数 0
- (R,B,G)=(10,10,100) の Y Cb Cr 変換は (62,-29,-37) です。
では、まず Y 成分について考えてみましょう。
Y 成分の DCT 係数は次のとおりです。
495 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
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
量子化の後、私が取得している単一のデータ単位のジグザグ順序は、Y コンポーネントの場合です。
30 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 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
上記のジグザグ配列のハフマンコーディングは次のとおりです。
- Y DC コーディング: 00111110
- Y ac コーディング: 1010 (ac ハフマン テーブル (輝度 Y) EOB 値は 1010 の場合)
- 同様に、Cb および Cr コンポーネントのハフマン コーディングは次のとおりです。
- cb dc コーディング: 11000010
- cb ac コーディング: 01 (ac ハフマン テーブル (クロミナンス Cb,Cr) の場合、EOB 値は 01)
- CR DC コーディング: 110101110
- cr ac コーディング: 01
私が得る最終的なハフマンコードは次のとおりです。
001111101010110000100111010111001 長さ 33
そのため、8 で割り切れるように、1 のパディングが行われます。
0011111010101100001001110101110011111111 Length 40.
ここで、個々の 0 または 1 は、実際には JPEG ファイルにそのまま保存する必要があるビットですが、ビットごとにファイルに書き込むことができないため、合計 8 ビットが取得され、基数の整数値に変換されます。 10 となり、1 バイト文字に格納されます。
私が間違っている場所について誰か提案を提供できますか?