Implementando IWICBitmapDecoder

Iwicbitmapdecoder

Quando um aplicativo solicita um decodificador, o primeiro ponto de interação com o codec é por meio da interface IWICBitmapDecoder . Essa é a interface de nível de contêiner que fornece acesso às propriedades de nível superior do contêiner e, mais importante, aos quadros que ele contém. Essa é a interface primária em sua classe de decodificador no nível do contêiner.

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 );
}

Alguns formatos de imagem têm miniaturas globais, contextos de cores ou metadados, enquanto muitos formatos de imagem os fornecem apenas por quadro. Os métodos para acessar esses itens são opcionais em IWICBitmapDecoder, mas são necessários em IWICBitmapFrameDecode. Da mesma forma, alguns codecs não usam formatos de pixel indexados e, portanto, não precisam implementar os métodos CopyPalette em nenhuma das interfaces. Para obter mais informações sobre os métodos IWICBitmapDecoder opcionais, consulte Implementando IWICBitmapFrameDecode, em que eles são mais comumente implementados.

QueryCapability

QueryCapability é o método usado para arbitragem de codec. (Consulte Descoberta e Arbitragem no tópico Como funciona o componente de imagem do Windows ). Se dois codecs forem capazes de decodificar o mesmo formato de imagem ou se ocorrer uma colisão de padrão na qual dois codecs usam o mesmo padrão de identificação, esse método permitirá que você selecione o codec que pode lidar melhor com qualquer imagem específica.

Ao invocar esse método, o WIC (Componente de Imagem do Windows) passa o fluxo real que contém a imagem. Você deve verificar se pode decodificar cada quadro dentro da imagem e enumerar por meio dos blocos de metadados para declarar com precisão quais recursos esse decodificador tem em relação ao fluxo de arquivos específico passado para ele. Isso é importante para todos os decodificadores, mas particularmente importante para formatos de imagem com base em contêineres TIFF (Tagged Image File Format). O processo de descoberta funciona correspondendo padrões associados a decodificadores no registro para padrões no arquivo de imagem real. Declarar seu padrão de identificação no registro garante que o decodificador sempre será detectado para imagens no formato de imagem. No entanto, o decodificador ainda pode ser detectado para imagens em outros formatos. Por exemplo, todos os contêineres TIFF incluem o padrão TIFF, que é um padrão de identificação válido para o formato de imagem TIFF. Isso significa que, durante a descoberta, pelo menos dois padrões de identificação serão encontrados em arquivos de imagem para qualquer formato de imagem baseado em um contêiner no estilo TIFF. Um será o padrão TIFF e o outro será o padrão de formato de imagem real. Embora seja menos provável, pode haver colisões de padrão entre outros formatos de imagem não relacionados também. É por isso que a descoberta e a arbitragem são um processo de duas fases. Sempre verifique se o fluxo de imagem passado para QueryCapability é, na verdade, uma instância válida do seu próprio formato de imagem. Além disso, se o codec decodificar um formato de imagem para o qual você não possui a especificação, sua implementação QueryCapability deverá marcar para a presença de qualquer recurso que possa ser válido sob a especificação de formato de imagem que o codec não implementa. Isso garantirá que os usuários não experimentem falhas desnecessárias de decodificação ou obtenham resultados inesperados com seu codec.

Antes de executar qualquer operação na imagem, você deve salvar a posição atual do fluxo, para que possa restaurá-la para sua posição original antes de retornar do método . A enumeração WICBitmapDecoderCapabilities que especifica os recursos é definida da seguinte maneira:

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

Você deve declarar WICBitmapDecoderCapabilitySameEncoder somente se o codificador foi aquele que codificou a imagem. Depois de verificar se você pode decodificar cada quadro no contêiner, declare WICBitmapDecoderCapabilityCanDecodeSomeImages se puder decodificar alguns, mas não todos os quadros, WICBitmapDecoderCapabilityCanDecodeAllImages se você puder decodificar todos os quadros ou nenhum deles se não puder decodificar nenhum deles. (Essas duas enumerações são mutuamente exclusivas; se você retornar WICBitmapDecoderCapabilityCanDecodeAllImages, WICBitmapDecoderCapabilityCanDecodeSomeImages será ignorado.) Declare WICBitmapDecoderCapabilityCanEnumerateMetadata depois de verificar se você pode enumerar por meio dos blocos de metadados no contêiner de imagem. Você não precisa marcar para uma miniatura em cada quadro. Se houver uma miniatura global e você puder decodificá-la, poderá declarar WICBitmapDecoderCapabilityCanDecodeThumbnail. Se não houver miniatura global, tente decodificar a miniatura do Quadro 0. Se não houver miniatura em nenhum desses locais, não declare essa funcionalidade.

