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. 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 suporte adicional para:
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, tornando-a uma animação.
Nomeação
É RECOMENDÁVEL usar os seguintes tipos ao se referir ao contêiner WebP:
Nome do formato do contêiner | WebP |
Extensão do nome de arquivo | .webp |
Tipo MIME | imagem/webp |
Identificador de tipo uniforme | org.webmproject.webp |
Terminologia e Noções básicas
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, também pode conter transparência informações, um perfil de cor e metadados. Chamamos a matriz de pixels de tela da imagem.
A numeração de bits nos diagramas de bloco começa em 0
para o bit mais significativo
('MSB 0'), conforme descrito na RFC 1166.
Confira abaixo outros termos usados neste documento:
- Leitor/gravador
- 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, little endian.
- FourCC (link em inglês)
- Um código de quatro caracteres (FourCC) é um uint32 criado ao concatenar quatro caracteres ASCII em ordem small-endian. Isso significa que "aaaa" (0x61616161) e "AAAA" (0x41414141) são tratados como FourCCs diferentes.
- Baseada em 1
- Um campo de número inteiro sem sinal 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. 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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Chunk FourCC: 32 bits
- Código ASCII de quatro caracteres usado para identificar o fragmento.
- Tamanho do bloco: 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, haverá 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 em que os pedaços FourCCs em maiúsculas são pedaços padrão que se aplicam a qualquer formato de arquivo RIFF, enquanto os FourCCs específicos de um formato de arquivo são todos em letras minúsculas. 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 seguintes mais 4
bytes para
o "WEBP" o FourCC. O arquivo NÃO DEVE conter dados depois dos dados
especificados por Tamanho do arquivo. 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 uniforme. O conteúdo de blocos individuais é descrito nas
em outras seções.
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 compatíveis com 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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
"VP8" 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('VP8 ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8 data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dados VP8: Chunk Tamanho bytes
- Dados do fluxo de bits VP8.
O quarto caractere no FourCC "VP8" é um espaço ASCII (0x20).
A especificação do formato de bitstream VP8 é descrita no Guia de codificação e formato de dados VP8 (link em inglês). Observe que o cabeçalho do frame VP8 contém o frame VP8 largura e altura. Isso é considerado a largura e a altura da tela.
A especificação VP8 descreve como decodificar a imagem no formato Y'CbCr. Para converter em RGB, Recommendation BT.601 DEVE ser usado. 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 perda)
Observação: leitores mais antigos podem não oferecer suporte a arquivos que usam o 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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Pedaço "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: Tamanho do bloco (bytes)
- Dados do fluxo de bits 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 VP8L. Isso é considerado 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 bloco "ICCP" opcional com um perfil de cor.
Um bloco "ANIM" opcional com dados de controle de animação.
Dados da imagem.
Um bloco "EXIF" opcional com metadados Exif.
Um bloco "XMP" opcional com metadados XMP.
Uma lista opcional de blocos desconhecidos.
No caso de uma imagem estática, os dados da imagem consistem em um único frame, de:
Um subbloco Alfa opcional.
Um subbloco do bitstream (em inglês).
No caso de 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, ou seja, "VP8X", 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8' e 'VP8L' PRECISAM aparecer na ordem descritos anteriormente. Os leitores devem falhar quando os pedaços necessários para a reconstrução e a correção de cores estiverem fora de ordem.
Os metadados e os fragmentos desconhecidos podem aparecer fora de ordem.
Lógica: os blocos necessários para a reconstrução devem aparecer primeiro na o arquivo para permitir que um leitor comece 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 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 "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. Dados em 'ANIM' e 'ANMF' Os pedaços devem ser usada 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 de 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'.
"ANIM" Parte:
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 de plano de fundo padrão da tela na ordem de bytes
[Blue, Green, Red, Alpha]. 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ções:
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 dos leitores DEVEM tratar o valor da cor do plano de fundo como uma dica e não são obrigados a usá-lo.
A tela é limpa 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 o sinalizador Animation no "VP8X" A parte está definida. Se a flag Animation não estiver definida e esse bloco estiver presente, ele PRECISA ser ignorado.
Pedaço "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 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
. - Frame height minus one: 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 de uma duração do frame 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 combinação (B): 1 bit
Indica como os pixels transparentes do frame atual devem ser combinados. 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 (consulte 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 mesclar. 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 tratado. exibido (antes de renderizar o próximo frame) na tela:
0
: não descarte. Deixe a tela como está.1
: descarta a cor de plano 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 que 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 PRECISA ser feita no espaço de cores linear, considerando o perfil de cores da imagem. Se o perfil de cor não estiver presente, o RGB padrão (sRGB) será usado. O sRGB também precisa ser linearizado devido a um gama de ~2,2.
- Dados do frame: tamanho do chunk bytes -
16
É composto por:
Um alfa subbloco opcional para o frame.
Um subbloco de bitstream para o frame.
Uma lista opcional de fragmentos desconhecidos.
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 precisam usar essas informações de nenhuma forma 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 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
: preditor = 0 - Método
1
: predictor = A - Método
2
: predictor = B - Método
3
: predictor = clip(A + B - C)
em que clip(v)
é igual a:
- 0 se v for menor que 0
- 255 se v > 255.
- v caso contrário
O valor final é derivado pela adição do valor descompactado X
ao
previsor e pelo uso da aritmética módulo-256 para agrupar o intervalo [256..511]
no intervalo [0..255]:
alpha = (predictor + X) % 256
Há casos especiais para as posições de pixel mais à esquerda e na parte superior. Por exemplo, o valor no 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.
Este bloco opcional contém dados alfa codificados para este 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 descrevam as dimensões da imagem.
Motivo: as dimensões já são conhecidas de outras fontes, portanto, armazená-las 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.
Justificativa: o canal verde pode fazer transformações adicionais etapas da 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 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 cores
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: Chunk size bytes
- Perfil ICC.
Esse bloco PRECISA aparecer antes dos dados da imagem.
DEVE haver no máximo um bloco desse tipo. Se houver mais blocos desse tipo, os leitores PODE ignorar todos, exceto o primeiro. Consulte a especificação do ICC para mais detalhes.
Se esse bloco não estiver presente, o sRGB DEVE ser usado.
Metadados
Os metadados podem ser armazenados em blocos "EXIF" ou "XMP".
Deve haver no máximo um bloco de cada tipo ('EXIF' e 'XMP'). Se houver mais blocos desse tipo, os leitores poderão 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 na coluna "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) cujo FourCC seja diferente de qualquer um dos blocos descritos neste documento, é é considerado um bloco desconhecido.
Motivação: permitir blocos desconhecidos permite a extensão futura do formato e também o armazenamento de dados específicos do aplicativo.
Um arquivo PODE conter blocos desconhecidos:
- no final do arquivo, conforme descrito em Arquivo WebP estendido cabeçalho ou
- no final de "ANMF" em blocos, conforme descrito nos Seção Animação.
Os leitores devem ignorar esses blocos. Os autores PRECISAM preservar esses blocos na ordem original, a menos que queiram 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
bloco "VP8X", Canvas Width Minus One + 1
pixels de largura por Canvas Height Minus
One + 1
pixels de altura. O campo Loop Count
do bloco "ANIM" controla quantas vezes o processo de animação é repetido. O valor é Loop Count - 1
para
valores Loop Count
diferentes de zero ou infinito se o Loop Count
for zero.
No início de cada iteração do loop, a tela é preenchida usando a cor de plano de fundo do bloco "ANIM" ou uma cor definida pelo aplicativo.
Os blocos "ANMF" contêm frames individuais fornecidos na ordem de exibição. Antes da renderização
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 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 é 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 layout 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 perda com um perfil ICC e metadados XMP pode ser semelhante a esta:
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)