Especificación del contenedor WebP

Introducción

WebP es un formato de imagen que usa (i) la codificación de fotogramas clave VP8 para comprimir los datos de imagen de forma con pérdida o (ii) la codificación WebP sin pérdida. Estos esquemas de codificación deben hacerlo más eficiente que los formatos anteriores, como JPEG, GIF y PNG. Está optimizado para permitir una transferencia de imágenes rápida en la red (por ejemplo, para sitios web). El formato WebP también tiene paridad de funciones (perfil de color, metadatos, animación, etc.) con otros formatos. En este documento, se describe la estructura de un archivo WebP.

El contenedor WebP (es decir, el contenedor RIFF para WebP) permite la compatibilidad de funciones más allá del caso de uso básico de WebP (es decir, un archivo que contiene una sola imagen codificada como un fotograma clave VP8). El contenedor WebP proporciona compatibilidad adicional con lo siguiente:

  • Compresión sin pérdida: Una imagen se puede comprimir sin pérdidas mediante el formato WebP sin pérdida.

  • Metadatos: Una imagen puede tener metadatos almacenados en formato de archivo de imagen intercambiable (Exif) o formato de Plataforma de metadatos extensible (XMP).

  • Transparencia: una imagen puede tener transparencia, es decir, un canal alfa.

  • Perfil de color: Una imagen puede tener un perfil de ICC incorporado como se describe en el Consorcio de colores internacional.

  • Animación: Una imagen puede tener varios fotogramas con pausas entre ellos, lo que la convierte en una animación.

Nombre

Se RECOMIENDA usar los siguientes tipos cuando se haga referencia al contenedor WebP:

Nombre del formato del contenedorWebP
Extensión del nombre del archivo.webp
Tipo de MIMEimagen/webp
Identificador de tipo de uniformeorg.webmproject.webp

Terminología y conceptos básicos

Las palabras clave "DEBE", "NO DEBE", "OBLIGATORIO", "DEBERÁ", "NO DEBERÍA", "NO DEBERÍA", "NO DEBERÍA", "RECOMENDADO", "NO SE RECOMIENDA", "MAYO" y "OPCIONAL" en este documento se deben interpretar como se describe en BCP 14, RFC 2119, RFC 8174, como y cuándo aparecen

Un archivo WebP contiene una imagen estática (es decir, una matriz codificada de píxeles) o una animación. De manera opcional, también puede contener información de transparencia, un perfil de color y metadatos. Nos referimos a la matriz de píxeles como el lienzo de la imagen.

La numeración de bits en diagramas de fragmentos comienza en 0 para el bit más importante ("MSB 0"), como se describe en RFC 1166.

A continuación, se incluyen términos adicionales usados en este documento:

Lector/escritor
El código que lee archivos WebP se conoce como lector, mientras que el código que los escribe se conoce como escritor.
Uint16
Un número entero de 16 bits, de tipo little-endian y sin firma.
Uint24
Es un número entero de 24 bits, de tipo little-endian y sin firma.
uint32
Un número entero de 32 bits, de tipo little-endian y sin firma.
FourCC
Un código de cuatro caracteres (FourCC) es un uint32 creado mediante la concatenación de cuatro caracteres ASCII en orden little-endian. Esto significa que "aaaa" (0x61616161) y "AAAA" (0x41414141) se tratan como diferentes FourCCs.
Basado en 1
Un campo de números enteros sin firma que almacena valores desplazados por -1, por ejemplo, ese campo almacenaría el valor 25 como 24.
ChunkHeader('ABCD')
Se usa para describir el encabezado FourCC y Chunk Size de los fragmentos individuales, en los que "ABCD" es el FourCC para el fragmento. El tamaño de este elemento es de 8 bytes.

Formato de archivo RIFF

El formato de archivo WebP se basa en el formato de documento RIFF (Resource Interchange File Format).

El elemento básico de un archivo RIFF es un fragmento. Consta de los siguientes elementos:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Chunk FourCC                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Chunk Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Chunk Payload                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fragmento de cuatro partes: 32 bits
Código ASCII de cuatro caracteres que se usa para la identificación de fragmentos.
Tamaño del fragmento: 32 bits (uint32)
Es el tamaño del fragmento en bytes, sin incluir este campo, el identificador del fragmento ni el padding.
Carga útil del fragmento: Tamaño del fragmento bytes
La carga útil de datos. Si el Tamaño del fragmento es impar, se agrega un solo byte de padding, que DEBE ser 0 a fin de cumplir con RIFF.

