Sei sulla pagina 1di 42

CASO DI STUDIO DI

SISTEMI MULTIMEDIALI

PROF. GIOVANNI DIMAURO

WEBP
UN NUOVO FORMATO IMMAGINE PER IL WEB

Di:
Angelo Curci, Matricola 556980
Vincenzo Mazzone, Matricola 557400
Leonardo Torella, Matricola 558355
INDICE

1. ABSTRACT..................................................................................................................4
2. COMPRESSIONE LOSSY.............................................................................................4
2.1 Funzionamento VP8...........................................................................................5
2.1.1 TIPI DI PREDIZIONE.....................................................................................7
2.1.2 PREDIZIONE DELLA CROMINANZA............................................................10
2.1.3 PREDIZIONE DELLA LUMINANZA..............................................................11
2.2 ELABORAZIONE................................................................................................12
2.3 TRASFORMATA DISCRETA DEL COSENO...........................................................12
2.3.1 DEFINIZIONE FORMALE............................................................................12
2.4 QUANTIZZAZIONE.............................................................................................13
2.5 ORDINAMENTO A ZIG ZAG (2D → 1D).............................................................14
2.6 CODIFICA ARITMETICA.....................................................................................14
2.6.1 FUNZIONAMENTO....................................................................................15
3. COMPRESSIONE LOSSLESS......................................................................................16
3.1 APPLICAZIONE AL FORMATO DI CODIFICA WEBP............................................16
3.2 FUNZIONAMENTO............................................................................................17
3.3 RIFF CONTAINER...............................................................................................17
3.4 TRASFORMAZIONI............................................................................................18
3.4.1 PREDICTOR TRANSFORM............................................................................0
3.4.2 COLOR TRANSFORM...................................................................................1
3.4.2.1 SUBTRACT GREEN TRANSFORM..........................................................2
3.4.2.2 COLOR INDEXING TRANSFORM...........................................................2
3.5 IMAGE DATA.......................................................................................................3
3.5.1 UTILIZZI DELL'IMAGE DATA.........................................................................3
3.5.2 CODIFICA DELL'IMAGE DATA.......................................................................3
3.5.2.1 HUFFMAN LITERALS CODE..................................................................4
3.5.2.2 LZ77 BACKWARD REFERENCE..............................................................4
3.5.2.3 COLOR CACHE CODING.......................................................................6
3.6 CODICE ENTROPICO............................................................................................6
3.6.1 PANORAMICA..............................................................................................6
3.6.2 FONDAMENTO LOGICO...............................................................................6
3.6.3 DECODIFICA DEL META HUFFMAN CODES.................................................7
3.6.3 DECODIFICA DELL'ENTROPY ENCODE IMAGE DATA....................................7
4. STRUTTURA DI UN FILE WEBP..................................................................................8
4.1 RIFF FILE FORMAT...............................................................................................1
4.2 WEBP FILE HEADER............................................................................................2
4.3 SIMPLE FILE FORMAT (LOSSY)............................................................................0
4.4 SIMPLE FILE FORMAT (LOSSLESS).......................................................................1
4.5 FORMATO ESTESO (EXTENDED FILE FORMAT)...................................................1
4.5.1 ANIMATION.................................................................................................3
4.5.2 Alpha...........................................................................................................6
4.5.3 BITSTREAM (VP8/VP8L)..............................................................................8
4.5.4 COLOR PROFILE...........................................................................................8
4.5.5 METADATI....................................................................................................8
4.6 EXAMPLE FILE LAYOUTS......................................................................................9
5. APPROFONDIMENTI................................................................................................10
5.1 LZ77..................................................................................................................10
5.2 CODIFICA DI HUFFMAN....................................................................................11
5.2.1 TECNICA BASE...........................................................................................11
1. ABSTRACT

Il WebP (letto weppy) è un nuovo tipo di formato per le immagini realizzato da Google con l'obiet-
tivo di ottimizzare le immagini per l'utilizzo nel web, andando quindi a sostituire il formato JPEG,
migliorandone l'efficienza e ampliandone le funzioni. Il WebP infatti, contrariamente al JPEG, per-
mette la gestione della trasparenza nelle immagini (con un aumento dei byte di solo il 22% rispet-
to alla stessa immagine senza trasparenze), la gestione delle animazioni e quindi di poter sostituire
anche i formati PNG e GIF, entrambi molto utilizzati all'interno del web. Secondo i dati raccolti da
google, le immagini salvate nel formato WebP sono di dimensioni tra il 25-34% più piccole delle
immagini salvate nel formato JPEG secondo l'indice SSIM 1. Il WebP permette di comprimere le im-
magini sia in formato lossy2 sia in formato lossless3, è importante sottolineare come anche le im-
magini in formato lossy possano gestire le trasparenze, questo dato è importante nella sostituzio-
ne del formato PNG in quanto, essendo il PNG un formato lossless, con il WebP sarà possibile ri -
durre la dimensione delle immagini tipicamente di tre volte rispetto al PNG. Tutto questo ha come
obiettivo il ridurre sensibilmente il consumo della banda all'interno del web.

2. COMPRESSIONE LOSSY

La compressione di tipo “lossy” è basata sul formato di compressione video VP8 (creato da On2
Technologies come successore del formato VP7). Il VP8 utilizza una tecnica di predizione a blocchi
che, come molti algoritmi di tipo predittivo, divide il frame in segmenti più piccoli chiamati macro -
blocchi. La codifica predittiva consiste nello studio dei pixel già decodificati presenti nelle imme-
diate vicinanze di ogni macroblocco in modo da prevedere le informazioni sul colore all'interno di
esso. Il WebP utilizza la codifica intra-frame del VP8.

1 SSIM index, o Structural Similarity è un metodo utilizzato per confrontare la similarità tra due immagini.
L'indice SSIM misura la qualità dell'immagine basandosi sulla stessa non compressa.
2 Nella compressione di tipo lossy una volta che l'immagine viene compressa, non è più possibile ricostruire l'imma-
gine originale.
3 Nella compressione di tipo lossless una volta che l'immagine viene compressa, è possibile ricostruire l'immagine
originale, in altre parole il processo è totalmente reversibile.
2.1 Funzionamento VP8
In questo paragrafo verrà spiegato il funzionamento di una parte dell'algoritmo VP8, in particolare quella utilizzata nel formato WebP.

Il VP8 è utilizzato per codificare frame video, in questo caso lavorerà su frame singoli, le immagini
da comprimere devono avere uno spazio di colori YUV, poiché le immagini hanno come modello di
colori l'RGB, devono essere convertite in YUV per massimizzare l'efficienza del codificatore, nel
modello RGB ogni canale può rappresentare 2 8 colori, in totale quindi è possibile rappresentare 224
colori (più di 16,5 milioni), più che sufficienti a ricoprire il raggio di colori percepibili dall'occhio
umano, convertendo le immagini in YUV è possibile separare le informazioni riguardo la luminanza
(Y) da quelle riguardo la crominanza (U, V), poiché l'occhio umano percepisce maggiormente le
differenze di luce piuttosto che quelle sui colori, sarà possibile comprimere maggiormente i due
canali UV data la bassa tolleranza dell'occhio umano di percepirne i cambiamenti rispetto al canale
Y. Il passaggio dal modello RGB a quello YUV avviene tramite delle formule basate su delle costan-
ti:
date le seguenti costanti:
WR= 0.299; WB = 0.114; WG = 1 – WR – WB = 0.587.

si avranno le seguenti formule:


Y = WR * R + WG * G + WB *B;
U = 0.436 * B – Y
1 – WB
V = 0.615 * R – Y
1 – WR
Fonte http://en.wikipedia.org/wiki/YUV

Questo passaggio è ovviamente reversibile e non comporta nessuna diminuzione della dimensio-
ne dell'immagine, in quanto anche per quanto riguarda l'YUV sarà possibile rappresentare 2 24 co-
lori, quindi saranno necessari 8 bit per ciascuna componente. L'immagine viene divisa in gruppi di
pixel, per ogni gruppo verrà memorizzata l'intera informazione sulla luminanza, mentre verrà fatta
una media delle informazioni di ogni pixel sulla crominanza per ciascun gruppo. In particolare il
VP8 lavora con il formato YUV 4:2:0, in questo formato ogni pixel da 8 bit sia di U che di V corri -
sponde a un blocco di pixel 2x2 del canale Y.

ESEMPIO:

Matrice 2x2 di pixel tridimensionale YUV:


[(Y00)255, (U00)110, (V00)143] [(Y01)200, (U01)99, (V01)122]
[(Y10)240, (U10)101, (V10)123] [(Y11)201, (U11)89, (V11)112]
Stessa matrice convertita in YUV 4:2:0:
[(Y00)255, (U')100, (V')125] [(Y01)200, (U')100, (V')125]
[(Y10)240, (U')100, (V')125] [(Y11)201, (U')100, (V')125]
dove U'= ( U00 + U01 + U10 + U11) / 4
V'= ( V00 + V01 + V10 + V11) / 4

