あ今回は、もう少し詳しく画像データフォーマットに関連した例題を調べてみます。また、DICOM画像など、内部の数値フォーマットがエンディアンに依存しているファイルについても解説します。
前回の復習となりますがが、1ピクセルがunsigned longにマッピングされたMacintosh用画像フォーマットの色成分の並びはαRGB(αは透明度)であり、OpenGL用テクスチャ画像フォーマットの方はRGBαです。よって、両者の変換を行うには(α値は0xff固定とする)、オリジナルデータを8bit左へシフトさせ、透明度として0xffを追加します。実際の変換ソースコードをもう一度見てみます。ビッグエンディアンに最適化した場合には...
*tex=((*buf++)<<8)+0xff;
となり、リトルエンディアンに最適化した場合には...
*tex=((*buf++)>>8)+0xff000000;
となります。リトルエンディアンの場合はちょっと奇異に見えます。これは、数値に対する加減乗除、シフト演算、理論演算などが、反転したデータに対して正しく行われるよう処理されるためです。例えば、8bit右へシフトすることは256で割るのと同じですから、0x11223344(long値)は0x00112233となります。この数値はメモリ内では44332211と並んでいますので、演算結果は33221100となります。数値演算的には8bit右へシフトさせましたが、画像フォーマット的に見ると左へ8bitシフトしていることが理解できます。
つまり、リトルエンディアンでは色成分がBGRαと列んでいると考えて各種演算を実行すれば結果オーライとなります(考えるだけ...実際は違う)。以下のzeroLevelImage()ルーチンは、RGBの各色の値がすべて指定範囲外である場合に、画像バッファのピクセルをゼロでクリアしています。画像データからRGBの各色成分を抜き出す処理のソースコード部分が、リトルエンディアンとビッグエンディアンでは異なります。

逆に、RGBの各色要素から画像バッファのピクセル(unsigned long値)を作成する場合は、以下のようになります。

次の例は、医療現場などで使われるDICOM画像ファイルの解析です。readDicomImage()は、FSSpecで指定されたDICOMファイルを読み込み、その画像データをオフスクリーンバッファ(CGrafPPort)に描画するためのルーチンです。TIFFやExif画像ファイルにはリトルエンディアンとビッグエンディアンの両フォーマットがあり、ヘッダ部分でどちらなのか判断可能です。しかし、DICOMファイルの場合はリトルエンディアンフォーマット固定であり、ファイル内に書き込まれているタグやshort,long整数は、ビッグエンディアン環境では反転させてから読み込む必要があります。

逆にリトルエンディアン環境であれば、ファイルから得られた数値データはそのまま変数に代入して利用しても良いことになります。以下の2つのルーチンは、DICOMファイルから得られた数値やタグ情報を適切に処理するために用意したものです。

次回は、Universal Binary化における最大の難関(笑)PowerPCのAltiVecコードをIntel CPUのSSE/SSE2コードに変換する話に突入します。まずは、アプリケーションでAltiVecやSSE/SSE2を利用しなければいけないケースについて色々と考察してみます。
copyright 2006 Ottimo, Inc. All rights reserved
無断転載・引用禁止
Contact us: koike@ottimo.co.jp