Especificação de contêiner WebP

Introdução

WebP é um formato de imagem que usa (i) a codificação de frame-chave VP8 para compactar dados de imagem com perda ou (ii) a codificação WebP sem perda. Esses esquemas de codificação o tornam mais eficiente do que formatos mais antigos, como JPEG, GIF e PNG. Ele é otimizado para transferência rápida de imagens pela rede, por exemplo, para sites. O formato WebP tem paridade de recursos (perfil de cor, metadados, animação etc.) com outros formatos. Este documento descreve a estrutura de um arquivo WebP.

O contêiner WebP (ou seja, o contêiner RIFF para WebP) permite o suporte a recursos além do caso de uso básico do WebP, ou seja, um arquivo que contém uma única imagem codificada como um frame-chave VP8. O contêiner do WebP oferece mais suporte ao seguinte:

  • Compactação sem perdas: uma imagem pode ser compactada sem perdas usando o Formato WebP sem perdas.

  • Metadados: uma imagem pode ter metadados armazenados no formato de arquivo de imagem intercambiável (Exif, na sigla em inglês) ou no formato Extensible Metadata Platform (XMP).

  • Transparência: uma imagem pode ter transparência, ou seja, um canal alfa.

  • Perfil de cor: uma imagem pode ter um perfil ICC incorporado, conforme descrito pelo International Color Consortium.

  • Animação: uma imagem pode ter vários frames com pausas entre eles, o que a transforma em uma animação.

Nomeação

É RECOMENDADO usar os seguintes tipos ao se referir ao contêiner WebP:

Nome do formato do contêinerWebP
Extensão do nome de arquivo.webp
Tipo MIMEimagem/webp
Identificador de tipo uniformeorg.webmproject.webp

Terminologia e conceitos básicos

As palavras-chave "PRECISA", "NÃO PODE", "OBRIGATÓRIO", "DEVE", "NÃO DEVE", "DEVE", "NÃO DEVE", "RECOMENDADO", "NÃO RECOMENDADO", "PODE" e "OPCIONAL" neste documento devem ser interpretadas conforme descrito em BCP 14 RFC 2119 RFC 8174, somente quando elas aparecem aqui em maiúsculas.

Um arquivo WebP contém uma imagem estática, ou seja, uma matriz codificada de pixels, ou uma animação. Opcionalmente, também pode conter informações de transparência, um perfil de cor e metadados. Chamamos a matriz de pixels como a tela da imagem.

A numeração de bits nos diagramas de blocos começa em 0 para o bit mais significativo ("MSB 0"), conforme descrito na RFC 1166 (em inglês).

Veja abaixo os termos adicionais usados neste documento:

Leitor/gravador
O código que lê arquivos WebP é conhecido como leitor, e o código que os grava é chamado de gravador.
uint16
Um número inteiro não assinado de 16 bits.
uint24
Um número inteiro não assinado de 24 bits.
uint32
Um número inteiro não assinado de 32 bits.
FourCC
Um código de quatro caracteres (FourCC, na sigla em inglês) é um uint32 criado pela concatenação de quatro caracteres ASCII em ordem few-endian. Isso significa que "aaaa" (0x61616161) e "AAAA" (0x41414141) são tratados como FourCCs diferentes.
Com base em 1
Um campo de número inteiro sem assinatura que armazena valores deslocados por -1, por exemplo, esse campo armazenaria o valor 25 como 24.
ChunkHeader('ABCD')
Usado para descrever os cabeçalhos FourCC e Chunk Size de partes individuais, em que "ABCD" é o FourCC do bloco. O tamanho desse elemento é 8 bytes.

Formato de arquivo RIFF

O formato de arquivo WebP é baseado no formato de documento RIFF (Resource Interchange File Format).

O elemento básico de um arquivo RIFF é um bloco. Ela consiste em:

 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
FourCC em bloco: 32 bits
Código ASCII de quatro caracteres usado para identificação de blocos.
Tamanho do fragmento: 32 bits (uint32)
O tamanho do bloco em bytes, sem incluir esse campo, o identificador do bloco ou o padding.
Payload do bloco: Chunk Size bytes
O payload de dados. Se Chunk Size for ímpar, um único byte de padding, que PRECISA ser 0 para se adequar ao RIFF, será adicionado.

