Specifiche container WebP

Introduzione

WebP è un formato dell'immagine che utilizza (i) la codifica dei fotogrammi chiave VP8 per comprimere i dati delle immagini in modo con perdita di dati o (ii) la codifica WebP senza perdita di dati. Questi schemi di codifica dovrebbero renderlo più efficiente rispetto ai formati precedenti, come JPEG, GIF e PNG. È ottimizzato per un trasferimento rapido delle immagini sulla rete (ad esempio per i siti web). Il formato WebP ha parità di funzionalità (profilo colore, metadati, animazione e così via) anche con altri formati. Questo documento descrive la struttura di un file WebP.

Il container WebP (ovvero il container RIFF per WebP) consente il supporto delle funzionalità oltre al caso d'uso di base di WebP (ovvero un file contenente una singola immagine codificata come frame chiave VP8). Il container WebP fornisce ulteriore supporto per:

  • Compressione senza perdita di dati: un'immagine può essere compressa senza perdita di dati utilizzando il formato WebP Lossless.

  • Metadati: un'immagine può contenere metadati archiviati in formato Exchangeable Image File Format (Exif) o Extensible Metadata Platform (XMP).

  • Trasparenza: un'immagine può avere trasparenza, ovvero un canale alfa.

  • Profilo di colore: un'immagine può avere un profilo ICC incorporato, come descritto dall'International Color Consortium.

  • Animazione: un'immagine può avere più frame separati da pause e diventare un'animazione.

Denominazione

È CONSIGLIATO di utilizzare i seguenti tipi quando si fa riferimento al contenitore WebP:

Nome formato contenitoreWebP
Estensione nome file.webp
Tipo MIMEimmagine/webp
Identificatore di tipo uniformeorg.webmproject.webp

Terminologia e nozioni di base

Le parole chiave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" e "OPTIONAL" in questo documento devono essere interpretate come descritto in BCP 14 RFC 2119 RFC 8174 quando e solo quando appaiono in maiuscolo.

Un file WebP contiene un'immagine statica (ovvero una matrice codificata di pixel) o un'animazione. Facoltativamente, può anche contenere informazioni sulla trasparenza, un profilo colore e metadati. Ci riferiamo alla matrice dei pixel come alla tela dell'immagine.