Depois de determinar os recursos do decodificador em relação ao fluxo de imagem passado para esse método, execute uma operação OR com o WICBitmapDecoderCapabilities que você verificou que esse decodificador pode executar nessa imagem e retorne o resultado. Lembre-se de restaurar o fluxo para sua posição original antes de retornar.

Initialize

Inicializar é invocado por um aplicativo depois que um decodificador é selecionado para decodificar uma imagem específica. O fluxo de imagem é passado para o decodificador e um chamador pode, opcionalmente, especificar a opção de cache WICDecodeOptions para lidar com os metadados no arquivo.

enum WICDecodeOptions
{
   WICDecodeMetadataCacheOnDemand,
   WICDecodeMetadataCacheOnLoad
}

Alguns aplicativos usam metadados mais do que outros. A maioria dos aplicativos não precisa acessar todos os metadados em um arquivo de imagem e solicitará metadados específicos conforme necessário. Outros aplicativos preferem armazenar em cache todos os metadados antecipadamente do que manter o fluxo de arquivos aberto e executar E/S de disco sempre que precisarem acessar metadados. Se o chamador não especificar uma opção de cache de metadados, o comportamento de cache padrão deverá ser cache sob demanda. Isso significa que nenhum metadado deve ser carregado na memória até que o aplicativo faça uma solicitação específica para esses metadados. Se o aplicativo especificar WICDecodeMetadataCacheOnLoad, os metadados deverão ser carregados na memória imediatamente e armazenados em cache. Quando os metadados são armazenados em cache no carregamento, o fluxo de arquivos pode ser liberado depois que os metadados são armazenados em cache.

Getcontainerformat

Para implementar GetContainerFormat, basta retornar o GUID do formato de imagem da imagem para a qual o decodificador é instanciado. Esse método também é implementado em IWICMetadataBlockReader e IWICBitmapEncoder.

GetDecoderInfo

GetDecoderInfo retorna um objeto IWICBitmapDecoderInfo . Para obter o objeto IWICBitmapDecoderInfo , basta passar o GUID do decodificador para o método CreateComponentInfo em IWICImagingFactory e solicitar a interface IWICBitmapDecoderInfo nele, conforme mostrado no exemplo a seguir.

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

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

GetFrameCount

GetFrameCount apenas retorna o número de quadros no contêiner. Alguns formatos de contêiner dão suporte a vários quadros e outros dão suporte apenas a um quadro por contêiner.

Getframe

GetFrame é um método importante na interface IWICBitmapDecoder porque o quadro contém os bits de imagem reais, e o objeto decodificador de quadro retornado desse método é o objeto que faz a decodificação real da imagem solicitada. Esse é o outro objeto que você precisa implementar ao escrever um decodificador. Para obter mais informações sobre decodificadores de quadro, consulte Implementando IWICBitmapFrameDecode.

GetPreview

GetPreview retorna uma visualização da imagem. Para obter uma discussão detalhada sobre visualizações, consulte o método Implementing IWICBitmapEncoder na interface Implementing IWICBitmapEncoder .

Se o formato de imagem contiver uma visualização JPEG inserida, é altamente recomendável que, em vez de escrever um decodificador JPEG para decodificá-lo, você delegue para o decodificador JPEG fornecido com a plataforma WIC para decodificar visualizações e miniaturas. Para fazer isso, procure o início dos dados de imagem de visualização no fluxo e invoque o método CreateDecoderFromStream no 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);

Referência

Iwicbitmapdecoder

Iwicbitmapframedecode

Conceitual

Interfaces do decodificador

Implementando IWICBitmapCodecProgressNotification (Decoder)

Como escrever um CODEC WIC-Enabled

Visão geral do componente de imagem do Windows