Especificação de contêiner WebP

Introdução

WebP é um formato de imagem que usa (i) a codificação de frames-chave VP8 para compactam dados de imagem com perda ou (ii) a codificação WebP sem perda. Esses esquemas de codificação devem torná-lo mais eficiente do que formatos mais antigos, como JPEG, GIF e PNG. Ele é otimizado para transferência rápida de imagem pela rede (por por exemplo, para sites). O formato WebP tem paridade de recursos (perfil de cor, metadados, animação etc.) com outros formatos também. 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 contendo uma única imagem codificada como um frame-chave VP8). O contêiner WebP oferece mais suporte para o seguinte:

  • Compressão sem perda: uma imagem pode ser compactada sem perdas usando o formato WebP Lossless.

  • Metadados: uma imagem pode ter metadados armazenados no formato de arquivo de imagem trocável (Exif) ou na plataforma de metadados extensível (XMP).

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

  • Perfil de cores: 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, transformando-o em uma animação.

Nomeação

É RECOMENDÁVEL usar os seguintes tipos ao se referir ao contêiner WebP:

Nome do formato do contêinerWebP
Extensão do nome de arquivo.webp
MIME-typeimagem/webp
Identificador de tipo uniformeorg.webmproject.webp

Terminologia e conceitos básicos

As palavras-chave "MUST" (precisa), "MUST NOT" (não pode), "REQUIRED" (obrigatório), "SHALL" (deve), "SHALL NOT" (não deve), "SHOULD" (deve), "SHOULD NOT" (não deve), "RECOMMENDED" (recomendado), "NOT RECOMMENDED" (não recomendado), "MAY" (pode) e "OPTIONAL" (opcional) neste documento devem ser interpretadas conforme descrito no BCP 14 RFC 2119 RFC 8174 quando, e somente quando, aparecerem em todas as maiúsculas, como mostrado aqui.

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

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

Confira abaixo outros termos usados neste documento:

Leitor/escritor
O código que lê arquivos WebP é chamado de leitor, enquanto o código que escreve isso é chamado de escritor.
uint16
Um número inteiro não assinado de 16 bits, little-endian.
uint24
Um número inteiro não assinado de 24 bits, little endian.
uint32
Um número inteiro não assinado de 32 bits e little-endian.
FourCC (link em inglês)
Um código de quatro caracteres (FourCC) é um uint32 criado concatenando quatro caracteres ASCII na ordem little-endian. Isso significa que "aaaa" (0x61616161) e "AAAA" (0x41414141) são tratados como FourCCs diferentes.
Baseado em 1
Um campo de número inteiro não assinado 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 blocos individuais. em que "ABCD" é o FourCC para o bloco. O tamanho desse elemento é 8 bytes.

Formato de arquivo RIFF

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

O elemento básico de um arquivo RIFF é um bloco. Ele 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Divisão de FourCC: 32 bits
Código ASCII de quatro caracteres usado para identificação de partes.
Tamanho da parte: 32 bits (uint32)
O tamanho do bloco em bytes, sem incluir este campo, o identificador do bloco ou o preenchimento.
Chunk Payload: Chunk Size bytes
O payload de dados. Se o Chunk size for ímpar, um único byte de padding, que PRECISA ser ser 0 para estar em conformidade com o RIFF, será adicionado.

Observação: o RIFF tem uma convenção de que os FourCCs em letras maiúsculas são padrão blocos que se aplicam a qualquer formato de arquivo RIFF, enquanto FourCC são específicos de um arquivo são todos minúsculos. O 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', '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 de todo o arquivo é, 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 para o FourCC "WEBP". O arquivo NÃO DEVE conter dados depois que os dados especificado por File size. Os leitores PODEM analisar esses arquivos, ignorando o final dados. Como o tamanho de qualquer bloco é par, o tamanho fornecido pelo cabeçalho RIFF também é par. O conteúdo de cada bloco é 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Pedaço "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: Tamanho do bloco (bytes)
Dados de bitstream VP8.

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