Observação:o RIFF tem uma convenção de que os FourCCs em letras maiúsculas são blocos padrão que se aplicam a qualquer formato de arquivo RIFF, enquanto os FourCCs específicos de um formato de arquivo são todos minúsculos. o formato WebP não segue essa convenção.

Cabeçalho do arquivo 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
Os caracteres ASCII "R", "I", "F" e "F".
Tamanho do arquivo: 32 bits (uint32)
O tamanho do arquivo em bytes, começando no deslocamento 8. O valor máximo desse campo é 2^32 menos 10 bytes. Portanto, o tamanho do arquivo inteiro é de, no máximo, 4 GiB menos 2 bytes.
"WEBP": 32 bits
Os caracteres ASCII "W", "E", "B" e "P".

Um arquivo WebP PRECISA começar com um cabeçalho RIFF com o "WEBP" do FourCC. O tamanho do arquivo no cabeçalho é o tamanho total dos blocos que seguem mais 4 bytes do FourCC "WEBP". O arquivo NÃO DEVE conter dados depois dos dados especificados em Tamanho do arquivo. Os leitores PODEM analisar esses arquivos, ignorando os dados à direita. Como o tamanho de qualquer fragmento é par, o tamanho fornecido pelo cabeçalho RIFF também é uniforme. O conteúdo de blocos individuais é descrito nas seções a seguir.

Formato de arquivo simples (com perda)

Esse layout DEVE ser usado se a imagem exigir codificação com perda e não exigir transparência ou outros recursos avançados fornecidos pelo formato estendido. Os arquivos com esse layout são menores e têm suporte de softwares mais antigos.

Formato de arquivo WebP simples (com perda):

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

Parte "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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
dados VP8: Chunk Size bytes
Dados de bitstream VP8.

O quarto caractere no FourCC "VP8" é um espaço ASCII (0x20).

A especificação do formato de bitstream VP8 é descrita no Guia de formato e decodificação de dados VP8. Observe que o cabeçalho do frame VP8 contém a largura e a altura do frame VP8. Supõe-se a largura e a altura da tela.

A especificação VP8 descreve como decodificar a imagem no formato Y'CbCr. Para converter para RGB, a recomendação BT.601 DEVE ser usada. Os aplicativos PODEM usar outro método de conversão, mas os resultados visuais podem ser diferentes entre os decodificadores.

Formato de arquivo simples (sem perdas)

Observação:leitores mais antigos podem não ser compatíveis com arquivos que usam o formato sem perdas.

Esse layout DEVE ser usado se a imagem exigir codificação sem perdas (com um canal de transparência opcional) e não exigir recursos avançados fornecidos pelo formato estendido.

Formato de arquivo WebP simples (sem perdas):

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

Parte "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dados VP8L: Chunk Size bytes
Dados de bitstream VP8L.

A especificação atual do bitstream VP8L pode ser encontrada em Formato de bitstream sem perda WebP (link em inglês). Observe que o cabeçalho VP8L contém a largura e a altura da imagem VP8L. Ela é considerada a largura e a altura da tela.

Formato de arquivo estendido

Observação:leitores mais antigos podem não ser compatíveis com arquivos que usam o formato estendido.

Um arquivo de formato estendido consiste em:

  • Um bloco "VP8X" com informações sobre os recursos usados no arquivo.

  • Um fragmento "ICCP" opcional com um perfil de cor.

  • Um fragmento "ANIM" opcional com dados de controle de animação.

  • Dados da imagem.

  • Um bloco "EXIF" opcional com metadados Exif.

  • Um fragmento "XMP" opcional com metadados XMP.

  • Uma lista opcional de blocos desconhecidos.

Para uma imagem estática, os dados da imagem consistem em um único frame, que é composto de:

Para uma imagem animada, os dados da imagem consistem em vários frames. Mais detalhes sobre frames podem ser encontrados na seção Animação.

Todos os fragmentos necessários para reconstrução e correção de cor, "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" e "VP8L", PRECISAM aparecer na ordem descrita anteriormente. Os leitores DEVEM falhar quando as partes necessárias para reconstrução e correção de cor estão fora de ordem.

Os metadados e blocos desconhecidos PODEM aparecer fora de ordem.

Lógica:os blocos necessários para a reconstrução precisam aparecer primeiro no arquivo para permitir que um leitor comece a decodificar uma imagem antes de receber todos os dados. Um aplicativo pode se beneficiar da variação da ordem dos metadados e dos blocos personalizados de acordo com a implementação.

