Especificación del contenedor WebP

Introducción

WebP es un formato de imagen que usa (i) la codificación de fotograma clave VP8 para comprimir datos de imagen con pérdidas o (ii) la codificación WebP sin pérdidas. Estos esquemas de codificación deben ser más eficientes que los formatos más antiguos, como JPEG, GIF y PNG. Está optimizada para una 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 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 de clave VP8). El contenedor WebP proporciona compatibilidad adicional para lo siguiente:

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

  • Metadatos: Una imagen puede tener metadatos almacenados en formato de Formato de archivo de imagen intercambiable (Exif) o Plataforma Extensible de Metadatos (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 lo describe el Consorcio Internacional de Color.

  • 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 de formato del contenedorWebP
Extensión del nombre del archivo.webp
Tipo MIMEimagen/WebP
Identificador de tipo uniformeorg.webmproject.webp

Terminología y conceptos básicos

Las palabras clave “DEBE”, “NO DEBE”, “OBLIGATORIO”, “DEBERÍA”, “NO DEBERÍA”, “DEBERÍA”, “NO DEBERÁ”, “RECOMENDADO”, “NO RECOMENDADO”, “MAYO” y “OPCIONAL” de este documento se deben interpretar como se describe en BCP 14 RFC 2119 RFC 8174 cuando aparecen en mayúscula, y solo cuando aparecen en mayúsculas.

Un archivo WebP contiene una imagen estática (es decir, una matriz de píxeles codificada) o una animación. De manera opcional, también puede contener información sobre 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 RFC 1166.

A continuación, se presentan algunos términos adicionales que se utilizan en este documento:

Lector/Escritor
El código que lee archivos WebP se conoce como un 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
Es un número entero de 24 bits, Little-endian sin firma.
uint32
Un número entero de 32 bits, Little-endian y sin firma.
FourCC
Un código de cuatro caracteres (FourCC) es un uint32 que se crea mediante la concatenación de 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 firma que almacena valores compensados por -1, por ejemplo, este campo almacenaría el valor 25 como 24.
ChunkHeader('ABCD')
Se usa para describir el encabezado FourCC y Chunk Size de fragmentos individuales, en el que “ABCD” es la 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. Consta de 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fragmento de FourCC: 32 bits
Código ASCII de cuatro caracteres que se usa para identificar los fragmentos.
Tamaño del bloque: 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: Chunk Size bytes
La carga útil de datos. Si el tamaño de división es impar, se agrega un solo byte de relleno, que DEBE ser 0 para cumplir con el formato RIFF.

Nota: RIFF tiene la convención de que los FourCC de 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 están en minúsculas. 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)
Es el tamaño del archivo en bytes, a partir del desplazamiento de 8. El valor máximo de este campo es de 2^32 menos 10 bytes y, por lo tanto, el tamaño del archivo completo es de 4 GiB menos 2 bytes como máximo.
“WEBP”: 32 bits
Los caracteres ASCII "W", "E", "B" y "P".

Un archivo WebP DEBE comenzar con un encabezado RIFF que contenga el formato 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 de "WEBP". El archivo NO DEBE contener ningún dato después de los datos especificados por File Size. Los lectores PUEDEN analizar estos archivos e ignorar los datos finales. Como el tamaño de cualquier fragmento es par, el tamaño que da el encabezado RIFF también lo es. 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 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Bloque '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 de división
Datos de transmisión de bits VP8.

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

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

La especificación de VP8 describe cómo decodificar la imagen al formato Y'CbCr. Para realizar la conversión a RGB, se DEBE usar la recomendación BT.601. Es posible que las aplicaciones usen 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 en el formato sin pérdidas.

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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Bloque '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 Chunk Size
Datos de flujo de bits de VP8L.

La especificación actual del flujo de bits VP8L se puede encontrar en Formato de flujo 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 ese es el ancho y el alto del lienzo.

Formato de archivo extendido

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

Los archivos de formato extendido consta de los siguientes elementos:

  • Un bloque "VP8X" con información sobre las funciones que se usaron en el archivo.

  • Un bloque "ICCP" opcional con un perfil de color.

  • Un bloque "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 de XMP.

  • Lista opcional de fragmentos desconocidos.