A especificação de formato bitstream VP8 é descrita em Formato de dados VP8 e decodificação. O cabeçalho do frame VP8 contém a largura e a altura do frame VP8. Isso é considerado a largura e a altura da tela.

A especificação VP8 descreve como decodificar a imagem para o formato Y'CbCr. Para converter em RGB, Recommendation BT.601 DEVE ser usado. Os aplicativos podem usam outro método de conversão, mas os resultados visuais podem variar entre os decodificadores.

Formato de arquivo simples (sem perdas)

Observação: leitores mais antigos podem não oferecer suporte a arquivos no formato lossless.

Esse layout DEVE ser usado se a imagem exigir codificação sem perdas (com uma canal de transparência opcional) e não exige o fornecimento de recursos avançados 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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

"VP8L" Parte:

 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: Tamanho do bloco (bytes)
Dados de bitstream VP8L.

A especificação atual do fluxo de bits VP8L pode ser encontrada em Formato de fluxo de bits sem perdas WebP. O cabeçalho VP8L contém a largura e a altura da imagem do VP8L. Essa é 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 "VP8X" Separe com informações sobre os recursos usados no arquivo.

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

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

  • Dados da imagem.

  • Um "EXIF" opcional Parte com metadados Exif.

  • Um bloco "XMP" opcional com metadados XMP.

  • Uma lista opcional de fragmentos desconhecidos.

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

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 pedaços necessários para reconstrução e correção de cores, ou seja, "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" e "VP8L", precisam aparecer na ordem descrita anteriormente. Os leitores DEVEM falhar quando blocos necessários para reconstrução e correção de cor estão fora de ordem.

Metadados e fragmentos desconhecidos podem aparecer fora ordem.

Motivo: os blocos necessários para a reconstrução precisam aparecer primeiro no arquivo para que um leitor possa começar a decodificar uma imagem antes de receber todos os dados. Um aplicativo pode se beneficiar de variar a ordem dos metadados e blocos personalizados para se adaptar à implementação.

Cabeçalho de 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 "ICCP" Pedaços.
Alfa (L): 1 bit
Defina se algum dos frames da imagem contém informações de transparência ("alfa").
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
Defina se esta é uma imagem animada. Os dados nos blocos "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 baseada em 1 da tela em pixels. A largura real da tela é 1 + Canvas Width Minus One.
Altura da tela menos um: 24 bits
Altura baseada 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 ser 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 de plano de fundo da tela em [Azul, Verde, Vermelho, Alfa] na ordem dos bytes. Esta cor PODE ser usada para preencher o espaço não utilizado na tela ao redor dos frames, além dos pixels transparentes do primeiro frame. A cor de plano de fundo também é usada quando o método de descarte é 1.

Observação:

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

  • Os aplicativos de visualização precisam tratar o valor da cor de plano de fundo como uma dica e não precisam usá-lo.

  • O canvas é apagado no início de cada loop. A cor de plano 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, significa infinito.

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

"ANMF" Parte:

Para imagens animadas, esse bloco contém informações sobre um único frame. Se a sinalização 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 exibir o próximo frame, em unidades de 1 milissegundo. A interpretação de um frame Duration 0 (e geralmente <= 10) é definido 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 mistura (B): 1 bit

Indica como os pixels transparentes do frame atual precisam ser mesclados com os pixels correspondentes da tela anterior:

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

  • 1: não misturar. Depois de descartar o frame anterior, renderize o frame atual na tela, substituindo o retângulo coberto pela 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 descartar. Deixe a tela como está.

  • 1: descarta a cor de fundo. Preencha o retângulo na tela. coberto pelo frame atual com a cor de fundo especificada na "ANIM" Pedaço.