La numerazione dei bit nei diagrammi dei blocchi inizia da 0 per il bit più significativo (('MSB 0'), come descritto in RFC 1166.

Di seguito sono riportati i termini aggiuntivi utilizzati nel documento:

Lettore/autore
Il codice che legge i file WebP è noto come lettore, mentre il codice che li scrive è definito writer.
uint16
Un numero intero senza segno a 16 bit, small-endian.
uint24
Un numero intero senza segno, small-endian a 24 bit.
uint32
Un numero intero senza segno, small-endian a 32 bit.
FourCC
Un codice di quattro caratteri (FourCC) è un codice uint32 creato concatenando quattro caratteri ASCII in ordine di poco-endian. Ciò significa che "aaaa" (0x61616161) e "AAAA" (0x41414141) sono trattati come FourCCs diversi.
In base a 1
Un campo con numero intero senza segno che memorizza valori offset da -1; ad esempio, un campo di questo tipo memorizza il valore 25 come 24.
ChunkHeader('ABCD')
Utilizzato per descrivere l'intestazione FourCC e Chunk size dei singoli blocchi, dove "ABCD" è la FourCC del blocco. Le dimensioni di questo elemento sono di 8 byte.

Formato file RIFF

Il formato file WebP si basa sul formato documento RIFF (Resource Interchange File Format).

L'elemento base di un file RIFF è un blocco. È composto da:

 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 bit
Codice ASCII a quattro caratteri utilizzato per l'identificazione del blocco.
Dimensioni blocco: 32 bit (uint32)
La dimensione del blocco in byte, escluso questo campo, l'identificatore del blocco o la spaziatura interna.
Payload blocco: dimensioni blocco byte
Il payload dei dati. Se la dimensione Dimensione blocco è dispari, viene aggiunto un singolo byte di spaziatura interna, che DEVE essere 0 per essere conforme al RIFF.

Nota: la convenzione di RIFF prevede che le colonne FourCC, composte interamente da lettere maiuscole, siano blocchi standard che si applicano a qualsiasi formato di file RIFF, mentre le colonne FourCC specifiche di un formato file sono tutte minuscole. WebP non segue questa convenzione.

Intestazione file 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 bit
I caratteri ASCII "R", "I", "F", "F".
Dimensioni file: 32 bit (uint32)
La dimensione del file in byte, a partire dall'offset 8. Il valore massimo di questo campo è 2^32 meno 10 byte, quindi la dimensione dell'intero file è al massimo 4 GiB meno 2 byte.
"WEBP": 32 bit
I caratteri ASCII "W", "E", "B", "P".

Un file WebP DEVE iniziare con un'intestazione RIFF con il "WEBP" di FourCC. La dimensione del file nell'intestazione corrisponde alla dimensione totale dei blocchi che seguono più 4 byte per il FourCC "WEBP". Il file NON DEVE contenere alcun dato dopo i dati specificati in Dimensioni file. I lettori POTREBBERO analizzare questi file, ignorando i dati finali. Poiché le dimensioni di ogni blocco sono uguali, anche le dimensioni specificate dall'intestazione RIFF sono uguali. I contenuti dei singoli blocchi sono descritti nelle sezioni seguenti.

Formato file semplice (non disponibile)

Questo layout DEVE essere utilizzato se l'immagine richiede una codifica con perdita di dati e non richiede trasparenza o altre funzionalità avanzate fornite dal formato esteso. I file con questo layout sono più piccoli e supportati da software meno recente.

Formato file WebP semplice (con perdita di dati):

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

Blocco "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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dati VP8: dimensioni blocco byte
Dati di flussi di bit VP8.

Si noti che il quarto carattere nel FourCC "VP8" è uno spazio ASCII (0x20).

Le specifiche del formato bitstream VP8 sono descritte nella Guida al formato e alla decodifica dei dati VP8. Tieni presente che l'intestazione del frame VP8 contiene la larghezza e l'altezza del frame VP8. Vengono considerate la larghezza e l'altezza della tela.

La specifica VP8 descrive come decodificare l'immagine nel formato Y'CbCr. Per convertire in RGB, DOVREBBE essere utilizzato il Consiglio BT.601. Le applicazioni POTREBBERO utilizzare un altro metodo di conversione, ma i risultati visivi potrebbero differire tra i decoder.

Formato file semplice (senza perdita)

Nota: i lettori meno recenti potrebbero non supportare i file nel formato senza perdita di dati.

Questo layout DEVE essere utilizzato se l'immagine richiede una codifica lossless (con un canale per la trasparenza facoltativo) e non richiede funzionalità avanzate fornite dal formato esteso.

Formato file WebP semplice (senza perdita di dati):

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

Blocco "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Dati VP8L: dimensioni blocco byte
Dati di flussi di bit VP8L.

La specifica attuale del flusso di bit VP8L è disponibile in WebP Lossless Bitstream Format. Tieni presente che l'intestazione VP8L contiene la larghezza e l'altezza dell'immagine VP8L. che vengono considerate la larghezza e l'altezza della tela.

Formato file esteso

Nota: i lettori meno recenti potrebbero non supportare i file che utilizzano il formato esteso.

Un file di formato esteso è costituito da:

  • Un blocco "VP8X" con informazioni sulle funzionalità utilizzate nel file.

  • Un blocco "ICCP" facoltativo con un profilo di colore.

  • Un blocco "ANIM" facoltativo con dati di controllo dell'animazione.

  • Dati dell'immagine.

  • Un blocco "EXIF" facoltativo con metadati EXIF.

  • Un blocco "XMP" facoltativo con metadati XMP.

  • Un elenco facoltativo di blocchi sconosciuti.

Per un'immagine statica, i dati dell'immagine sono costituiti da un singolo frame, composto da:

Per un'immagine animata, i dati immagine sono costituiti da più frame. Ulteriori dettagli sui frame sono disponibili nella sezione Animazione.

Tutti i blocchi DEVONO essere posizionati nello stesso ordine indicato sopra. Se un blocco viene visualizzato nel posto sbagliato, il file non è valido, ma i lettori POTREBBERO analizzare il file, ignorando i blocchi che non sono nell'ordine corretto.

Motivazione:l'impostazione dell'ordine dei blocchi dovrebbe consentire un'analisi dei file più rapida. Ad esempio, se un blocco "ALPH" non appare nella posizione richiesta, un decoder può scegliere di interrompere la ricerca. La regola di ignorare i blocchi in ritardo dovrebbe fare in modo che i programmi che devono eseguire una ricerca completa diano gli stessi risultati di quelli che si arrestano in anticipo.

Intestazione del file WebP esteso:

 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    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Riservato (Rsv): 2 bit
DEVE essere 0. I lettori DEVONO ignorare questo campo.
Profilo ICC (I): 1 bit
Imposta se il file contiene un blocco "ICCP".
Alfa (L): 1 bit
Imposta se uno o più frame dell'immagine contengono informazioni sulla trasparenza ("alpha").
Metadati EXIF (E): 1 bit
Da impostare se il file contiene metadati EXIF.
Metadati XMP (X): 1 bit
Imposta se il file contiene metadati XMP.
Animazione (A): 1 bit
Da impostare se questa è un'immagine animata. I dati nei blocchi "ANIM" e "ANMF" dovrebbero essere utilizzati per controllare l'animazione.
Riservato (R): 1 bit
DEVE essere 0. I lettori DEVONO ignorare questo campo.
Riservato: 24 bit
DEVE essere 0. I lettori DEVONO ignorare questo campo.
Larghezza canvas meno uno: 24 bit
Larghezza in base a 1 del canvas in pixel. La larghezza effettiva del canvas è 1 + Canvas Width Minus One.
Altezza canvas meno uno: 24 bit
Altezza in base a 1 della tela in pixel. L'altezza effettiva della tela è 1 + Canvas Height Minus One.

Il prodotto di larghezza tela e altezza canvas DEVE essere al massimo 2^32 - 1.

Le specifiche future potrebbero aggiungere altri campi. I campi sconosciuti DEVONO essere ignorati.

Animazione

Un'animazione è controllata dai blocchi "ANIM" e "ANMF".

Blocco "ANIM":

Per un'immagine animata, questo blocco contiene i parametri globali dell'animazione.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Colore di sfondo: 32 bit (uint32)
Il colore di sfondo predefinito della tela in ordine di byte [blu, verde, rosso, alpha]. Questo colore POTREBBE essere utilizzato per riempire lo spazio inutilizzato sul canvas intorno ai frame, nonché per i pixel trasparenti del primo frame. Il colore di sfondo viene utilizzato anche quando il metodo di smaltimento è 1.

Nota:

  • Il colore di sfondo POTREBBE contenere un valore alfa non opaco, anche se il flag Alpha nel blocco "VP8X" non è impostato.

  • Le applicazioni del visualizzatore DEVONO considerare il valore del colore di sfondo come suggerimento e non è necessario utilizzarlo.

  • Il canvas viene cancellato all'inizio di ogni loop. Il colore di sfondo POTREBBE essere usato per ottenere questo risultato.

Conteggio loop: 16 bit (uint16)
Il numero di ripetizioni dell'animazione. Se è 0, significa infinitamente.

Questo blocco DEVE essere visualizzato se nel blocco "VP8X" è impostato il flag Animation. Se il flag Animazione non è impostato e questo blocco è presente, DEVE essere ignorato.

Blocco "ANMF":

Per le immagini animate, questo blocco contiene informazioni su un singolo frame. Se il flag dell'animazione non è impostato, questo blocco NON DEVE essere 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 bit (uint24)
La coordinata X dell'angolo in alto a sinistra del frame è Frame X * 2.
Frame Y: 24 bit (uint24)
La coordinata Y dell'angolo in alto a sinistra del frame è Frame Y * 2.
Larghezza frame meno uno: 24 bit (uint24)
La larghezza in base a 1 del frame. La larghezza del frame è 1 + Frame Width Minus One.
Altezza frame meno uno: 24 bit (uint24)
L'altezza in base a 1 del frame. L'altezza del frame è 1 + Frame Height Minus One.
Durata frame: 24 bit (uint24)
Il tempo di attesa prima di visualizzare il frame successivo, in unità di 1 millisecondo. Tieni presente che l'interpretazione della durata frame pari a 0 (e spesso <= 10) è definita dall'implementazione. Molti strumenti e browser assegnano una durata minima simile a quella del file GIF.
Riservato: 6 bit
DEVE essere 0. I lettori DEVONO ignorare questo campo.
Metodo di combinazione (B): 1 bit

Indica come i pixel trasparenti del frame corrente devono essere uniti ai pixel corrispondenti del canvas precedente:

  • 0: utilizza la combinazione alfa. Dopo aver eliminato il frame precedente, esegui il rendering del frame corrente sulla tela utilizzando la combinazione alpha (vedi sotto). Se il frame corrente non ha un canale alfa, supponiamo che il valore alfa sia 255, sostituendo di fatto il rettangolo.

  • 1: non unire. Dopo aver eliminato il frame precedente, esegui il rendering del frame corrente sulla tela sovrascrivendo il rettangolo coperto dal frame corrente.

Metodo di smaltimento (D): 1 bit

Indica come trattare il frame corrente dopo che è stato visualizzato (prima di eseguire il rendering del frame successivo) sul canvas:

  • 0: non smaltire. Lascia invariata la tela.

  • 1: elimina il colore dello sfondo. Riempi il rettangolo sulla tela ricoperta dal frame corrente con il colore di sfondo specificato nel blocco "ANIM".

Note:

  • Lo smaltimento del frame si applica solo al rettangolo del frame, ovvero al rettangolo definito da Frame X, Frame Y, larghezza frame e altezza frame. Potrebbe coprire o meno l'intera tela.

  • Alpha-blending:

    Dato che ciascuno dei canali R, G, B e A è a 8 bit e i canali RGB non sono premoltiplicati tramite alfa, la formula per unire "dst" a "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
    
  • La combinazione alfa DEVE essere eseguita nello spazio colore lineare, tenendo conto del profilo colore dell'immagine. Se il profilo di colore non è presente, deve essere utilizzato il colore RGB standard (sRGB). Tieni presente che anche sRGB deve essere linearizzato a causa di una gamma di ~2,2.

Dati frame: Dimensione blocco - 16 byte

Composto da:

Nota: il payload "ANMF", Dati frame sopra, è costituito da singoli blocchi riempiti, come descritto nel formato file RIFF.

Alpha

 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...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Riservato (Rsv): 2 bit
DEVE essere 0. I lettori DEVONO ignorare questo campo.
Pre-elaborazione (P): 2 bit

Questi bit informativi vengono utilizzati per segnalare la pre-elaborazione eseguita durante la compressione. Il decoder può usare queste informazioni, ad esempio, per oscurare i valori o smussare i gradienti prima della visualizzazione.

  • 0: nessuna pre-elaborazione.
  • 1: riduzione del livello.

I decodificatori non sono tenuti a utilizzare queste informazioni in alcun modo specificato.

Metodo di filtro (F): 2 bit

I metodi di filtro utilizzati sono descritti di seguito:

  • 0: nessuno.
  • 1: filtro orizzontale.
  • 2: filtro verticale.
  • 3: filtro gradiente.

Per ogni pixel, l'applicazione di filtri viene eseguita utilizzando i calcoli che seguono. Supponiamo che i valori alfa che circondano la posizione X corrente siano etichettati come:

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

Cerchiamo di calcolare il valore alfa nella posizione X. Innanzitutto, viene eseguita una previsione in base al metodo di filtro:

  • Metodo 0: predittore = 0
  • Metodo 1: predittore = A
  • Metodo 2: predittore = B
  • Metodo 3: predittore = clip(A + B - C)

dove clip(v) è uguale a:

  • 0 se v < 0,
  • 255 se v > 255 oppure
  • V altrimenti

Il valore finale viene derivato aggiungendo il valore decompresso X al predittore e utilizzando l'aritmetica modulo-256 per inserire l'intervallo [256..511] nell'intervallo [0..255]:

alpha = (predictor + X) % 256

Esistono casi speciali per le posizioni dei pixel più a sinistra e più in alto. Ad esempio, il valore in alto a sinistra nella posizione (0, 0) utilizza 0 come valore predittore. Altrimenti:

  • Per i metodi di filtro orizzontale o a gradiente, vengono previsti i pixel più a sinistra nella posizione (0, y) utilizzando la posizione (0, y-1) appena sopra.
  • Per i metodi di filtro verticale o a gradiente, vengono previsti i pixel più in alto nella posizione (x, 0) utilizzando la posizione (x-1, 0) a sinistra.
Metodo di compressione (C): 2 bit

Il metodo di compressione utilizzato:

  • 0: nessuna compressione.
  • 1: compresso utilizzando il formato WebP senza perdita di dati.
Flusso di bit alpha: Dimensione blocco - 1 byte

Flusso di bit alpha codificato.

Questo blocco facoltativo contiene dati alpha codificati per questo frame. Un frame che contiene un blocco "VP8L" NON DEVE contenere questo blocco.

Motivazione: le informazioni sulla trasparenza fanno già parte del Chunk "VP8L".

I dati del canale alfa vengono archiviati come dati non compressi non compressi (quando il metodo di compressione è "0") o compressi utilizzando il formato senza perdita di dati (quando il metodo di compressione è "1").

  • Dati non elaborati: sono costituiti da una sequenza di byte di lunghezza = larghezza * altezza, che contiene tutti i valori di trasparenza a 8 bit nell'ordine di scansione.

  • Compressione del formato senza perdita di dati: la sequenza di byte è un flusso di immagini compresso (come descritto in "WebP Lossless Bitstream Format") con dimensioni implicite larghezza x altezza. Ciò significa che questo flusso di immagini NON contiene intestazioni che descrivono le dimensioni dell'immagine.

    Motivazione: le dimensioni sono già note da altre origini, pertanto memorizzarle di nuovo sarebbe ridondante e soggetto a errori.

    Una volta che il flusso di immagini è stato decodificato in valori di colore Alpha, Red, Green, Blue (ARGB), seguendo il processo descritto nella specifica del formato senza perdita di dati, le informazioni sulla trasparenza devono essere estratte dal canale verde della quadrupla ARGB.

    Motivazione: al canale verde sono consentiti passaggi di trasformazione aggiuntivi nella specifica, a differenza degli altri canali, che possono migliorare la compressione.

Bitstream (VP8/VP8L)

Questo blocco contiene dati di flusso di bit compressi per un singolo frame.

Un blocco di bitstream può essere (i) un blocco "VP8", utilizzando "VP8" (nota il significativo spazio di quattro caratteri) come FourCC oppure (ii) un blocco "VP8L", utilizzando "VP8L" come FourCC.

I formati dei blocchi "VP8" e "VP8L" sono descritti rispettivamente nelle sezioni Formato file semplice (non disponibile) e Formato file semplice (senza perdita).

Profilo colore

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Profilo colore: dimensioni blocco byte
Profilo ICC.

Questo blocco DEVE apparire prima dei dati dell'immagine.

DEVE esserci al massimo un blocco di questo tipo. Se ci sono più blocchi di questo tipo, i lettori POTREBBERO ignorare tutti tranne il primo. Consulta la specifica ICC per i dettagli.

Se questo blocco non è presente, DOVREBBE essere presupposto sRGB.

Metadati

I metadati possono essere archiviati in blocchi "EXIF" o "XMP".

DOVREBBE essere presente al massimo un blocco di ogni tipo ("EXIF" e "XMP"). Se ci sono più blocchi di questo tipo, i lettori POSSONO ignorare tutti tranne il primo.

I blocchi sono definiti come segue:

Blocco "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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadati EXIF: dimensioni blocco byte
Metadati delle immagini in formato EXIF.

Blocco "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Metadati XMP: dimensioni blocco byte
Metadati delle immagini in formato XMP.

Nota che il quarto carattere nel FourCC "XMP" è uno spazio ASCII (0x20).

Ulteriori indicazioni sulla gestione dei metadati sono disponibili nelle linee guida per la gestione dei metadati del gruppo di lavoro sui metadati.

Blocchi sconosciuti

Un blocco RIFF (descritto nella sezione Formato file RIFF) il cui FourCC è diverso da uno qualsiasi dei blocchi descritti in questo documento viene considerato un blocco sconosciuto.

Motivazione: se consenti l'utilizzo di blocchi sconosciuti, puoi eseguire una previsione per l'estensione futura del formato e consentire anche l'archiviazione di dati specifici dell'applicazione.

Un file POTREBBE contenere blocchi sconosciuti:

I lettori DOVRANNO ignorare questi blocchi. Gli autori DEVONO conservarli nel loro ordine originale (a meno che non intendano modificare specificamente questi blocchi).

Montaggio della tela da cornici

Qui forniamo una panoramica di come un lettore DEVE assemblare una tela nel caso di un'immagine animata.

Il processo inizia con la creazione di un canvas utilizzando le dimensioni specificate nel blocco "VP8X", Canvas Width Minus One + 1 pixel di larghezza per Canvas Height Minus One + 1 pixel di altezza. Il campo Loop Count del blocco "ANIM" controlla quante volte viene ripetuto il processo di animazione. È Loop Count - 1 per valori Loop Count diversi da zero o infinito se Loop Count è zero.

All'inizio di ogni iterazione loop, la tela viene riempita con il colore di sfondo del blocco "ANIM" o un colore definito dall'applicazione.

I blocchi "ANMF" contengono singoli frame specificati in ordine di visualizzazione. Prima di eseguire il rendering di ogni frame, viene applicato il Disposal method del frame precedente.

Il rendering del frame decodificato inizia in base alle coordinate cartesiane (2 * Frame X, 2 * Frame Y), utilizzando come origine l'angolo in alto a sinistra del canvas. Frame Width Minus One + 1 pixel di larghezza per Frame Height Minus One + 1 pixel di altezza vengono visualizzati sul canvas utilizzando Blending method.

La tela viene visualizzata per Frame Duration millisecondi. Questo continua finché non vengono visualizzati tutti i frame specificati dai blocchi "ANMF". Viene quindi avviata una nuova iterazione in loop o il canvas viene lasciato nello stato finale se tutte le iterazioni sono state completate.

Il seguente pseudocodice illustra il processo di rendering. La notazione VP8X.field indica il campo nel blocco "VP8X" con la stessa descrizione.

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

Esempi di layout di file

Un'immagine con codifica con perdita di dati alpha può avere il seguente aspetto:

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

Un'immagine con codifica senza perdita di dati può avere il seguente aspetto:

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

Un'immagine senza perdita di dati con un profilo ICC e metadati XMP potrebbe avere il seguente aspetto:

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

Un'immagine animata con metadati EXIF potrebbe avere il seguente aspetto:

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)