CJpegDecoder - みる会図書館


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

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

・ファイルの読み出し メニューから CFiIe] ー COpen. 」を選ぶと、 CJpegDecoderApp : : ChooseDocument ( ) が呼び出されます。こで、ファイルタイプを , JPEG , と指定しています。 / / Browse for a document . UDesktop: :Deactivate( ) : / / Deactivate the desktop . CJpegDecoderApp : : ChooseDocument ( ) VOid SFTypeList PPC DEBUG D00 PP \ ファイル リンク Fig. 4.4 JPEGDecoder StandardFi 1eRep1y App 石 0 ・ 0 龜 ファイル theTypeList theReply; JPEGDecoder ま : ファイルタイプの指定 ClnBitStream. cpp 陽 CJpegDecoder. cpp CJpegDecoder App. 叩 置 CJpegDocument. 叩 CJpegView. cp 陽 MuPP—DebugHeaders. pch + + . JpegDecoder. ppob . JpegDecoder. r 0 . C010rA1 rt に 0n5. rsrc . PP Action strings. rsrc . PP App1eEvents. rsrc . PP Deb リ 9A1 . rc . PP Doc リ n A1曾r愑 . rsrc App1e Events Commanders は F れ & Stream Support Uti1ities を Link T ・「・彙 5 99 ファイル ー 8K 1 624 10444 2 1 24 引 00 1340 n/a n/a n/a n/a n/a n/a n/a n/a 20K 54K 29K 17K 13K 17K 152K 52K 54K 205K 0 615K 537 1780 1 61 9 1626 1055 n/a n/a n/a n/a n/a n/a n/a n/a 6 55K 1 OK 66K 0 1 51 K 4.1 曰△ 上位クラス 105

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