Cabeçalho do arquivo WebP estendido:

 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
PRECISA ser 0. Os leitores PRECISAM ignorar esse campo.
Perfil ICC (I): 1 bit
Define se o arquivo contém um bloco "ICCP".
Alfa (L): 1 bit
Define se algum dos frames da imagem contém informações de transparência ("alpha").
Metadados EXIF (E): 1 bit
Define se o arquivo contém metadados Exif.
Metadados XMP (X): 1 bit
Define se o arquivo contém metadados XMP.
Animação (A): 1 bit
Define se a imagem for animada. Os dados em fragmentos "ANIM" e "ANMF" precisam ser usados para controlar a animação.
Reservado (R): 1 bit
PRECISA ser 0. Os leitores PRECISAM ignorar esse campo.
Reservado: 24 bits
PRECISA ser 0. Os leitores PRECISAM ignorar esse campo.
Largura da tela menos um: 24 bits
Largura
com base em 1 da tela em pixels. A largura real da tela é 1 + Canvas Width Minus One.
Altura da tela menos um: 24 bits
Altura
com base em 1 da tela em pixels. A altura real da tela é 1 + Canvas Height Minus One.

O produto de Largura da tela e Altura da tela PRECISA ter no máximo 2^32 - 1.

Especificações futuras podem adicionar mais campos. Os campos desconhecidos PRECISAM ser ignorados.

Animação

Uma animação é controlada por blocos "ANIM" e "ANMF".

Pedaço "ANIM":

Para uma imagem animada, esse bloco contém os parâmetros globais da animação.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Cor do plano de fundo: 32 bits (uint32)
A cor padrão do plano de fundo da tela na ordem de bytes [Azul, Verde, Vermelho, Alfa]. Essa cor PODE ser usada para preencher o espaço não utilizado na tela ao redor dos frames, bem como os pixels transparentes do primeiro frame. A cor do plano de fundo também é usada quando o método de descarte é 1.

Observação:

  • A cor de fundo PODE conter um valor alfa não opaco, mesmo que a flag Alpha no chunk "VP8X" não esteja definida.

  • Os aplicativos do visualizador DEVEM tratar o valor da cor do plano de fundo como uma dica e não precisam usá-la.

  • A tela é apagada no início de cada loop. A cor de fundo PODE ser usada para isso.

Contagem de loops: 16 bits (uint16)
O número de vezes que a animação será repetida. Se for 0, isso significa infinitamente.

Esse bloco PRECISA aparecer se o flag Animation no "VP8X" estiver definido. Se a flag Animation não estiver definida e esse bloco estiver presente, ela PRECISA ser ignorada.

Parte "ANMF":

Para imagens animadas, esse bloco contém informações sobre um único frame. Se a flag de animação não estiver definida, esse bloco NÃO DEVE 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Frame X: 24 bits (uint24)
A coordenada X do canto superior esquerdo do frame é Frame X * 2.
Frame Y: 24 bits (uint24)
A coordenada Y do canto superior esquerdo do frame é Frame Y * 2.
Largura do frame menos um: 24 bits (uint24)
A largura baseada em 1 do frame. A largura do frame é 1 + Frame Width Minus One.
Altura do frame menos um: 24 bits (uint24)
A altura baseada em 1 do frame. A altura do frame é 1 + Frame Height Minus One.
Duração do frame: 24 bits (uint24)
É o tempo de espera antes de mostrar o próximo frame, em unidades de 1 milissegundo. A interpretação da duração do frame como 0 (e geralmente <= 10) é definida pela implementação. Muitas ferramentas e navegadores atribuem uma duração mínima semelhante ao GIF.
Reservado: 6 bits
PRECISA ser 0. Os leitores PRECISAM ignorar esse campo.
Método de combinação (B): 1 bit

Indica como os pixels transparentes do frame atual devem ser misturados com os pixels correspondentes da tela anterior:

  • 0: usa a combinação Alfa. Depois de descartar o frame anterior, renderize o frame atual na tela usando a mistura Alfa (confira abaixo). Se o frame atual não tiver um canal Alfa, presuma que o valor Alfa seja 255, substituindo efetivamente o retângulo.

  • 1: não combinar. Depois de descartar o frame anterior, renderize o frame atual na tela substituindo o retângulo coberto pelo frame atual.

Método de descarte (D): 1 bit

