Implémentation d’IWICBitmapDecoder
Iwicbitmapdecoder
Lorsqu’une application demande un décodeur, le premier point d’interaction avec le codec est via l’interface IWICBitmapDecoder . Il s’agit de l’interface au niveau du conteneur qui fournit l’accès aux propriétés de niveau supérieur du conteneur et, plus important encore, aux trames qu’il contient. Il s’agit de l’interface principale de votre classe de décodeur au niveau du conteneur.
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 );
}
Certains formats d’image ont des miniatures globales, des contextes de couleur ou des métadonnées, tandis que de nombreux formats d’image les fournissent uniquement par image. Les méthodes d’accès à ces éléments sont facultatives sur IWICBitmapDecoder, mais elles sont requises sur IWICBitmapFrameDecode. De même, certains codecs n’utilisent pas de formats de pixels indexés et n’ont donc pas besoin d’implémenter les méthodes CopyPalette sur l’une ou l’autre interface. Pour plus d’informations sur les méthodes facultatives IWICBitmapDecoder , consultez Implémentation d’IWICBitmapFrameDecode, où elles sont le plus couramment implémentées.
QueryCapability
QueryCapability est la méthode utilisée pour l’arbitrage de codec. (Voir Découverte et arbitrage dans la rubrique Fonctionnement du composant d’imagerie Windows ). Si deux codecs sont capables de décoder le même format d’image, ou si une collision de modèle se produit dans laquelle deux codecs utilisent le même modèle d’identification, cette méthode vous permet de sélectionner le codec qui peut le mieux gérer une image spécifique.
Lorsque vous appelez cette méthode, le composant WIC (Windows Imaging Component) vous transmet le flux réel contenant l’image. Vous devez vérifier si vous pouvez décoder chaque image dans l’image et énumérer par le biais des blocs de métadonnées, afin de déclarer avec précision les fonctionnalités dont dispose ce décodeur en ce qui concerne le flux de fichiers spécifique qui lui a été transmis. Cela est important pour tous les décodeurs, mais particulièrement important pour les formats d’image basés sur des conteneurs TIFF (Tagged Image File Format). Le processus de découverte fonctionne en faisant correspondre les modèles associés aux décodeurs dans le Registre à des modèles dans le fichier image réel. La déclaration de votre modèle d’identification dans le Registre garantit que votre décodeur sera toujours détecté pour les images dans votre format d’image. Toutefois, votre décodeur peut toujours être détecté pour les images dans d’autres formats. Par exemple, tous les conteneurs TIFF incluent le modèle TIFF, qui est un modèle d’identification valide pour le format d’image TIFF. Cela signifie que, lors de la découverte, au moins deux modèles d’identification seront trouvés dans les fichiers image pour n’importe quel format d’image basé sur un conteneur de style TIFF. L’un sera le modèle TIFF et l’autre sera le modèle de format d’image réel. Bien que moins probable, il peut y avoir des collisions de modèles entre d’autres formats d’image non liés. C’est pourquoi la découverte et l’arbitrage sont un processus en deux étapes. Vérifiez toujours que le flux d’image passé à QueryCapability est en fait un instance valide de votre propre format d’image. En outre, si votre codec décode un format d’image pour lequel vous n’êtes pas propriétaire de la spécification, votre implémentation QueryCapability doit case activée pour la présence de toute fonctionnalité qui peut être valide sous la spécification de format d’image que votre codec n’implémente pas. Cela garantit que les utilisateurs ne rencontrent pas d’échecs de décodage inutiles ou n’obtiennent pas de résultats inattendus avec votre codec.
Avant d’effectuer une opération sur l’image, vous devez enregistrer la position actuelle du flux afin de pouvoir le restaurer à sa position d’origine avant de revenir de la méthode. L’énumération WICBitmapDecoderCapabilities qui spécifie les fonctionnalités est définie comme suit :
enum WICBitmapDecoderCapabilities
{
WICBitmapDecoderCapabilitySameEncoder,
WICBitmapDecoderCapabilityCanDecodeAllImages,
WICBitmapDecoderCapabilityCanDecodeSomeImages,
WICBitmapDecoderCapabilityCanEnumerateMetadata,
WICBitmapDecoderCapabilityCanDecodeThumbnail
}
Vous devez déclarer WICBitmapDecoderCapabilitySameEncoder uniquement si votre encodeur est celui qui a encodé l’image. Après avoir vérifié si vous pouvez décoder chaque image dans le conteneur, déclarez soit WICBitmapDecoderCapabilityCanDecodeSomeImages si vous pouvez décoder certaines images, mais pas toutes les images, WICBitmapDecoderCapabilityCanDecodeAllImages si vous pouvez décoder toutes les images, ou non si vous ne pouvez pas décoder l’une d’entre elles. (Ces deux énumérations s’excluent mutuellement ; si vous retournez WICBitmapDecoderCapabilityCanDecodeAllImages, WICBitmapDecoderCapabilityCanDecodeSomeImages sera ignoré.) Déclarez WICBitmapDecoderCapabilityCanEnumerateMetadata après avoir vérifié que vous pouvez énumérer les blocs de métadonnées dans le conteneur d’images. Vous n’avez pas besoin d’case activée pour une miniature dans chaque image. S’il existe une miniature globale et que vous pouvez la décoder, vous pouvez déclarer WICBitmapDecoderCapabilityCanDecodeThumbnail. S’il n’existe aucune miniature globale, essayez de décoder la miniature du frame 0. S’il n’existe aucune miniature à l’un de ces emplacements, ne déclarez pas cette fonctionnalité.
Après avoir déterminé les fonctionnalités du décodeur par rapport au flux d’images transmis à cette méthode, effectuez une opération OR avec les capacités WICBitmapDecoderCapabilities que vous avez vérifiées que ce décodeur peut exécuter sur cette image, puis retournez le résultat. N’oubliez pas de restaurer le flux à sa position d’origine avant de revenir.
Initialize
L’initialisation est appelée par une application une fois qu’un décodeur a été sélectionné pour décoder une image spécifique. Le flux d’images est passé au décodeur et un appelant peut éventuellement spécifier l’option de cache WICDecodeOptions pour traiter les métadonnées dans le fichier.
enum WICDecodeOptions
{
WICDecodeMetadataCacheOnDemand,
WICDecodeMetadataCacheOnLoad
}
Certaines applications utilisent les métadonnées plus que d’autres. La plupart des applications n’ont pas besoin d’accéder à toutes les métadonnées d’un fichier image et demandent des métadonnées spécifiques en fonction de leurs besoins. D’autres applications préfèrent mettre en cache toutes les métadonnées à l’avance plutôt que de garder le flux de fichiers ouvert et d’effectuer des E/S de disque chaque fois qu’elles ont besoin d’accéder aux métadonnées. Si l’appelant ne spécifie pas d’option de cache de métadonnées, le comportement de mise en cache par défaut doit être mis en cache à la demande. Cela signifie qu’aucune métadonnées ne doit être chargée dans la mémoire tant que l’application n’a pas effectué une demande spécifique pour ces métadonnées. Si l’application spécifie WICDecodeMetadataCacheOnLoad, les métadonnées doivent être chargées en mémoire immédiatement et mises en cache. Lorsque les métadonnées sont mises en cache à la charge, le flux de fichiers peut être libéré une fois les métadonnées mises en cache.
GetContainerFormat
Pour implémenter GetContainerFormat, retournez simplement le GUID du format d’image de l’image pour laquelle le décodeur est instancié. Cette méthode est également implémentée sur IWICMetadataBlockReader et IWICBitmapEncoder.
GetDecoderInfo
GetDecoderInfo retourne un objet IWICBitmapDecoderInfo . Pour obtenir l’objet IWICBitmapDecoderInfo , transmettez simplement le GUID de votre décodeur à la méthode CreateComponentInfo sur IWICImagingFactory, puis demandez l’interface IWICBitmapDecoderInfo , comme illustré dans l’exemple suivant.
IWICComponentInfo* pComponentInfo = NULL;
HRESULT hr;
hr = m_pImagingFactory->CreateComponentInfo(CLSID_This, &pComponentInfo);
hr = pComponentInfo->QueryInterface(IID_IWICBitmapDecoderInfo, (void**)ppIDecoderInfo);
GetFrameCount
GetFrameCount retourne simplement le nombre d’images dans le conteneur. Certains formats de conteneur prennent en charge plusieurs images, tandis que d’autres ne prennent en charge qu’une seule image par conteneur.
GetFrame
GetFrame est une méthode importante sur l’interface IWICBitmapDecoder , car le frame contient les bits d’image réels et l’objet décodeur de trame retourné par cette méthode est l’objet qui effectue le décodage réel de l’image demandée. Il s’agit de l’autre objet que vous devez implémenter lors de l’écriture d’un décodeur. Pour plus d’informations sur les décodeurs d’images, consultez Implémentation d’IWICBitmapFrameDecode.
GetPreview
GetPreview retourne un aperçu de l’image. Pour obtenir une présentation détaillée des préversions, consultez Implémentation de la méthode IWICBitmapEncoder sur l’interface Implementing IWICBitmapEncoder .
Si votre format d’image contient une préversion JPEG incorporée, il est vivement recommandé, au lieu d’écrire un décodeur JPEG pour le décoder, de déléguer au décodeur JPEG fourni avec la plateforme WIC pour le décodage des aperçus et des miniatures. Pour ce faire, recherchez au début des données d’image d’aperçu dans le flux et appelez la méthode CreateDecoderFromStream sur IWICImagingFactory.
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);
Rubriques connexes
-
Informations de référence
-
Conceptuel
-
Implémentation d’IWICBitmapCodecProgressNotification (Décodeur)