Fig. 4.2 JpegDecodeWin. dsw ワーりスへス ワクスへ。ース・ JpegDecodeWin ・ : 1 フ。ロデェ外 ー曰・ Jp ・ gDecodeWin ファイル ヨ fX ド日 5 了 C 国 afxprint.rc 由ヨ外部依存関係 ReadMe. ⅸ弋 曰 Jpeg DecodeWin. reg 圄 T00 旧 . bmp 国 JpegDecodeWinDoc.ico 国 JpegDecodeWin.rc2 曰 JpegDecodeWin. ico 曰・」 Resource Files StdAfx. h Resource. h MainFrm. h 国 JpegDec0deWinVie•,cv. h 国 JpegDecodeWinDoc. h JpegDecodeWin. h JPEG. H 圄 Dibh OJpegDecoder. h 0 旧日 it 駅ョ m.h 国 ChiIdFrm.h 白・・ , 日 Header F 三 凹 StdAfx. cpp 凹 MainFrm.cpp 凹 JpegDecodeWinVievv. cpp 凹 JpegDecodeWinDoc. cpp 凹 Jpeg DecodeWin. rc 凹 Jpeg DecodeWin. cpp 凹 D 旧 . cpp 凹 CJpegDecoder. cpp 凹 ClnBitStream.cpp BOOL CJpegDecodeWinDoc : : LoadJpegFi1e (LPCTSTR pszFName) ・ ClassVie',"' ー田一。。 eVievv 朝 FileView ? 扁。 v 滬。 第 4 章実装 / / ファイルサイズの取得 return FALSE : AfxMessageBox ( strMessage ) : pszFName, " ファイル読み込み工ラー " 房 strMessage . Format ( "%s\n%s" CString strMessage; if ( !JpegFi1e . Open(pszFName, CFi1e: :modeReadlCFi1e: :typeBinary) ) { CStdioFi1e JpegFi1e; / / JPEG ファイル

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

こで、ファイルタイプを , JPEG , に指定しています。多くのグラフィックスソフトで 哉別できるでしよう。 次に、 cpictDocument: : D 。 save ( ) が呼び出されます。で、 cpictView からデ ータを取得しています。 DoAESave ( ) も DoSave ( ) もほとんどデフォルトのままですから、すぐ理解できるでし よっ。 三一卩 VOid CPictDocument: :DoSave ( ) / / Open the data fork . mFi1e—>OpenDataFork( fsRdWrPerm ) : / / Get the text from the text view . HandIe theDataH = mPicture—>GetDataHand1e ( ) : / / Lock the text handle . StHand1eLocker theLock( theDataH ) : / / Write the text し 0 the f 土 le . mFi1e—>WriteDataFork( *theDataH, / / C10se the data fork . mFi1e—>C10seDataFork() : / / Saving makes doc un—dirty . mPicture—>SetDirty( false ) ー :GetHand1eSize ( theDataH ) ■コ 2 ・ JPEG 復号アプリケーション ・プロジェクトの構成 JPEG 復号アプリケーションプロジェクトは、 'JPEGDecoder" という名称にします。プ ロジェクトウインドウを Fig. 4.4 に示します。 プロジェクトの種類は " DOC Powerplant FAT" です。テキストの代わりに画像を扱うよ うに変更します。また、印刷や保存などはサポートしません。 アプリケーションクラスは CJpegDecoderApp です。 ドキュメントクラスは CJpegDocument で、これは LSing1eD 。 c からの派生クラスで す。復号する JPEG ファイルをオープンして表示します。 JPEG データの復号と表示を行うのが CJpegView です。これは LV 土 ew から派生させて います。 ウインドウは 1 種類で、名前は "JPEGWindow" 、リソース ID は 1000 です。このウイン ドウには LActiveScr011er (Class ID : 'ascr', pane ID : 1 ) と LView (Class ID : 'PICV', Pane ID : 2 ) が 1 っすつあります。 そのほかに CJpegDecoder と c 工 nB 土し s し rea 爪が含まれています。 102 第 4 章実装

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

でも宣言するテープルは 4 つあるかもしれませんから、土 n い 4 ] [ 64 ] の 2 次元配列とします。 結局、復号器の量子化テープルは、℃ JpegDecoder. h" のなかで次のように定義しました。 土 n に mQT [ 4 ] [ 6 4 ]; / / 量子化テープル要素 x 4 成分 、マーカ マーカは符号時の書き込み処理や、復号時のファイル解析で頻繁に用いるデータです。 数値で直接表記するよりも、意味が明確なシンボルで表記したほうがソースの可読性が上 ーこにその一部を掲載します。 がります。そこで、 "JPEG. h" で enum 宣言を行います。 / / マーカコード enum eMarker { / / フレーム開始 / / 非差分ハフマン符号 34.4 emSOF0 ( 中略 ) / / ノ、フマンテ emDHT ( 中略 ) / / その他 emSO 工 emE O 工 0xc0 ′ / / 基本 DCT 方式 ープル指定 0xc4, 0xd8 ′ 0xd9 ′ / / ハフマンテ / / 画像開始 / / 画像終了 ープル定義 ( 以下略 ) RGB データ 3.4.5 ・画像データは 1 画素 1 バイトに対応し、画像の左から右に、ついで上から下へ連続 ・画像データは R, G, B の 3 成分を、成分ごとに連続したアドレスに格納する ・画像は長方形とする ・ RGB 各色は 0 ( 最弱 ) から 255 ( 最強 ) までの値をとる ・ 1 画素につき赤 ( R ) 、緑 ( G ) 、青 ( B ) の 3 色の強さ ( レベル ) で表示する す。このデータの形式を以下のとおりに決めます。 RGB 表色系のデータは CJpegCoder の入力と、 CJpegDecoder の出力として利用しま したアドレスに格納する 3.4 丁ータの設計 61

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

現在の読み出しピット位置がバイトの先頭ならば、現在の読み出しアドレスを返します。 現在の読み出しビット位置がバイトの先頭でないときは、現在の読み出しアドレスの次の アドレスを返します。 4.4.3 非公開メソッド ■ 11 ・読み出しアドレスのインクリメントとアクセス違反のチェック 工 ncBuf ( ) は読み出しアドレスをインクリメントして、バッフアの終了アドレスと比較 します。そして、終了アドレスならばⅢ ReadF1ag を 0 にして読み出しを禁止します。 VOid C 工 nBitStream: : 工 ncBuf( void ) if( + + mBuf > = mEndOfBuf ) mReadFIag / / 次のアクセスでエラー 読み出しアドレスをインクリメントしただけでは、エラーにはなりません。バッフア外 のアドレスを読み出そうとしたときにエラーになります。ですから、次に読もうとしたと CJpegDecoder. cpp で使用するヘッダファイルは以下のとおりです。 ヘッダファイル 4.5 ゴー スです。 CJpegDecoder は、メモリ上の JPEG データを復号して、 RGB データを作成するクラ 生 5 ー CJpegDecoder クラス きに、 mReadF1ag でアクセスが可能かどうかをチェックするのです。 #include #include #include #include #include <math . h> <string . h> " JPEG . h " "C 工 nBitStream . h" "CJpegDecoder . h" cos() を使用するので math. h をインクルードしています。 JPEG. h は CJpegCoder. cpp が使用したものと同じものです。定数や SJpegPr 。 per し y 構造体の定義などを行っていま す。 4.5 CJpegDecoder クラス 159

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

実際に表示を行うには、 Windows の場合と同様に、表示用画像データをあらかじめ背 景色などに設定しておき、復号画像で上書きしていくとよいでしよう。そして、適当なタ イミングで表示画像の再描画ができるようにします。それには、 DoDecode() の返値で更 新すべきかどうかがわかるようにするとよいでしよう。 JPEG データを通信などの低速な手段で読み込む場合は、 JPEG データ格納領域を読み出 しルーチンと CJpegDecoder で共有しなければなりません。そして、 CJpégDecoder で は読み込みが完了していない部分にアクセスできないようにする必要があります。これは、 DoDecode ( ) の引数でなえるようにするとよいでしよう。 その場合、 c ユ pegDec 〇 der はハフマン符号の復号進行状況も保持しなければなりませ ん。もし、 1 つのハフマン符号語を復号する途中で JPEG データがまだ読み込まれていな いと、中途半端な位置で処理が中断してしまいます。すると、呼び出し元に制御を返すこ とができなくなってデッドロックしてしまいます。しかも、 DoDecode ( ) が呼び出された 時点では、そのとき必要な JPEG データの長さがわかりません。ハフマン符号を復号して みなければわからないのです。 ですから、 DoDecode() はインタバルなどの適当な単位での処理だけでなく、ハフマン 符号の復号の段階でも処理を中断して制御をアプリケーションに返すようにしなければな りません。 67 ープログレッシブ オンラインなどの低速の入力を用いて、 JPEG 画像のリアルタイム表示を行うのに便利 な機能がプログレッシブ表示機能です。これは、はじめにばやけた画像を表示し、徐々に 細部まで表示していく方式です。このような伝送・表示方法を採用すると、通信の途中で 画像の概要がわかりますから、もし不要な画像ならば、通信をキャンセルすることもでき ます。 プログレッシプはとても複雑な方式ですから、本書の限られたページ数ではすべてを解 説できません。この節の解説を元に、実際にプログレッシプ形式のデータを解析してみて ください。本格的なプログラミングにあたっては、 JPEG 勧告書を通読することをお勧め 6.7.1 仕組み します。 222 第 6 章発展 おして再表示します。これを数回繰り返すと、ばやけた画像が徐々にハッキリと表示され 波成分が送られてきたら、 DCT 係数データを更新して再度逆 DCT 変換し、画像を作りな 器は、高周波成分を 0 として逆 DCT 変換して画像を作り、一旦これを表示します。高周 周波成分を、画像全体について先に送り、次第に高周波成分を送るというものです。復号 プログレッシプの仕組みは、 DCT 係数データを送信するときに、画像の概要を示す低

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

リスタートインタバルは、有効のときだけ JPEG データ内で指定があります。ですから、 mRestart ェ nterval を 0 ( 無効 ) に初期化しておかなければなりません。 ビットストリームは SetJpegData ( ) で生成し、デストラクタで廃棄します。もし、 CJpegDecoder のインスタンスを作っておきながら、 SetJpegData( ) が呼ばれすに廃棄 土 f ( mHT は ] [ j ] . C0deTP 土 f ( mHT [ 土 ] [ j ] . Si zeTP CJpegDecoder : ¯CJpegDecoder ( void ) デストラクタは、動的に確保したメンバの廃棄を行います。 012 ・デストラクタ 最後に cos テープルを作成します。 ます。 された場合、☆Ⅲ工 BSP のデストラクタが呼び出されないように、初期値を n 土 1 にしておき / / テープル廃棄 for( 土 n し i=O; 土く 2 ー土 + + ) for ( 土 n にゴ =O : ゴく 4 ー j + + ) / / 0 : DC 成分 , / / 4 成分 ! = nil ) ! = n 土 1 ) . SizeTP; 1 : AC 成分 de 1 e し e delete de 1 e し e / / コメント領域廃棄 mHT[i] [j ] . CodeTP; mHT [ 土 ] [ j ] 土 f ( mHT は ] [ j ] . Va1ueTP ! = ni 1 ) mHT[i] [j] . Va1ueTP; delete m 工 BSP; 土 f ( ml BS p ! = ni 1 ) / / ビットストリームの廃棄 delete mProperty . Comment; if ( mproperty . Comment ! = n 土 1 ) 同様に、コメント領域とビットストリームオプジェクトも確認しながら廃棄します。 演算子で廃棄しています。 ります。そこで、テープルへのポインタをすべて調べて、 n 土 1 でないもののみを dele に e 処理などで、すべてのテープルが作成されずに、デストラクタが呼び出される可能性もあ ハフマンテープルは、 JPEG データによって確保された数が異なります。また、エラー SetJpegData() は、メモリ上にすでに読み込まれている JPEG データのアドレスとサ 0 」 3 ・ JPEG データを設定する イズを受け取り、ビットストリームオプジェクトを生成します。 / / JPEG データ char* aJpegDataP ′ CJpegDecoder : : SetJpegData ( 土 n し 4.5 CJpegDecoder クラス

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

JPEG データの最後には必す EOI マーカを書き出さなければなりません。すべての処理 を行った後、このメソッドでその書き込みを行います。 。。 , 354 ーコ 1 ・概要 CJpegDecoder クラス 符号化処理では実装を容易にするために、いくつかの制限を加えることができましたが、 復号処理ではあまり多くの制限を加えるわけにはいきません。実用性がなくなってしまう からです。それどころか、復号器に対する要求は、マルチタスキング ( スレッド ) 対応や リアルタイム表示など数多くあります。 それらの要求のすべてに対応することは難しいですが、本書では最も基本的な復号器と CJpegDec 。 der が実現しなければならない機能は次のとおりです。 ■】 2 ・機能 JPEG データで、出力は RGB 表色系のデータとその画像の属性です。 CJpegDecoder は JPEG データを復号して RGB 表色系のデータを作成します。入力は して CJpegDecoder を実現しました。 また、 JPEG データには、テープルだけのデータ、スキャンだけのデータ、テープルと ・スキャンデータを復号する ・復号用テーブルを作成する ・画像属性を取り出す かります。 復号処理の部分をもう少し詳しく検討すると、次の 3 つの処理からなっていることがわ ・画像属性を渡す ・復号後の画像データへのアドレスを渡す ・ JPEG データを復号する ・ JPEG データを受け取る スキャンの両方があるデータの 3 種類があります。この 3 種類のデータをそれぞれ適切に 第 3 章仕様と論理設計 す。また、テープルの初期化も行います。 コンストラクタは定数の初期化と逆 DCT 変換の計算で用いる cos テープルを作成しま CJpegDecoder ( void ) : ・コンストラクタ ロ」 3 ・インタフェース 解釈して、テープルの作成と復号処理を行わなければなりません。

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

Fig. 6.4 リアルタイム表示のための構成 JPEG データ読み込み部 更新 書き込み 更新通知 更新通知 アクセス制限アドレス 確認 書き込み済み 読み出し JPEG データ JPEG 復号器 画面表示部 読み出し 復号された 画像の一部 復号画像データ 背景パターン 書き込み Windows の場合 CJpegDecoder を独立したスレッド上で動作させます。 JPEG データを通信回線などか らメモリにロードするスレッドと、復号された画像を画面表示するスレッドを作成します。 次に、 JPEG データを格納する領域を共有メモリとして作成します。メモリロードスレ ッドが、通信回線などからデータを読み出し、このメモリに書き込みます。適当な量を書 き込むたびに、 CJpegDecoder が読み出してもよい JPEG データのアドレスをセマフォな どで通知するようにします。 CJpegDecoder は、許可されたアドレスを越えないように注意しながら復号を行いま す。もし、許可された領域を復号し終えたら、アドレスが更新されるまで待ちます。この 機能は c ェ nB 土し s し ream を改造して実現します。 復号画像領域も共有メモリなどで作成します。あらかじめ白や黒などの背景色にしてお き、復号しながらその領域を上書きしていくようにします。 CJpegDecoder は、適当な 処理単位で画面表示スレッドに描画の更新メッセージを送るようにし、画面表示スレッド 鸞 6.6. ー 6.6 リアルタイム表示 6.62 で、復号が終わったところまで表示が可能になります。 ます、前節のプリエンプテイプなマルチタスキングに対応させる改造を行います。これ Macintosh の場合 はそれに応じて画面を更新します。更新のタイミングは MCU 横 1 列分が適当でしよう。

10. 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 のテスト したデータ ) の異常が原因と考えてよいでしよう。