Indica como o frame atual será tratado depois de ser exibido (antes de renderizar o próximo frame) na tela:

  • 0: não descarte. Deixe a tela como está.

  • 1: descarte de acordo com a cor do plano de fundo. Preencha o retângulo na tela coberta pelo frame atual com a cor de fundo especificada no bloco "ANIM".

Observações:

  • O descarte do frame só se aplica ao retângulo do frame, ou seja, ao retângulo definido pelo Frame X, Frame Y, a largura do frame e a altura do frame. Ela pode ou não cobrir toda a tela.

  • Combinação alfa:

    Considerando que cada um dos canais R, G, B e A tem 8 bits e os canais RGB não são pré-multiplicados por alfa, a fórmula para mesclar "dst" em "src" é:

    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
    
  • A mistura alfa DEVE ser feita em espaço de cores linear, considerando o perfil de cor da imagem. Se o perfil de cor não estiver presente, o RGB padrão (sRGB) será usado. sRGB também precisa ser linearizado devido a uma gama de aproximadamente 2,2.

Dados do frame: fragmento16 bytes

Consiste em:

Observação: o payload "ANMF", dados do frame, consiste em blocos preenchidos individuais, conforme descrito pelo formato de arquivo 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
PRECISA ser 0. Os leitores PRECISAM ignorar esse campo.
Pré-processamento (P): 2 bits

Esses bits informativos são usados para sinalizar o pré-processamento que foi executado durante a compactação. O decodificador pode usar essas informações para, por exemplo, pontilhar os valores ou suavizar os gradientes antes da exibição.

  • 0: sem pré-processamento.
  • 1: redução de nível.

Os decodificadores não precisam usar essas informações de nenhuma maneira especificada.

Método de filtragem (F): 2 bits

Os métodos de filtragem usados são descritos da seguinte maneira:

  • 0: nenhuma.
  • 1: filtro horizontal.
  • 2: filtro vertical.
  • 3: filtro de gradiente.

Para cada pixel, a filtragem é realizada usando os cálculos a seguir. Suponha que os valores alfa em torno da posição X atual sejam rotulados como:

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

Procuramos calcular o valor alfa na posição X. Primeiro, é feita uma previsão dependendo do método de filtragem:

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

em que clip(v) é igual a:

  • 0 se v < 0,
  • 255 se v > 255 ou
  • v caso

O valor final é derivado adicionando o valor descompactado X ao previsor e usando a aritmética do módulo 256 para unir o intervalo [256..511] ao [0..255]:

alpha = (predictor + X) % 256

Há casos especiais para as posições de pixel mais à esquerda e acima. Por exemplo, o valor superior esquerdo no local (0, 0) usa 0 como o valor do preditor. Se esse não for seu caso, faça o seguinte:

  • Para métodos de filtragem horizontal ou gradiente, os pixels mais à esquerda no local (0, y) são previstos usando o local (0, y-1) logo acima.
  • Para métodos de filtragem vertical ou gradiente, os pixels mais superiores no local (x, 0) são previstos usando o local (x-1, 0) à esquerda.
Método de compactação (C): 2 bits

O método de compactação usado:

  • 0: sem compactação.
  • 1: comprimido usando o formato WebP sem perda.
Bitstream Alfa: Tamanho do bloco - 1 bytes

Bitstream alfa codificado.

Esse bloco opcional contém dados alfa codificados para o frame. Um frame contendo um pedaço "VP8L" NÃO DEVE conter esse bloco.

Lógica: as informações de transparência já fazem parte do agrupamento "VP8L".

Os dados do canal Alfa são armazenados como dados brutos não compactados (quando o método de compactação é "0") ou compactados usando o formato sem perdas (quando o método é "1").

  • Dados brutos: consiste em uma sequência de bytes de comprimento = largura * altura, contendo todos os valores de transparência de 8 bits na ordem de verificação.

  • Compressão de formato sem perda: a sequência de bytes é um stream de imagem compactado (conforme descrito em Formato WebP sem perda de Bitstream) de dimensões implícitas de largura x altura. Ou seja, esse stream de imagem NÃO contém cabeçalhos que descrevam as dimensões da imagem.

    Lógica: as dimensões já são conhecidas por outras fontes. Por isso, armazená-las novamente seria redundante e propenso a erros.

    Depois que o fluxo de imagem é decodificado em valores de cor alfa, vermelho, verde, azul (ARGB), seguindo o processo descrito na especificação de formato sem perdas, as informações de transparência precisam ser extraídas do canal verde do quadruplet ARGB.

    Lógica: o canal verde tem etapas de transformação extras na especificação, ao contrário dos outros canais, que podem melhorar a compactação.

