Implementación de IWICMetadataBlockReader

IWICMetadataBlockReader

A menudo existen varios bloques de metadatos dentro de una imagen, cada uno de los cuales expone diferentes tipos de información en diferentes formatos. En el modelo de Componente de imágenes de Windows (WIC), los controladores de metadatos son componentes distintos que, como los descodificadores, se pueden detectar en tiempo de ejecución. Cada formato de metadatos tiene un controlador independiente y cada uno de estos controladores de metadatos se puede usar con cualquier formato de imagen que admita el formato de metadatos que controla. Por lo tanto, si el formato de imagen admite EXIF, XMP, IPTC u otro formato, puede aprovechar las ventajas de los controladores de metadatos estándar para estos formatos que se incluyen con WIC y no es necesario escribir los suyos propios. Por supuesto, si crea un nuevo formato de metadatos, debe escribir un controlador de metadatos para él, que se detectará e invocará en tiempo de ejecución igual que los estándar.

Nota

Si el formato de imagen se basa en un contenedor de formato de archivo de imagen etiquetado (TIFF) o JPEG, no tendrá que escribir ningún controlador de metadatos (a menos que desarrolle un formato de metadatos nuevo o propietario). En los contenedores TIFF y JPEG, los bloques de metadatos se encuentran dentro de los IFD y cada contenedor tiene una estructura IFD diferente. WIC proporciona controladores IFD para ambos formatos de contenedor que navegan por la estructura IFD y delegan a los controladores de metadatos estándar para acceder a los metadatos dentro de ellos. Por lo tanto, si el formato de imagen se basa en cualquiera de estos contenedores, puede aprovechar automáticamente los controladores WIC IFD. Sin embargo, si tiene un formato de contenedor propietario que tiene su propia estructura de metadatos de nivel superior única, debe escribir un controlador que pueda navegar por esa estructura de nivel superior y delegar en los controladores de metadatos adecuados, al igual que lo hacen los controladores IFD).

 

De la misma manera, WIC proporciona una capa de abstracción para las aplicaciones que les permite trabajar con todos los formatos de imagen de la misma manera a través de un conjunto coherente de interfaces, WIC proporciona una capa de abstracción para los autores de códecs con respecto a los formatos de metadatos. Como se indicó anteriormente, los autores de códecs normalmente no necesitan trabajar directamente con los distintos formatos de metadatos que pueden estar presentes en una imagen. Sin embargo, cada autor de códecs es responsable de proporcionar una manera de enumerar los bloques de metadatos para que se pueda detectar y crear instancias de un controlador de metadatos adecuado para cada bloque.

Debe implementar esta interfaz en la clase de descodificación de nivel de marco. También puede que tenga que implementarlo en la clase de descodificador de nivel de contenedor si el formato de imagen expone metadatos globales fuera de cualquier fotograma de imagen individual.

interface IWICMetadataBlockReader : IUnknown
{
   // All methods required
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetCount ( UINT *pcCount );
   HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
   HRESULT GetReaderByIndex ( UINT nIndex, IWICMetadataReader **ppIMetadataReader );
}

GetContainerFormat

GetContainerFormat es el mismo que el método GetContainerFormat en Implementing IWICBitmapDecoder.

GetCount

GetCount devuelve el número de bloques de metadatos de nivel superior asociados al marco.

GetEnumerator

GetEnumerator devuelve un enumerador que el autor de la llamada puede usar para enumerar los bloques de metadatos del marco y leer sus metadatos. Para implementar este método, debe crear un lector de metadatos para cada bloque de metadatos e implementar un objeto de enumeración que enumera sobre la colección de lectores de metadatos. El objeto de enumeración debe implementar IEnumUnknown para que pueda convertirlo en IEnumUnknown cuando lo devuelva en el parámetro ppIEnumMetadata .

Al implementar el objeto de enumeración, puede crear todos los lectores de metadatos al crear por primera vez el objeto IWICMetadataBlockReader o al crear por primera vez el objeto de enumeración, o bien puede crearlos de forma diferida dentro de la implementación del método IEnumUnknown::Next . En muchos casos, es más eficaz crearlos de forma diferenciosa, pero, en el ejemplo siguiente, todos los lectores de bloques se crean en el constructor para ahorrar espacio.

public class MetadataReaderEnumerator : public IEnumUnknown
{
   UINT m_current;
   UINT m_blockCount;
   IWICMetadataReader** m_ppMetadataReader;
   IStream* m_pStream;