Una volta avvenuta la conversione ogni blocco di pixel 2x2 non occuperà più 96 bit di memoria ma
solo 48 bit di memoria. Questa conversione risulterebbe inutile se l'immagine fosse in scala grigi,
in quanto come è facile immaginare la scala grigi occuperebbe esclusivamente il canale Y mentre
rimarrebbero a 0 i valori di U e V.
Il prossimo passo dell'algoritmo VP8 consiste nel suddividere l'immagine in segmenti più piccoli
chiamati macroblocchi, per ogni macroblocco poi, l'algoritmo cerca di predire le informazioni sul
colore basandosi su i blocchi già processati precedentemente procedendo dal blocco in alto a sini -
stra verso destra, ripartendo poi da capo per ogni riga di macroblocchi. L'algoritmo utilizza due
classi di predizione: l'intra-prediction e l'inter-pediction, poiché il WebP utilizza solo l'intra-predic-
tion, in questo paragrafo verrà approfondita solo tale predizione.

Il VP8 intra-prediction mode utilizza 3 tipi di macroblocchi:


16x16 luminanza
4x4 luminanza
8x8 crominanza

Le predizioni sulla crominanza (U e V) e sulla luminanza (Y) sono indipendenti l'uno con l'altra.
ovviamente, dividendo l'immagine in blocchi di pixel, non è detto che tutti i blocchi saranno
16x16, 4x4, o 8x8, il codificatore riempirà l'immagine nei bordi superiore e laterale sinistro di pixel
“nulli” finché tutta l'immagine sarà divisibile in blocchi interi. In sintesi come mostrato nell'imma-
gine che segue, ogni macroblocco M quindi predetto utilizzando il macroblocco immediatamente
sopra M, in particolare l'ultima riga di pixel R in basso al blocco, il macroblocco a sinistra di R, in
particolare il pixel P in basso a destra e il macroblocco immediatamente a sinistra di M, in partico -
lare la colonna di pixel L pixel a destra del blocco, come mostrato nell'immagine:

P R

L M

Tutti i pixel dei macroblocchi adiacenti ad M utilizzati per la predizione, sono già stati predetti, in
questo caso nel codificatore avviene anche una decodifica momentanea che permette appunto la
codifica di M utilizzando informazioni già compresse.

2.1.1 TIPI DI PREDIZIONE

Esistono 4 tipi di predizione, più altri sottotipi per un totale di 10 metodi differenti adesso elencati
utilizzando come riferimento l'immagine precedente:
R0 R1 R2 R3
L0 R0 R1 R2 R3
L1 R0 R1 R2 R3 1. Predizione Verticale: il macroblocco M viene predetto replicando i pi-
L2 R0 M
R1 R2 R3 xel della riga R in ogni colonna di M.
L3 R0 R1 R2 R3

L0 L0 L0 L0 L0 L0
L1 L1 L1 L1 L1 L1 2. Predizione Orizzontale: il macroblocco M viene predetto replicando la

L2 L2 L2M L2 L2 L2 colonna L in ogni riga di M.

L3 L3 L3 L3 L3 L3

PR 0
R1 R2 R3
3. Predizione “True Motion”: ogni pixel Mxy del macroblocco M viene cal-
L0 M00 M01 M02 M03
colato sommando il pixel in corrispondenza della riga R e quello della
L1 M10 M11 M12 M13
colonna L sottraendo il risultato con il pixel P. Il risultato potrebbe con-
L2 M20 M21 M22 M23
tenere valori Mxy < di 0 o Mxy > di 255, in tal caso l'algoritmo porterà tali
L3 M30 M31 M32 M33
valori a 0 se Mxy < 0 altrimenti a 255 se Mxy > 255.

P R
4. Predizione “media”: il macroblocco M viene riempito con la media dei
P+R+L
L valori dei pixel di L, R e il pixel P.
1+nR+nL

R0 R1 R2 R3
R1 R2 R3 R4
5. Predizione Verticale-Sinistra: il macroblocco M viene predetto replican-
R2 R3 R4 R5
R3 M
R4 R5 R6
do i pixel della riga R in ogni colonna di M translando i pixel verso sini -
stra man mano che si scende con le righe.
R4 R5 R6 R7
R0 R1 R2 R3
6. Predizione Verticale-Destra: il macroblocco M viene predetto replican-
R-1 R0 R1 R2
do i pixel della riga R in ogni colonna di M translando i pixel verso destra
R-2 R-1 R0 R1
R-3 M
R-2 R-1 R0
man mano che si scende con le righe.

R-4 R-3 R-2 R-1

L0 L-1 L-2 L-3 L-4 L-5 7. Predizione Orizzontale-Basso: il macroblocco M viene predetto repli-
L1 L0 L-1 L-2 L-3 L-4 cando la colonna L in ogni riga di M, translando man mano la colonna L
L2 M
L1 L0 L-1 L-2 L-3 verso il basso.
L3 L2 L1 L0 L-1 L-2

L0 L1 L2 L3 L4 L5
8. Predizione Orizzontale-Alto: il macroblocco M viene predetto replican-
L1 L2 L3 L4 L5 L6
L2 L3 L4 M L5 L6 L7
do la colonna L in ogni riga di M, translando man mano la colonna L ver-
so l'alto.
L3 L4 L5 L6 L7 L8

PR 0
R1 R2 R3
L0 P R0 R1 R2
9. Predizione Destra-Basso: il macroblocco M viene predetto replicando i
L1 L0 P R0 R1
pixel della riga R, di P e della colonna L in basso e a destra.
L2 L1 L0 P R1
L3 L2 L1 L0 P

R0 R1 R2 R3 P 10. Predizione Sinistra-Basso: il macroblocco M viene predetto replicando i


R1 R2 R3 P L3
pixel della riga R, di P e della colonna L in basso e a sinistra. Utilizzata
R2 R3 P L3 L2
durante le predizioni per la luminanza sul lato destro dell'immagine.
R3 P L3 L2 L1
P L3 L2 L1 L0
2.1.2 PREDIZIONE DELLA CROMINANZA
La predizione sulla crominanza è leggermente più semplice rispetto a quella sulla luminanza, per questo motivo verrà spiegata prima della predizio -
ne sulla luminanza, inoltre ogni metodo applicato per la crominanza è identico sia per U sia per V, quindi verranno calcolati in parallelo.

P R

L M

