付録 E: イメージ プラグインの追加

Maya の特長は、固有のイメージ ファイル トランスレータ機能を作成できる外部プラグイン モジュール機構です。これは Maya に新しいイメージを追加するためのシステムであり、Maya API とは異なります。これらのプラグイン モジュールは、アプリケーションを開始するときにいつでも使用可能です。イメージ ファイルにアクセスする場合に表示されるイメージ ファイル タイプのリストからこれらにアクセスできます。

プラグイン イメージ モジュールは動的な共有オブジェクトとして実装され(DSO または DLL)、C または C++ で記述できます。この場合、イメージ ファイルの読み取りと書き込みを行うアルゴリズムを実装するだけです。ユーザ インタフェースとフロー制御は Maya によって暗黙的に処理されます。

この文書では、イメージ プラグイン モジュールを記述するためのプロトコルについて説明します。複数のフレームまたはムービー ファイルのサポート方法については説明しません。サンプル コードは Developer Kit の image サブフォルダに収められています。

このセクションでは次の項目について説明します。

イメージ ファイル フォーマット プラグインを書き込むと、これをコンパイルして、Maya にロードできる共有オブジェクトを作成する必要があります。gcc コンパイラを使用したサンプルを構築するための、Makefile と buildconfig が Developer Kit に用意されています。Windows では、Visual C++ でイメージ プラグインを構築するためのソリューションとプロジェクト ファイルが用意されています。イメージ プラグインのサンプルを構築する前に、最初に MAYA_LOCATION を設定する必要があります。構築するプラグインは、Maya が新しいイメージ フォーマットにアクセスする前に、$MAYA_LOCATION/bin/plug-ins/image フォルダにコピーしてください。イメージ プラグインは、Maya にロードできるように用意されたコンパイラとリンカーのフラグを使用して構築する必要があります。

概要

Maya は、主にイメージ ファイルの読み取りと書き込みのためにイメージ プラグインから関数を起動します。これが発生する場所には、レンダリング ウィンドウなどがあります。このウィンドウでは、特定のフォーマットとしてイメージを保存することを選択できます。さらに、このウィンドウに既存のレンダリング イメージをロードすることも可能です。このウィンドウの読み取り操作および書き込み操作用に定義したカスタム フォーマットを選択することができます。

エントリ ポイント

各プラグインには、定義数のエントリ ポイントがあります。Maya はこれらのエントリ ポイントを使用して、イメージ プラグインがサポートする機能を定義します。

エントリ ポイントは変数や関数などです。たとえば、プラグインの名前は変数エントリ ポイント imageName で定義され、読み取り用のイメージ ファイルを開く関数は、関数エントリ ポイント imageReadOpen で定義されます。

エントリ ポイントには必須とオプションのものがあります。必須のエントリ ポイントについては次のセクションで説明します。オプションのエントリ ポイントについては「オプション エントリ ポイント」で説明します。

ヒント: 作成するプラグインに Maya との互換性を持たせる場合、必須のエントリ ポイントを実装するだけです。作成するプラグインのオプションのエントリ ポイントは、Maya で起動できない場合があるため、必須ではありません。

必須のエントリ ポイント

次のエントリ ポイントは定義する必要があります。

必須のエントリ ポイントが削除されると、プラグインがロードされないため、その名前はメニューに表示されません。

program

定義

char *program

説明

このエントリ ポイントは、プラグインを使用できるアプリケーションを指定します。すべてのアプリケーションがこのプラグインでサポートされるイメージ ファイルの読み取りと書き込みを実行できるようにするには、これに Wavefront を設定します。

注: このエントリ ポイントの定義は必須です。

char *program = "Wavefront";

type

定義

char *type

修正される問題

このエントリ ポイントは、構築するプラグインのタイプを示します。Maya のイメージ ファイル プラグインのタイプは、image です。

注: このエントリ ポイントの定義は必須です。

char *type = "image";

version

定義

char *version

説明

このエントリ ポイントは、プラグインを記述したプロトコルのバージョンを示します。常に IMF_PROTOCOL_CURRENT を使用します。

注: このエントリ ポイントの定義は必須です。

char *version = IMF_PROTOCOL_CURRENT;

imageKey

定義

char *imageKey

説明

このエントリ ポイントは、プラグインを特定するための固有のキーを指定します。

注: このエントリ ポイントの定義は必須です。

char *imageKey = "myFormat";

imageName

定義

char *imageName

説明

