IWICBitmapDecoder の実装

IWICBitmapDecoder

アプリケーションがデコーダーを要求すると、コーデックとの最初の対話ポイントは IWICBitmapDecoder インターフェイスを介して行われます。 これは、コンテナーの最上位のプロパティへのアクセスを提供するコンテナー レベルのインターフェイスであり、最も重要なのは、コンテナーに含まれるフレームです。 これは、コンテナー レベルのデコーダー クラスのプライマリ インターフェイスです。

interface IWICBitmapDecoder : IUnknown
{
// Required methods
   HRESULT QueryCapability (IStream *pIStream, 
      DWORD *pdwCapabilities );
   HRESULT Initialize ( IStream *pIStream,
      WICDecodeOptions cacheOptions );
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetDecoderInfo ( IWICBitmapDecoderInfo **pIDecoderInfo );
   HRESULT GetFrameCount ( UINT *pCount );
   HRESULT GetFrame ( UINT index, 
      IWICBitmapFrameDecode **ppIBitmapFrame );

// Optional methods
   HRESULT GetPreview ( IWICBitmapSource **ppIPreview );
   HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
   HRESULT GetColorContexts ( UINT cCount, 
      IWICColorContext **ppIColorContexts, 
      UINT *pcActualCount );
   HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader **ppIMetadataQueryReader);
   HRESULT CopyPalette ( IWICPalette *pIPalette );
}

一部の画像形式にはグローバルサムネイル、カラーコンテキスト、またはメタデータが含まれていますが、多くの画像形式ではフレームごとにのみ提供されます。 これらの項目にアクセスするためのメソッドは IWICBitmapDecoder では省略可能ですが、 IWICBitmapFrameDecode では必須です。 同様に、一部のコーデックではインデックス付きピクセル形式を使用しないため、どちらのインターフェイスでも CopyPalette メソッドを実装する必要はありません。 オプションの IWICBitmapDecoder メソッドの詳細については、「 IWICBitmapFrameDecode の実装」を参照してください。このメソッドは最も一般的に実装されています。

QueryCapability

QueryCapability は、コーデックの調停に使用される方法です。 (「Windows イメージング コンポーネントのしくみ」トピックの「検出と仲裁」を参照してください)。 2 つのコーデックが同じイメージ形式をデコードできる場合、または 2 つのコーデックが同じ識別パターンを使用するパターン競合が発生した場合、この方法では、特定のイメージを最も適切に処理できるコーデックを選択できます。

このメソッドを呼び出すと、Windows Imaging Component (WIC) によって、イメージを含む実際のストリームが渡されます。 イメージ内の各フレームをデコードし、メタデータ ブロックを列挙できるかどうかを確認して、渡される特定のファイル ストリームに関してこのデコーダーが持つ機能を正確に宣言する必要があります。 これはすべてのデコーダーにとって重要ですが、タグ付けされたイメージ ファイル形式 (TIFF) コンテナーに基づく画像形式では特に重要です。 検出プロセスは、レジストリ内のデコーダーに関連付けられているパターンを実際のイメージ ファイル内のパターンと照合することによって機能します。 レジストリで識別パターンを宣言すると、イメージ形式のイメージに対してデコーダーが常に検出されます。 ただし、デコーダーは他の形式の画像でも検出される可能性があります。 たとえば、すべての TIFF コンテナーには、TIFF イメージ形式の有効な識別パターンである TIFF パターンが含まれます。 つまり、検出中に、TIFF スタイルのコンテナーに基づくイメージ形式のイメージ ファイルに、少なくとも 2 つの識別パターンが見つかります。 1 つは TIFF パターンで、もう 1 つは実際の画像形式パターンになります。 可能性は低くなりますが、他の無関係な画像形式間でもパターンの競合が発生する可能性があります。 これが、検出と仲裁が 2 段階のプロセスである理由です。 QueryCapability に渡されるイメージ ストリームが実際には独自のイメージ形式の有効なインスタンスであることを常に確認してください。 また、コーデックが仕様を所有していないイメージ形式をデコードする場合、QueryCapability 実装では、コーデックが実装していないイメージ形式の仕様で有効な機能が存在する場合にチェックする必要があります。 これにより、ユーザーは不要なデコードエラーが発生したり、コーデックで予期しない結果が得られないようにすることができます。

イメージに対して操作を実行する前に、ストリームの現在位置を保存しておく必要があります。そのため、 メソッドから戻る前に元の位置に復元できます。 機能を指定する WICBitmapDecoderCapabilities 列挙は、次のように定義されます。

enum WICBitmapDecoderCapabilities
{   
   WICBitmapDecoderCapabilitySameEncoder,
   WICBitmapDecoderCapabilityCanDecodeAllImages,
   WICBitmapDecoderCapabilityCanDecodeSomeImages,
   WICBitmapDecoderCapabilityCanEnumerateMetadata,
   WICBitmapDecoderCapabilityCanDecodeThumbnail
}

