ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング : SophiaFramework 逆引き FAQ・コード集

BREW コールバック関数の登録と呼び出し(JPEG 画像データを読み込んで表示する方法)

BREW ネイティブのコールバック関数を登録し、呼び出すためのサンプルコードです。

ファイルストレージまたはメモリストレージに保存された JPEG 画像データを読み込んで表示するコードを以下に記します。

BREW の仕様では、JPEG 画像データの表示処理は、ファイルストレージまたはメモリストレージに保存された JPEG 画像データの読み込みが完了したときに呼び出されるコールバック関数内に記述する必要があります。

ファイルストレージまたはメモリストレージに保存された JPEG 画像データを読み込むためのストリームは、 SFBImage::SetStream() 関数を使って設定します。

コールバック関数は SFBImage::Notify() 関数を使って登録します。

なお、コールバック関数を登録する SFBImage 型のインスタンス変数は jpegreader クラスの変数として登録します。メンバ関数などローカル変数として登録すると、スマートポインターで管理されるため変数スコープから外れたときに、メモリは自動的に解放され、コールバック関数が呼び出されません。

また、コールバック関数の実体は、ダミーのコールバック関数内から呼び出されます。コールバック関数の登録では、ダミーのコールバック関数を登録します。

■クラスの定義

SFMTYPEDEFCLASS(jpegreader)
class  : public SFYApplication {
    SFMSEALCOPY(jpegreader)
private:
    SFBImageSmp _image;
public:
    static SFCInvokerPtr Factory(Void);
private:
    explicit jpegreader(Void) static_throws;
    virtual ~jpegreader(Void);
    SFCError LoadImage(SFXPathConstRef path);
    SFCError ExampleDirectFile(SFXFilePtr file); 
    SFCError ExampleThroughMemory(SFXFilePtr file, UInt32 size);
    XANDLER_DECLARE_BOOLEVENT(OnKey)
   
    // コールバック関数の実体
    Void OnImage(Void);  
    // ダミーのコールバック関数
    friend Void read_finished(VoidPtr, IImage*, AEEImageInfo*, SIntN);  
};

※注意:
1.JPEG 画像データを読み込む変数 _image は、クラス変数として定義します。JPEG 画像データを読み込むためのメンバ関数 LoadImage() 内のローカル変数として定義すると、JPEG 画像データの読み込み完了時に自動的に解放されるため、JPEG 画像を表示するためのダミーのコールバック関数 read_finished() が呼び出されません。

2.JPEG 画像を表示するためのダミーのコールバック関数 read_finished()は、friend 関数として定義します。

3.JPEG 画像を表示する実際の処理は、jpegreader::OnImage() 関数に記述します。このメンバ関数は、ダミーのコールバック関数 read_finished() から呼び出されます。

■クラスの実装

// パスから JPEG 画像データを読み込む
SFCError jpegreader::LoadImage(SFXPathConstRef path)
{
    SFXFile   file;
    UInt32    size;
    SFCError  error(SFERR_NO_ERROR);

    if ((_image = SFBImage::NewInstance(AEECLSID_JPEG, &error)) != null) {

        if ((error = file.OpenReadOnly(path)) == SFERR_NO_ERROR) {

            if ((error = file.GetSize(path, &size)) == SFERR_NO_ERROR) {

                // ファイルストレージから JPEG 画像を読み込む場合
                // ExampleDirectFile(&file);  

                // メモリストレージから JPEG 画像を読み込む場合
                ExampleThroughMemory(&file, size);
             }
        }
    }
    return error;
}

// ファイルストレージから JPEG 画像データを読み込む
SFCError jpegreader::ExampleDirectFile(SFXFilePtr file)
{
    // ダミーのコールバック関数を登録する
    _image->Notify((PFNIMAGEINFO)read_finished, this);

    // ファイルストレージのストリームを設定する
    return _image->SetStream(*file);
}

// メモリストレージから JPEG 画像データを読み込む
SFCError jpegreader::ExampleThroughMemory(SFXFilePtr file, UInt32 size)
{
    SFXBuffer  buffer;
    VoidPtr    ptr;
    SFXMemory  memory;
    SFCError   error(SFERR_NO_ERROR);

    if (size > 0) {

        if ((error = buffer.SetSize(size)) == SFERR_NO_ERROR) {

            ptr = buffer.Detach();

            if ((error = file->Read(ptr, &size)) == SFERR_NO_ERROR) {

                if ((error = buffer.Attach(ptr, size)) ==SFERR_NO_ERROR) {

                    if ((error = memory.Open(buffer)) == SFERR_NO_ERROR) {

                        // ダミーのコールバック関数を登録する
                        _image->Notify((PFNIMAGEINFO)read_finished, this);

                        // メモリストレージのストリームを設定する
                        error = _image->SetStream(memory);
                    }
                }
            }
        }
    }
    else {
        error = SFERR_FAILED;
    }
    return error;
}

// 実際のコールバック関数(実体:  JPEG 画像を描画する)
Void jpegreader::OnImage(Void)
{
    SFXRectangle  rx;
    AEEImageInfo  info;

    rx.Set(GetLocalBound());

    _image->GetInfo(&info);

    //  JPEG 画像を描画する
    _image->Draw((rx.GetWidth()-info.cx)/2, (rx.GetHeight()-info.cy)/2);

    return;
}

// ダミーのコールバック関数(PFNIMAGEINFO 型)
Void read_finished(VoidPtr reference, IImage* /* image*/, AEEImageInfo* /* info*/, SIntN /* error*/)
{
    // 実際のコールバック関数を呼び出す
    static_cast<jpegreaderPtr>(reference)->OnImage();

    return;
}

※注意:
4.JPEG 画像表示処理の実体は、ダミーのコールバック関数 read_finished() から呼び出される実際のコールバック関数 jpegreader::OnImage() 内に実装します。

5.JPEG 画像データを読み込むためのファイルストレージまたはメモリストレージを SFBImage::SetStream() 関数を使って設定し、SFBImage::Notify() 関数を使ってダミーのコールバック関数 read_finished() を登録します。

サンプルコードダウンロード( jpegreader.zip: 99.7kb )

□関連情報:BREW FAQ : JPEG 形式で保存した画像ファイルを読み込むには