このエントリ ポイントは、メニューに表示されるプラグインの名前を定義します。ユーザが区別できるように固有の名前を定義する必要があります。

注: このエントリ ポイントの定義は必須です。

char *imageName = "My Image Format";

imageReadOpen

定義

int imageReadOpen

(

IMF_OBJECT *imf

}

パラメータ 修正される問題
imf

Modified

イメージ ファイル ヘッダ

戻り値  

IMF_C_NORMAL イメージが正常に開かれた場合。IMF_C_ エラーが発生した場合。

修正される問題

この関数は、読み取り用にファイルを開くときにコールされます。

imf パラメータには、ファイルの読み取りに必要なすべての情報が含まれます。imageReadOpen を呼び出す前に、ここにファイル名を含めます。このルーチンの実行後、ここにファイルにアクセスするルーチンへのポインタ、サイズの情報、読み取るイメージの他のアトリビュート、イメージの走査線を読み込むバッファなども含める必要があります。

この関数を記述する基本手順を以下に示します。

複数のイメージ(フル イメージやサムネール表示など)を含むイメージ ファイルもあります。ここでは、ファイルからメイン イメージのみを読み取る場合について説明しています。

詳細な手順を次に示します。

  1. ファイル名が完全でない場合は補完します。次に、指定したファイルを開きます。正常に開かれた場合にのみ続行します。失敗した場合は、ERR_printf を使用してメッセージを生成し、imf__errIMF_C_CANNOT_OPEN に設定して、FALSE を返します。
  2. イメージ カウントを 1 に設定して、1 つのイメージ構造を配分および初期化して、このイメージに関する情報を含めます。

``` imf->info.count = 1; imf->info.image = malloc( sizeof( IMF_IMAGE ) ); (void) imf__init_ifd( imf );

```

  1. malloc を使用して、割り当てた固有のデータ構造に、ファイルを記述するフォーマット固有の情報を保存します。このプライベート データ構造には、現在のファイル記述子、最新のスキャンラインの読み取り、アクティブ ウィンドウなどの項目を含めることができます。:

``` private = malloc( sizeof( PRIVATE ) ); private->... = ...; imf->data = malloc( sizeof( POINTER ) ); imf->data[0] = private;

```

  1. イメージ アクセス ルーチンを imf->scan および imf->close に割り当てます。イメージ ファイルにルックアップ テーブルが含まれている場合は、imf->lut_read にルックアップ テーブルを読み取るルーチンも指定します。
  2. ファイル フォーマットで入力機能が定義されている場合は、imf->info.settings から抽出します (詳細については、IMF_CAPABILITY を参照してください)。
  3. ファイルからヘッダ情報を読み取り、プライベート データ構造にこれを格納します。さらに、imf->infoimf->info.image[0] のデータ構造内で各種フィールドも定義する必要があります。

imf->info 構造では、イメージがルックアップ テーブルを含むかどうかに応じて、lut_exists fieldを設定します。

programmachineuserdatetimeframe 番号、job_num、および色度情報(red_prigreen_priblue_priwhite_pt)がファイル自体に格納されている場合は、これらも設定できます。

また、imf->info.image[0] ですべてのフィールドを設定する必要があります。aux_formataux_countaux_type、および aux_bits フィールドは z チャネル情報を示します。curve.gamma フィールドには、ファイル内で定義したガンマを設定するか、または IMF_def_input_gamma を呼び出して既定のガンマを設定する必要があります。

  1. スキャンラインの読み取りルーチンが 1 行のピクセルを読み取るスキャンライン バッファを配分します。

``` private_data_ptr->buffer = IMF_chan_alloc( imf->info.image, image_width, imf->info.key, NULL );

```

  1. 関数が正常に開き、イメージ ファイル ヘッダを読み取った場合は TRUE、エラーが発生した場合は FALSE を返します。

注: このエントリ ポイントの定義は必須です。

スキャンライン読み取り関数

定義

int your_scan_read_func

(

POINTER data,

int scan,

POINTER **line_buff

)

パラメータ 修正される問題
data

入力

イメージにコネクトするプライベート データ

scan 入力

読み取るスキャンライン

line_buff 出力

imageReadOpen に配分されるスキャンライン バッファ。読み取られたピクセル行を含みます。

戻り値  

IMF_C_BAD_SCAN スキャンがイメージの範囲外である場合。IMF_C_NORMAL スキャンラインが正常に読み取られた場合。および IMF_C_READ_ERR エラーが発生した場合。

修正される問題

