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 sin pérdida de WebP. Estos esquemas de codificación deberían hacerlo más eficiente que los formatos más antiguos, como JPEG, GIF y PNG. Está optimizado para la transferencia rápida de imágenes a través de 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 con 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 de WebP proporciona compatibilidad adicional con lo siguiente:

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

  • Metadatos: Una imagen puede tener metadatos almacenados en formato de archivo de imagen intercambiable (Exif) o en 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 ICC incorporado, como lo describe el International Color Consortium.

  • 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 hace referencia al contenedor WebP:

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

Terminología y conceptos básicos

Las palabras clave “DEBER”, “NO DEBER”, “OBLIGATORIO”, “DEBES”, “NO DEBES”, “DEBES HACER”, “NO DEBES HACER”, “RECOMENDADO”, “NO RECOMENDADO”, “PUEDES” y “OPCIONAL” en este documento se deben interpretar como se describe en el BCP 14 RFC 2119 RFC 8174 cuando, y solo cuando, aparecen en mayúsculas, como se muestra aquí.

Un archivo WebP contiene una imagen fija (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 los diagramas de fragmentos comienza en 0 para el bit más significativo ("MSB 0"), como se describe en la RFC 1166.

A continuación, se incluyen términos adicionales que se usan 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, little-endian y sin firma.
uint24
Un número entero sin firma de 24 bits.
uint32
Un número entero de 32 bits sin firma y orden de bytes little endian.
FourCC
Un código de cuatro caracteres (FourCC) es un uint32 que se crea concatenando cuatro caracteres ASCII en orden little-endian. Esto significa que "aaaa" (0x61616161) y "AAAA" (0x41414141) se tratan como FourCCs diferentes.
Basado en 1
Un campo de número entero sin firmar que almacena valores compensados por -1. Por ejemplo, un campo de este tipo almacenaría el valor 25 como 24.
ChunkHeader('ABCD')
Se usa para describir los encabezados FourCC y Chunk Size de fragmentos individuales, en los que “ABCD” es el FourCC del 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 (formato de archivo de intercambio de recursos).

El elemento básico de un archivo RIFF es un fragmento. Consiste en lo siguiente:

 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fragmentación FourCC: 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 en bytes
La carga útil de datos. Si el Tamaño del fragmento es impar, se agrega un solo byte de relleno, que DEBE ser 0 para cumplir con RIFF.

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

Encabezado de 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”, “F”.
Tamaño del archivo: 32 bits (uint32)
Es el tamaño del archivo en bytes, comenzando con el desplazamiento 8. El valor máximo de este campo es 2^32 menos 10 bytes y, por lo tanto, el tamaño de todo el archivo es de, como máximo, 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 FourCC “WEBP”. El archivo NO DEBE contener datos después de los datos especificados por Tamaño del archivo. Los lectores PUEDEN analizar esos archivos, ignorando los datos finales. Como el tamaño de cualquier fragmento es par, el tamaño que proporciona el encabezado RIFF también es par. El contenido de los fragmentos individuales se describe en las siguientes secciones.

Formato de archivo simple (con pérdida)

SE DEBE usar este diseño 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 simple (con pérdida):

 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 “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: Bytes de Tamaño del fragmento
Datos de flujo de bits VP8.

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

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

La especificación de VP8 describe cómo decodificar la imagen en 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érdida)

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

SE DEBE usar este diseño 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 "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: Bytes de Tamaño del fragmento
Datos de flujo de bits de VP8L.

La especificación actual del flujo de bits VP8L se puede encontrar en WebP Lossless Bitstream Format. Ten en cuenta que el encabezado VP8L contiene el ancho y la altura de la imagen de 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 consta de 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 "ANIM" opcional con datos de control de animación.

  • Datos de imágenes.

  • Un fragmento "EXIF" opcional con metadatos EXIF

  • Un fragmento "XMP" opcional con metadatos XMP

  • Es una lista opcional de fragmentos desconocidos.

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

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

Todos los fragmentos necesarios para la reconstrucción y la corrección de colores, es decir, "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" y "VP8L", DEBEN aparecer en el orden descrito anteriormente. Los lectores DEBEN fallar cuando los fragmentos necesarios para la reconstrucción y la corrección de colores están desordenados.

Es POSIBLE que los metadatos y los fragmentos desconocidos aparezcan desordenados.

Razonamiento: Los fragmentos necesarios para la reconstrucción deben aparecer primero en el archivo para permitir que un lector comience a decodificar una imagen antes de recibir todos los datos. Una aplicación puede beneficiarse de variar el orden de los metadatos y los fragmentos personalizados para que se adapten a la implementación.

