Auteurs
La spécification APNG a été rédigée par :
- Stuart Parmenter <[email protected]>
- Vladimir Vukicevic <[email protected]>
- Andrew Smith <[email protected]>
Aperçu
APNG est une extension du format Portable Network Graphics (PNG), qui ajoute la gestion des images animées. Elle est prévue pour remplacer les images animées simples qui utilisaient traditionnellement le format GIF, tout en ajoutant la gestion des images 24-bits et la transparence 8-bits. APNG est une alternative plus simple à MNG, fournissant une spécification pour la plupart des utilisations d'images animées sur Internet.
APNG est rétrocompatible avec PNG ; tout décodeur PNG devrait être capable d'ignorer les bouts d'informations spécifiques à APNG et d'afficher une image statique.
Terminologie
L'image par défaut est l'image décrite par les blocs standards « IDAT », et est l'image qui sera affichée par les décodeurs ne gérant pas APNG.
Le canevas est la zone sur le dispositif de sortie où les trames doivent être affichées. Le contenu du canevas n'est pas nécessairement accessible au décodeur. Selon la spécification PNG, si un bloc « bKGD » existe il peut être utilisé pour remplir le canevas si aucun autre fond préférable n'existe.
Le buffer de sortie est un tableau de pixels dont les dimensions sont spécifiées par les paramètres width et height du bloc PNG « IHDR ». Conceptuellement, chaque trame est construite dans le buffer de sortie avant d'être composée sur le canevas. Le contenu du buffer de sortie est accessible par le décodeur. Les coins du buffer de sortie correspondent à ceux du canevas.
Noir totalement transparent signifie que les composantes rouge, verte, bleue et alpha sont toutes mises à zéro.
Dans les descriptions de blocs, une valeur unsigned int
sera un entier non signé sur 32 bits dont les octets sont dans l'ordre du réseau, limité à l'intervalle 0 à (2^31)-1 ; une valeur unsigned short
sera un entier non signé sur 16 bits dont les octets sont dans l'ordre du réseau, limité à l'intervalle 0 à (2^16)-1 ; et une valeur byte
sera un entier non signé sur 8 bits dans l'intervalle 0 à (2^8)-1.
Gestion d'erreurs
APNG est conçu pour permettre l'affichage incrémental de trames avant que l'image entière ait été lue. Ceci implique que certaines erreurs peuvent ne pas être détectées avant le démarrage partiel de l'animation. Il est vivement recommandé que les décodeurs arrêtent d'afficher les trames qui suivent dès qu'il rencontrent une erreur, arrêtent l'animation et se contentent de revenir à un affichage de l'image par défaut. Un décodeur qui détecte une erreur avant que l'animation démarre doit afficher directement l'image par défaut. Un message d'erreur peut être affiché pour l'utilisateur si nécessaire.
Structure
Un flux APNG est un flux PNG normal tel que défini dans la spécification PNG, avec trois types de blocs supplémentaires décrivant l'animation et contenant les données des trames supplémentaires.
Pour qu'il soit reconnu comme APNG, un bloc « acTL » doit apparaître dans le flux avant tout bloc « IDAT ». La structure « acTL » est décrite plus bas.
Conceptuellement, au début de chaque exécution, le buffer de sortie doit être complètement initialisé à un rectangle noir totalement transparent, avec les dimensions renseignées dans le bloc « IHDR ».
L'image par défaut peut être définie comme la première trame de l'animation par la présence d'un unique bloc « fcTL » avant « IDAT ». Si ce n'est pas le cas, l'image par défaut ne fera pas partie de l'animation.
Les trames suivantes sont encodées dans des blocs « fdAT », qui ont la même structure que les blocs « IDAT » mais précédés d'un numéro de séquence. Les informations de positionnement et d'affichage pour chaque trame sont stockées dans des blocs « fcTL ». La structure complète des blocs « fdAT » et « fcTL » est décrite ci-dessous.
Les limites de l'ensemble de l'animation sont spécifiées par les paramètres width et height du bloc PNG « IHDR », que l'image par défaut fasse partie ou non de l'animation. L'image par défaut doit être complétée par des pixels complètement transparents si de l'espace supplémentaire est nécessaire pour les trames suivantes.
Chaque trame est identique à chaque exécution, les applications ne doivent donc pas hésiter à mettre les trames en cache.
Numéros de séquence des blocs
Les blocs « fcTL » et « fdAT » ont un numéro de séquence de 4 octets. Les deux types de blocs partagent la même séquence. Le rôle de ce nombre est de permettre détecter (et éventuellement de corriger) les erreurs de séquence dans un PNG animé, car la spécification PNG n'impose pas d'ordre particulier pour les blocs auxiliaires.
Le premier bloc « fcTL » doit contenir le numéro de séquence 0, et les numéros de séquence dans les autres blocs « fcTL » et « fdAT » doivent être dans l'ordre, sans trous ni doublons.
Le tableau ci-dessous illustre l'utilisation des numéros de séquence pour les image avec plus d'une trame et plus d'un bloc « fdAT ».
Si l'image par défaut est la première trame :
Numéro de séquence | Bloc |
---|---|
(aucun) | « acTL » |
0 | « fcTL » (première trame) |
(aucun) | « IDAT » (première trame — utilisée comme image par défaut) |
1 | « fcTL » (deuxième trame) |
2 | « fdAT » (premier « fDAT » pour la deuxième trame) |
3 | « fdAT » (deuxième « fDAT » pour la deuxième trame) |
… | … |
Si l'image par défaut ne fait pas partie de l'animation :
Numéro de séquence | Bloc |
---|---|
(aucun) | « acTL » |
(aucun) | « IDAT » (image par défaut) |
0 | « fcTL » (première trame) |
1 | Premier « fdAT » pour la première trame |
2 | Deuxième « fDAT » pour la première trame |
… | … |
Les décodeurs doivent traiter des blocs APNG désordonnés comme une erreur. Les éditeurs connaissant le format APNG devraient les restaurer dans l'ordre correct à l'aide des numéros de séquence.
« acTL » : le bloc de contrôle de l'animation
Le bloc « acTL » est un bloc auxiliaire tel que défini dans la spécification PNG (ancillary chunk). Il doit apparaître avant le premier bloc « IDAT » dans un flux PNG valide.
Le bloc « acTL » contient :
Décalage d'octets | Nom du champ | Type de champ | Description |
---|---|---|---|
0 | num_frames
| unsigned int
| Le nombre de trames dans l'APNG. |
4 | num_plays
| unsigned int
| Le nombre de fois que l'animation doit être répétée. 0 indique une répétition infinie. |
num_frames
indique le nombre total de trames dans l'animation. Ce nombre doit être identique au nombre de blocs « fcTL ». 0 n'est pas une valeur acceptable. 1 est valide pour un APNG d'une seule trame. Si cette valeur n'est pas identique au nombre de trames, il convient de traiter ceci comme une erreur.
num_plays
indique le nombre de fois que l'animation doit être jouée ; si c'est 0, l'animation doit jouer indéfiniment. Si la valeur est supérieure à zéro, l'animation doit s'arrêter sur la dernière trame à la fin de la dernière exécution.
« fcTL » : le bloc de contrôle de trame
Le bloc « fcTL » est un bloc auxiliaire tel que défini dans la spécification PNG (ancillary chunk). Il doit apparaître avant les blocs « IDAT » ou « fdAT » de la trame à laquelle il s'applique. En particulier :
- Pour l'image par défaut, si un bloc « fcTL » est présent il doit apparaître avant le permier bloc « IDAT ». Sa position relative au bloc « acTL » n'est pas spécifiée.
- Pour la première trame qui n'est pas l'image par défaut (il peut donc s'agir de la première ou de la deuxième trame), le bloc « fcTL » doit apparaître après tous les blocs « IDAT » et avant les blocs « fdAT » pour la trame.
- Pour toutes les trames suivantes, le bloc « fcTL » de la trame N doit apparaître après les blocs « fdAT » de la trame N-1 et avant les blocs « fdAT » de la trame N.
- D'autres blocs auxiliaires peuvent apparaître entre les blocs APNG, même entre des blocs « fdAT ».
Exactement un bloc « fcTL » est nécessaire pour chaque trame.
Décalage d'octets | Nom du champ | Type de champ | Description |
---|---|---|---|
0 | sequence_number
| unsigned int
| Numéro de séquence du bloc d'animation, commençant à 0. |
4 | width
| unsigned int
| Largeur de la trame suivante. |
8 | height
| unsigned int
| Hauteur de la trame suivante. |
12 | x_offset
| unsigned int
| Position X à laquelle afficher la trame suivante. |
16 | y_offset
| unsigned int
| Position Y à laquelle afficher la trame suivante. |
20 | delay_num
| unsigned short
| Numérateur de la fraction de délai de trame. |
22 | delay_den
| unsigned short
| Dénominateur de la fraction de délai de trame. |
24 | dispose_op
| byte
| Type de nettoyage de la zone de trame après qu'elle ait été rendue. |
25 | blend_op
| byte
| Type de rendu de la zone de trame pour cette trame. |
La trame doit être rendue à l'intérieur de la région définie par x_offset
, y_offset
, width
et height
. Les décalages et les dimensions doivent être positifs et les régions ne peuvent pas s'étendre en dehors de l'image par défaut.
Contraintes sur les régions de trame :
x_offset
>= 0y_offset
>= 0width
> 0height
> 0x_offset
+width
<= 'IHDR' widthy_offset
+height
<= 'IHDR' height
Les paramètres delay_num
et delay_den
forment une fraction indiquant le temps d'affichage de la trame courante, en secondes. Si le dénominateur vaut 0, il sera traité comme s'il valait 100 (c'est-à-dire que delay_num
spécifie alors 1/100e de seconde). Si la valeur du numérateur est 0, le décodeur devrait afficher la trame suivante aussi rapidement que possible, même si une limite inférieure raisonnable peut être définie.
Les intervalles de temps devraient être indépendants du temps nécessaire pour décoder et afficher chaque trame, afin que les animations soient exécutées à la même vitesse quelles que soient les performances de l'implémentation du décodeur.
dispose_op
spécifie la manière de changer le tampon de sortie à la fin du délai (avant l'affichage de la trame suivante).
Les valeurs acceptables pour dispose_op
sont :
Valeur | Constante | Description |
---|---|---|
0 | APNG_DISPOSE_OP_NONE
| Aucun nettoyage n'est fait sur cette trame avant d'afficher la suivante ; le contenu du tampon de sortie est laissé tel quel. |
1 | APNG_DISPOSE_OP_BACKGROUND
| La région de la trame dans le tampon de sortie est rempli de noir totalement transparent avant d'afficher la trame suivante. |
2 | APNG_DISPOSE_OP_PREVIOUS
| La région de la trame dans le tampon de sortie est réinitialisée au contenu précédent avant d'afficher la trame suivante. |
Si le premier bloc « fcTL » utilise une valeur dispose_op
de APNG_DISPOSE_OP_PREVIOUS
, elle devrait être traitée commeAPNG_DISPOSE_OP_BACKGROUND
.
blend_op<code> indique si la trame doit être mélangée avec le contenu actuel du tampon de sortie suivant les canaux alpha, ou si elle doit rempalcer complètement sa région sur le tampon de sortie.
Les valeurs acceptables pour <code>blend_op sont :
Valeur | Constante | Description |
---|---|---|
0 | APNG_BLEND_OP_SOURCE
| Toutes les composantes de couleur de la trame, y compris le canal alpha, écrasent le contenu actuel de la région de la trame sur le tampon de sortie. |
1 | APNG_BLEND_OP_OVER
| La trame doit être composée sur le tampon de sortie selon son canal alpha, à l'aide d'une opération OVER simple telle que définie dans la section Alpha Channel Processing de la spécification Extensions to the PNG Specification, Version 1.2.0. Notez que la deuxième variation de l'exemple de code est applicable. |
Notez que pour la première trame, les deux modes sont fonctionnellement équivalents puisque le tampon de sortie est vidé au début de chaque exécution.
Le bloc « fcTL » correspondant à l'image par défaut, si elle existe, a les restrictions suivantes :
- Les champs
x_offset
ety_offset
doivent être à 0. - Les champs
width
etheight
doivent être égaux aux champs correspondants dans le bloc « IHDR ».
Comme noté précédemment, le tampon de sortie doit être complètement initialisé en noir totalement transparent au début de chaque exécution. Ceci permet de s'assurer que chaque exécution de l'animation sera identique. Les décodeurs peuvent éviter cette étape explicite de nettoyage à condition qu'un résultat identique soit garanti. Par exemple, si l'image par défaut fait partie de l'animation, et utilise une valeur blend_op
de APNG_BLEND_OP_SOURCE
, le nettoyage n'est pas nécessaire puisque tout le tampon de sortie sera écrasé.
« fdAT » : le bloc de données de trame
Le bloc « fdAT » a la même fonction qu'un bloc « IDAT ». Il en a également la même structure, sauf qu'il est précédé d'un numéro de séquence.
Au moins un bloc « fdAT » est nécessaire pour chaque trame. Le flux de données compressé est alors la concaténation du contenu des champs de données de tous les blocs « fdAT » d'une trame. Lorsqu'il est décompressé, le flux de données est constitué des données complètes des pixels d'une image PNG, en ce compris l'octet de filtre au début de chaque ligne de parcours, comme dans les données décompressées de tous les blocs « IDAT ». Il utilise les mêmes profondeur d'octets, type de couleur, méthode de compression, méthode de filtre, méthode d'interlaçage et palette (si applicable) que l'image par défaut.
Décalage d'octets | Nom du champ | Type de champ | Description |
---|---|---|---|
0 | sequence_number
| unsigned int
| Numéro de séquence du bloc d'animation, à partir de 0. |
4 | frame_data
| X bytes
| Données de trame pour cette trame. |
Chaque trame hérite de toutes les propriétés spécifiées par tout bloc critique ou auxiliaire avant le premier « IDAT » du fichier, sauf la hauteur et la largeur, qui viennent du bloc « fcTL ».
Si le bloc PNG « pHYs » est présent, les images APNG et leurs valeurs x_offset
et y_offset
doivent être dimensionnées de la même manière que l'image principale. Conceptuellement, un tel dimensionnement se produit lors de la transposition du tampon de sortie vers le canevas.
Révisions de cette spécification
Depuis 0.1
- Renommage des blocs en « anIm » et « frAm » pour appliquer les conventions de nommage des blocs PNG
- Ajout d'une explication plus détaillée de la structure APNG dans la Section 2.
- Ajout d'informations pour l'interaction du PNG avec d'autres blocs dans la section 3.2.
- Changement des décalages et délais des blocs « frAm » en des entiers signés.
Depuis 0.2
- Changement du bloc « frAm » en « afRa » pour éviter les conflits avec le bloc MNG « FRAM ».
- Changement du format : au lieu de séquences de IHDR..IDAT..IEND, les trames autres que la trame 0 sont stockées dans des blocs « afRa ».
- Ajout de
start_frame
à « anIm » pour indiquer la trame sur laquelle l'animation doit commencer.
- Retrait de
num_frames
du bloc « anIm »
Depuis 0.3
- Ajout des descriptions des blocs « aCTL », « fdAT » et « fcTL » d'après les dernières discussions sur png-list
- Ajout de la section 4, « Interactions avec d'autres blocs PNG » ; description des palettes globales et locales et de la transparence
- Changement de la section sur le bloc « oFFs » pour faire référence à des blocs plus généraux
- Mise à jour de la description d'« aDAT » pour indiquer que toutes les trames doivent soit être dans un seul bloc, ou que le premier bloc doit être vide.
- Ajout d'un avertissement sur le fait que toute région de trame (x,y,width,height) doit se trouver complètement dans le canevas du PNG parent
- Correction de la description de
dispose_op
(après, pas avant)
- Changement de
dispose_op
etrender_op
; ajout d'une description de l'étape de nettoyage, ajout du flagBLEND
- Changement de
delay_time
en un numérateur et un dénominateur, pour spécifier des délais qui ne forment pas des nombres entiers de millisecondes.
- Ajout d'une note pour clarifier que l'animation de palettes n'est pas gérée.
- Retrait de
start_frame
d'aCTL ; obligation de fcTL pour la trame 0 ; ajout du flagSKIP_FRAME
à fCTL.
Depuis 0.4
- Réintroduction de
num_frames
dans aCTL
- Déplacement de
sequence_number
depuis aDAT vers fCTL
- Modification du contenu de aDAT en fCTL+IDATs+fEND
- Ajout de clarifications sur ce qui est permis ou non
- Renommage d'aCTL en acTL, fCTL en fcTL, aDAT en fdAT et fEND en feND pour appliquer les conventions de nommage des blocs PNG
Depuis 0.5
- Ajout des CRC IHDR et PLTE au bloc acTl
- Les acTL fcTL et adAT sont résistants à la copie, et ont été renommés en acTl, fcTl et adAt
Depuis 0.6
- Le bloc fdAt n'est plus un conteneur d'autres blocs, mais plutôt un remplaçant de bloc IDAT
- Retrait du bloc feND
- Ajout d'un champ de numéro de séquence à fdAt
- Reintroduction des champs
width
etheight
dans fcTl
Depuis 0.7
- Retrait du flag
hidden
, à la place la première trame peut être masquée lorsqu'un fcTl manquant le signale
- IDAT, fcTl et fdAt peuvent à présent être séparés par d'autre blocs
Depuis 0.8
- Retrait des CRC pour IHDR et PLTE d'acTl
- Les acTL fcTL et adAT sont à présent résistants à la copie, et sont renommés en acTL, fcTL and adAT
Depuis 0.9
- Séparation de
render_op
endispose_op
etblend_op
Depuis 0.10
- Aucun changement
Encodeur de test et exemples d'images
Des exemples d'images sont disponibles sur la page de l'implémentation d'APNG à l'adresse https://littlesvr.ca/apng/
Un encodeur (open source) est disponible dans les versions du moteur Gecko à partir de la version 1.9 alpha 4.
Une application (open source) utilisant l'encodeur de Mozilla pour assembler des APNG est disponible à l'adresse https://littlesvr.ca/apng/apngedit.html
Voir également
- Portable Network Graphics (PNG) Specification (Second Edition)
- Extensions to the PNG Specification, Version 1.2.0
- Graphics Interchange Format 89a