CJpegCoder - みる会図書館


検索対象: JPEG-概念からC++による実装まで
55件見つかりました。

1. JPEG-概念からC++による実装まで

Fig. 4.3 JPEGCoder ロ 金 , PPC DEBUG D00 PP リンク フプイ 3 CJpegCoder. cpp 驫再 pp 0 ti0 ファイル JPEGCoder 回日 レ ・ CJpegC0derApp. 叩 COutBitStream. cpp 物 CPictDocument. 叩 CPictView. cp MuPP. 』噌bリ9H鮎der3. pch + + . D00 power 円 ant. ppob . Doc PowerP1 ョ . r 0 . C010rA1er 00n ミ . rsrc . PP Action strings. rsrc . PP App1eEvents. r鰤0 . PP DebugA1erts. rsrc . PP Document A1er . r 0 は Action は再 p 1 ・ EY ・彙 5 は Fi1e & Stream Support U 彙れ i 彙 Link T 「・写 99 ファイル 15K 5552 221 6 2292 4148 1536 n/a n/a n/a n/a n/a n/a n/a n/a 20K 54K 29K 17K 13K 17K 152K 32K 54K 205K 0 6 ー 2K 4636 1655 643 1 750 1 075 n/a n た n/a n/a n/a n/a 55K 1 OK 66K 0 154K テキストの代わりに画像を扱う プロジェクトの種類は "DOC PowerpIant FAT" です。 ように変更します。また、印刷はサポートしません。 アプリケーションクラスは CJpegCoderApp です。 ドキュメントクラスは cp 土 c し D 。 cu Ⅲ en セで、これは LS 土 ng1eD 。 c からの派生クラスで す。符号化する PICT ファイルをオープンして表示し、 JPEG データの保存を行います。 PICT データの表示と、 JPEG 符号化を行うのが cp 土 c し v 土 ew で、これは LV 土 ew から派生 させています。 ウインドウは 1 種類で、名前は "Picture Window" 、リソース ID は 1000 です。このウイ ンドウには LActiveScr011er (CIass ID : 'ascr', pane ID : 1 ) と LView (Class ID : 'PICV', Pane ID : 2 ) が 1 っすつあります。 そのほかに、 CJpegCoder と cou し B 土し s し ream が含まれています。 ・ファイルの読み出し メニューから CFile] - COpen … ] を選ぶと、 CJpegCoderApp : : ChooseDocument ( ) が呼び出されます。こでは、対象となるファイルタイプを , p ェ CT , に指定しています。 4.1 上位クラス

2. JPEG-概念からC++による実装まで

3.1 ーコーディング規約 ソースプログラムのコーディング規約 ( 命名規則 ) について、簡単に説明しておきます。 本書で使用している規約は、簡単なものです。 Windows プログラミングで推奨されてい るような、変数や返値の型にとらわれた長い接頭辞などは使用していません ( ファイルの オープンや画面表示などの、プラットフォームに依存した部分はそれぞれの習慣に準拠し ています ) 。 3 ゴゴ シンボル名 シンポルは、基本的に英単語をつなげたものとします。このときスペースは削除します。 そして、各単語の先頭は大文字で、その他の文字は基本的に小文字を用います。たとえば、 JPEG 符号器は英語で "JPEG coder" ですが、これを "JpegCoder" としてシンポルの核に します。 このようなシンポル名の核に、接頭辞と接尾辞をつけてシンボル名とします。接頭辞は、 Table 3.1 の規則に従います。 TabIe 3.1 シンポルの接頭辞 接頭辞 型 使用例 CJpegCoder SJpegProperty mProperty kSqrt2 eMarker emSOF0 クラス 構造体 メンバ変数 定数 列挙型 列挙子 em 関数名やローカル変数名には、接頭辞をつけません。接尾辞は Tab1e3.2 のとおりです。 TabIe 3.2 シンポルの接尾辞 型 接尾辞 使用例 mRgbP aJpegDataH kYDcHuf fmanT ポインタ ノ、ンドル テープル 第 3 章仕様と論理設計

3. JPEG-概念からC++による実装まで