Encabezado del 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 ICC (I): 1 bit
Se establece si el archivo contiene un fragmento "ICCP".
Alfa (L): 1 bit
Se establece si alguno de los fotogramas de la imagen contiene información de transparencia ("alfa").
Metadatos EXIF (E): 1 bit
Se establece si el archivo contiene metadatos Exif.
Metadatos XMP (X): 1 bit
Establece si el archivo contiene metadatos XMP.
Animación (A): 1 bit
Establece si se trata de una imagen animada. Los datos de los fragmentos "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
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 en píxeles basada en 1. La altura real del lienzo es 1 + Canvas Height Minus One.

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

Es posible que en especificaciones futuras se agreguen más campos. SE DEBEN OBTENER los campos desconocidos.

Animación

Una animación está controlada por fragmentos "ANIM" y "ANMF".

Fragmento "ANIM":

En el caso de 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)
Es el color de fondo predeterminado del lienzo en orden de bytes [azul, verde, rojo, alfa]. SE PUEDE usar este color para completar el espacio sin usar en el lienzo alrededor de los fotogramas, así como los píxeles transparentes del primer fotograma. El color de fondo también se usa cuando el método de eliminación es 1.

Notas:

  • El color de fondo PUEDE contener un valor alfa no opaco, incluso si no se establece la marca Alpha en el fragmento “VP8X”.

  • Las aplicaciones de visualización DEBEN tratar el valor del color de fondo como una sugerencia y no necesitan usarlo.

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

Recuento de bucles: 16 bits (uint16)
Es la cantidad de veces que se debe repetir la animación. Si es 0, significa de forma ilimitada.

Este bloque DEBE aparecer si se configura la marca Animation en el fragmento "VP8X". Si no se establece la marca Animation y este fragmento está presente, se DEBE ignorar.

Fragmento "ANMF":

En el caso de las imágenes animadas, este bloque contiene información sobre un único fotograma. Si no se establece 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.
Y de fotogramas: 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 marco basado en 1. El ancho del marco es 1 + Frame Width Minus One.
Altura de la trama menos uno: 24 bits (uint24)
Es la altura basada en 1 del marco. La altura del marco es 1 + Frame Height Minus One.
Duración del fotograma: 24 bits (uint24)
Es el tiempo de espera antes de mostrar el siguiente fotograma, en unidades de 1 milisegundo. Ten en cuenta que la interpretación de la duración del fotograma de 0 (y, a menudo, <= 10) la define 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 combinación (B): 1 bit

Indica cómo se deben combinar los píxeles transparentes de la fotograma actual con los píxeles correspondientes del lienzo anterior:

  • 0: Usa la compaginación alfa. Después de descartar el fotograma anterior, renderiza el fotograma actual en el lienzo con la compaginación alfa (consulta a continuación). Si el fotograma actual no tiene un canal alfa, supone que el valor alfa es 255, lo que reemplaza al rectángulo.

  • 1: No combinar. Después de descartar el 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 muestra (antes de renderizar el siguiente fotograma) en el lienzo:

  • 0: No se debe descartar. Deja el lienzo como está.

  • 1: Se descarta el color de fondo. Rellena el rectángulo en el lienzo cubierto por el fotograma actual con el color de fondo especificado en el fragmento "ANIM".

Notas:

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

  • Combinación alfa:

    Dado que cada uno de los canales R, G, B y A es de 8 bits, y los canales RGB no se multiplican 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 compaginación alfa DEBE realizarse en el espacio de color lineal, teniendo en cuenta el perfil de color de la imagen. Si no está presente el perfil de color, se debe suponer que es RGB estándar (sRGB). (Ten en cuenta que sRGB también debe linealizarse debido a una gamma de alrededor de 2.2).

Datos de trama: Tamaño del fragmento de bytes - 16

Consiste en lo siguiente:

Nota: La carga útil "ANMF", datos de trama, consta de fragmentos rellenos individuales, 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, suavizar los gradientes o difuminar los valores antes de la visualización.

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

Los decodificadores no están obligados a usar esta información de ninguna manera especificada.

Método de filtrado (F): 2 bits

Los métodos de filtrado que se usan se describen a continuación:

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

Para cada píxel, el filtrado se realiza mediante los siguientes cálculos. Supongamos que los valores alfa que rodean la posición X actual están etiquetados de la siguiente manera:

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

Buscamos calcular el valor alfa en la posición X. En primer lugar, 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 lo siguiente:

  • 0 si v < 0,
  • 255 si v > 255
  • v de lo contrario

Para obtener el valor final, se agrega el valor descomprimido X al predictor y se usa la aritmética de módulo 256 para unir el rango [256..511] al de [0..255]:

alpha = (predictor + X) % 256