Nota: RIFF tiene una convención de que los FourCC con mayúsculas en mayúsculas son fragmentos estándar que se aplican a cualquier formato de archivo RIFF, mientras que los FourCC específicos para un formato de archivo son todos en minúscula. WebP no sigue esta convención.

Encabezado del archivo WebP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'R'      |      'I'      |      'F'      |      'F'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           File Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'W'      |      'E'      |      'B'      |      'P'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
"RIFF": 32 bits
Los caracteres ASCII “R”, “I”, “F” y “F”.
Tamaño del archivo: 32 bits (uint32)
Tamaño del archivo en bytes, a partir del desplazamiento 8. El valor máximo de este campo es de 2^32 menos 10 bytes y, por lo tanto, el tamaño completo de todo el archivo es de 4 GiB menos 2 bytes.
"WEBP": 32 bits
Los caracteres ASCII "W", "E", "B" y "P".

Un archivo WebP DEBE comenzar con un encabezado RIFF con el FourCC 'WEBP'. El tamaño del archivo en el encabezado es el tamaño total de los fragmentos que siguen más 4 bytes para el “WEBP” de FourCC. El archivo NO DEBE contener datos después de los datos especificados por File Size. Los lectores PUEDEN analizar esos archivos sin tener en cuenta los datos finales. Como el tamaño de cualquier fragmento es par, el tamaño proporcionado por el encabezado RIFF también es uniforme. El contenido de los fragmentos individuales se describe en las siguientes secciones.

Formato de archivo simple (con pérdida)

Este diseño DEBE usarse si la imagen requiere codificación con pérdida y no requiere transparencia ni otras funciones avanzadas que proporciona el formato extendido. Los archivos con este diseño son más pequeños y son compatibles con software más antiguo.

Formato de archivo WebP (con pérdida) simple:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        'VP8 ' Chunk                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Fragmento de VP8:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8 ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8 data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Datos de VP8: Tamaño de Chunk Size
Datos de flujo de bits VP8.

Ten en cuenta que el cuarto carácter del "VP8" de FourCC es un espacio ASCII (0x20).

La especificación del formato de flujo de bits VP8 se describe en la Guía de formato y decodificación de datos de VP8. Ten en cuenta que el encabezado del marco VP8 contiene el ancho y la altura del marco. Se supone que corresponde al ancho y la altura del lienzo.

En la especificación de VP8, se describe cómo decodificar la imagen al formato Y'CbCr. Para convertir a RGB, se DEBE usar la recomendación BT.601. Las aplicaciones PUEDEN usar otro método de conversión, pero los resultados visuales pueden diferir entre los decodificadores.

Formato de archivo simple (sin pérdidas)

Nota: Es posible que los lectores más antiguos no admitan archivos con el formato sin pérdida.

Este diseño DEBE usarse si la imagen requiere codificación sin pérdida (con un canal de transparencia opcional) y no requiere funciones avanzadas que proporciona el formato extendido.

Formato de archivo WebP simple (sin pérdidas):

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         'VP8L' Chunk                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Fragmento de "VP8L":

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8L')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8L data                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Datos de VP8L: Tamaño del fragmento bytes
Datos de flujo de bits VP8L.

La especificación actual del flujo de bits VP8L se puede encontrar en Formato de transmisión de bits sin pérdida de WebP. Ten en cuenta que el encabezado VP8L contiene el ancho y la altura de la imagen VP8L. Se supone que es el ancho y la altura del lienzo.

Formato de archivo extendido

Nota: Es posible que los lectores más antiguos no admitan archivos con el formato extendido.

Un archivo de formato extendido consiste en lo siguiente:

  • Un fragmento 'VP8X' con información sobre las funciones utilizadas en el archivo.

  • Un fragmento 'ICCP' opcional con un perfil de color.

  • Un fragmento opcional de "ANIMACIÓN" con datos de control de animación.

  • Datos de la imagen.

  • Un fragmento 'EXIF' opcional con metadatos EXIF.

  • Un fragmento 'XMP ' opcional con metadatos XMP.

  • Una lista opcional de fragmentos desconocidos.

