Spécification du conteneur WebP

Introduction

WebP est un format d'image qui utilise (i) l'encodage d'image clé VP8 pour compresser les données d'image avec pertes ou (ii) l'encodage WebP sans perte. Ces schémas d'encodage devraient le rendre plus efficace que les anciens formats, tels que JPEG, GIF et PNG. Il est optimisé pour un transfert d'image rapide sur le réseau (par exemple, pour les sites Web). Le format WebP présente également la parité des fonctionnalités (profil de couleur, métadonnées, animation, etc.) avec les autres formats. Ce document décrit la structure d'un fichier WebP.

Le conteneur WebP (c'est-à-dire le conteneur RIFF pour WebP) permet une compatibilité des fonctionnalités en plus du cas d'utilisation de base de WebP (c'est-à-dire un fichier contenant une seule image encodée en tant qu'image clé VP8). Le conteneur WebP offre une compatibilité supplémentaire pour les éléments suivants:

  • Compression sans perte: à l'aide du format WebP sans perte, une image peut être compressée sans perte.

  • Métadonnées: les métadonnées d'une image peuvent être stockées au format Exif (Exchangeable Image File Format) ou au format XMP (Extensible Metadata Platform).

  • Transparence: une image peut avoir de la transparence, c'est-à-dire un canal alpha.

  • Profil de couleur: une image peut intégrer un profil ICC, comme décrit par l'International Color Consortium.

  • Animation: une image peut comporter plusieurs images séparées par des pauses, ce qui en fait une animation.

Dénomination

Il est RECOMMANDÉ d'utiliser les types suivants lorsque vous faites référence au conteneur WebP:

Nom du format du conteneurWebP
Extension de nom de fichier.webp
Type MIMEimage/webp
Uniform Type Identifier (Identifiant uniforme de type)org.webmproject.webp

Terminologie et principes de base

Les mots clés "DOIT", "DOIT PAS", "OBLIGATOIRE", "DOIT", "NE DOIT PAS", "DOIT", "NE DEVRAIT PAS", "RECOMMANDÉ", "NON RECOMMANDÉ", "PEUT" et "FACULTATIF" dans ce document doivent être interprétés comme décrit dans la RFC 2119 de la BCP 14 RFC 8174 lorsqu'ils apparaissent en majuscules et en majuscules uniquement.

Un fichier WebP contient une image fixe (c'est-à-dire une matrice de pixels encodée) ou une animation. Il peut également contenir des informations de transparence, un profil de couleur et des métadonnées. La matrice de pixels est appelée canevas de l'image.

Dans les diagrammes par blocs, la numérotation des bits commence à 0 pour le bit de poids fort ("MSB 0"), comme décrit dans le document RFC 1166.

Vous trouverez ci-dessous les termes supplémentaires utilisés dans ce document:

Lecteur/Rédacteur
Le code qui lit les fichiers WebP est appelé lecteur, tandis que le code qui les écrit est appelé auteur.
uint16
Entier non signé de 16 bits en Little-endian.
uint24
Entier non signé de 24 bits en Little-endian.
uint32
Entier non signé de 32 bits en Little-endian.
FourCC
Un code à quatre caractères (FourCC) est un uint32 créé en concaténant quatre caractères ASCII dans l'ordre Little-endian. Cela signifie que "aaaa" (0x61616161) et "AAAA" (0x41414141) sont traités comme des FourCCs différents.
Basé sur 1
Champ d'entier non signé stockant des valeurs décalées de -1. Par exemple, un champ de ce type stockerait la valeur 25 sous la forme 24.
ChunkHeader('ABCD')
Permet de décrire les en-têtes FourCC et Chunk Size de chaque fragment, où "ABCD" correspond au FourCC du fragment. La taille de cet élément est de 8 octets.

Format de fichier RIFF

Le format de fichier WebP est basé sur le format de document RIFF (Resource Interchange File Format).

L'élément de base d'un fichier RIFF est un segment. Elle comprend les éléments suivants:

 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                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Bloc FourCC: 32 bits
Code ASCII à quatre caractères utilisé pour identifier les fragments.
Taille du bloc: 32 bits (uint32)
Taille du fragment en octets. Ce champ, l'identifiant du fragment et la marge intérieure ne sont pas inclus.
Charge utile du segment: taille du fragment (octets)
Charge utile des données. Si la taille des fragments est impaire, un seul octet de marge intérieure (qui DOIT être 0 pour être conforme à RIFF) est ajouté.

Remarque : La convention RIFF : les FourCC par blocs tout en majuscules sont des fragments standards qui s'appliquent à n'importe quel format de fichier RIFF, tandis que les FourCC spécifiques à un format de fichier sont tous en minuscules. WebP ne respecte pas cette convention.

En-tête du fichier WebP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'R'      |      'I'      |      'F'      |      'F'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           File Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'W'      |      'E'      |      'B'      |      'P'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
"RIFF": 32 bits
Les caractères ASCII "R", "I", "F" et "F".
Taille du fichier: 32 bits (uint32)
Taille du fichier en octets, à partir du décalage de 8. La valeur maximale de ce champ est de 2^32 moins 10 octets. La taille de l'ensemble du fichier est donc de 4 Gio moins 2 octets.
'WEBP': 32 bits
Les caractères ASCII "W", "E", "B" et "P".

Un fichier WebP DOIT commencer par un en-tête RIFF avec la mention "WEBP" FourCC. La taille du fichier dans l'en-tête correspond à la taille totale des fragments qui suivent plus 4 octets pour le FourCC "WEBP". Le fichier NE DOIT PAS contenir de données après celles spécifiées par le paramètre File Size (Taille de fichier). Les lecteurs PEUVENT analyser ces fichiers, en ignorant les données de fin. Comme la taille d'un fragment est pair, la taille donnée par l'en-tête RIFF l'est également. Le contenu de chaque fragment est décrit dans les sections suivantes.

Format de fichier simple (perdu)

Cette mise en page DOIT être utilisée si l'image nécessite un encodage avec perte et ne nécessite pas de transparence ni d'autres fonctionnalités avancées fournies par le format étendu. Les fichiers avec cette mise en page sont plus petits et compatibles avec les logiciels plus anciens.

Format de fichier WebP simple (avec perte) :

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

Ensemble "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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Données VP8: taille des fragments (octets)
Données de flux de bits VP8.

Notez que le quatrième caractère du FourCC "VP8" est un espace ASCII (0x20).

La spécification du format de flux de bits VP8 est décrite dans le guide sur le format et le décodage des données VP8. Notez que l'en-tête de frame VP8 contient la largeur et la hauteur du frame VP8. Cette valeur correspond à la largeur et à la hauteur du canevas.

La spécification VP8 explique comment décoder l'image au format Y'CbCr. Pour effectuer la conversion au format RVB, vous devez utiliser la recommandation BT.601. Les applications PEUVENT utiliser une autre méthode de conversion, mais les résultats visuels peuvent différer d'un décodeur à l'autre.

Format de fichier simple (sans perte)

Remarque:Les lecteurs plus anciens n'acceptent peut-être pas les fichiers au format sans perte.

Cette mise en page DOIT être utilisée si l'image nécessite un encodage sans perte (avec un canal de transparence facultatif) et ne nécessite pas les fonctionnalités avancées fournies par le format étendu.

Format de fichier WebP simple (sans perte) :

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

Ensemble "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Données VP8L: taille des fragments (octets)
Données de flux de bits VP8L.

La spécification actuelle du flux de bits VP8L est disponible sur la page WebP Lossless Bitstream Format. Notez que l'en-tête VP8L contient la largeur et la hauteur de l'image VP8L. Cela correspond à la largeur et à la hauteur du canevas.

Format de fichier étendu

Remarque:Il est possible que les lecteurs plus anciens ne soient pas compatibles avec les fichiers au format étendu.

Un fichier au format étendu se compose des éléments suivants:

  • Un fragment "VP8X" contenant des informations sur les fonctionnalités utilisées dans le fichier.

  • Un bloc "ICCP" facultatif avec un profil de couleur.

  • Un bloc "ANIM" facultatif avec des données de commande d'animation.

  • Données d'image.

  • Un bloc "EXIF" facultatif avec des métadonnées Exif.

  • Un bloc "XMP" facultatif avec des métadonnées XMP.

  • Liste facultative de segments inconnus.

Pour une image fixe, les données d'image consistent en une seule image composée des éléments suivants:

Pour une image animée, les données de l'image sont composées de plusieurs images. Pour en savoir plus sur les frames, consultez la section Animation.

Tous les fragments nécessaires à la reconstruction et à la correction des couleurs, c'est-à-dire "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" et "VP8L", DOIVENT apparaître dans l'ordre décrit précédemment. Les lecteurs DOIVENT échouer lorsque les fragments nécessaires à la reconstruction et à la correction des couleurs sont dans le désordre.

Les fragments métadonnées et inconnus PEUVENT apparaître dans le désordre.

Logique:Les fragments nécessaires à la reconstruction doivent apparaître en premier dans le fichier pour permettre au lecteur de commencer à décoder une image avant de recevoir toutes les données. Il peut être utile pour une application de modifier l'ordre des métadonnées et des fragments personnalisés pour s'adapter à l'implémentation.

En-tête étendu du fichier 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   WebP file header (12 bytes)                 |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8X')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R|                   Reserved                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Canvas Width Minus One               |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...  Canvas Height Minus One    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Réservé (Rsv): 2 bits
DOIT être 0. Les lecteurs DOIVENT ignorer ce champ.
Profil ICC (I): 1 bit
À définir si le fichier contient un bloc "ICCP".
Alpha (L): 1 bit
Définit si l'un des cadres de l'image contient des informations de transparence ("alpha").
Métadonnées EXIF (E): 1 bit
À définir si le fichier contient des métadonnées Exif.
Métadonnées XMP (X): 1 bits
Indique si le fichier contient des métadonnées XMP.
Animation (A): 1 bit
À définir s'il s'agit d'une image animée. Les données des fragments "ANIM" et "ANMF" doivent être utilisées pour contrôler l'animation.
Réservé (R): 1 bit
DOIT être 0. Les lecteurs DOIVENT ignorer ce champ.
Réservé: 24 bits
DOIT être 0. Les lecteurs DOIVENT ignorer ce champ.
Largeur du canevas moins 1: 24 bits
Largeur basée sur 1 du canevas en pixels. La largeur réelle de la toile est de 1 + Canvas Width Minus One.
Hauteur de la toile moins un: 24 bits
Hauteur basée sur 1 du canevas en pixels. La hauteur réelle de la toile est de 1 + Canvas Height Minus One.

Les valeurs des produits Largeur du canevas et Hauteur du canevas DOIVENT être égales à 2^32 - 1 au maximum.

D'autres champs peuvent être ajoutés ultérieurement. Les champs inconnus DOIVENT être ignorés.

Animation

Une animation est contrôlée par les fragments "ANIM" et "ANMF".

"ANIMATION" :

Pour une image animée, ce fragment contient les paramètres globaux de l'animation.

 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           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Couleur d'arrière-plan: 32 bits (uint32)
Couleur d'arrière-plan par défaut du canevas selon l'ordre d'octets [bleu, vert, rouge, alpha]. Cette couleur PEUT être utilisée pour remplir l'espace inutilisé sur le canevas autour des cadres, ainsi que les pixels transparents du premier cadre. La couleur d'arrière-plan est également utilisée lorsque la méthode de suppression est 1.

Remarque :

  • La couleur d'arrière-plan PEUT contenir une valeur alpha non opaque, même si l'indicateur Alpha du bloc "VP8X" n'est pas défini.

  • Les applications du lecteur DOIVENT traiter la valeur de la couleur d'arrière-plan comme une indication et ne sont pas tenues de l'utiliser.

  • Le canevas est effacé au début de chaque boucle. La couleur d’arrière-plan PEUT être utilisée pour y parvenir.

Nombre de boucles: 16 bits (uint16)
Nombre de fois où l'animation est lue en boucle. Si la valeur est 0, cela signifie qu'il s'agit d'une infinité.

Ce fragment DOIT apparaître si l'indicateur Animation du bloc "VP8X" est défini. Si l'indicateur Animation n'est pas défini et que ce fragment est présent, il DOIT être ignoré.

Morceau "ANMF" :

Pour les images animées, ce fragment contient des informations sur un seul frame. Si l'indicateur d'animation n'est pas défini, ce fragment NE DOIT PAS être présent.

 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                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Cadre X: 24 bits (uint24)
La coordonnée X de l'angle supérieur gauche du cadre est Frame X * 2.
Cadre Y: 24 bits (uint24)
La coordonnée Y de l'angle supérieur gauche du cadre est Frame Y * 2.
Largeur du cadre moins 1: 24 bits (uint24)
Largeur basée sur 1 du cadre. La largeur du cadre est de 1 + Frame Width Minus One.
Hauteur de l'image moins un: 24 bits (uint24)
Hauteur basée sur 1 du cadre. La hauteur du cadre est de 1 + Frame Height Minus One.
Durée de la trame: 24 bits (uint24)
Délai d'attente avant l'affichage de l'image suivante, exprimé en unités de 1 milliseconde. Notez que l'interprétation de la durée de frames de 0 (et souvent <= 10) est définie par l'implémentation. De nombreux outils et navigateurs attribuent une durée minimale semblable à GIF.
Réservé: 6 bits
DOIT être 0. Les lecteurs DOIVENT ignorer ce champ.
Méthode de combinaison (B): 1 bit

Indique à quel point les pixels transparents du cadre actuel doivent être fusionnés avec les pixels correspondants du canevas précédent:

  • 0: utilise la combinaison alpha. Après avoir supprimé l'image précédente, affichez l'image actuelle sur le canevas à l'aide de la combinaison alpha (voir ci-dessous). Si l'image actuelle ne possède pas de canal alpha, partez du principe que la valeur alpha est de 255, remplaçant ainsi le rectangle.

  • 1: ne pas fusionner. Après avoir supprimé le frame précédent, affichez le frame actuel sur le canevas en écrasant le rectangle couvert par le frame actuel.

Méthode de mise au rebut (D): 1 bit

Indique comment le frame actuel doit être traité après avoir été affiché (avant l'affichage du frame suivant) sur le canevas:

  • 0: ne pas éliminer. Laissez le canevas tel quel.

  • 1: supprimer la couleur d'arrière-plan. Remplissez le rectangle du canevas couvert par le cadre actuel avec la couleur d'arrière-plan spécifiée dans le morceau "ANIM".

Remarques :

  • La suppression des cadres ne s'applique qu'au rectangle de cadre, c'est-à-dire au rectangle défini par les éléments Frame X, Frame Y, frame width et frame height. Il peut ne pas couvrir toute la toile.

  • Mélange alpha:

    Étant donné que chacun des canaux R, G, B et A est de 8 bits et que les canaux RVB ne sont pas prémultipliés par la valeur alpha, la formule de mélange de "dst" avec "src" est la suivante:

    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 combinaison alpha DOIT être effectuée dans un espace de couleur linéaire, en tenant compte du profil de couleur de l'image. Si le profil de couleur n'est pas présent, le RVB standard (sRVB) est utilisé. (Notez que sRVB doit également être linéarisé en raison d'un gamma d'environ 2,2.)

Données de trame: Taille de segment16 octets

Comporte:

Remarque: La charge utile "ANMF", Frame Data, est constituée de fragments remplis individuels, comme décrit par le format de fichier 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...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Réservé (Rsv): 2 bits
DOIT être 0. Les lecteurs DOIVENT ignorer ce champ.
Prétraitement (P): 2 bits

Ces bits informatifs sont utilisés pour signaler le prétraitement effectué lors de la compression. Le décodeur peut utiliser ces informations pour, par exemple, tramer les valeurs ou lisser les gradients avant l'affichage.

  • 0: aucun prétraitement.
  • 1: réduction du niveau.

Les décodeurs ne sont pas tenus d'utiliser ces informations d'une manière spécifiée.

Méthode de filtrage (F): 2 bits

Les méthodes de filtrage utilisées sont décrites comme suit:

  • 0: aucune.
  • 1: filtre horizontal.
  • 2: filtre vertical.
  • 3: filtre de dégradé.

Pour chaque pixel, le filtrage est effectué en utilisant les calculs suivants. Supposons que les valeurs alpha entourant la position X actuelle soient libellées comme suit:

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

Nous cherchons à calculer la valeur alpha à la position X. Tout d'abord, une prédiction est effectuée en fonction de la méthode de filtrage:

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

clip(v) est égal à:

  • 0 si v < 0,
  • 255 si v > 255, ou
  • v sinon

La valeur finale est obtenue en ajoutant la valeur décompressée X au prédicteur et en utilisant l'arithmétique modulo-256 pour encapsuler la plage [256..511] dans la plage [0..255] :

alpha = (predictor + X) % 256

Il existe des cas particuliers pour les positions de pixel les plus à gauche et les plus élevées. Par exemple, la valeur en haut à gauche de l'emplacement (0, 0) utilise 0 comme valeur de prédicteur. Sinon :

  • Pour les méthodes de filtrage horizontal ou par gradient, les pixels les plus à gauche à l'emplacement (0, y) sont prédits à l'aide de l'emplacement (0, y-1) situé juste au-dessus.
  • Pour les méthodes de filtrage vertical ou par dégradé, les pixels situés en haut de l'écran à l'emplacement (x, 0) sont prédits à l'aide de l'emplacement (x-1, 0) situé à gauche.
Méthode de compression (C): 2 bits

La méthode de compression utilisée:

  • 0: aucune compression.
  • 1: compressé au format WebP sans perte.
Flux de bits alpha: Taille du fragment1 octets

Flux de bits alpha encodé.

Ce fragment facultatif contient des données alpha encodées pour cette trame. Une trame contenant un bloc "VP8L" NE DOIT PAS contenir ce fragment.

Logique: Les informations de transparence font déjà partie du fragment "VP8L".

Les données du canal alpha sont stockées sous forme de données brutes non compressées (lorsque la méthode de compression est "0") ou compressées à l'aide du format sans perte (lorsque la méthode de compression est "1").

  • Données brutes: il s'agit d'une séquence d'octets de longueur = largeur * hauteur, contenant toutes les valeurs de transparence de 8 bits dans l'ordre d'analyse.

  • Compression de format sans perte: la séquence d'octets est un flux d'images compressé (comme décrit dans la section WebP Lossless Bitstream Format) de dimensions implicites (largeur x hauteur). Autrement dit, ce flux d'images ne contient AUCUN en-tête décrivant les dimensions de l'image.

    Logique: Les dimensions sont déjà connues d'autres sources. Par conséquent, les stocker à nouveau serait redondant et source d'erreurs.

    Une fois le flux d'images décodé en valeurs de couleur Alpha, Rouge, Vert, Bleu (ARVB), en suivant le processus décrit dans la spécification du format sans perte, les informations de transparence doivent être extraites du canal vert du quadruplet ARVB.

    Logique: Contrairement aux autres canaux, le canal vert autorise des étapes de transformation supplémentaires dans la spécification qui peuvent améliorer la compression.

Flux de bits (VP8/VP8L)

Ce fragment contient des données de flux de bits compressées pour une seule trame.

Un fragment de flux de bits peut être (i) un bloc "VP8" utilisant "VP8" (notez l'espace de quatrième caractère significatif) comme FourCC, ou (ii) un fragment "VP8L" utilisant "VP8L" comme FourCC.

Les formats des fragments "VP8" et "VP8L" sont décrits dans les sections Simple File Format (Lossy) et Simple File Format (Lossless).

Profil de couleur

 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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Profil de couleur: taille des fragments (octets)
Profil ICC.

Ce fragment DOIT apparaître avant les données d'image.

Il DOIT y avoir au maximum un bloc de ce type. S'il y a plus de fragments de ce type, les lecteurs PEUVENT ignorer tous les fragments, sauf le premier. Pour en savoir plus, consultez la spécification ICC.

Si ce fragment n'est pas présent, le modèle sRVB DOIT être utilisé.

Métadonnées

Les métadonnées peuvent être stockées dans des fragments "EXIF" ou "XMP".

Il DOIT y avoir au maximum un fragment de chaque type ("EXIF" et "XMP"). S'il y a plus de fragments de ce type, les lecteurs PEUVENT ignorer tous les fragments à l'exception du premier.

Les fragments sont définis comme suit:

Bloc '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                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Métadonnées EXIF: Taille du fragment (octets)
Métadonnées d'image au format Exif.

Bloc "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                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Métadonnées XMP: taille des fragments (octets)
Métadonnées d'image au format XMP.

Notez que le quatrième caractère du FourCC "XMP" est un espace ASCII (0x20).

Des conseils supplémentaires sur la gestion des métadonnées sont disponibles dans les Consignes pour la gestion des métadonnées du groupe de travail sur les métadonnées.

Friandises inconnues

Un bloc RIFF (décrit dans la section Format de fichier RIFF) dont le format FourCC est différent de l'un des fragments décrits dans ce document est considéré comme un segment inconnu.

Logique: Autoriser les fragments inconnus permet d'étendre ultérieurement le format et de stocker toutes les données spécifiques à l'application.

Un fichier PEUT contenir des fragments inconnus:

Les lecteurs DOIVENT ignorer ces fragments. Les rédacteurs DOIVENT les conserver dans leur ordre d'origine (sauf s'ils ont spécifiquement l'intention de modifier ces fragments).

Assemblage de la toile à partir des cadres

Cette présentation explique comment un lecteur DOIT assembler un canevas dans le cas d'une image animée.

Le processus commence par la création d'un canevas en utilisant les dimensions fournies dans le bloc "VP8X" (Canvas Width Minus One + 1 pixels de large sur Canvas Height Minus One + 1 pixels de haut). Le champ Loop Count du bloc "ANIM" contrôle le nombre de répétitions du processus d'animation. Il s'agit de Loop Count - 1 pour les valeurs Loop Count non nulles ou infini si la valeur Loop Count est égale à zéro.

Au début de chaque itération de boucle, le canevas est rempli avec la couleur d'arrière-plan du bloc "ANIM" ou une couleur définie par l'application.

Les fragments "ANMF" contiennent des images individuelles classées dans l'ordre d'affichage. Avant d'afficher chaque image, l'élément Disposal method de l'image précédente est appliqué.

Le rendu de l'image décodée commence aux coordonnées cartésiennes (2 * Frame X, 2 * Frame Y) et utilise l'angle supérieur gauche du canevas comme point de départ. Frame Width Minus One + 1 pixels de large sur Frame Height Minus One + 1 pixels de haut sont affichés sur le canevas à l'aide de Blending method.

La toile est affichée pendant Frame Duration millisecondes. Le processus se poursuit jusqu'à ce que toutes les images fournies par les fragments "ANMF" soient affichées. Une nouvelle itération de boucle commence, ou le canevas reste dans son état final si toutes les itérations ont été terminées.

Le pseudo-code suivant illustre le processus de rendu. La notation VP8X.field correspond au champ du bloc "VP8X" avec la même description.

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

Exemples de mises en page de fichiers

Une image encodée avec pertes avec un canal alpha peut se présenter comme suit:

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

Une image encodée sans perte peut se présenter comme suit:

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

Une image sans perte avec un profil ICC et des métadonnées XMP peut se présenter comme suit:

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

Une image animée avec les métadonnées Exif peut se présenter comme suit:

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)