   MetadataReaderEnumerator() 
   {
       // Set m_blockCount to the number of metadata blocks in the frame. 
      ...
      m_ppMetadataReader = IWICMetadataReader*[m_blockCount];
       m_current = 0;

      for (UINT x=0; x < m_blockCount; x++) 
      {
         // Find the position in the file where the xth
         // block of metadata lives and seek m_piStream 
         // to that position.
         ...

         m_pComponentFactory->CreateMetadataReaderFromContainer(
            GUID_ContainerFormatTiff,
                        NULL,
                        WICPersistOptions.WICPersistOptionsDefault | 
            WICMetadataCreationOptions.WICMetadataCreationDefault, 
                        m_pStream, &m_ppMetadataReader[x]);
        }
    }

    // Implementation of IEnumUnknown and IUnknown interfaces
    ...
}

Para crear los lectores de metadatos, use el método CreateMetadataReaderFromContainer . Al invocar este método, se pasa el GUID del formato de contenedor en el parámetro guidContainerFormat . Si tiene una preferencia de proveedor para un lector de metadatos, puede pasar el GUID de su proveedor preferido en el parámetro pGuidVendor . Por ejemplo, si su empresa escribe controladores de metadatos y quiere usar su propio si está presente, puede pasar el GUID del proveedor. En la mayoría de los casos, simplemente pasaría NULL y dejaría que el sistema seleccione el lector de metadatos adecuado. Si solicita un proveedor específico y ese proveedor tiene instalado un lector de metadatos en el equipo, WIC devolverá el lector del proveedor. Sin embargo, si el proveedor solicitado no tiene instalado un lector de metadatos en el equipo y, si hay un lector de metadatos adecuado disponible, ese lector se devolverá aunque no sea del proveedor preferido. Si no hay ningún lector de metadatos en el equipo para el tipo de metadatos del bloque , el generador de componentes devolverá el controlador de metadatos desconocidos, que tratará el bloque de metadatos como un objeto binario grande (BLOB) y deserializará el bloque de metadatos del archivo sin ningún intento de analizarlo.

Para el parámetro dwOptions , realice una operación OR entre el WICPersistOptions adecuado con el WICMetadataCreationOptions adecuado. WiCPersistOptions describe cómo se diseña el contenedor. Little-endian es el valor predeterminado.

enum WICPersistOptions
{   
   WICPersistOptionDefault,
   WICPersistOptionLittleEndian,
   WICPersistOptionBigEndian,
   WICPersistOptionStrictFormat,
   WICPersistOptionNoCacheStream,
   WICPersistOptionPreferUTF8
};

WiCMetadataCreationOptions especifica si desea recuperar UnknownMetadataHandler si no se encuentra ningún lector de metadatos en el equipo que puede leer el formato de metadatos de un bloque determinado. WICMetadataCreationAllowUnknown es el valor predeterminado y siempre debe permitir la creación de UnknownMetadtataHandler. UnknownMetadataHandler trata los metadatos no reconocidos como BLOB. No puede analizarlo, pero lo escribe en la secuencia como un BLOB y lo conserva intacto cuando se escribe en la secuencia durante la codificación. Esto hace que sea seguro crear controladores de metadatos para los formatos de metadatos o metadatos propietarios que no se incluyen en el sistema. Dado que los metadatos se conservan intactos, aunque no haya ningún controlador presente en el equipo que lo reconozca, cuando se instale un controlador de metadatos adecuado más adelante, los metadatos seguirán estando ahí y se pueden leer. Si no permite la creación de UnknownMetadataHandler, la alternativa es descartar o sobrescribir metadatos no reconocidos. Se trata de una forma de pérdida de datos.

Nota

Si escribe su propio controlador de metadatos para metadatos propietarios, nunca debe incluir referencias a nada fuera del propio bloque de metadatos. Aunque UnknownMetadataHandler conserva los metadatos intactos, los metadatos se mueven cuando se editan los archivos y las referencias a cualquier elemento fuera de su propio bloque ya no serán válidos cuando esto suceda.

 

enum WICMetadataCreationOptions
{
   WICMetadataCreationDefault = 0x00000000,
   WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
   WICMetadataCreationFailUnknown = 0x00010000,
   WICMetadataCreationMask = 0xFFFF0000
};

El parámetro pIStream es la secuencia real que se va a descodificar. Antes de pasar la secuencia, debe buscar el principio del bloque de metadatos para el que solicita un lector. El lector de metadatos adecuado para el bloque de metadatos en la posición actual de IStream se devolverá en el parámetro ppiReader .

GetReaderByIndex

GetReaderByIndex devuelve el lector de metadatos en el índice solicitado de la colección.

Referencia

IWICMetadataBlockReader

Conceptual

Implementación de IWICBitmapFrameDecode

Implementación de IWICBitmapSourceTransform

Cómo escribir un CÓDEC de WIC-Enabled

Información general sobre el componente de creación de imágenes de Windows