En el caso de una imagen fija, los datos de la imagen constan de un solo fotograma, que se compone de lo siguiente:

En el caso de una imagen animada, los datos de la imagen constan de varios marcos. Puedes encontrar más detalles en la sección Animación.

Todos los fragmentos DEBEN colocarse en el mismo orden que el descrito anteriormente. Si aparece un fragmento en el lugar equivocado, el archivo no es válido, pero los lectores PUEDEN analizarlo y, además, ignorar los fragmentos que están desordenados.

Razón: Configurar el orden de los fragmentos debería permitir un análisis más rápido de los archivos. Por ejemplo, si un fragmento "ALPH" no aparece en su posición requerida, un decodificador puede optar por dejar de buscarlo. La regla para ignorar fragmentos tardíos debe hacer que los programas que deban realizar una búsqueda completa generen los mismos resultados que los que se detienen antes.

Encabezado de archivo WebP extendido:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   WebP file header (12 bytes)                 |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8X')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R|                   Reserved                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Canvas Width Minus One               |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...  Canvas Height Minus One    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Reservado (Rsv): 2 bits
DEBE ser 0. Los lectores DEBEN ignorar este campo.
Perfil de ICC (I): 1 bit
Establece si el archivo contiene un fragmento "ICCP".
Alfa (L): 1 bit
Establece si alguno de los fotogramas de la imagen contienen información de transparencia ("alfa").
Metadatos Exif (E): 1 bit
Establece si el archivo contiene metadatos EXIF.
Metadatos de XMP (X): 1 bit
Configura esta opción si el archivo contiene metadatos XMP.
Animación (A): 1 bit
Configura esta opción si es una imagen animada. Los datos en “ANIM” y “ANMF” deben usarse para controlar la animación.
Reservado (R): 1 bit
DEBE ser 0. Los lectores DEBEN ignorar este campo.
Reservado: 24 bits
DEBE ser 0. Los lectores DEBEN ignorar este campo.
Ancho del lienzo menos uno: 24 bits
Es el ancho del lienzo en píxeles basado en 1. El ancho real del lienzo es de 1 + Canvas Width Minus One.
Altura del lienzo menos uno: 24 bits
Altura del lienzo basada en 1 en píxeles. La altura real del lienzo es de 1 + Canvas Height Minus One.

El producto de Canvas Width y Canvas Height DEBE ser como máximo 2^32 - 1.

Las futuras especificaciones podrían agregar más campos. Los campos desconocidos se DEBEN ignorar.

Animación

Una animación se controla mediante fragmentos de "ANIM" y "ANMF".

Fragmento de "ANIM":

Para una imagen animada, este fragmento contiene los parámetros globales de la animación.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANIM')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Background Color                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Loop Count           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Color de fondo: 32 bits (uint32)
El color de fondo predeterminado del lienzo en orden de bytes [Blue, Green, Red, Alpha]. Este color PUEDE usarse para completar el espacio sin usar en el lienzo alrededor de los marcos, así como los píxeles transparentes del primer marco. El color de fondo también se usa cuando el método de eliminación es 1.

Nota:

  • El color de fondo PUEDE contener un valor alfa no opaco, incluso si la marca Alpha del fragmento "VP8X" no está configurada.

  • Las aplicaciones de visualización DEBEN tratar el valor de color de fondo como una pista y no son necesarias para usarlo.

  • El lienzo se borra al comienzo de cada bucle. El color de fondo PUEDE usarse para lograr esto.

Recuento de bucle: 16 bits (uint16)
Es la cantidad de veces que se repite indefinidamente la animación. Si es 0, significa infinamente.

Este fragmento DEBE aparecer si se establece la marca Animation en el fragmento 'VP8X'. Si la marca Animation no está configurada y este fragmento está presente, DEBE ignorarse.

Fragmento de "AnmF":