Para una imagen estática, los datos de imagen consisten en un solo marco, que se compone de lo siguiente:

En el caso de una imagen animada, los datos de imagen constan de varios marcos. 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 color, es decir, “VP8X”, “ICCP”, “ANIM”, “ANMF”, “ALPH”, “VP8” y “VP8L”, DEBEN aparecer en el orden que se describió antes. 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.

Razón: Los fragmentos necesarios para la reconstrucción deben aparecer primero en el archivo a fin de 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
Establece si el archivo contiene un fragmento "ICCP".
Alfa (L): 1 bit
Establece si alguno de los fotogramas de la imagen contiene información de transparencia ("alfa").
Metadatos EXIF (E): 1 bit
Indica si el archivo contiene metadatos EXIF.
Metadatos de XMP (X): 1 bit
Se establece si el archivo contiene metadatos de XMP.
Animación (A): 1 bit
Establece si se trata de una imagen animada. Los datos en los fragmentos "ANIM" y "ANMF" deberían 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 basado en 1 en píxeles. El ancho real del lienzo es de 1 + Canvas Width Minus One.
Altura del lienzo menos uno: 24 bits
Es la altura del lienzo basada en 1 en píxeles. La altura real del lienzo es de 1 + Canvas Height Minus One.

Los productos Canvas Width y Canvas Height DEBEN tener como máximo 2^32 - 1.

Es posible que las especificaciones futuras agreguen más campos. Los campos desconocidos DEBEN ignorarse.

Animación

Una animación es controlada por bloques "ANIM" y "ANMF".

Bloque de '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)
El color de fondo predeterminado del lienzo en orden de bytes [azul, verde, rojo, alfa]. Este color PUEDE usarse para llenar el espacio sin usar en el lienzo alrededor de los marcos, 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.

Nota:

  • Es posible que el color de fondo contenga un valor alfa no opaco, incluso si no se configura la marca Alpha en el bloque "VP8X".

  • Las aplicaciones de visualización DEBEN tratar el valor del color de fondo como una sugerencia y no es necesario que lo usen.

  • Se borra el lienzo al comienzo de cada bucle. Se puede usar el color de fondo para lograrlo.

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

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

Bloque 'ANMF':

En el caso de las imágenes animadas, este bloque contiene información sobre un solo fotograma. Si la marca de animación no está configurada, 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 marco basado en 1. El ancho del marco es de 1 + Frame Width Minus One.
Altura del marco menos uno: 24 bits (uint24)
Es la altura del marco basada en 1. La altura del marco es 1 + Frame Height Minus One.
Duración de trama: 24 bits (uint24)
Es el tiempo que se debe esperar antes de mostrar el siguiente fotograma, en unidades de 1 milisegundo. Ten en cuenta que la implementación define la interpretación de la duración del fotograma de 0 (y, a menudo, <= 10). 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 qué tan transparentes deben combinarse los píxeles del marco actual con los píxeles correspondientes del lienzo anterior:

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

  • 1: No mezclar. Después de descartar el fotograma anterior, reemplaza el rectángulo que cubre el fotograma actual para renderizar el actual en el lienzo.

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

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

  • 0: No deseche. Deja el lienzo tal como está.

  • 1: Quita el color de fondo. Rellena el rectángulo en el lienzo cubierto por el marco actual con el color de fondo especificado en el bloque "ANIM".

Notas:

  • La eliminación del marco solo se aplica al rectángulo del marco, es decir, al rectángulo definido por el marco X, el marco Y, el ancho del marco y la altura del marco. 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 están multiplicados previamente 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 combinación alfa SE DEBE realizar 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 supondrá el valor RGB estándar (sRGB). (Ten en cuenta que sRGB también debe ser linealizado debido a un gamma de ~2.2).

Datos de fotogramas: Chunk Size - 16 bytes

Consiste en lo siguiente:

Nota: La carga útil de “ANMF”, Frame Data, 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, por ejemplo, para interpolar los valores o suavizar los gradientes antes de que se muestren.

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