Observações:

  • A eliminação de frames só se aplica ao retângulo do frame, ou seja, o retângulo definido por Frame X, Frame Y, largura do frame e 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 o RGB os canais não são pré-multiplicados por alfa, a fórmula para combinação "dst" para "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 PRECISA ser feita no espaço de cores linear, considerando o perfil de cores da imagem. Se o perfil de cores for ausente, o padrão RGB (sRGB) deve ser usado. (Observe que sRGB também precisa ser linearizado devido a uma gama de ~2,2.)

Frame Data: Chunk Size bytes - 16

Consiste em:

Observação: o payload "ANMF", Frame Data, 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 realizado 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 são obrigados a usar essas informações de forma específica.

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 Gradiente.

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

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

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

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

em que clip(v) é igual a:

  • 0 se v < zero,
  • 255 se v > 255 ou
  • v diferente

O valor final é derivado adicionando o valor descompactado X ao preditor e uso da aritmética módulo-256 para unir o intervalo [256..511] para o de [0..255]:

alpha = (predictor + X) % 256

Há casos especiais para as posições de pixel mais à esquerda e mais à direita. Para Por exemplo, o valor do canto superior esquerdo na localização (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 de gradiente, os pixels mais à esquerda em localização (0, y) são previstas usando a localização (0, y-1) logo acima.
  • Para métodos de filtragem vertical ou gradiente, os pixels da parte de cima na localização (x, 0) são previstos usando a localização (x-1, 0) à esquerda.
Método de compactação (C): 2 bits

O método de compactação usado:

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

Bitstream alfa codificado.

Esse bloco opcional contém dados alfa codificados para esse frame. Um frame que contenha um bloco "VP8L" NÃO deve conter esse bloco.

Justificativa: as informações de transparência já fazem parte do "VP8L" Pedaços.

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

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

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

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

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

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

Bitstream (VP8/VP8L)

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

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

Os formatos dos blocos "VP8" e "VP8L" são 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 cores: bytes Chunk Size
Perfil ICC.

Esse bloco PRECISA aparecer antes dos dados da imagem.

DEVE haver no máximo um bloco desse tipo. Se houver mais desses blocos, os leitores poderão ignorar todos, exceto o primeiro. Consulte a especificação do ICC para mais detalhes.

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

Metadados

Os metadados podem ser armazenados em blocos "EXIF" ou "XMP".

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

Os blocos são definidos da seguinte maneira:

Bloco "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: Tamanho do bloco (bytes)
Metadados de imagem no formato Exif.

Pedaço "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: tamanho do bloco bytes
Metadados de imagem no formato XMP.

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

Confira mais orientações sobre como lidar com metadados na Metadados do Grupo de trabalho de metadados: "Diretrizes para o processamento de metadados".

Partes desconhecidas

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

Lógica: permitir blocos desconhecidos fornece uma provisão para extensão futura 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á-las na ordem original (a menos que eles pretendam especificamente modificar esses blocos).

Montagem de telas com molduras

Aqui, fornecemos 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 "VP8X" Pedaço de Canvas Width Minus One + 1 pixels de largura por Canvas Height Minus One + 1 pixels de altura. O campo Loop Count do "ANIM" A divisão controla como muitas vezes o processo de animação é repetido. Isto é Loop Count - 1 para valores Loop Count diferentes de zero ou infinito se Loop Count for zero.

No início de cada iteração do loop, o canvas é preenchido usando o cor de fundo de "ANIM" Bloco ou uma cor definida pelo aplicativo.

"ANMF" Os blocos contêm frames individuais fornecidos na 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 são renderizados na tela usando Blending method.

A tela é exibida por Frame Duration milissegundos. Isso continua até todos os frames fornecidos por "ANMF" Os blocos foram exibidos. Uma nova iteração de loop é é iniciada, ou a tela é deixada no estado final se todas as iterações concluído.

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

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

Exemplos de layouts de arquivos

Uma imagem codificada com perdas 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 vai ficar assim:

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)