En el caso de las imágenes animadas, este fragmento contiene información sobre un solo marco. Si no se estableció la marca de animación, este fragmento NO DEBE estar presente.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANMF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Frame X                |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...          Frame Y            |   Frame Width Minus One     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...             |           Frame Height Minus One              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                 Frame Duration                |  Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Frame Data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Marco X: 24 bits (uint24)
La coordenada X de la esquina superior izquierda del marco es Frame X * 2.
Marco Y: 24 bits (uint24)
La coordenada Y de la esquina superior izquierda del marco es Frame Y * 2.
Ancho del marco menos uno: 24 bits (uint24)
Es el ancho del fotograma basado en 1. El ancho del marco es de 1 + Frame Width Minus One.
Altura del marco menos uno: 24 bits (uint24)
Altura del marco basada en 1. La altura del marco es 1 + Frame Height Minus One.
Duración del marco: 24 bits (uint24)
Es el tiempo de espera antes de mostrar el siguiente fotograma, en unidades de 1 milisegundo. Ten en cuenta que la implementación de la duración del marco de 0 (y, a menudo, <= 10) se define mediante la implementación. Muchas herramientas y navegadores asignan una duración mínima similar a la de los GIF.
Reservado: 6 bits
DEBE ser 0. Los lectores DEBEN ignorar este campo.
Método de fusión (B): 1 bit

Indica qué píxeles transparentes del marco actual se deben combinar con los píxeles correspondientes del lienzo anterior:

  • 0: Usa la mezcla alfa. Después de deshacerte del fotograma anterior, renderiza el fotograma actual en el lienzo con una combinación alfa (consulta a continuación). Si el fotograma actual no tiene un canal alfa, supón que el valor alfa es 255 y reemplaza el rectángulo de manera efectiva.

  • 1: No mezclar. Después de deshacerte del fotograma anterior, renderiza el fotograma actual en el lienzo reemplazando el rectángulo cubierto por el fotograma actual.

Método de eliminación (D): 1 bit

Indica cómo se debe tratar el fotograma actual después de que se haya mostrado (antes de renderizar el siguiente fotograma) en el lienzo:

  • 0: No desechar. No modifiques el lienzo.

  • 1: Se descarta el color de fondo. Completa el rectángulo del lienzo cubierto por el marco actual con el color de fondo especificado en el fragmento ANIMACIÓN.