WICBitmapDecoderCapabilitySameEncoder は、エンコーダーがイメージをエンコードしたエンコーダーである場合にのみ宣言する必要があります。 コンテナー内の各フレームをデコードできるかどうかを確認した後、一部のフレームをデコードできるが一部のフレームをデコードできない場合は WICBitmapDecoderCapabilityCanDecodeSomeImages 、すべてのフレームをデコードできる場合は WICBitmapDecoderCapabilityCanDecodeAllImages を宣言します。デコードできない場合はどちらも宣言しません。 (これら 2 つの列挙型は相互に排他的です。 WICBitmapDecoderCapabilityCanDecodeAllImages を返す場合、 WICBitmapDecoderCapabilityCanDecodeSomeImages は無視されます)。イメージ コンテナー内のメタデータ ブロックを列挙できることを確認した後、 WICBitmapDecoderCapabilityCanEnumerateMetadata を宣言します。 フレームごとにサムネイルをチェックする必要はありません。 グローバル サムネイルがあり、それをデコードできる場合は、 WICBitmapDecoderCapabilityCanDecodeThumbnail を宣言できます。 グローバル サムネイルがない場合は、フレーム 0 のサムネイルのデコードを試みます。 どちらの場所にもサムネイルがない場合は、この機能を宣言しないでください。

このメソッドに渡されるイメージ ストリームに関してデコーダーの機能を決定した後、このデコーダーがこのイメージで実行できることを確認した WICBitmapDecoderCapabilities を使用して OR 操作を実行し、結果を返します。 戻る前に、ストリームを元の位置に復元することを忘れないでください。

Initialize

特定 のイメージをデコードするためにデコーダーが選択された後、アプリケーションによって初期化が呼び出されます。 イメージ ストリームはデコーダーに渡され、呼び出し元は必要に応じて、ファイル内のメタデータを処理するための WICDecodeOptions キャッシュ オプションを指定できます。

enum WICDecodeOptions
{
   WICDecodeMetadataCacheOnDemand,
   WICDecodeMetadataCacheOnLoad
}

一部のアプリケーションでは、他のアプリケーションよりもメタデータが使用されます。 ほとんどのアプリケーションは、イメージ ファイル内のすべてのメタデータにアクセスする必要がなく、必要に応じて特定のメタデータを要求します。 他のアプリケーションでは、ファイル ストリームを開いたままにして、メタデータにアクセスする必要があるたびにディスク I/O を実行するよりも、すべてのメタデータを前もってキャッシュする必要があります。 呼び出し元がメタデータ キャッシュ オプションを指定しない場合、既定のキャッシュ動作は必要に応じてキャッシュする必要があります。 つまり、アプリケーションがそのメタデータに対して特定の要求を行うまで、メタデータをメモリに読み込む必要はありません。 アプリケーションで WICDecodeMetadataCacheOnLoad が指定されている場合は、メタデータをすぐにメモリに読み込み、キャッシュする必要があります。 読み込み時にメタデータがキャッシュされると、メタデータがキャッシュされた後にファイル ストリームが解放される可能性があります。

GetContainerFormat

GetContainerFormat を実装するには、デコーダーがインスタンス化されているイメージのイメージ形式の GUID を返すだけです。 このメソッドは、 IWICMetadataBlockReaderIWICBitmapEncoder にも実装されます。

GetDecoderInfo

GetDecoderInfoIWICBitmapDecoderInfo オブジェクトを 返します。 IWICBitmapDecoderInfo オブジェクトを取得するには、デコーダーの GUID を IWICImagingFactoryCreateComponentInfo メソッドに渡し、次の例に示すように IWICBitmapDecoderInfo インターフェイスを要求するだけです。

IWICComponentInfo* pComponentInfo = NULL;
HRESULT hr;
 
hr = m_pImagingFactory->CreateComponentInfo(CLSID_This, &pComponentInfo);

hr = pComponentInfo->QueryInterface(IID_IWICBitmapDecoderInfo, (void**)ppIDecoderInfo);

GetFrameCount

GetFrameCount は 、コンテナー内のフレーム数を返すだけです。 一部のコンテナー形式では複数のフレームがサポートされ、他の形式ではコンテナーごとに 1 つのフレームのみがサポートされます。

GetFrame

GetFrameIWICBitmapDecoder インターフェイスの重要なメソッドです。フレームには実際のイメージ ビットが含まれており、このメソッドから返されるフレーム デコーダー オブジェクトは、要求されたイメージの実際のデコードを行うオブジェクトであるためです。 これは、デコーダーを記述するときに実装する必要があるもう 1 つのオブジェクトです。 フレーム デコーダーの詳細については、「 IWICBitmapFrameDecode の実装」を参照してください。

GetPreview

GetPreview はイメージのプレビューを返します。 プレビューの詳細については、 IWICBitmapEncoder インターフェイスの実装に関する ページの「IWICBitmapEncoder メソッドの実装」を参照してください。

画像形式に埋め込み JPEG プレビューが含まれている場合は、デコードする JPEG デコーダーを記述する代わりに、プレビューとサムネイルをデコードするために WIC プラットフォームに付属する JPEG デコーダーに委任することを強くお勧めします。 これを行うには、ストリーム内のプレビュー イメージ データの先頭に移動し、IWICImagingFactoryCreateDecoderFromStream メソッドを呼び出します。

IWICBitmapDecoder* pPreviewDecoder = NULL;
IWICBitmapFrameDecode* pPreviewFrame = NULL;
IWICBitmapSource* pPreview = NULL;
HRESULT hr;

hr = m_pImagingFactory->CreateDecoderFromStream(
                               m_pStream, NULL, 
                               WICDecodeMetadataCacheOnDemand, &pPreviewDecoder);
hr = pPreviewDecoder->GetFrame(0, pPreviewFrame);
hr = pPreviewFrame->QueryInterface(IID_IWICBitmapSource, (void**)&pPreview);

リファレンス

IWICBitmapDecoder

IWICBitmapFrameDecode

概念

デコーダー インターフェイス

IWICBitmapCodecProgressNotification (デコーダー) の実装

WIC-Enabled コーデックを記述する方法

Windows Imaging コンポーネントの概要