生 3 ー CJpegC0der クラス CJpegCoder は RGB データを JPEG 符号化するクラスです。 ー 4.3 ゴ : ヘッダファイル CJpegCoder. cpp でインクルードするヘッダファイルは次のとおりです。 #include #include #include #include #include #include #include く stdlib . h> <string . h> <math . h> " JPEG . h " "COutBitStream . h" ” CJpegCoder . h" "CoderTab1es . h" abs ( ) , strlen(), cos() を使用するので、それぞれ stdlib. h, string. h, math. h をイ ンクルードしています。 CoderTables. h は符号化用の各種テープルを定義しているヘッダファイルです。 インタフェース コンストラクタでは、メンバ変数の初期化を行います。 11 ・コンストラクタ CJpegCoder : : CJpegCoder ( const u char* redp, const u_. Char* const u_char* b1ueP ) / / 元画像赤成分へのポインタ / / 元画像緑成分へのポインタ / / 元画像青成分へのポインタ / / 元画像データへのポインタ mRgbP [ 0 ] (u—char* ) redP; mRgbP [ 1 ] (u—char* ) greenp; mRgbP [ 2 ] (u—char* ) bluep; / / 変数の初期化 mPreDC [ 0 ] = mPreDC [ 1 ] mOBSP = n 土 1 ー / / c 。 s テープル作成 mPreDC [ 2 ] 116 for( 土 n し n=O; n<8; n + + ) for( 土 n しⅢ = 0 ー m く 8 : m + + ) 第 4 章実装

4. JPEG-概念からC++による実装まで

5.1.4 ー = 。 ツール テストを行うには次のソフトが必要です。 ・テ / ヾッガ ・ JPEG データの表示ができるソフト ( ネットスケーブナビゲータなど ) また、次のようなソフトや道具があるとより便利です。 ・ファイルのバイナリーダンプができるソフト ・ 2 つのファイルをバイナリーで比較できるソフト ・関数電卓 ・縦罫線のあるメモ用紙 ・画面の拡大表示ができるツール ・ JPEG データと BMP, P ℃ T データが作成できるソフト マットでの作成はもちろん、 JPEG データも作れるソフトがあれば、より便利です。 認が容易なテストデータが作れると便利です。 BMP や PICT などの OS で使用するフォー テストデータは付録 CD - ROM に用意しましたが、発生している不具合に合わせて、確 です。また、バイナリーで編集ができると動作の確認のための実験を行いやすくなります。 バイナリーのダンプはデバッガなどでもできますが、専用ツールがあるとたいへん便利 [C-JPEG] (CJpegCoder での符号化例 JPEG ファイル ) CBMP] (CJpegCoder 用 BMP ファイル ) [TestData] は、以下のように配置しています。 付録 CD-ROM の CTestData] フォルダにテストデータを用意しました。 Windows 用で 5.2 ーテストデータについて 186 第 5 章テスト で符号化したものです。 CJpegCoder の符号化テストの際に利用してください。 CC-JPEG] フォルダのデータは、 CBMP], CPICT] フォルダのデータを c こ pegc 。 der [D-JPEG] ( 市販グラフィックソフトでの符号化例 JPEG ファイル ) [C-JPEG] (CJpegCoder での符号化例 JPEG ファイル ) (CJpegCoder 用 P ℃ T ファイル ) CP ℃ T] [TestData] Macintosh 用では、以下のようになっています。 [D-JPEG] ( 市販グラフィックソフトでの符号化例 JPEG ファイル )

5. JPEG-概念からC++による実装まで

まず、引数で渡された R , G, B 画像データへのポインタをⅢ RgbP [ ] に格納します。 ( 2 ☆Ⅲ + mCosT[n] [m] 8 ー COS( n ☆ kPaiDiv16 ) : 1 ) ☆ 次に、 Y, Cb, cr 各成分の直前のプロックの DC 成分の値を 0 にします。 ビットストリーム☆ m 〇 BSP は、画像のサイズがわからないと生成できません。廃棄はデ ストラクタで行いますが、生成されていないものを廃棄するとエラーが発生するので、判 別のため mOBSP に n 土 1 (NULL) を代入しておきます。 最後に、 DCT 変換で使用する cos テープルを作成します。 0 」 2 ・デストラクタ デストラクタでは、 *mOBSP を廃棄します。 ¯CJpegCoder ( VOid ) CJpegCoder : / / ビットストリームの廃棄 土 f ( mOBSP ! = ni 1 ) delete mOBSP; 動的に確保したオプジェクトは☆ m0BSP だけです。 上位クラスから RGB データを渡されてから *m0BS p を生成します。それ以前にエラー などによってデストラクタが呼び出されたときに、まだ生成されていないビットストリー ムを廃棄しないように、オプジェクトのアドレスを調べます。 ロ】 3 ・画像属性の設定 SetJpegProperty() は符号化作業と JPEG データに添付する必要のある画像属性を設 定します。 void CJpegCoder : : SetJpegProperty ( const SJpegProperty& aPropertY ) . VThumbnai 1 HThumbn a 土 1 . MinorReviSIons IIIPrOPertY . Maj orReviSions mproperty . Samp1ePrecision aProperty; mProperty mProperty . mProperty mProperty . Format / / 制限 mProperty / / 成分数 / / 8 ビット固定 ( 念のため ) フォーマット種別 1 : JF 工 F / / バージョン小数点上位 / / バージョン小数点下位 / / サムネイル横画素数 / / サムネイル縦画素数 / / 画像の属性 画像の属性は、引数で与えられた SJpegPr 。 per む y 構造体で行います。 SetJpeg property( ) は、 aproperty の値をそのまま mproperty に格納します。 4.3 しかし、 CJpegC 。 der にはいくつかの制限を与えているので、指定された値をそのまま CJpegCoder クラス 117