Los decodificadores no necesitan usar esta información de ninguna manera especificada.

Método de filtro (F): 2 bits

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

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

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

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

El objetivo es 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
  • en caso contrario

El valor final se deriva cuando se agrega el valor descomprimido X al predictor y se usa la aritmética módulo-256 para unir el rango [256..511] en el rango [0..255]:

alpha = (predictor + X) % 256

Existen casos especiales para las posiciones de los píxeles que se encuentran en el extremo izquierdo y el superior. Por ejemplo, el valor de la esquina superior izquierda en la ubicación (0, 0) usa 0 como valor del predictor. En caso contrario:

  • Para los métodos de filtrado horizontal o por gradiente, los píxeles más a la izquierda en la ubicación (0, y) se predicen mediante la ubicación (0, y-1) justo arriba.
  • Para los métodos de filtrado vertical o por gradiente, los píxeles superiores en la ubicación (x, 0) se predicen mediante 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 usa es el siguiente:

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

Flujo de bits alfa codificado.

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

Razón: La información sobre transparencia ya forma parte del segmento "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 mediante el formato sin pérdidas (cuando el método de compresión es "1").

  • Datos sin procesar: Consisten en una secuencia de bytes de longitud = ancho * altura, 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 un flujo de imágenes comprimida (como se describe en "Formato de flujo de bits sin pérdida de WebP") con dimensiones implícitas de ancho x alto. Es decir, este flujo de imágenes NO contiene ningún encabezado que describa las dimensiones de la imagen.

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

    Una vez que la transmisión de imágenes se decodifique en valores de color Alfa, rojo, verde, azul (ARGB), siguiendo el proceso descrito en la especificación de formato sin pérdida, la información de transparencia debe extraerse del canal verde del cuadrupleto ARGB.

    Razón: El canal verde cuenta con 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", con "VP8" (ten en cuenta el espacio significativo de cuatro caracteres) como su FourCC, o (ii) un fragmento "VP8L", con "VP8L" como su FourCC.

Los formatos de los fragmentos “VP8” y “VP8L” son como 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 de Chunk Size
Perfil de ICC.

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

DEBERÍA haber, como máximo, uno de esos fragmentos. Si hay más fragmentos de este tipo, los lectores PUEDEN ignorar todos, excepto el primero. Consulte la especificación de la ICC para obtener más información.

Si este fragmento no está presente, se DEBE suponer sRGB.

Metadatos

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

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

Los fragmentos se definen de la siguiente manera:

Bloque '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 de división bytes
Metadatos de imagen en formato EXIF

Bloque '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: Tamaño de división bytes
Metadatos de imagen en formato XMP

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

Puedes encontrar más orientación sobre el manejo de metadatos en el artículo “Guidelines for Handling Metadata” 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 fragmentos descritos en este documento se considera un fragmento desconocido.

Razón: Permitir fragmentos desconocidos proporciona una disposición para futuras extensiones 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 de modificar estos fragmentos específicamente).

Ensamblaje de lienzos desde marcos

A continuación, se proporciona una descripción general de cómo un lector DEBE armar 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", con Canvas Width Minus One + 1 píxeles de ancho por Canvas Height Minus One + 1 píxeles de alto. El campo Loop Count del bloque "ANIM" controla cuántas veces se repite el proceso de animación. Este es Loop Count - 1 para valores Loop Count distintos de cero o infinito si Loop Count es cero.

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

Los fragmentos “ANMF” contienen marcos individuales que se muestran en orden de visualización. 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) y usa la esquina superior izquierda del lienzo como el origen. Frame Width Minus One + 1 píxeles de ancho por Frame Height Minus One + 1 píxeles de alto se renderizan en el lienzo con Blending method.

El lienzo se muestra durante Frame Duration milisegundos. Esto continúa hasta que se muestran todos los fotogramas proporcionados por fragmentos "ANMF". Se inicia una iteración de bucle nueva 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.
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
    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 archivo

Una imagen codificada con pérdidas y alfa puede verse de la siguiente manera:

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

Una imagen con codificación 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 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 de EXIF podría tener el siguiente aspecto:

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)