Hay casos especiales para las posiciones de píxeles más a la izquierda y más arriba. Por ejemplo, el valor de la esquina superior izquierda en la ubicación (0, 0) usa 0 como valor del predictor. En caso contrario:

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

El método de compresión que se usó:

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

Flujo de bits alfa codificado.

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

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

Los datos del canal alfa se almacenan como datos sin procesar sin comprimir (cuando el método de compresión es “0”) o comprimidos 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 × altura, que contiene todos los valores de transparencia de 8 bits en orden de escaneo.

  • Compresión de formato sin pérdida: La secuencia de bytes es un flujo de imágenes comprimido (como se describe en "WebP Lossless Bitstream Format") de dimensiones implícitas de ancho × alto. Es decir, este flujo de imágenes NO contiene encabezados que describan las dimensiones de la imagen.

    Justificación: Las dimensiones ya se conocen de otras fuentes, por lo que almacenarlas de nuevo sería redundante y propenso a errores.

    Una vez que el flujo de imágenes se decodifica en valores de color alfa, rojo, verde y azul (ARGB), siguiendo el proceso descrito en la especificación del formato sin pérdidas, la información de transparencia se debe extraer del canal verde del cuádruple ARGB.

    Motivación: Al canal verde se le permiten pasos de transformación adicionales en la especificación, a diferencia de los otros canales, que pueden mejorar la compresión.

Flujo de bits (VP8/VP8L)

Este fragmento contiene datos de flujo de bits comprimidos para una sola trama.

Un fragmento de flujo de bits puede ser (i) un fragmento "VP8", que usa "VP8" (observa el espacio significativo del cuarto carácter) como su FourCC, o (ii) un fragmento "VP8L", que usa "VP8L" como su FourCC.

Los formatos de los fragmentos "VP8" y "VP8L" son los que 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: Tamaño del fragmento en bytes
Perfil ICC.

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

DEBE haber un máximo de un fragmento de este tipo. Si hay más fragmentos de este tipo, los lectores PUEDEN ignorarlos todos, excepto el primero. Consulta las especificaciones del ICC para obtener más información.

Si no está presente, SE DEBE suponer que es sRGB.

Metadatos

Los metadatos se pueden almacenar en fragmentos "EXIF" o "XMP".

DEBE haber un máximo de un fragmento de cada tipo ("EXIF" y "XMP"). Si hay más fragmentos de este tipo, los lectores PUEDEN ignorarlos todos, excepto el primero.

Los fragmentos se definen de la siguiente manera:

Fragmento "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 en bytes
Metadatos de imagen en formato Exif.

Fragmento "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 XMP: Tamaño del fragmento de bytes
Son metadatos de imagen en formato XMP.

Ten en cuenta que el cuarto carácter del FourCC "XMP" 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 (que se describe en la sección Formato de archivo RIFF) cuyo FourCC es diferente de cualquiera de los fragmentos descritos en este documento se considera un fragmento desconocido.

Justificación: Permitir fragmentos desconocidos proporciona una previsión para la extensión futura del formato y también permite el almacenamiento de 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 específica de modificar estos fragmentos).

Ensamblado de lienzos a partir 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 indicadas en el fragmento "VP8X", que tiene 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 "ANIM" controla cuántas veces se repite el proceso de animación. Es Loop Count - 1 para valores de Loop Count distintos de cero o infinito si Loop Count es cero.

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

Los fragmentos de “ANMF” contienen marcos individuales ordenados en orden de visualización. Antes de renderizar cada fotograma, se aplica el Disposal method del fotograma anterior.

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

El lienzo se muestra durante Frame Duration milisegundos. Esto continúa hasta que se muestran todos los fotogramas que proporcionan los fragmentos "ANMF". Luego, se comienza una nueva iteración del bucle o el lienzo queda en su estado final si se completaron todas las iteraciones.

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

VP8X.flags.hasAnimation MUST be TRUE
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
         background color ANIM.background_color or
         application-defined color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
  loop_count = ∞
frame_params ← nil
next chunk in image_data is ANMF MUST be TRUE
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
    VP8X.canvasWidth >= frame_right MUST be TRUE
    VP8X.canvasHeight >= frame_bottom MUST be TRUE
    for subchunk in 'Frame Data':
      if subchunk.tag == "ALPH":
        alpha subchunks not found in 'Frame Data' earlier MUST be
          TRUE
        frame_params.alpha = alpha_data
      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
        bitstream subchunks not found in 'Frame Data' earlier MUST
          be TRUE
        frame_params.bitstream = bitstream_data
    apply dispose_method.
    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

Ejemplos de diseños de archivos

Una imagen con codificación con pérdida y alfa puede verse de la siguiente manera:

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

Una imagen codificada sin pérdida 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 ICC y metadatos XMP puede ser como la siguiente:

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)