Bitstream (VP8/VP8L)

Esse bloco contém dados de bitstream compactados para um único frame.

Um bloco do bitstream pode ser (i) um "VP8", usando "VP8" (observe o espaço significativo de quarto caractere) como FourCC, ou (ii) um bloco "VP8L", usando "VP8L" como seu FourCC.

Os formatos de blocos "VP8" e "VP8L" são conforme descritos nas seções Formato de arquivo simples (com perda) e Formato de arquivo simples (sem perda), respectivamente.

Perfil de cor

 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 cor: Chunk Size bytes
Perfil ICC.

Esse bloco PRECISA aparecer antes dos dados da imagem.

DEVE haver no máximo um pedaço desse tipo. Se houver mais desses fragmentos, os leitores PODEM ignorar todos, exceto o primeiro. Consulte a Especificação do ICC para detalhes.

Se esse bloco não estiver presente, o sRGB DEVE ser usado.

Metadados

Os metadados podem ser armazenados em fragmentos 'EXIF' ou 'XMP '.

DEVE haver no máximo um bloco de cada tipo ("EXIF" e "XMP"). Se houver mais desses blocos, os leitores PODEM ignorar todos, exceto o primeiro.

Os blocos são definidos da seguinte maneira:

Parte "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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadados Exif: Chunk Size bytes
Metadados de imagem no formato Exif.

Parte do "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadados XMP: bloco bytes
Metadados de imagem no formato XMP.

O quarto caractere no FourCC "XMP" é um espaço ASCII (0x20).

Mais orientações sobre o tratamento de metadados podem ser encontradas nas Diretrizes para o tratamento de metadados do Grupo de trabalho de metadados.

Pedaços desconhecidos

Um bloco RIFF (descrito na seção Formato de arquivo RIFF) com o FourCC diferente de qualquer um dos fragmentos descritos neste documento é considerado um bloco desconhecido.

Lógica: permitir blocos desconhecidos fornece uma provisão para extensão futura do formato e também permite o armazenamento de quaisquer dados específicos do aplicativo.

Um arquivo PODE conter blocos desconhecidos:

Os leitores DEVEM ignorar esses blocos. Os escritores DEVEM preservá-los na ordem original (a menos que tenham a intenção específica de modificar esses pedaços).

Montagem de telas com frames

Aqui, apresentamos uma visão geral de como um leitor PRECISA montar uma tela no caso de uma imagem animada.

O processo começa com a criação de uma tela usando as dimensões fornecidas no bloco "VP8X", com Canvas Width Minus One + 1 pixels de largura por Canvas Height Minus One + 1 pixels de altura. O campo Loop Count do fragmento "ANIM" controla quantas vezes o processo de animação é repetido. Isso é Loop Count - 1 para valores Loop Count diferentes de zero ou infinito se Loop Count for zero.

No início de cada iteração de loop, a tela é preenchida usando a cor de fundo do pedaço "ANIM" ou uma cor definida pelo aplicativo.

Os blocos "ANMF" contêm frames individuais fornecidos em ordem de exibição. Antes de renderizar cada frame, o Disposal method do frame anterior é aplicado.

A renderização do frame decodificado começa nas coordenadas cartesianas (2 * Frame X, 2 * Frame Y), usando o canto superior esquerdo da tela como a origem. Frame Width Minus One + 1 pixels de largura por Frame Height Minus One + 1 pixels de altura são renderizados na tela usando o Blending method.

A tela é mostrada por Frame Duration milissegundos. Isso continua até que todos os frames fornecidos por blocos "ANMF" tenham sido exibidos. Uma nova iteração de loop é iniciada ou a tela é deixada no estado final se todas as iterações tiverem sido concluídas.

O pseudocódigo a seguir ilustra o processo de renderização. A notação VP8X.field significa o campo no bloco "VP8X" com a mesma descrição.

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

Exemplos de layouts de arquivo

Uma imagem codificada com perda com alfa pode ter a seguinte aparência:

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

Uma imagem codificada sem perdas pode ter a seguinte aparência:

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

Uma imagem sem perdas com um perfil ICC e metadados XMP pode ter a seguinte aparência:

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

Uma imagem animada com metadados EXIF pode ter a seguinte aparência:

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)