La predizione sulla crominanza utilizza macroblocchi di dimensioni 8x8 pixel, per ogni macroblocco
vengono generati quattro blocchi tramite l'utilizzo di quattro predizioni:
predizione verticale (se il blocco corrente è situato nella riga superiore dell'immagine, tutti i pixel
della riga R utilizzata per predire il blocco avranno valore 127);
predizione orizzontale (se il blocco corrente è situato nella colonna sinistra dell'immagine, tutti i
pixel della colonna utilizzata per predire il blocco avranno valore 129);
predizione media (se il blocco corrente è situato nell'angolo superiore sinistro dell'immagine,
l'intero blocco sarà riempito con valore 128, se il blocco invece è situato all'interno della riga supe-
riore dell'immagine, verrà calcolata la media solo della colonna L, se invece è situato all'interno
della colonna sinistra dell'immagine, verrà calcolata la media solo dei va lori della riga R);
predizione “true motion” (se il blocco corrente è situato nell'angolo superiore sinistro dell'imma-
gne o comunque nella riga superiore o colonna sinistra dell'immagine, i valori di R e L saranno gli
stessi descritti nella predizione orizzontale/verticale mentre P avrà valore 128).
2.1.3 PREDIZIONE DELLA LUMINANZA

La luminanza viene predetta due volte, una volta utilizzando blocchi di pixel 16x16 e un altra volta
utilizzando i blocchi 4x4. La procedura è simile alla predizione della crominanza, la sostanziale dif-
ferenza sta nel fatto che i blocchi analizzati non saranno 8x8 ma 16x16, in oltre per la luminanza a
parte i quattro metodi di predizione utilizzati per la crominanza esiste un altro metodo più com-
plesso, tale metodo consiste nel dividere il blocco di pixel 16x16 in 16 sotto-blocchi di 4x4 pixel.
Ogni sotto-blocco Sxy potrà essere predetto indipendentemente con uno dei 10 metodi di predizio-
ne (elencati in 2.1.1).

P1 R1 P2 R2 P3 R3 P4 R4

L1 S1 L2 S 2 L3 S3 L4 S4
P5 R5 P6 R6 P 7 R7 P 8 R8

L5 S5 L6 S6 L7 SM7 L8 S8

P9 R9 P10 R10 P11 R11 P12 R12


16 pixel

L9 S9 L10 S10 L11 S11 L12 S12

P13 R13 P14 R14 P15 R15 P16 R16

L13 S13 L14 S14 L15 S15 L16 S16

16 pixel
2.2 ELABORAZIONE

Una volta predetti, i valori ottenuti dai blocchi vengono sottratti ai valori del blocco originale gene-
rando i blocchi residui, analizzando poi i risultati di ogni residuo, l'algoritmo mantiene esclusiva-
mente il blocco con il miglior risultato ottenuto dalla sottrazione, cioè quello con valori più bassi e
prosegue la codifica dei dati dei dati applicando la Trasformata Discreta del Coseno (DCT).

2.3 TRASFORMATA DISCRETA DEL COSENO

La trasformata discreta del coseno esprime una sequenza finita di data points 4 in termini di som-
me di funzioni coseno che oscillano su frequenze differenti. In campo informatico la DCT è impor-
tante per la compressione di dati di tipo lossy, non solo viene utilizzata per video ed immagini ma
anche per audio (mp3, il più famoso algoritmo di compressione audio, utilizza il DCT).

Un’immagine può essere pensata come una composizione della somma di diverse variazioni di lu-
minosità di forma cosinusoidale di diversa frequenza spaziale, fase e intensità. Le alte frequenze
definiscono i dettagli dell’immagine, mentre le basse frequenze indicano le ombreggiature.

2.3.1 DEFINIZIONE FORMALE

da Wikipedia

Dove:
• N : dimensione dei blocchi (4 pixel);
• f(x, y): valori in posizione (x, y) del blocco da trasformare;
• F(u, v): valori DCT di posizione (u, v) con u, v = [0, 3] dove u è la frequenza spaziale orizzon-
tale e v quella verticale;

4 I data points sono i punti cardine dell'oggetto studiato, in questo caso i punti più importanti di un'immagine
L'algoritmo suddivide l'immagine residua in blocchi di 4x4 pixel, ognuno di essi può essere visto
come un vettore nello spazio a 16 dimensioni, e rappresentano la base delle immagini (detta base
Canonica). Ogni blocco dopo l'applicazione della DCT, viene trasformato dal dominio dello spazio
al dominio delle frequenze. Ogni blocco trasformato sarà rappresentato da uno spettro di frequen-
ze dell'immagine costituita da un raggruppamento di pixel bianchi e neri. Le aree bianche rappre-
sentano una maggiore intensità luminosa presente in quelle zone. In questo modo è possibile indi -
viduare le aree sacrificabili in quanto l'occhio umano non le percepisce o comunque non ne distin-
guerebbe completamente i dettagli. Parlando in generale, applicando la DCT su una matrice di va-
lori, il risultato sarà una matrice di pari dimensioni contenente coefficienti di cui nel valore in alto
a sinistra ci sarà la media dei valori nel dominio dello spazio del blocco detta Componente Conti-
nua (Coefficiente DC), gli altri coefficienti sono detti Coefficienti AC. In questo modo risulta più
semplice smorzare le alte frequenze (coefficienti in basso a destra) data l'impossibilità dell'occhio
umano di coglierne i dettagli.

Esempio:
Blocco immagine Applicazione della DCT

255 0 255 0 510 195.1686 0 471.1786

255 0 255 0 0 0 0 0

255 0 255 0 0 0 0 0

255 0 255 0 0 0 0 0
Valori calcolati tramite la funzione 2dct() di matlab.

Tale trasformazione di per sé non crea nessuna compressione dell'immagine, infatti per memoriz-
zare un blocco 4x4 saranno necessari comunque 16 Byte di memoria, inoltre non c'è perdita di in-
formazioni in quanto la trasformazione è completamente reversibile. Tale trasformazione però
rende molto più efficiente le successive procedure.

2.4 QUANTIZZAZIONE

Dopo aver ottenuto l'immagine residua trasformata tramite DCT, viene applicato il metodo di
“quantizzazione”. Tale operazione permette di rappresentare i coefficienti tramite un incremento
del fattore di compressione, più precisamente avviene una riduzione dei bit necessari per memo-
rizzare un valore intero riducendone la precisione. L'effetto voluto è quello di arrotondare i valori
originali prossimi a 0 portandoli esattamente a 0, smorzare le alte frequenze e arrotondare con
maggiore precisione le basse frequenze. Una volta applicata la quantizzazione, dato lárrotonda-
mento dei valori, non sarà più possibile effettuare una funzione inversa per trovare i dati originali,
ecco perché la quantizzazione è il momento in cui avviene la compressione di dati con perdita di
informazioni, l'immagine ricostruita sarà il risultato di un ipotizzazione dei dati posseduti per avvi-
cinarsi il più possibile a quelli originali.

2.5 ORDINAMENTO A ZIG ZAG (2D → 1D)

Dopo la quantizzazione il blocco conterrà molti valori pari a 0, tutti quei valori permetteranno una
efficiente applicazione della codifica aritmetica consentendo finalmente di ridurre i bit necessari
per salvare l'immagine. A questo punto ogni blocco conterrà valori alti nella parte in alto a sinistra
riducendosi a 0 man mano che si raggiunge la parte in basso a destra. Per sfruttare questa situa -
zione i coefficienti verranno ordinati in modo tale da raggruppare gli 0 in sequenze più lunghe pos -
sibile, questo ordinamento verrà effettuato trasformando la matrice in una stringa continua dove
verranno inseriti i valori della matrice prendendoli tramite un percorso a zig-zag:

A questo punto verranno inserite all'interno di ogni blocco informazioni contenenti i dati sul tipo
di quantizzazione effettuata e sul tipo di predizione che ha portato alla realizzazione del residuo,
tali informazioni sanno poi utilizzate dal decodificatore per ricostruire l'immagine. A questo punto
avremo una stringa di dati contenente ridondanza di valori 0, questi valori verranno “eliminati”
tramite la codifica aritmetica.

2.6 CODIFICA ARITMETICA

La codifica aritmetica è una tecnica di compressione lossless. Normalmente in informatica i dati


sono rappresentati come un insieme fisso di bit, per esempio i caratteri sono spesso rappresentati
con otto bit. La codifica aritmetica partendo dal presupposto che alcuni simboli tendono ad appa-
rire più frequentemente di altri assegna dei codici di lunghezza variabile ai simboli al fine di mini-
mizzare il numero totale di bit da trasmettere. Questa strategia viene utilizzata anche da altri siste-
mi di codifica, come la codifica di Huffman, ma mentre la codifica di Huffman associa una specifica
codifica a ogni singolo simbolo la codifica aritmetica associa una singola codifica all'intero messag-
gio o a blocchi di questo.

2.6.1 FUNZIONAMENTO

La codifica aritmetica produce una compressione sub-ottima (secondo la teoria della compressio-
ne dei dati il valore ottimale è −log 2P bit per ogni simbolo con probabilità P). L'algoritmo di com-
pressione parte definendo un modello dei dati, una loro distribuzione probabilistica, questa in-
fluenza in misura preponderante la bontà della compressione.
Per esempio, un semplice modello statico potrebbe definire:
• 60% di possibilità di avere un simbolo NEUTRO
• 20% di possibilità di avere un simbolo POSITIVO
• 10% di possibilità di avere un simbolo NEGATIVO
• 10% di possibilità di avere un simbolo di FINE-DEL-FILE (questo simbolo serve al decodifica-
tore per dire che il flusso da decodificare è terminato)
Il modello di esempio utilizza solo quattro simboli ed è un modello didattico, ma conoscendo il
contesto si possono sviluppare modelli più sofisticati, per esempio se si sa di dover codificare un
testo in inglese si sa che la lettera "u" è molto più comune della lettera "Q" o "q" e quindi si po-
tranno assegnare le probabilità di conseguenza. I modelli possono anche essere adattivi, in questo
caso adattano le probabilità dei simboli all'andamento dei dati. Ovviamente il decodificatore deve
conoscere il modello usato dal codificatore.
La codifica è composta fondamentalmente da tre passi:
1. il nuovo simbolo viene prelevato;
2. il corrente intervallo di codifica viene definito (all'inizio l'intervallo di codifica è quello mas-
simo quindi [0,1) ma durante la codifica si riduce);
3. Si calcola la probabilità dei simboli, questo passo è necessario se l'algoritmo stima le pro -
babilità durante la codifica, se sono definite in modo fisso questo passo non viene esegui -
to.
Seguendo l'esempio precedente si suddividono gli intervalli tramite una probabilità fissa.
• Il simbolo NEUTRO ha intervallo [0, 0.6)
• Il simbolo POSITIVO ha intervallo [0.6, 0.8)
• Il simbolo NEGATIVO ha intervallo [0.8, 0.9)
• Il simbolo FINE-DEL-FILE ha intervallo [0.9, 1)
Quando tutti i simboli vengono codificati il risultato è un intervallo che identifica in modo non am -
biguo la sequenza di simboli che l'ha generato. Quindi ogni sistema che conosce il modello e
l'intervallo è in grado di ricostruire la sequenza di simboli. A questo punto l'immagine elaborata
deve solo essere pacchettizzata.

3. COMPRESSIONE LOSSLESS

Lossless data compression è una classe di algoritmi per la compressione dei dati che permette
all’originale di essere perfettamente ricostruito partendo dalla sua versione compressa. Al contra-
rio gli algoritmi “lossy” permettono solo la ricostruzione di un approssimazione dell’originale, an-
che se con queste tecniche si migliora il tasso di compressione (e quindi la dimensione del file).
Le tecniche di compressione lossless vengono utilizzate in diverse applicazioni oltre a quella speci-
fica che andremo ad analizzare, come ad esempio nel formato file ZIP, nel tool GNU chiamato gzip
e spesso viene inoltre utilizzato come componente all’interno delle stesse tecniche “lossy”. Come
evidenziato precedentemente, queste tecniche sono utili nel momento in cui sia importante che il
dato decompresso sia identico a quello originale, poiché eventuali sue alterazioni risulterebbero
deleterie.

3.1 APPLICAZIONE AL FORMATO DI CODIFICA WEBP

L’applicazione della codifica lossless al formato immagine WebP per la compressione delle im-
magini ARGB5 comporta una memorizzazione dei valori di ogni singolo pixel, includendo i valori
cromatici zero alpha. Questa tecnica utilizza immagini ad una risoluzione minore, ricorsivamen-
te legate al formato stesso, per memorizzare dati statistici sulle immagini (codici di entropia uti-
lizzati, predittori spaziali, conversione dello spettro cromatico e tabella dei colori). La maggior
parte dei dati viene memorizzata utilizzando poi codifiche secondo Huffmann ed LZ77 insieme
ad una cache dei colori. Ad oggi sono state dimostrate velocità di decodifica ed un tasso di com-
5 ARGB: Il valore di un pixel costituito da valori alpha, rosso, verde e blu. Immagine ARGB: un array bidimensionale
contenente pixel ARGB.
pressione del 25% maggiore rispetto all’odierno formato PNG.

3.2 FUNZIONAMENTO

Durante la codifica i bytes vengono letti nell’ordine naturale del flusso che li contiene, e ogni bit
viene letto utilizzando il principio “least significant bit first”. Quando più bit vengono letti allo
stesso tempo, l’intero oggetto viene ricostruito dai dati originali. I bit più significativi dell’oggetto
risultante lo sono anche per quello originale.
Assumendo che ogni componente cromatico (alpha, red, blue e green) è rappresentato utilizzando
un byte, definito come un tipo “uint8”, un intero pixel ARGB viene rappresentato da un tipo chia-
mato “uint32”, ovvero un unsigned integer composto da 32 bits. Nel codice che mostra il compor-
tamento della codifica, il valore alpha viene codificato nei bit da 31 a 24, il rosso da 23 a 16, il ver-
de da 15 a 8 e il blu da 7 a 0 (anche se diverse implementazioni del formato rispetto allo standard
sono libere di utilizzare un altra rappresentazione interna). Un immagine WebP Lossless contiene
inoltre dati “di intestazione” che si riferiscono ad informazioni riguardo la codifica (cruciali per la
decodifica) ed a dati generici sull’immagine (altezza e larghezza).

3.3 RIFF CONTAINER

All’inizio del RIFF header troviamo il “RIFF container”, constituito dai seguenti 21 byte:
1. Stringa RIFF
2. Un valore “little-endian”6 a 32 bit riguardante la lunghezza e l’intera dimensione del blocco
controllato dal RIFF header. Normalmente quest’ultima è equivalente alla dimensione del
payload (dimensione del file meno 8 bytes, 4 per l’identificatore “RIFF” e 4 per memorizza-
re il valore stesso)
3. Stringa “WEBP” (nome del RIFF container)
4. Stringa “VP8L” (etichetta chunk per immagini codificate secondo lossless)
5. Valore Little-endian a 32 bit riguardante il numero di byte nel flusso dati Lossless
6. Un byte “signature” 0x2f (slash)
I primi 28 bit del bitstream specificano la larghezza e l’altezza dell’immagine, codificate come interi
a 14 bit.
Questa dinamica a 14 bit limita la massima dimensione di un immagine (in termini di estensione) a

6 Little-endian modalità usate dai computer per immagazzinare in memoria dati di dimensione superiore al byte ini-
ziando a memorizzare dal byte meno significativo per finire al byte più significativo.
16384x16384 pixel. Il bit “alpha_is_used” viene utilizzato solo come “flag” e non ha impatti sulla
decodifica, venendo impostato a 255 se tutti i valori alpha sono 255 nell’immagine e ad 1 in caso
contrario. Il “version_number” è un dato a 3 bit che deve essere impostato a 0, ed ogni altro valo-
re verrà interpretato come un errore.
int alpha_is_used = ReadBits(1);

int version_number = ReadBits(3);

3.4 TRASFORMAZIONI
Definiamo come “trasformazioni” le manipolazioni reversibili dei dati dell’immagine che possono
ridurre l’entropia simbolica residua modellando le correlazioni spazio-cromatiche. La compressio-
ne finale può risultare più densa grazie a queste ultime.

Un immagine può essere soggetta a quattro tipi di trasformazione, indicando la presenza di queste
ultime con un bit settato ad “1”. Ognuna di esse può essere usata solo una volta, e solo sull’imma-
gine ARGB al livello principale: le immagini a risoluzione scalata non hanno trasformazioni, e nem -
meno il bit “0” indicante l’assenza delle trasformazioni.

Solitamente un codificatore utilizza queste trasformazioni per ridurre “l’entropia di Shannon”7


nell’immagine risultante. Quest’ultima viene “decisa” in base al principio della minimizzazione
dell’entropia. Se una trasformazione è presente allora i seguenti due bit specificano quale delle
quattro trasformazioni esistenti ha avuto luogo:

enum TransformType {
PREDICTOR_TRANSFORM = 0,
COLOR_TRANSFORM = 1,
SUBTRACT_GREEN = 2,
COLOR_INDEXING_TRANSFORM = 3,
};

Il tipo di trasformazione è seguito dal trasform data, contenente le informazioni richieste per ap-
plicare la trasformazione inversa e dipende dal tipo di trasformazione. Verrà descritto quindi per
ciascun tipo il relativo transformation data.

7 L'Entropia di Shannon è il limite minimo della compressione dei dati senza perdita d'informazione.
3.4.1 PREDICTOR TRANSFORM

Il Predictor Transform riduce l’entropia utilizzando il principio secondo il quale i pixel vicini sono
solitamente correlati. Il valore del pixel corrente è quindi predetto da quelli già decodificati (in or-
dine di scansione) e solo il valore residuo (risultante da valore attuale- valore predetto) è codifica-
to. La “predictor mode” determina il tipo di predizione da utilizzare dividendo l’immagine in “qua-
drati” ed utilizzando per ognuno di essi il metodo più appropriato.

I primi 3 bit del “prediction data” definiscono la grandezza del blocco in numero di bit, mentre il
numero di colonne è utilizzato per indicizzarli bidimensionalmente. I dati trasformati contengono
la “prediction mode” per ogni “quadrato” dell’immagine, utilizzata da tutti i pixel all’interno di
quest’ultimo e codificato come se fosse uno di questi.
Ci sono 14 differenti modalità di predizione, ed in ognuna il valore del pixel corrente è predetto se -
condo il valore già conosciuto di quelli vicini. Scegliendo questi ultimi (TL, T, TR, and L) del pixel
corrente P come segue:

O O O O O O O O O O O
O O O O O O O O O O O
O O O O TL T TR O O O O
O O O O L P X X X X X
X X X X X X X X X X X
X X X X X X X X X X X

dove le sigle sono abbreviazioni per le direzioni in cui rispettivamente si trovano. Utilizzando la si -
tuazione precedente come esempio, veranno definite le diverse modalità di previsione come se-
gue:

Modalità Valore predetto di ciascun canale del pixel corrente

0 0xff000000 (rappresenta il colore nero in ARGB)

1 L
2 T

3 TR

4 TL

5 Average2(Average2(L, TR), T)

6 Average2(L, TL)

7 Average2(L, T)

8 Average2(TL, T)

9 Average2(T, TR)

10 Average2(Average2(L, TL), Average2(T, TR))

11 Select(L, T, TL)

12 ClampAddSubtractFull(L, T, TL)

13 ClampAddSubtractHalf(Average2(L, T), TL)

3.4.2 COLOR TRANSFORM8

L’obbiettivo della “Color Transform” è di deinterlacciare i valori R, G e B di ciascun pixel. Con que -
sta trasformazione viene lasciato il verde così com’è, il rosso viene modificato in base al verde, e il
blu basandosi sul verde e quindi sul rosso.
Se il predictor transform sceglie di utilizzare questo metodo, divide prima l’immagine in “blocchi” ,
per poi utilizzare la stessa modalità di trasformazione per tutti i pixel all’interno. Per ogni blocco ci
sono tre tipi di elementi secondo cui modificare i colori.
typedef struct {

uint8 green_to_red;
uint8 green_to_blue;
uint8 red_to_blue;
} ColorTransformElement;

L’attuale modifica ai colori è esegguita definendo un “color transform delta”. Questo elemento di-
pende dal “ColorTransformElement”, costante per ogni pixel in un particolare blocco. Il delta è ag-
giunto durante la trasformazione. Il processo inverso prevede soltanto la sottrazione di questo

8 Color Transform Image: Un’immagine bidimensionale a risoluzione abbassata contenente i dati riguardanti le cor-
relazioni tra le componenti colore.
“delta”.
Verranno ora descritti i contenuti dei dati risultanti dal processo di color transform in maniera tale
che la decodifica possa applicare la procedura inversa per recuperare gli originali valori di rosso e
di blu. I primi 3 bit contengono le dimensioni del blocco dell’immagine in bit, esattamente come
nel predictor transform. La restante parte dei dati color transform contiene istanze di ColorTran-
sformElement corrispondenti a ciascun blocco dell’immagine. Queste vengono quindi trattate
come pixel dell’immagine e decodificate come tali. Durante questo processo viene applicata la tra-
sformazione inversa sui valori ARGB dei pixel e, come menzionato prima, questa trasformazione
consiste nel sottrarre i valori in “ColorTransformElement” dai canali del rosso e del blu.

3.4.2.1 SUBTRACT GREEN TRANSFORM

Il Subtract Green Transform sottrae i valori del verde dai valori del rosso e del blu di ciascun pixel,
e quando si và a decodificare basta riaggiungere i valori del verde sottratti nel momento della co-
difica.

3.4.2.2 COLOR INDEXING TRANSFORM

Se non ci sono molti valori unici potrebbe essere più efficiente creare un “contenitore” dei colori e
sostituire i valori dei pixel con gli indici di quest’ultimo. La color Indexing Transform 9 fa esattamen-
te questo.
La color indexing transform controlla il numero di valori unici ARGB nell’immagine e, se inferiore
ad una certa soglia (256), crea un array di quei valori. In base a quest’ultimo sostituisce quei valori
con i corrispettivi indici: il canale verde dei pixel è sostituito dall’indice, mentre tutti i valori alpha
vengono impostati a 255 e quelli rossi e blu a 0.
La risultante di questo processo contiene la dimensione della tabella dei colori e gli elementi al
suo interno. La tabella colori è salvata utilizzando lo stesso formato secondo cui viene memorizza-
ta l’immagine. Essa può essere ottenuta leggendo un immagine trascurando il RIFF header, la di-
mensione dell’immagine e le trasformazioni, assumendo l’altezza di un pixel e la larghezza di “co -
lor_table_size”. La tabella dei colori è inoltre sempre “subtraction-coded” per ridurre l’entropia
dell’immagine. I delta delle palette cromatiche contengono solitamente molta meno entropia dei
colori stessi, portando a un risparmio significativo per le immagini più piccole. Nella decodifica

9 Color Indexing Image: Un'immagine uno-dimensionale che può essere indicizzata utilizzando un small integer.
ogni colore finale nella tabella colori può essere ottenuto aggiungendo il valore del colore prece -
dente per ciascuno di essi, e memorizzando gli 8 bit meno significativi del risultato.
La trasformazione inversa per l’immagine consiste semplicemente nella sostituzione dei valori dei
pixel (che sono indici alla tabella colori) col l’attuale valore della tabella dei colori. L’indicizzazione
è eseguita basandosi sul componente verde del colore ARGB.
Se l’indice è uguale o più grande della “color_table_size”, il colore viene impostato a 0x00000000
(nero trasparente).
Quando la tabella colori è piccola (uguale o inferiore a 16 colori), diversi pixel vengono considerati
come unico, unendoli a gruppi di 2,4 o 8 riducendo rispettivamente la larghezza dell’immagine.
Questa tecnica permette una più efficente distribuzione entropica dei nodi codificati sui pixel vici-
ni, ma può essere usata soltanto quando c’è un numero piccolo di valori unici.

3.5 IMAGE DATA

Image Data è un array di valori dei pixel ordinati secondo la linea di scansione.

3.5.1 UTILIZZI DELL'IMAGE DATA

L’Image Data viene utilizzato in differenti situazioni:

1. immagini ARGB: memorizza i pixel dell’immagine;


2. immagine entropica: Memorizza i codici meta-Huffman. Le componenti rosso e verde di un
pixel definiscono la codifica meta-Huffman usati in un particolare blocco dell’immagine
ARGB.
3. Predictor Image10: Memorizza i metadati per la Predictor Transform. La componente verde
di un pixel definisce quale dei 14 predittori è utilizzato all’interno di un particolare blocco
dell’immagine ARGB.

3.5.2 CODIFICA DELL'IMAGE DATA

La codifica dell’image data è indipendente dalle diverse situazioni. Prima di tutto l’immagine è di-

10 Predictor Image: Un’immagine bidimensionale a risoluzione abbassata indicante quale predittore spaziale è utiliz-
zato per un particolare quadrato nell’immagine.
visa in blocchi di lunghezza fissa (tipicamente in blocchi 16x16.) Ciascuno di questi blocchi è mo-
dellato utilizzando il proprio codice entropico lo stesso codice entropico.
Memorizzare il codice entropico comporta un costo che può essere minimizzato se blocchi simili
statisticamente condividono lo stesso codice entropico. In questo modo è necessario memorizzare
il codice entropico una sola volta.
Ciascun pixel è codificato utilizzando uno di tre possibili metodi: Literals Huffman Code, LZ77 back-
ward reference, color cache11 code.

3.5.2.1 HUFFMAN LITERALS CODE

Il pixel è memorizzato usando la codifica di Hufmann dei valori del verde, rosso, blu e alpha (in
quest’ordine).

3.5.2.2 LZ77 BACKWARD REFERENCE

Le backward reference sono tuple di lunghezza e codice distanza. La lunghezza indica il numero di
pixel da copiare (in ordine di scansione.) Il distance code è il numero indicante la posizione di cia -
scun pixel precedentemente visto, a partire dalla quale i pixel devono essere copiati. I valori di lun-
ghezza e distanza sono memorizzati utilizzando il LZ77 prefix coding 12, che divide le variabili large
integer in due parti: il prefix code, memorizzato utilizzando del codice entropico, e gli extra bits,
memorizzati così come sono.
Vantaggi: questo approccio riduce la richiesta di memoria per il codice entropico. Inoltre, grandi
valori sono di norma rari, quindi gli extra bits saranno utilizzati per pochissimi valori nell’immagi-
ne. Quindi questo approccio risulta complessivamente in una migliore compressione.
La tabella seguente chiarisce l’uso del prefix codes e degli extra bits utilizzati per memorizzare dif-
ferenti range di valori.

Value Range Prefix Code Extra Bits

1 0 0

11 Un piccolo array di indirizzi hash per memorizzare i colori utilizzati recentemente, rendendo possibile richiamarli
con poco codice.
12 Prefix Coding: Un modo per codificare entropicamente interi più grandi che codifica pochi pezzi dell’intero utiliz-
zando una codifica entropica e i restanti con una codifica raw. Questo permette alle descrizioni dei codici entropici
di rimanere relativamente piccolo anche quando il range dei simboli è molto ampio.
2 1 0

3 2 0

4 3 0

5..6 4 1

7..8 5 1

9..12 6 2

13..16 7 2

... ... ...

3072..4096 23 10

... ... ...

524289..786432 38 18

786433..1048576 39 18

Distance mapping13
Come detto precedentemente, il distance code è un numero indicante la posizione del pixel analiz-
zato in precedenza, dal cui punto in poi i pixel seguenti sono copiati.
Un distance code più grande di 120 denota la distanza del pixel in ordine di scansione, spostato di
120. Le più piccole distance codes [1...120] sono riservate per i pixel “vicini” al pixel corrente. Que-
sto vicinato consiste dei seguenti 120 pixel:
i pixel che sono da 1 a 7 righe sopra, fino 8 colonne a sinistra e fino a 7 colonne a destra del pixel
corrente. [Totale pixels = 7 * (8 + 1 + 7) = 112]
i Pixel che sono sulla stessa riga del pixel corrente, e sono fino ad 8 colonne a sinistra del pixel cor-
(0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), (-1, 2),
rente (Totale: 8 pixels.)
(2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), (1, 3), (-1, 3),
Esempio di distance mapping: (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), (-3, 2), (0, 4), (4, 0),
(1, 4), (-1, 4), (4, 1), (-4, 1), (3, 3), (-3, 3), (2, 4), (-2, 4),
(4, 2), (-4, 2), (0, 5), (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0),
(1, 5), (-1, 5), (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2),
(4, 4), (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0),
(1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), (-6, 2),
(4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), (6, 3), (-6, 3),
(0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), (-5, 5), (7, 1), (-7, 1),
(4, 6), (-4, 6), (6, 4), (-6, 4), (2, 7), (-2, 7), (7, 2), (-7, 2),
(3, 7), (-3, 7), (7, 3), (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5),
(8, 0), (4, 7), (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6),
(-6, 6), (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7),
(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)

13 Distance Mapping: Modifica le distanze LZ77 per avere il più piccolo valore dei pixel in prossimità 2D.
Per esempio il distance code 1 indica un offset di (0,1) per il pixel vicino, ovvero il pixel sopra quel -
lo corrente. La coordinata indica 0 pixel di differenza sull’asse orizzontale ed un pixel di differenza
sull’asse verticale. Allo stesso modo il distance code 3 indica il pixel in alto a sinistra.

3.5.2.3 COLOR CACHE CODING

La color cache memorizza un set di colori utilizzati recentemente nell’immagine. I codici color ca-
che sono memorizzati così come segue: prima di tutto c’è un bit di valore 1 che indica se la color
cache è stata utilizzata. Se il bit ha valore 0 nessun codice color cache esiste, e quindi non vengono
trasmessi nel codice Huffman che decodifica i green symbols e i length prefix codes.
All’inizio della decodifica o codifica dell’immagine, tutte le voci in ogni color cache sono settate sul
valore zero. La cache dei codici dei colori viene mantenuta inserendo ogni pixel, ottenuto tramite
backward reference o come literals, all’interno della cache nell’ordine in cui appaiono nel flusso
dati.

3.6 CODICE ENTROPICO

3.6.1 PANORAMICA

La maggior parte dei dati viene codificata utilizzando il canonico codice Huffman. Da qui, i codici
sono trasmessi inviando la lunghezza del codice Huffman, al contrario dell’attuale codice Huffman.
In particolare, il formato Webp utilizza la varianza-spaziale della codifica Huffman. In altre parole,
blocchi differenti dell’immagine possono potenzialmente utilizzare differenti codici entropici.

3.6.2 FONDAMENTO LOGICO

Differenti aree dell’immagine possono avere differenti caratteristiche. Quindi, permettendo loro di
utilizzare differenti codici entropici l’algoritmo fornisce una maggiore flessibilità e (potenzialmen-
te) una migliore compressione.
L’immagine codificata consiste di due parti:
1. Meta Huffman codes;14
2. Entropy-coded image data.15

3.6.3 DECODIFICA DEL META HUFFMAN CODES


Come osservato in precedenza, il formato consente l’uso di differenti codifiche Huffman per diffe-
renti blocchi dell’immagine. I Meta Huffman Codes sono indici che identificano quale codice Huff-
man utilizzare in differenti parti dell’immagine. Questa tecnica può essere utilizzata solo in imma-
gini ARGB.
In base al valore di un bit, si vengono a determinare due diverse situazioni:

1. se il bit ha valore zero, allora in ogni parte dell’immagine viene utilizzato un unico meta
Huffman Code. Nessun ulteriore dato viene memorizzato.
2. se il bit ha valore 1, l’immagine utilizza molteplici meta Huffman codes. Essi sono memoriz-
zati come una entropy image (la entropy image definisce quale codice Huffman è utilizzato
nelle varie parti dell’immagine).
Dato un pixel (x, y) , vi è una serie di cinque codici Huffman associati ad esso. Questi codici sono:
Huffman Code #1: usato per il canale verde, backward reference lenght e color cache;
Huffman Code #2, #3 e #4: utilizzati rispettivamente per i canali rosso, blue e alpha;
Huffman Code #5: utilizzato per la backward reference distance.

Da qui in poi si farà riferimento a questo set come “Huffmann code group”.

Il numero degli Huffman code groups nell’immagine ARGB può essere ottenuto trovando il meta
Huffman code più grande all’interno della entropy image. Poichè ciascun gruppo contiene cinque
diversi codici Huffman, il numero totale di codici Huffman è:
5 * num_huff_groups

3.6.3 DECODIFICA DELL'ENTROPY ENCODE IMAGE DATA


14 Meta Huffman Code: Uno Small Integer (più grande di 16 bits) che indicizza un elemento nella meta Huffman ta-
ble.
15 Entropy Image: Un'immagine bidimensionale a risoluzione abbassata, la quale indica quale codifica entropica do-
vrebbe essere utilizzata in un rispettivo quadrato nell’immagine.
Sia (x, y) la posizione corrente nell’immagine. Come prima cosa, il decoder identifica il corrispon-
dente gruppo Huffman code. Ottenuto il gruppo, il pixel viene letto e decodificato leggendo il nuo-
vo simbolo S dal bitstream utilizzando l’Huffman Code #1. S è un qualsiasi numero intero compre-
so nell’intervallo [0, 256 + 24 + color_cache_size]
1. if S < 256
a. Utilizza S come componente verde;
b. Leggi il rosso dal bitstream utilizzando la codifica Huffman #2
c. Leggi il blu dal bitstream utilizzando la codifica Huffman #3
d. Leggi l’ alpha dal bitstream utilizzando la codifica Huffman #4
2. if S < 256 + 24
a. Usa S - 256 come codice prefisso
b. Legge l’extra bits (for length?) dal bitstream
c. Determina la backward-reference length L dal codice prefisso e l’ extra bits letto.
d. Legge il distance prefix code dal bitstream usando la codifica Huffman #5
e. Legge gli extra bits per la distanza dal bitstream
f. Determina tramite backward-reference la distanza D dal distance prefix code e legge gli
extra bits.
g. Copia i pixel L (in ordine di scansione) dalla sequenza di pixel precedenti ad essi di D pi -
xels.
3. if S >= 256 + 24
a. Usa S - (256 + 24) come indice nella color cache.
b. Prendi il colore ARGB dalla color cache a quell’indice.

4. STRUTTURA DI UN FILE WEBP

Un file WebP contiene un immagine statica (ad esempio, una matrice di pixel codificata) o un'ani-
mazione. Opzionalmente, può anche contenere informazioni sulla trasparenza, profilo colore e
metadati. Nel caso in cui abbiamo bisogno di fare riferimento solo alla matrice di pixel, la chiame-
remo lcanvas (ovvero tela dell'immagine).
Qui di seguito sono elencati i termini aggiuntivi utilizzati nel presente documento:
Writer/Reader
Il codice che legge i file WebP è indicato come un lettore, mentre il codice che li scrive è indicato
come uno scrittore.

UINT16
Intero senza segno a 16-bit, little-endian.

UINT24
Intero senza segno a 24-bit, little-endian.

UINT32
Intero senza segno a 32-bit, little-endian.

FourCC
Un FourCC (codice di quattro caratteri) è un uint32 creata concatenando quattro caratteri ASCII
per little-endian.

1-based
Un campo intero senza segno che memorizza i valori dell'offset sottraendoci 1, ad esempio un va-
lore a 25 lo memorizza come 24.

Si specifica che nel seguente paragrafo ci saranno alcune strutture di formato parzialmente
simili(con le stesse caratteristiche), quindi per evitare di ripetitività verranno spiegate solo le carat-
teristiche nuove delle suddette strutture.

4.1 RIFF FILE FORMAT

Il RIFF (Formato File per l'Interscambio di Risorse) è una struttura per i file taggata per le risorse
multimediali. In poche parole, RIFF non è un formato, ma una struttura che definisce una classe di
formati più specifici, alcuni dei quali categorizzati come sottotipi. L'elemento base di un file RIFF è
chiamato chunk(pezzo, porzione). I chunk sono identificati da codici a quattro caratteri(four-cha-
racter) preimpostati, e l'inserimento di un codice non preimpostato porterà al non riconoscimento
del file da parte del visualizzatore. Il chunk fondamentale è un chunk RIFF, che deve iniziare con
un secondo codice a quattro caratteri oltre al primo, che identificherà il RIFF nella sua particolare
forma o sottotipo.
Le applicazioni che riproducono o renderizzano il file RIFF possono ignorare i chunk con etichette
che non vengono riconosciute. Inoltre un chunk può a suo volta contenere un altro chunk innesta-
to. La struttura RIFF è la base di alcuni importanti formati di file, ma non sono stati usati nella
struttura wrapper di alcun formato di file da metà degli anni novanta.
Il file WebP è basato sul formato contenitore RIFF(resource interchange file format)
Qui sotto viene mostrato come è strutturato un contenitore RIFF. Esso è formato da una serie di
chunk(pezzo), e consiste in:
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 FileType |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Il chunk FourCC composto da 32 bits è un codice ASCII a quattro caratteri, viene utilizzato per
l'identificazione del chunk.
Il chunk Size composto da 32 bits (uint32), indica la dimensione del chunk FileType più la dimen -
sione dei dati che seguono, escludendo questo campo e il chunk identificatore.
Il chunk FileType è un FourCC che identifica lo specifico tipo di file.
Il chunk Data campo a dimensione variabile, e consiste in un insieme o lista di altri chunks , dove i
chunk o meglio i subchunk contengono 3 campi, ovvero il chunk FourCC, il chunk Size e i dati effet-
tivi.

4.2 WEBP FILE HEADER

Un file Webp deve iniziare con un intestazione RIFF con il FourCC 'WEBP'. La dimensione del file
nell'intestazione è il totale delle dimensioni dei chunks che seguono, più i 4 bytes per 'WEBP' in
FourCC. Il file non dovrebbe contenere nient'altro dopo. Come la dimensione di ogni chunk è pari,
anche la dimensione memorizzata nell'intestazione è pari.
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' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Composto dai seguenti chunk:


RIFF costituito da 32 bits, nonchè dai 4 caratteri ASCII "R" "I" "F" "F".
Il File Size composto da 32 bits (uint32) contiene la dimensione del file in bytes partendo dall'off-
set 8. Il massimo valore di questo campo è 2^32 meno 10 bytes, quindi la dimensione dell'intero
file è al massimo 4 GB meno 2 bytes.
E infine il chunk 'WEBP' identico al chunk RIFF ma che contiene i caratteri 'W' 'E' 'B' 'P'.

4.3 SIMPLE FILE FORMAT (LOSSY)

Questo layout è la struttura che deve essere utilizzata quando si richiede per l'immagine una codi -
fica di tipo lossy e quindi non si richiede la trasparenza o altre caratteristiche avanzate che solita-
mente vengono fornite dal formato esteso. I file con questa struttura sono più piccoli e sono sup-
portati dai vecchi software.
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Il Webp file header(12 bytes) è formato esattamente dai pacchetti visti precedentemente, cioè dal
chunk RIFF, il chunk FileSize e il chunk per l'intestazione WEBP. Tutti e 3 i chunk sono a 32 bit o 4
bytes, quindi sommandoli otteniamo i 12 bytes dell'header.
Successivamente troviamo il VP8 chunk così costituito:

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

Il VP8 data chunk contiene tutti i dati della compressione in VP8.


4.4 SIMPLE FILE FORMAT (LOSSLESS)16

Questo layout è la struttura che deve essere adottata se per l'immagine presa in considerazione si
richiede una codifica di tipo lossless(con un canale opzionale dedicato alla trasparenza) e non ri-
chiede le funzionalità avanzate del formato esteso.
Questo tipo di codifica genera dei file che potrebbero non essere supportati dai lettori di vecchia
generazione.

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

Per questo chunk vale lo stesso discorso visto per il Simple File Format(lossy).

VP8L data: dimensione in bytes dei chunks.


VP8L bitstream data: dove sono presenti i dati processati dall'algoritmo VP8L.

16 I vecchi lettori potrebbero non supportare il formato WebP se viene usato il lossless.
4.5 FORMATO ESTESO (EXTENDED FILE FORMAT)

La versione estesa del formato Webp consiste in:


• Un 'VP8X' chunk con le informazioni riguardo alle funzionalità utilizzate nel file.
• Un chunk opzionale 'ICCP' con profilo colore.
• Un chunk opzionale 'ANIM' con i dati di controllo delle animazioni.
• I dati delle immagini.
• Un chunk opzionale 'EXIF' con i metadati nella specifica EXIF.
• Un chunk opzionale 'XMP ' con i metadati nella specifica XMP.
Per una still image(immagine statica) l'immagine è composta da un singolo fotogramma, mentre
una animated image(immagine animata) è composta da più immagini. Nel sottoparagrafo Anima-
tion esamineremo i dettagli delle immagini animate. Si aggiunge che anche per il formato esteso i
vecchi lettori protrebbero avere dei problemi e quindi non supportare questo tipo di formato.
L'ordine dei chunks è molto importante infatti essi devono essere piazzati nello stesso ordine de-
scritto precedentemente, se un chunk compare nel posto sbagliato, il file è corrotto, ma il lettore
potrebbe leggere il file, ignorando i chunk che arrivano troppo tardi.
La motivazione è che Impostare un ordine preciso dei chunk dovrebbe consentire un parsing dei
file più veloce. Per esempio se un chunk "ALPH" non compare nella posizione richiesta, un decodi -
ficatore ha la possibilità di interrompere la ricerca del chunk. La scelta di ignorare i chunks in ritar-
do dovrebbe rendere i programmi che eseguono una ricerca completa in grado di fornire gli stessi
risultati di quelli che si fermano prima.
L'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|F| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Canvas Width Minus One | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

... Canvas Height Minus One |


+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I vari campi dell'intestazione:

• Reserved (Rsv): formato da 2 bits, dovrebbe essere 0.


• L'ICC profile(I) che possiede un solo bit ed è settato se contiene un profilo ICC.
• Alpha (L) rappresentato da 1 bit, e serve ad indicare(se impostato) che uno qualsiasi dei
frame dell'immagine contiene informazioni sulla trasparenza(nonchè "alpha").
• L'EXIF metadata (E) è un flag di 1 bit, utilizzato per segnalare se il chunk contiene metadati
della specifica EXIF. Allo stesso modo viene dedicato anche un flag per indicare la presenza
di metadati nella specifica XMP, conservato in XMP metadata (X).
• il flag Animation (A) è impostato se questo è un immagine animata. I dati in 'ANIM' e
'ANMF' chunks dovrebbero essere usati per controllare l'immagine.
• Reserved è uno spazio riservato del chunk, con dimensione di 24 bits(dovrebbe essere 0).
Infine troviamo i campi Canvas Width Minus One e Canvas Height Minus One entrambi a 24 bit
indicano rispettivamente la larghezza e la lunghezza dell'immagine in pixel. Tali misure sono 1-ba -
sed, cioè il valore effettivo della larghezza è uguale a 1 + la misura del campo Canvas Width Minus
One, lo stesso discorso vale per l'altezza conservata in Canvas Height Minus One. Questi due cam-
pi hanno un limite, infatti la loro misura massima può essere 2^32 meno 1.

4.5.1 ANIMATION

Le animazioni sono controllate dai chunks ANIM e ANMF. Questo chunk contiene i parametri utili
per le animazioni, ovvero i cosidetti global parameters.
ANIM chunk:

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

L'ANIM chunk è costituito da un chunk di intestazione uguale ai chunk di intestazione visti prece -
dentemente un chunk chiamato Background Color che rappresenta il colore di sfondo, rappresen-
tato da 32 bits (uint32). Il colore di sfondo di default della matrice di pixel è in ARGB(alph, Red,
Green, Blue) e può essere utilizzato per riempire gli spazi vuoti sulla matrice intorno ai frames, così
come i pixel trasparenti del primo frame. Questo viene utilizzato anche quando il metodo di smal -
timento è 1.
Il colore di sfondo può contenere valori riguardanti la trasparenza(cioè alpha), anche se il flag che
riguarda alpha(flag L) nel chunk di VP8X non è settato.
Le applicazioni che si occupano della visualizzazione dell'immagine dovrebbero interpretare il co-
lore di sfondo come un 'suggerimento' e quindi non dovrebbero usarlo obbligatoriamente.
L'ultimo chunk è il Loop Count a 16 bits (uint16) e serve ad indicare il numero di volte dei cicli di
animazione, settarlo a 0 significa creare un ciclo di animazione che si ripeterà infinite volte.
Questo chunk viene considerato solo se il flag di animazione(animation flag) nel chunk di VP8X è
settato, altrimenti viene semplicemente ignorato viene ignorato.

ANMF chunk:
Anche questo chunk è per le immagini animate, ma in questo caso contiene solo informazioni ri -
guardo un singolo frame. Nel caso in cui il flag d'animazione non dovesse essere impostato il
chunk non dovrebbe essere inserito.

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

I Frame X e Frame Y (entrambi composti da 24 bits e uint24) sono usate per trovare le coordinate
(x,y) dell'angolo in alto a sinistra dell'immagine, ma il valore effettivo è dato dal prodotto di Frame
X * 2(stessa cosa per Frame Y).
Il chunk contiene inoltre due campi che indicano la larghezza e la lunghezza del frame, che funzio-
nano esattamente come i 2 campi Canvas visti precedentemente, questi due campio sono Frame
Width e Frame Height (1-based, a 24 bit).
Il chunk Frame Duration(durata del fotogramma) a 24 bits (uint24) sta ad indicare il tempo di atte-
sa prima di visualizzare il fotogramma successivo, viene espresso in millisecondi. In particolare, im-
postare la durata del frame a 0 porterà ad aggiornamento di più aree della matrice in una sola vol -
ta durante l'animazione.
Il consueto spazio riservato del chunk che dovrebbe essere 0, Reserved a 6 bits.
Il Blending method (B) ad un 1 bit, Indica come i pixels di trasparenza del frame corrente(current
frame) devono essere miscelati con i corrispondenti pixels della matrice precedente. Questo può
avere due modalità e sono:
• 0: Usa l'alpha blending 17. Dopo essersi occupati del frame precedente, renderizza il frame
corrente sulla matrice dei pixel usando l'alpha-blending. Se il frame corrente non dovesse
avere un canale alpha, assume 255 come valore alpha.
• 1: Non si miscelano. Dopo essersi occupati del frame precedente, renderizza il frame cor-
rente sulla matrice dei pixels senza tener conto del frame precedente.

Il chunk Disposal method (D) (flag) stabilisce Il metodo di smaltimento, ovvero indica come il fra-
me corrente deve essere trattato dopo che è stato visualizzato(prima del rendering del fotogram-
ma successivo). Ci sono due modalità di smaltimento, con il flag impostato a 0 la matrice in realtà
non viene smaltita e viene lasciata cosi comè, mentre con il flag a 1(usa il colore di sfondo) riempie
il rettangolo della matrice dove si trova il frame corrente con il colore di sfondo specificato nel
chunk ANIM.
Lo smaltimento del frame si applica soltanto al rettangolo del frame, definito dai frame x e frame
y (che indicano le coordinate dell'angolo in alto a sinistra) e frame width e frame heigth (indicano
larghezza e altezza), che potrebbe anche non riempire completamente lo spazio del canvas.
Infatti bisogna fare una distinzione tra canvas e frame, il frame potrebbe essere più piccolo dello
spazio utilizzato dall'animazione(matrice dei pixels utilizzati per l'animazione) che è appunto lo
spazio del canvas.

17 Alpha-blending: Dato che ognuno dei canali R, G, B e A(alpha) è a 8 bit, e i canali RGB non sono premoltiplicati da
alpha, inoltre dovrebbe essere fatto nello spazio lineare del colore, tenendo conto però del profilo del colore (co-
lor profile) dell'immagine. Se il profilo del colore(o modello) non è presente si assume per default l'sRGB.
Infine la parte di Frame Data che può avere dimensioni di 16 bytes, può contenere un subchunk
alpha opzionale per l'immagine e un subchunk bistream(che vedremo più avanti) sempre per
l'immagine.

4.5.2 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... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

I 2 bits dedicati al Pre-processing (P) sono dei bit informativi, sono utilizzati per segnalare la pre-
elaborazione che è stata eseguita durante la compressione. Il decoder può usare queste informa-
zioni per e.g. dither the values or smooth the gradients prior to display.
Abbiamo quindi lo 0 per indicare che non è stata eseguita alcuna pre-elaborazione, mentre 1 : li-
vello di riduzione.
Il Metodo di filtraggio (F) ha 4 possibili soluzioni. Con 0 indichiamo nessun filtraggio, con il flag a 1
avviene un filtraggio orizzontale mentre per 2 e 3 abbiamo un filtraggio verticale o gradiente ri-
spettivamente.
Per ogni singolo pixel, il filtraggio viene effettuato eseguendo i seguenti calcoli. Si supponga che i
valori alpha che circondano la posizione X attuale sono etichettati come:

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

Si cercherà di calcolare il valore alpha in posizione X, una prima previsione è fatta dipendentemen-
te dal metodo di filtraggio:
• Metodo 0: previsore = 0
• Metodo 1: previsore = A
• Metodo 2: previsore = B
• Metodo 3: previsore = clip(A + B - C)
Dove la funzione clip(v) è uguale a :
• 0 se v < 0
• 255 se v > 255
• v altrimenti
Il valore finale è ottenuto aggiungendo al valore X decompresso il previsore e usando il modulo di
256 per avere un range compreso sempre tra [0-255]:
alpha = (previsore + X) % 256
Ci sono dei casi speciali per i pixel in posizioni particolari, come ad esempio per quello più a sini-
stra e in alto:
• Il valore superiore sinistro nella posizione(0,0) usa 0 come valore previsore.
• Per i metodi di filtraggio orizzontale o gradiente, i pixes più a sinistra in posizione (0, y)
sono predetti utilizzando la locazione (0, y-1) cioè quello esattamente sopra.
• Per i metodi di filtraggio verticale o gradiente, i pixels più in alto in posizione (x, 0) sono
predetti utilizzando la posizione (x-1, 0) sulla sinistra.

I decodificatori non sono tenuti ad utilizzare queste informazioni in un modo preciso o prescifica-
to, possono gestirle in maniera diversa e autonoma.

Con il flag C(2 bit) viene specificato il metodo di compressione, che nel caso fosse impostato a 0
non si ha alcun tipo di compressione, mentre con il flag a 1 si utilizza la compressione del formato
WebP lossless.
Il chunk Alpha bitstream con dimensione a partire da 1 bytes, è un chunk opzionale e contiene i
dati alpha codificati per questo frame. Nel caso in cui un frame contenga un chunk di tipo 'VP8L'
non dovrebbe contenere invece il chunk Alpha bitstream, perchè le informazioni sulla trasparenza
sono già presenti nel chunk 'VP8L'.
I dati del canale alpha sono immagazzinati in un file dati raw non compressi (quando il metodo di
compressione è '0') o compressi se si utilizza il formato lossless (in questo caso il metodo di com -
pressione è '1'.
Nel caso dei dati raw esso sono costituiti da una sequenza di byte di lunghezza larghezza*altezza,
contenente tutti gli 8-bit dei valori di trasparenza containing all the 8-bit transparency values in
scan order.
Quando si parla di formato di compressione lossless la sequenza di byte è una image-stream com-
pressa (come descritto nel paragrafo 4.4) di dimensioni larghezza x altezza. Cioè, questa image-
stream non contiene tutte le intestazioni che descrivono le dimensioni dell'immagine, questo per-
ché la dimensione dell'immagine è già nota per via di altri fonti, quindi andare ad inserirla nuova-
mente sarebbe ridondante e potrebbe produrre degli errori.
Una volta che l'immagine è codificata nel modello di colori ARGB, seguendo il processo descritto
nella parte riguardante il formato lossless, l'informazione di trasparenza deve essere estratta dal
canale verde della quadrupla ARGB. Si sceglie il canale verde perché permette dei passi di trasfor-
mazioni in più nelle specifiche - cosa che non è permessa con gli altri canali – che può portare mi -
glioramenti nella compressione.

4.5.3 BITSTREAM (VP8/VP8L)

Questo chunk contiene dati bitstream compressi per un singolo frame. Un bitstream chunk può
essere sia (i) un VP8 chunk, usando "VP8 "(da notare che è stato aggiunto lo spazio bianco per
avere comunque i "four-character" occupati correttamente) come tag oppure(ii) un VP8L chunk
usando il tag "VP8L".
I formati dei chunk VP8 e VP8L sono esattamente come descritti nei precedenti paragrafi (Simple
File Format(Lossy)(4.3) e Simple File Format(Losseless)(4.4) rispettivamente.

4.5.4 COLOR PROFILE

Questo chunk deve apparire prima dei dati di immagini, e non dovrebbero essercene più di uno.
Nel caso in cui dovesse esserci più di un chunk il lettore può ignorarli tutti tranne il primo, mentre
nel caso in cui il chunk non dovesse essere presente, si assume per default l'sRGB.

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

4.5.5 METADATI
I metadati forniscono delle informazioni riguardanti il file preso in considerazioni, queste informa-
zioni possono variare da ora e data a info più dettagliate come nel caso di una foto scattata da una
fotocamera, dove verranno inserite informazioni riguardo al produttore, o l'apertura, velocità di
scatto, bilanciamento del bianco e cosi via. Tali metadati possono essere immagazzinati nei chunks
in 'EXIF' o 'XMP '. Dovrebbe esserci al massimo un chunk di ogni tipo ('EXIF' and 'XMP '). Nel caso
in cui ci siano più chunks di tale tipo il lettore può ignorare tutti i chuks tranne il primo. Inoltre un
file può eventualmente contenere entrambi i chunks, cioè sia 'EXIF' e 'XMP '.

I 2 chunks sono quasi identici, l'unica differenza è che uno contiene il chunk con i dati in EXIF e
l'altro con i dati in XMP. Sono definiti come segue:
EXIF chunk:
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Il chunk EXIF Metadata contiene tutti i metadati dell'immagine per la specifica EXIF.
XMP chunk:

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

Il chunk XMP Metadata contiene tutti i metadati dell'immagine per la specifica XMP.

4.6 EXAMPLE FILE LAYOUTS


Una codifica lossy dell'immagine con alpha può essere come segue:

RIFF/WEBP
• VP8X (descrizione delle caratteristiche usate)
• ALPH (alpha bitstream)
• VP8 (bitstream)
Una codifica lossless dell'immagine può apparire come segue:

RIFF/WEBP
• VP8X (descriptions of features used)
• VP8L (lossless bitstream)

Una codifica dell'immagine lossless con ICC profile e metadati XMP può apparire in questo modo:

RIFF/WEBP
• VP8X (descrizione delle caratteristiche usate)
• ICCP (color profile)
• VP8L (lossless bitstream)
• XMP (metadata)
Un immagine animata con metadati EXIF può apparire come segue:

RIFF/WEBP
• VP8X (descrizione delle caratteristiche usate)
• ANIM (parametri globali di animazioni)
• ANMF (parametri del frame1 + dati)
• ANMF (parametri del frame1 + dati)
• ANMF (parametri del frame1 + dati)
• ANMF (parametri del frame1 + dati)
• EXIF (metadati)

5. APPROFONDIMENTI

5.1 LZ77

L'LZ77 è un algoritmo di compressione lossless pubblicato da Abraham Lempel e Jacob Ziv nel
1977. Esso si basa sulla sostituzione di parti delle immagini che si ripetono più volte con un punta -
tore.
L'algoritmo scandisce l'immagine mantenendo memoria dei dati incontrati, e quando incontra una
porzione di dati che è già stata scandita, sostituisce i dati ripetuti con un puntatore lunghezza-
distanza che indica essenzialmente di copiare una certa lunghezza di dati, da una determinata di -
stanza.
Pseudo-codice:

while( lookAheadBuffer not empty )


{
get a pointer(position, match) to the longest match in the window for the lookahead buffer;

if ( length > MINIMUM_MATCH_LENGTH ) {


output a (position, length) pair;
shift the window length characters along;
} else {
output the first character in the look ahead buffer;
shift the window 1 character along;
}
}

5.2 CODIFICA DI HUFFMAN

Per codifica di Huffman si intende un algoritmo di codifica dell’entropia per la compressione di


dati (nel nostro caso di immagini.) Il principio è quello di trovare il sistema ottimale per codificare
stringhe basandosi sulla frequenza relativa di ciascun carattere.

La codifica di Huffman usa un metodo specifico per scegliere la rappresentazione di ciascun sim-
bolo, risultando in un codice senza prefissi (cioè in cui nessuna stringa binaria di nessun simbolo è
il prefisso della stringa binaria di nessun altro simbolo) che esprime il carattere più frequente nella
maniera più breve possibile.

5.2.1 TECNICA BASE

Questa tecnica funziona creando un albero binario di simboli:

1. Ordina i simboli, in una lista, in base al conteggio delle loro occorrenze;

2. Finché la lista non contiene alcun simbolo, ripete i seguenti passi:

a) Dalla lista vengono presi i due simboli con la frequenza di conteggio minore. Crea un
albero di Huffman che ha come "figli" questi due elementi, e crea un nodo di
"genitori";

b) Assegna la somma del conteggio delle frequenze dei figli ai genitori e li pone nella lista
in modo da mantenere l’ordine.
c) Cancella il figlio dalla lista.

3. Assegna una parola codice ad ogni elemento basandosi sul path a partire dalla radice.

La codifica di Huffman è ottimale quando la probabilità di ciascun simbolo in input è una potenza
negativa di due. Le codifiche senza prefissi tendono ad essere inefficienti sui piccoli alfabeti, quan-
do le probabilità spesso cadono tra potenze di due.

Potrebbero piacerti anche