この関数は Maya によってコールされ、イメージ ファイルからスキャンラインを読み取ります。イメージ ファイルはイメージの方向に基づいて、下から上または上から下のいずれかの方向に読み取られます。

以下の手順に従って、スキャンライン読み取り関数を作成します。

  1. 指定したスキャンラインを読み取ります。スキャンライン番号は下から上の順序に基づきます。たとえば、イメージ サイズが 480 ラインで、方向が IMF_C_TOP_LEFT である場合、スキャンラインは 479 (一番上)、478 (上から 2 番目)、477、... 0 (一番下)の順序で読み取られます。順序が IMF_C_BOT_LEFT である場合は、0 (一番下)、1 (下から 2 番目)、2、...479 (一番上)の順序で読み取られます。
  2. imageReadOpen に割り当てられたバッファにスキャンラインを転送します。IMF_chan_alloc によって割り当てられたバッファには、ファイルのチャネル単位のビット数に応じて、8、16、32 ビットの符号なしの数字が含まれます (チャネル単位のビット数はニアレストの数字に切り上げられます)。

スキャンラインの各成分は個別の隣接しているバッファに格納されます。これらは、割り当てられた成分へのポインタの配列であるパラメータ line_buff に格納されて返されます。

/*

* Unsigned char's are used for 1 to 8-bit values;

* unsigned short's, for 8 to 16-bit values;

* unsigned long's, for 17 to 32-bit values.

*/

*line_buff = data->buffer;

pr = (unsigned char *) data->buffer[0];

pg = (unsigned char *) data->buffer[1];

pb = (unsigned char *) data->buffer[2];

pm = (unsigned char *) data->buffer[3];

for ( i = 0; i < data->image_width; ++i )

{

*(pr++) = red_values[i];

*(pg++) = green_values[i];

*(pb++) = blue_values[i];

*(pm++) = matte_values[i];

}

ファイルにルックアップ テーブルが含まれている場合は、line_buff でルックアップ テーブルにインデックスではなく、RGB データを返す必要があります。

  1. 必要に応じて、IMF_C_BAD_SCANIMF_C_NORMAL、または IMF_C_READ_ERR を返します。

スキャンライン読み取り関数は、イメージの最新のスキャンラインを読み取るとは限りません。これは Maya が読み取る必要のない最新のスキャンラインをスキップする場合があるためです。プラグインでは、imageReadOpen の呼び出し後に Maya が いつでも終了関数を呼び出せるように許可する必要があります。

終了関数

定義

int your_close_func

(

IMF_OBJECT *imf

)

パラメータ 修正される問題
imf

Modified

イメージ ファイル記述子

戻り値  

IMF_C_NORMAL ファイルが閉じられ、メモリの再配分が成功した場合。IMF_C_failure_code エラーが発生した場合(IMF_C_WRITE_ERR など)。

修正される問題

この関数は、Maya でイメージ ファイルの読み取りまたは書き込みが完了するたびにコールされます。以下の手順に従って、終了関数を作成します。

  1. イメージ ファイルを閉じます。
  2. imf->data で示されるプライベート データの割り当てを解除して、imf->dataNULL に設定します。imageReadOpen または imageWriteOpen のスキャンライン バッファの割り当てを解除するには、IMF_chan_free を使用します。
  3. ファイルの終了およびメモリのクリーンアップに成功した場合は、IMF_C_NORMAL を返します。失敗した場合は、IMF_C_failure_code を返します。

imageWriteOpen

定義

int imageWriteOpen

(

IMF_OBJECT *imf

)

パラメータ 修正される問題
imf

Modified

イメージ ファイル記述子

戻り値  

TRUE イメージが正常に開かれた場合。FALSE エラーが発生した場合。

修正される問題

この関数は、書き込み用にファイルを開くときにコールされます。

imf パラメータには、ファイルの書き込みに必要なすべての情報が含まれます。imageWriteOpen を呼び出す前に、ここにファイル名を含めます。このルーチンの実行後、ファイルにアクセスするルーチンのポインタ、サイズの情報、および書き込むイメージの他のアトリビュートなども含める必要があります。

この関数を作成する基本手順を以下に示します。

詳細な手順を次に示します。

  1. 指定したファイルを開きます。正常に開かれた場合にのみ続行します。失敗した場合は、ERR_printf を使用してメッセージを生成し、imf__errIMF_C_CANNOT_OPEN に設定して、FALSE を返します。
  2. imf->info および imf->info.image[0] を使用して、書き込むファイルに関するアトリビュートを抽出します。
  3. malloc を使用して、割り当てた固有のデータ構造に、ファイルを記述するフォーマット固有の情報を保存します。このプライベート データ構造には、現在のファイル記述子、アクティブ ウィンドウなどの項目を含めることができます。:

``` private = malloc( sizeof( PRIVATE ) ); private->... = ...; imf->data = malloc( sizeof( POINTER ) ); imf->data[0] = private;

```

  1. imf->scan および imf->close でイメージ アクセス ルーチンを指定します。
  2. ファイル フォーマットで出力機能が定義されている場合は、imf->info.settings から抽出します (詳細については、IMF_CAPABILITY を参照してください)。
  3. 定義する場合は、ファイル ヘッダとルックアップ テーブルを書き込みます。
  4. 関数が正常に開き、イメージ ファイル ヘッダを読み取った場合は IMF_C_NORMAL を返します。エラーが発生した場合は、IMF_C_failure_code を返します。

イメージ ファイルを開こうとして失敗した場合、Maya は imf__free_obj( imf ) を呼び出して、imageWriteOpen に渡された IMF_OBJECT を解放します。したがって、エラー処理コードで imf__free_obj を呼び出さないでください。

注: このエントリ ポイントの定義は必須です。

スキャンライン書き込み関数

定義

int your_scan_write_func

(

POINTER data,

int scan,

POINTER *line_buff

)

パラメータ 修正される問題
data

入力

イメージにコネクトするプライベート データ

scan 入力

書き込むスキャンライン

line_buff 出力

現在のスキャンラインのピクセルを含むバッファ

戻り値  

IMF_C_BAD_SCAN スキャンがイメージの範囲外である場合。IMF_C_NORMAL スキャンラインが正常に書き込まれた場合。IMF_C_WRITE_ERR エラーが発生した場合。

修正される問題

この関数は Maya によってコールされ、スキャンラインをイメージ ファイルに書き込みます。イメージ ファイルはイメージの方向に基づいて、下から上または上から下のいずれかの方向に書き込まれます。

以下の手順に従って、スキャンライン書き込み関数を作成します。

  1. 指定したスキャンラインを書き込みます。スキャンライン番号は下から上の順序に基づきます。たとえば、イメージ サイズが 480 ラインで、方向が IMF_C_TOP_LEFT である場合、スキャンラインは 479 (一番上)、478 (上から 2 番目)、477、... 0 (一番下)の順序で書き込まれます。順序が IMF_C_BOT_LEFT である場合、0 (一番下)、1 (下から 2 番目)、2、...479 (一番上)の順序で書き込まれます。
  2. line_buff が Maya によって渡されたスキャンライン バッファである場合、line_buff[0] からは赤、line_buff[1] からは緑、line_buff[2] からは青のカラー チャネル情報を取得します。マット チャネルは、line_buff[3] にあります(存在する場合)。z チャネルは、line_buff[4] にあります(存在する場合)。ピクセルは左から右に格納されます。

``` pr = (unsigned char ) line_buff[0]; pg = (unsigned char ) line_buff[1]; pb = (unsigned char ) line_buff[2]; pm = (unsigned char ) line_buff[3]; for ( i = 0; i < data->image_width; ++i ) { red_values[i] = (pr++); green_values[i] = (pg++); blue_values[i] = (pb++); matte_values[i] = (pm++); }

```

ファイル フォーマットで使用されるフォーマットに値を変換して、スキャンラインをファイルに書き込みます。

  1. IMF_C_BAD_SCANIMF_C_NORMAL、または IMF_C_READ_ERR を返します。

オプションのエントリ ポイント

いくつかの追加のエントリ ポイントが存在します。オプションのエントリ ポイントが定義されていない場合、既定値が使用されます。使用するファイル フォーマットが機能をサポートしていない場合、無視されるオプションのエントリ ポイントもあります。

imageAccess

定義

unsigned int imageAccess

説明

この変数はプラグインがサポートする読み取りおよび書き込みメソッドを指定します。記述する定数はビット フィールドです。

既定値は IMF_C_READ|IMF_C_WRITE です。

この例は、ルックアップ テーブルをサポートするファイル用です。

``` unsigned int imageAccess = IMF_C_LUT_READ | IMF_C_LUT_WRITE | IMF_C_READ | IMF_C_WRITE;

```

イメージ プラグインの追加の詳細については、引き続き、付録 E のパート 2 で説明します。