Notas:

  • La eliminación de marcos solo se aplica al rectángulo de marcos, es decir, el rectángulo definido por el marco X, el marco Y, el ancho del marco y la altura del marco. Puede o no cubrir todo el lienzo.

  • Mezcla alfa:

    Dado que cada uno de los canales R, G, B y A es de 8 bits, y los canales RGB no se prepropagan por alfa, la fórmula para combinar "dst" en "src" es la siguiente:

    blend.A = src.A + dst.A * (1 - src.A / 255)
    if blend.A = 0 then
      blend.RGB = 0
    else
      blend.RGB =
          (src.RGB * src.A +
           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
    
  • La mezcla alfa DEBE realizarse en el espacio de color lineal teniendo en cuenta el perfil de color de la imagen. Si el perfil de color no está presente, se debe suponer que es RGB estándar (sRGB). (Ten en cuenta que sRGB también debe ser linealizado debido a un gamma de ~2.2).

Datos del marco: Tamaño del fragmento - 16 bytes

Consiste en lo siguiente:

Nota: La carga útil "ANMF", Frame Data anterior, consta de fragmentos individuales con relleno, como se describe en el formato de archivo RIFF.

Alfa

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ALPH')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C |     Alpha Bitstream...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Reservado (Rsv): 2 bits
DEBE ser 0. Los lectores DEBEN ignorar este campo.
Procesamiento previo (P): 2 bits

Estos bits informativos se usan para indicar el procesamiento previo que se realizó durante la compresión. El decodificador puede usar esta información para, por ejemplo, interpolar los valores o suavizar los gradientes antes de la visualización.

  • 0: Sin procesamiento previo.
  • 1: Reducción de nivel.

No es necesario que los decodificadores usen esta información de ninguna manera especificada.

Método de filtrado (F): 2 bits

Los métodos de filtrado que se utilizan se describen de la siguiente manera:

  • 0: Ninguna
  • 1: Filtro horizontal.
  • 2: Filtro vertical.
  • 3: Filtro de gradiente.

Para cada píxel, se filtra mediante los siguientes cálculos. Supongamos que los valores alfa que rodean la posición X actual están etiquetados como:

 C | B |
---+---+
 A | X |

Buscamos calcular el valor alfa en la posición X. Primero, se realiza una predicción según el método de filtrado:

  • Método 0: predictor = 0
  • Método 1: predictor = A
  • Método 2: predictor = B
  • Método 3: predictor = clip(A + B - C)

donde clip(v) es igual a:

  • 0 si v < 0,
  • 255 si v > 255, o
  • v de otra forma

El valor final se deriva si se agrega el valor descomprimido X al predictor y se usa la aritmética de modulo-256 para unir el rango [256..511] al [0..255]:

alpha = (predictor + X) % 256

Existen casos especiales para las posiciones de píxeles de la izquierda y de la parte superior. Por ejemplo, el valor superior izquierdo en la ubicación (0, 0) usa 0 como valor predictivo. En caso contrario:

  • Para los métodos de filtrado horizontal o de gradientes, se predicen los píxeles más a la izquierda en la ubicación (0, y) mediante la ubicación (0, y-1) justo arriba.
  • Para los métodos de filtrado vertical o de gradiente, se predicen los píxeles superiores en la ubicación (x, 0) mediante la ubicación (x-1, 0) a la izquierda.
Método de compresión (C): 2 bits

Método de compresión utilizado:

  • 0: Sin compresión.
  • 1: Se comprime con el formato WebP sin pérdida.
Flujo de bits alfa: Tamaño del fragmento: 1 bytes

Flujo de bits alfa codificado.

Este fragmento opcional contiene datos alfa codificados para este fotograma. Un marco que contiene un fragmento 'VP8L' NO DEBE contener este fragmento.

Razón: La información de transparencia ya forma parte del cierre de "VP8L".

Los datos del canal alfa se almacenan como datos sin procesar sin comprimir (cuando el método de compresión es "0") o se comprimen con el formato sin pérdida (cuando el método de compresión es "1").

  • Datos sin procesar: Consiste en una secuencia de bytes de longitud = ancho * alto, que contiene todos los valores de transparencia de 8 bits en orden de análisis.

  • Compresión de formato sin pérdida: La secuencia de bytes es una transmisión de imagen comprimida (como se describe en “Formato de flujo de bits WebP sin pérdida”) de dimensiones implícitas de ancho x alto. Es decir, esta transmisión de imágenes NO contiene encabezados que describan las dimensiones de la imagen.

    Razón: Las dimensiones ya son conocidas en otras fuentes, por lo que volver a almacenarlas sería redundante y podría generar errores.

    Una vez que la transmisión de imágenes se decodifica en los valores de color alfa, rojo, verde y azul (ARGB), según el proceso descrito en la especificación del formato sin pérdida, la información de transparencia se debe extraer del canal verde del cuadruplo ARGB.

    Razón: El canal verde admite pasos de transformación adicionales en la especificación, a diferencia de los otros canales, que pueden mejorar la compresión.

Bitstream (VP8/VP8L)

Este fragmento contiene datos de flujo de bits comprimidos para un solo fotograma.

Un fragmento de flujo de bits puede ser (i) un “fragmento VP8”, con “VP8” (ten en cuenta el espacio significativo de cuarto carácter) como su FourCC, o (ii) un fragmento ”VP8L”, utilizando "VP8L" como su FourCC.

Los formatos de los fragmentos “VP8” y “VP8L” se describen en las secciones Formato de archivo simple (con pérdida) y Formato de archivo simple (sin pérdida), respectivamente.

Perfil de color

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ICCP')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                       Color Profile                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Perfil de color: bytes del tamaño del fragmento
Perfil de ICC.

Este fragmento DEBE aparecer antes de los datos de la imagen.

DEBE haber al menos uno de estos fragmentos. Si hay más fragmentos de este tipo, es posible que los lectores los ignoren, excepto el primero. Para obtener más información, consulte la especificación de ICC.

Si este fragmento no está presente, se debe suponer que es sRGB.

Metadatos

Los metadatos pueden almacenarse en fragmentos "EXIF" o "XMP".

Debe haber como máximo un fragmento de cada tipo ("EXIF" y "XMP"). Si hay más fragmentos, PUEDEN ignorarlos, excepto el primero.

Los fragmentos se definen de la siguiente manera:

Fragmento de “EXIF”:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('EXIF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        Exif Metadata                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadatos Exif: Tamaño del fragmento bytes
Metadatos de imagen en formato Exif.

Fragmento de "XMP":

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('XMP ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        XMP Metadata                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadatos de XMP: Chunk Size bytes
Metadatos de imágenes en formato XMP.

Ten en cuenta que el cuarto carácter del "XMP" de FourCC es un espacio ASCII (0x20).

Puedes encontrar orientación adicional sobre el manejo de metadatos en los Lineamientos para el manejo de metadatos del grupo de trabajo de metadatos.

Fragmentos desconocidos

Un fragmento RIFF (descrito en la sección Formato de archivo RIFF), cuyo FourCC es diferente de cualquiera de los que se describen en este documento, se considera un fragmento desconocido.

Razón: Permitir fragmentos desconocidos permite aprovisionar una extensión futura del formato y también almacenar datos específicos de la aplicación.

Un archivo PUEDE contener fragmentos desconocidos:

Los lectores DEBEN ignorar estos fragmentos. Los escritores DEBEN conservarlos en su orden original (a menos que tengan la intención de modificar estos fragmentos).

Conjunto de lienzos de marcos

Aquí proporcionamos una descripción general de cómo un lector DEBE ensamblar un lienzo en el caso de una imagen animada.

El proceso comienza con la creación de un lienzo con las dimensiones proporcionadas en el fragmento "VP8X", Canvas Width Minus One + 1 píxeles de ancho por Canvas Height Minus One + 1 píxeles de alto. El campo Loop Count del fragmento ANIMACIÓN controla cuántas veces se repite el proceso de animación. Es Loop Count - 1 para valores Loop Count distintos de cero o infinito si Loop Count es cero.

Al comienzo de cada iteración de bucle, el lienzo se llena con el color de fondo del fragmento "ANIM" o un color definido por la aplicación.

Los fragmentos "ANMF" contienen marcos individuales ordenados de forma gráfica. Antes de renderizar cada fotograma, se aplica el Disposal method del fotograma anterior.

La renderización del marco decodificado comienza en las coordenadas cartesianas (2 * Frame X, 2 * Frame Y), con la esquina superior izquierda del lienzo como origen. Los píxeles de Frame Width Minus One + 1 de ancho por Frame Height Minus One + 1 píxeles de alto se renderizan en el lienzo mediante el Blending method.

El lienzo se muestra durante Frame Duration milisegundos. Esto continúa hasta que se muestren todos los fotogramas que proporcionó "ANMF". Se inicia una iteración de bucle nueva o, si se completaron todas, el lienzo queda en su estado final.

En el siguiente pseudocódigo, se ilustra el proceso de renderización. La notación VP8X.field hace referencia al campo del fragmento "VP8X" con la misma descripción.

assert VP8X.flags.hasAnimation
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
         background color ANIM.background_color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
  loop_count = ∞
frame_params ← nil
assert next chunk in image_data is ANMF
for loop = 0..loop_count - 1
  clear canvas to ANIM.background_color or application-defined color
  until eof or non-ANMF chunk
    frame_params.frameX = Frame X
    frame_params.frameY = Frame Y
    frame_params.frameWidth = Frame Width Minus One + 1
    frame_params.frameHeight = Frame Height Minus One + 1
    frame_params.frameDuration = Frame Duration
    frame_right = frame_params.frameX + frame_params.frameWidth
    frame_bottom = frame_params.frameY + frame_params.frameHeight
    assert VP8X.canvasWidth >= frame_right
    assert VP8X.canvasHeight >= frame_bottom
    for subchunk in 'Frame Data':
      if subchunk.tag == "ALPH":
        assert alpha subchunks not found in 'Frame Data' earlier
        frame_params.alpha = alpha_data
      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
        assert bitstream subchunks not found in 'Frame Data' earlier
        frame_params.bitstream = bitstream_data
    render frame with frame_params.alpha and frame_params.bitstream
      on canvas with top-left corner at (frame_params.frameX,
      frame_params.frameY), using Blending method
      frame_params.blendingMethod.
    canvas contains the decoded image.
    Show the contents of the canvas for
    frame_params.frameDuration * 1 ms.
    dispose_method = frame_params.disposeMethod

Diseños de archivo de ejemplo

Una imagen codificada con pérdida con alfa podría verse de la siguiente manera:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)

Una imagen codificada sin pérdidas puede verse de la siguiente manera:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- VP8L (lossless bitstream)
+- XYZW (unknown chunk)

Una imagen sin pérdida con un perfil de ICC y metadatos de XMP puede verse de la siguiente manera:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP  (metadata)

Una imagen animada con metadatos EXIF puede verse de la siguiente manera:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)