ビットマップ データを JPEG 形式で圧縮し、通常の画像ビューアーで開くことができる .jpg ファイルを出力として書き込む必要がある C++ プロジェクトを開発しています。どの種類のライブラリも使用できません。
すべての JPEG 圧縮が完了しました。私が見逃しているのは、ファイルに正しく書き込む方法だけです。
私はすでにJFIF形式のファイル仕様を調べて、たくさんグーグルで検索しましたが、それを行う方法がわかりません。
より詳細には、すべてのヘッダーをファイルに正しく配置する必要があります。3 つのカラー コンポーネントを書き込む準備ができた後、どうすればそれを行うことができますか? (コンポーネントを記述する順序、サブサンプリングされたコンポーネントの処理方法 (他のものはありますか?))
編集:
サンプル出力画像へのリンク (ランダムに生成された 8x8 RGB ビットマップから開始)。
https://dl.dropbox.com/u/46024798/out.jpg
画像のヘッダーは、これが 3 つの色成分を持つ JPEG 8x8px であり、サブサンプリングが 4:4:4 であることを指定する必要があります。
より詳細には、私がしたことは次のとおりです。
- [0..255] の範囲の値を持つ 3 つのランダムな 8x8 ブロックを生成します。
- すべての要素から 128 を引きます (現在は [-128..127] の範囲内)
- 3 つのブロックに離散余弦変換を適用する
- 結果をクオンタイズする
- 量子化の結果をジグザグに並べる
- ファイルに書き込む値をハフマン テーブルで検索します (End Of Block マーカーなどを使用)。
JPEG 圧縮の場合は、これで問題ありません。
次に、ファイルを書き込みます。
- まず、SOI ヘッダー、APP0 マーカー、「魔法の文字列」JFIF、バージョン、単位、密度、およびサムネイル情報を書き込みます。
- 次に、量子化テーブル
- 次に、画像の精度、寸法、コンポーネント数、サブサンプリング情報、DC ハフマン テーブル、AC ハフマン テーブルを含むフレーム開始マーカー
- 次に、Start Of Scan ヘッダー (おそらく私が失敗した場所) で、各コンポーネントに使用するハフマン テーブルの ID と、正確には意味がわからないその他のもの (スペクトル選択??、逐次近似) を指定します。 ??)
- 最後に、ハフマン エンコードされた値を次の順序で記述します。
- Yブロック全部
- すべての Cb ブロック
- すべての Cr ブロック
- そして画像の終わり