6. JPEG-概念からC++による実装まで

■」 4 ・メンバ変数 u_char* mBuf : u char* mEndOfBuf : 土 n し 土 n し 土 n に mBitPos; mNextF1ag; mReadF1ag; / / 読み出しアドレス バッフアの終了アドレス / / 読み出しビット位置 / / ( 上位ビットが 7 、下位ビットが o ) / / 次のバイトを読んでいいかどうか / / 1 : 読み出し可 , 0 : 読み出し不可 このクラスが終始保持しなければならない値は、バッフアの終了アドレスです。また、 読み出し作業で参照・更新する値は、読み出しアドレスと読み出しビット位置です。読み 出しビット位置 mBitPos は、 COutBitStream の mBitPos と同じ動作をします。 メモリアクセスエラーをふせぐため、 mReadF1ag をアクセスの許可 / 不許可を示すフ ラグに使います。 工ントロピー符号化セグメント中では、マーカではない oxFF の次に oxoo が記述され ています。このため、 oxFF に続く oxoo を読み飛ばさなければなりません。この動作を 行うため、判定用変数心 ex し F1ag を用意してあります。 ■ 15 ・非公開メソッド ・読み出しアドレスのインクリメントとアクセス違反のチェック void 工 ncBuf ( void ) : c 工 nB 土セ s む rea Ⅲの内部メソッドは工 ncBuf ( ) だけです。 ドレスの更新とアクセス違反のチェックを行います。 このメソッドは、読み出しア ■】 1 ・概要 3.5.3 CJpegC0der クラス JPEG 符号器を 1 つのクラスとして実現すると、符号化処理とそれに関わるデータをカ プセル化することができるので、たいへん好都合です。本書では、 CJpegCoder という名 前で符号器クラスを作成しました。 CJpegCoder は RGB 表色系の画像データを受け取り、 JPEG データを作成します。そし て、作成したデータのアドレスと、そのサイズを呼び出し元に返します。 また、 cJpegCoder には 3.3.2 節 ( p. 54 ) で決めた制限を設けます。 第】 2 ・機能 CJpegCoder に必要な機能は次のとおりです。 第 3 章仕様と論理設計 ・ JPEG データのアドレスとサイズを渡す ・符号化を実行する ・画像属性を受け取る ・ RGB データを受け取る

7. JPEG-概念からC++による実装まで

ただちに結果がわかります。実は、ファイルの比較をするのであれば、ヘッダ部分もエン トロピー符号化セグメント部分も同時にテストできるのですが、問題をきり分けやすくす るために、 こでは 2 つに分けて考えることにします。 0 」 1 ・ヘッダ書き込み c こ pegc 〇 der ではテープルを固定しています。ヘッダの書き込み内容のテストは 1 度行 えばよいでしよう。 ファイルコンペアで相違が見つかった場合は、 CJpegDecoder を利用して前処理のテ ストをしてください ( 5.3.2 節 , p. 19D 。メンバ変数の値に異常が見つかったら、 CJpegCoder: :writeHeader( ) の該当部分をデバッガでステップ実行して動作を確認し てください。 ロ 12 ・符号化 ます、入力データファイルを選んでオープンします。そして、符号化を行い、ファイル を保存します。その結果を℃ - JPEG] フォルダの同名ファイルと比較します。比較には ファイルコンペアソフトを使うか、または JPEG データを表示できるソフトを使って目で 確認してください。目で確認するときは画面の拡大表示ができるツールがあれば、特に色 の変化の激しい部分を拡大して確認してください。 2 つのデータの表示結果が異なる場合は、 5.4.4 節 ( p. 206 ) を参考にして、原因となりそ うな部分に見当をつけ、プレークポイントを設定して実行します。プログラムが一時停止 したらメモリ領域や変数の内容を確認します。 また、 c ユ pegDec 。 der のテストが終わっていれば、エントロピー符号化セグメントの 一部が異なるときには、次のようにして場所を調べられます。 CJpegDecoder で復号処理を行い、データに異常がある場所を見つけます。そのとき のユニット位置、プロック位置、成分番号、 DCT 係数番号などをメモします。 c こ pegc 。 der で、元画像に対して同じ位置を符号化する直前で停止するようにデバッガでプレークポイ ントを設定します。プログラムが停止したらステップ実行して動作を確認してください。 542 ヘッダ書き込みのテスト 前処理での異常は c ユ pegDecoder のバグではなく、入力データ (CJpegCoder で符号化 で符号化したファイルを検証してください。 CJpegDecoder のテストが終わっていれば、 き ) は 5.3.2 節 ( p. 19D の CJpegDecoder の前処理のテストを参考にして、 CJpegCoder ファイルコンペアで相違が見つかったとき ( または、ファイルコンペアツールがないと してください。 当な名前をつけて保存してください。そして、 HEADER. JPG とファイルコンペアで比較 ヘッダの内容を確認するために、 HEADER. * を入力データとします。符号化結果に適 5.4 CJpegCoder のテスト したデータ ) の異常が原因と考えてよいでしよう。

8. JPEG-概念からC++による実装まで

ー ] 5 ・量子化 量子化を行うメソッドが Quan 巨 za 。 n ( ) です。 for( 土 n し土 = 0 ー土く 64 ー土 + + ) { ( 土 n に☆ ) ()s ? kCQuantumT 土 n し☆ qt int cs ) / / 成分番号 CJpegCoder : : Quantization ( VOid mDCTDataP[i] / = qt [i]; kYQuantumT ) ー 量子化テープルは成分によって切り替える必要があるので、 Quantization() は成分 量子化は、 mDCTDataP [ ] を量子化テープルで割ることによって行います。結果も 番号を引数に取ります。 ハフマン符号化を行うメソッドが CodeHuffman() です。 CJpegCoder で最も複雑なメ 16 ・エントロピー符号化 mDCTDataP[] に格納するので、 / = 演算子を使用しています。 CJpegCoder : : CodeHuffman ( void ソッドです。 / / 成分番号 int CS ) / / DC 成分用ハフマンテープル cons し SHuf fmanCodeTab1e& dcT = cs ? kCDcHuffmanT / / AC 成分用ハフマンテープル const SHuffmanCodeTab1e& cs ? kCAcHuf fmanT kYDcHuf fmanT : kYAcHuffmanT : acT / / EOB のインデックス const / / ZRL のインデックス const / / DC 成分 int diff mDCTDataP[0] z r 1 工 dx = c s ? eob 工 dx = cs ? kCEOBidx kCZRLidx kYEOBidx : kYZRLidx; mPreDC [cs] ー mPreDC [cs] = mDCTDataP [ 0 ] : / / DC 成分差分値 / / 更新 土 n し absDiff 土 n し dldx = 0 : : / / 差分値の絶対値 / / 差分値のビット数 ( 符号語表インデックス ) abs ( di f f ) / / カテゴリ ( 差分値のビット数 ) を求める while( absDiff > O ) { absDiff > > = 1 : d 工 dx + + ー / / 絶対値が 0 になるまで / / 右シフト / / シフト回数 = 差分値ビット数 128 / / ハフマンテープルの要素数より大きいとき 第 4 章実装

9. JPEG-概念からC++による実装まで

そこで、 RGB データの受け渡しを行うときには、必ず画像属性データの受け渡しも行 うことにします。画像属性データとは、画像の縦横の大きさや、解像度など、 JPEG/JFIF = = = = 3.3.2 、符号化処理の機能範囲 で記録される属性をまとめたものとします。 欠点がありますが、 JPEG データのサイズはさほど大きくなりません。 とにします。この制約は、 RGB 表色系との変換に必要な計算時間が節約できないという レー画像の圧縮時にも Cb , Cr 成分を添付します。つまり、グレー画像も 3 成分で表すこ 分岐は、 JPEG アルゴリズムの理解の妨げになる可能性があるので、 CJpegCoder ではグ ところで、 JFIF ではグレー画像を Y 成分だけで表します。成分数の違いによる処理の 分 4 プロックを符号化したあと、 Cb, Cr 成分を 1 プロックすっ符号化します。 成分が複数ある場合はインタリープを行わなければなりません。 CJpegCoder では Y 成 このサンプリング比は、面積比で 4 : 1 : 1 の間引きということもあります。 とします。つまり、縦横とも 1 ドットおきに画素を抽出して使用します ( Fig. 2.14 , p. 28 ) 。 間引きを行うことで、 JPEG データの量を削減します。サンプリング比は縦、横とも 2 : 1 ほど広くなく、画質に与える影響も Y 成分ほど大きくありません。そこで、色差データの な影響を与えるので間引きを行いません。一方、 Cb, cr ( 色差 ) 成分は変化の範囲がさ JFIF では、 YCbCr 表色系を利用します。自然画像では、 Y ( 輝度 ) 成分は画質に大き JFIF に固定して使用します。 フォーマットを用います。 CJpegCoder では、本書執筆時の最新バージョンである 1.02 の 定していません。そこで、アプリケーション間での交換を目的としている場合は、 JFIF JPEG では、画像を成分ごとに符号化しますが、どの表色系を利用するかについては規 ■ 11 ・ J 日 F と間引き それを参考にして実用的なプログラムを開発してください。 ではふれません。量子化テープルの変更方法については 6.3 節 ( p. 216 ) で説明しますので、 しかし、量子化テープルの作成についての解説は、たいへん複雑になりますので、本書 ーザが調整できる」という特徴までも制限してしまうからです。 まり現実的とはいえません。それは、 JPEG の特徴の 1 つ、「復号画像の品質と圧縮率をユ ハフマン符号の固定は、たいへん現実的な制限です。一方、量子化テープルの固定はあ の実装例の CJpegCoder では、固定したハフマン符号と量子化テープルを使用します。 テープルの作成が必要です。しかし、その手間は無視できないほど大きなものです。本書 圧縮効率や画像品質を高めるためには、ハフマン符号の工夫や、実験を元にした量子化 手数がさほど多くない範囲に機能を限定します。 を満たす必要はありません。そこで、それなりの圧縮効率と画像品質を保ち、かっ、実装 をカバーする必要がありますが、符号器は規定の一部に適合していればよく、規定すべて 第 2 章で説明したとおり、 JPEG には幅広い規定があります。復号器は、規定のすべて 第 3 章仕様と論理設計

10. JPEG-概念からC++による実装まで

■」 3 ・インタフェース ・コンストラクタ ( RGB データを受け取る ) CJpegCoder ( const u char* redP, const u Char* greenP, const u char* b1ueP ) : / / 元画像赤成分へのポインタ / / 元画像緑成分へのポインタ / / 元画像青成分へのポインタ アプリケーションは CJpegCoder のインスタンスを生成する際に、 R, G, B の 3 成分に 分解した画像データへのアドレスを渡します。コンストラクタは、この値をメンバ変数に 格納します。そして、メンバ変数の初期化と DCT で使用する cos テープルを作成します。 cos テープルはあらかじめ作成しておいて定数としてもたせたほうが初期化をすばやく 行えますが、要素数が 64 と少ないのでコンストラクタで計算させることにしました。 ・デストラクタ ¯CJpegCoder ( VOid ) ー デストラクタでは coutBitStream のインスタンス☆Ⅲ OBSP の廃棄を行います。 ・画像属性の設定 ・ / / 画像の属性 VOid SetJpegProperty( const SJpegProperty& aProperty ) ー 符号化する画像の属性を設定します。この値はメンバ変数Ⅲ pr 。 per し y に格納します。 ・符号化を実行する int DoCoding( void ) : / / 返値 : 処理結果 符号化処理を実行します。メモリアクセスなどのエラーがあると emRun meErr 。 r ( ー 1 ) を返します。 ・ J PEG データのアドレスとサイズを渡す void GetJpegData ( char* ☆ aJpegDataP, 土 n し & S 土 Z e ) ー / / JPEG データ / / JPEG データのサイズ アプリケーションが JPEG データを取り出すために必要な JPEG データへのポインタと サイズを返します。返されたデータの領域は呼び出し側で廃棄する必要があります。符号 化処理中にエラーが発生した場合は、 ■ 4 ・メンバ変数 / / 入力 , 中間データ u—char* mRgbP [ 3 ]; 土 n に 土 n し 土 n し mYB10ckP[4] [ 64 mCbB10ckP[64] ー mCrB10ckP[64] 冫 このメソッドを呼び出してはいけません。 3.5 クラスの設計 / / 色差プロックデータ / / 色差プロックデータ / / 輝度プロックデータ / / 元画像へのポインタ