Conversion analogique/numérique et formats de stockage
Introduction
Nous avons vu dans le chapitre consacré à l'échantillonage des données que les données analogiques en sortie de capteur étaient transformées en données numériques. Ces données sont ensuite retraitées comme nous l'avons vu par les opérations de dématriçage ou demosaïquage; on applique ensuite une transformation gamma pour constituer une image dans un format acceptable pour un système de restitution numérique (ordinateur, etc).
Il existe deux façons de réaliser ces opérations de dématriçage et de transformation gamma: soit à l'intérieur de l'appareil lui-même, et dans ce cas les données stockées sur le média de stockage (généralement une carte mémoire) seront directement des données de type "photographique", soit à l'extérieur de la caméra, et dans ce cas les données stockées sont les données directement fournies par le capteur converties en données numériques. Nous allons maintenant détailler le passage des données analogiques aux données numériques, et le stockage de ces données, soit sous forme brute, soit après transformation par les algorithmes de dématriçage/transformation gamma.
Dataflow
Nous allons tout d'abord revoir rapidement le cheminement de l'information depuis le capteur jusqu'au médium de stockage dans le cas du stockage de l'information brute (RAW):
Le gain analogique
Le gain analogique est appliqué à la sortie du capteur; il consiste à amplifier le signal, et correspond pour le photographe à choisir une sensibilité ISO plus grande que la sensibilité native du capteur (sur la majorité des DSLR la sensibilité native est de 100ISO). Cette amplification permet de gagner des niveaux de luminosité, mais elle amplifie également le bruit généré par le capteur lui-même (voir le chapitre sur les propriétés des capteurs).
A ce titre augmenter la sensibilité consiste donc à augmenter également le bruit, ce qui explique l'augmentation du bruit sur les photographies en même temps que l'on augmente la sensibilité. Bien entendu, les fabricants tentent au maximum de diminuer les bruits inhérents au capteur, mais certains sont inévitables pour des raisons physiques.
Réduction matérielle du bruit
L'étape suivante est optionnelle et consiste à essayer de réduire le bruit par une méthode "matérielle". Cette méthode ne doit en aucun cas être confondue avec les méthodes logicielles de traitement du bruit.
On sait en fait que le bruit généré par chacun des photosites est unique (propre à chaque photosite) mais qu'en revanche il ne varie pas énormément d'une prise à une autre pour un photosite et un temps d'exposition donnés. L'idée consiste donc à faire une prise "noire" après la prise de la photographie elle-même. Cette prise "noire" permet de connaitre le niveau de bruit de chaque photosite en l'absence de tout signal lumineux. Ces valeurs sont alors soustraites photosite par photosite aux valeurs de la photographie elle-même.
Cette méthode marche surtout bien pour les temps d'exposition élevés, lorsque le bruit principal est effectivement le bruit lié au circuit du capteur lui-même. Elle apparait généralement sur l'appareil sous la forme d'une option "Noise Reduction ON".
Il faut noter que bien souvent la réduction de bruit a lieu après l'étape de conversion A/N et non avant, ce qui ne change rien à notre propos.
Quantification
L'opération de quantification à laquelle nous nous intéressons est celle qui consiste à transformer le signal analogique issu de chaque photosite en une valeur numérique.
Le signal analogique a une valeur maximale (voir le chapitre consacré aux propriétés des capteurs) qui s'exprime généralement en Volts. La question consiste à savoir comment nous allons discrétiser ce signal sous forme numérique. Il s'agit donc de choisir le nombre de bits sur lequel nous allons représenter notre signal. L'opération est ensuite une simple conversion par une règle de trois; si la valeur max du signal est Vmax et que nous choisissons de travailler sur n bits, alors le signal V observé sera transformé dans la valeur entière:
R = 2n V / Vmax
La question est de savoir comment choisir la valeur de n. Ce problème est discuté plus en détail dans le chapitre consacré au fonctionnement des capteurs. DIsons en résumé qu'il ne faut pas choisir une valeur de n trop petite car de l'information serait perdue, mais qu'il est aussi inutile de choisir une valeur trop grande. En effet, il existe une certaine imprécision sur la mesure du signal V qui est liée une fois de plus au bruit et il faut donc qu'un niveau de quantification (qui est égal à Vmax / 2n) soit toujours du même ordre de grandeur que l'erreur en question. Il s'agit là d'une bonne règle pour trouver la valeur de n la plus adaptée.
Aujourd'hui, la majorité des DSLR ont des convertisseurs analogique/numérique qui travaillent sur 12 bits, les compacts ont longtemps utilisé des convertisseurs sur 8 bits, et certains appareils (Fuji gràce à un système comportant deux photocapteurs par photosites ou la série des Canon EOS-40D/1D MarkIII/1DsMarkII) commencent à employer des capteurs sur 14 bits. Il faut cependant être prudent: le nombre de bits est aussi employé parfois dans un but marketing, et s'il est toujours facile de rajouter des bits à un convertisseur A/N, il n'est pas toujours certain que ces bits supplémentaires soient réellement significatifs; il est en effet possible qu'ils soient complètement absorbés dans le bruit du circuit analogique.
Rappelons nous enfin que les données sorties du capteur sont des données qui sont linéairement proportionnelles au signal, et qu'elles devront être corrigés plus tard pour être transformées en données "photographiques" pour deux raisons: la première tient à la transformation gamma qu'il faudra appliquer, la seconde à l'équilibrage des différents canaux de couleurs qu'il faudra faire pour tenir compte de deux facteurs: la différence de sensibilité du capteur suivant le canal concerné, et la balance des couleurs à réaliser en fonction de l'éclairage lors de la prise de vue. Tous ces points sont détaillés dans les chapitres consacrés à la colorimétrie et au fonctionnement des capteurs.
Nous allons dans le chapitre suivant nous intéresser aux différents formats de fichier.
Formats de données et formats de fichiers
Programmes pour jouer
Avant toutes choses, si vous souhaitez "jouer" avec les formats de
données, le programme
exfield.ml
pourra vous aider à visualiser la structure générale des fichiers TIFF
et JPEG, ainsi que celle de la majorité fichiers RAW (Canon CR2, Epson ERF ou
Nikon NEF par exemple). Il est également capable de traiter le cas de
structures TIFF inclues dans des structures JPEG, et inversement. Une
version exécutable pour windows est disponible
ici.
Ce programme a été écrit relativement rapidement; il n'est
certainement pas parfait, mais il permet de visualiser assez
simplement les structures générales, les tags et leurs valeurs. Le
source est disponible
ici.
Pour visualiser les octets bruts, le classique programme
od disponible sur la plupart des systèmes de type Unix est
parfaitement adapté. Une version pour Windows est disponible
là.
Généralités
Les données informatiques sont toujours stockées sous forme d'octets. Un octet correspond à un groupe de 8 bits (pour les gens intéressés, cette "norme" s'est imposé au début des années 60 à cause de la prééminence des IBM/360). Une donnée sur 12 ou 14 bits devra donc être stockée sous la forme de deux octets consécutifs. L'ordre choisi (poids fort d'abord ou poids faible d'abord) de ces deux octets est généralement appelé "endianness"
Il est possible de choisir l'un ou l'autre de ces deux façons de stocker les données. Le débat sur l'endianness fait rage dans la communauté informatique depuis des années sans qu'il soit vraiment clair qu'il y a un réel avantage à choisir l'un ou l'autre.
La version la plus simple du stockage des données consisterait donc à écrire simplement sur la carte mémoire le flux complet en provenance du capteur. Pour un capteur de 16MPix, nous aurions donc un fichier de l'ordre de 32 millions d'octets (32Mo). En fait, les choses ne se passent pas aussi simplement pour plusieurs raisons: la première, et nous y reviendrons plus loin, est que les fabricants stockent dans les fichiers un certain nombre d'informations supplémentaires (vitesse d'obturation, diaphragme, etc...), la seconde est que l'on emploie en général des algorithmes de compression de données pour réduire la taille du fichier, la troisième, qui est lié au problème de l'endianness expliqué ci-dessus vient du fait que le fichier doit préciser certaines informations intrinsèques sur le format de codage..
Il faut aussi noter qu'il existe souvent une confusion entre format de description de données et format de structure de fichiers. Cette confusion est relativement normale, car il n'existe pas de distinction absolument franche, mais il en existe neanmoins une.
Un format de fichier décrit l'organisation des données à l'intérieur d'un fichier (une séquence d'octets). A ce titre, il décrit en général une structure arborescente et explicite l'organisation des différents champs entre eux. Le format TIFF est clairement un format de ce type
Un format de données explicite la représentation des données individuelles. Cela peut-être fait par des associations de tags, de champs de longueur (comme pour TIFF ou EXIF), ou des arborescences ASCII organisés par un DTD XML (comme la norme XMP).
Un format de données peut être inclus dans un format de fichier quelconque. AInsi, on trouvera des données EXIF aussi bien dans un format TIFF que dans un format JPEG. Mais plus redoutablement, un format de fichier peut aussi être inclus dans un autre format de fichier (ainsi, on peut inclure directement une structure complète de fichier JPEG dans un fichier TIFF, et pas seulement un champ de données.
D'autre part, certaines normes comme TIFF définissent à la fois des formats de fichiers et des formats de données, ce qui n'aide pas à mieux comprendre le fonctionnement général.
Ce mélange explique qu'il n'est pas simple de se débattre dans la jungle des données...
Dans toute la suite, nous examinerons sur des exemples les structures de différents types de fichiers. Il faut être conscient de la limite de l'approche: tous les fichiers du même type ne respecteront pas exactement la description faite sur l'exemple considéré.
RAW ou JPEG
Avant d'aller plus loin, évacuons tout de suite la fameuse
polémique du "Vaut-il mieux utiliser un format RAW ou un format JPEG?"
Cette question n'a pas de réponse unique; les deux types de format ont
leurs avantages et leurs inconvénients.
- Les fichiers RAW permettent de retravailler beaucoup plus facilement l'image en post-traitement. En effet, ce format stocke généralement l'image avec une précision de 12 ou 14 bits par élément de capteur: cela permet en particulier de récupérer des lumières "brulées" ou au contraire de retrouver des détails perdus dans les zones sombres. D'autre part, dans la mesure où il retranscrit exactement l'information sortie du capteur, il est plus facile de retravailler les informations de couleur et en particulier la balance des blancs. Enfin, il est possible d'employer des algorithmes de dématriçage beaucoup plus puissant que ceux qui sont employés dans l'appareil, car le temps de traitement n'est pas aussi critique sur un PC que sur un appareil photo. Enfin, la qualité de la photographie est maximale puisqu'elle n'a connu aucune perte (les formats RAW compressent parfois les données, mais en utilisant systématiquement des algorithmes "Lossless", c'est à dire qui ne perdent aucune donnée).
- Le format JPEG permet de stocker l'image dans un format beaucoup plus compact, et surtout directement visualisable et utilisable. On peut imprimer les photographies ou les donner à tirer directement à partir de la carte mémoire et ce dans n'importe quelle borne ou n'importe quel laboratoire photo, sans avoir à passer par le PC.
Enfin, certains appareils, surtout anciens, proposent une sauvegarde directement au format TIFF "standard" 16 bits. Il s'agit d'images stockés sous la forme de 3 couches (R,G,B) contenant chacune une description de la couleur en 16 bits de précision. Le seul avantage de ce format par rapport au JPEG est qu'il garantit qu'aucune information n'est perdue, ni au niveau de la dynamique de l'image ni au niveau du piqué. En revanche, ces fichiers sont généralement énormes, généralement plus gros que les fichiers RAW.
Format TIFF
Avant toute chose, nous allons nous intéresser au format TIFF. La norme TIFF a une importance toute particulière, car elle a été utilisée par nombre de constructeurs pour leurs fichiers RAW, comme le nouveau format CR2 de Canon, le format ERF de l'Epson RD-1 et bien d'autres (les formats RAW des constructeurs contiennent bien entendu des extensions au format TIFF, mais la structure générale reste la même).
La norme TIFF a été posée par ALDUS. La compagnie a été rachetée par Adobe, et la version définitive de la norme TIFF (la 6.0) date de 1992.
Un fichier TIFF est, comme tout fichier, une séquence de d'octets. Il commence par un en-tête de 8 octets, appelé en-tête du fichier d'image, ou en anglais Image File Header (IFH). Cet en-tête pointe sur un répertoire du fichier image (en anglais Image FIle Directory (IFD)). Le répertoire contient les informations décrivant l'image, ainsi que les pointeurs sur l'image elle-même.
Il faut bien comprendre qu'un même fichier TIFF peut contenir plusieurs IFD s'il contient plusieurs images. C'est en particulier le cas pour les fichiers de type CR2 de chez Canon (et le cas pour la majorité des fichiers dits RAW).
- Image File Header:
Un en-tête de fichier TIFF est composé de la séquence des 8 octets suivants:
- Octets 0-1 : "II" (0x49 0x49 en hexa ou 73 73 en décimal) si l'ordre des octets est du little-endian; "MM" (0x4d 0x4d en hexa ou 77 77 en décimal) si l'ordre des octets est du big-endian (I est pour Intel, M pour Motorola)
- Octets 2-3 : un entier sur deux octets dont la valeur est 42. Suivant que l'on est en little endian ou en big endian la séquence d'octets sera en hexa (0x2a Ox00) ou (0x00 0x2a) et (42 0) ou (0 42) en décimal.
- Octets 4-7 : offset en bytes (c'est à dire distance par rapport à l'origine en octets) du premier IFD. Dans la norme TIFF, les offsets sont toujours absolus, c'est à dire pris par rapport au début du fichier. Il s'agit d'un entier codé sur 4 octets.
Il faut noter que le premier IFD ne commence pas nécessairement directement derrière l'IFH. Il faut impérativement aller à l'offset codé par ces 4 derniers octets; certains constructeurs, en particulier Canon, étendent l'IFH pour y stocker des informations propriétaires comme nous le verrons plus loin. Voici un exemple d'en-tête de fichier TIFF pour une image au format standard généré par Photoshop:
0000000 73 73 42 0 8 0 0 0 24 0 254 0 4 0 1 0 I I * nul bs nul nul nul can nul ~ nul eot nul soh nul
On distingue clairement les deux 'I' indiquant un format little endian, la séquence 42 0 identifiant le TIFF et la séquence 8 0 0 0 codant le nombre 8 en little endian, et indiquant donc que le premier IFD se trouve à partir du 8ème octet du fichier.
En revanche, si nous prenons un en-tête de fichier généré par un Epson RD-1, nous avons un autre cas:0000000 77 77 0 42 0 0 0 8 0 24 0 254 0 4 0 0 M M nul * nul nul nul bs nul can nul ~ nul eot nul nul
Nous sommes ici devant un format big-endian indiqué par le double 'M'. Le nombre 42 est maintenant codé par la séquence 0 42 et l'offset du premier IFD est toujours 8 mais est codé maintenant par la séquence 0 0 0 8.
- Image File Descriptor:
Un IFD se décompose en un nombre n codé sur 2 octets décrivant le nombre d'entrées du répertoires suivi de n séquences de 12 octets décrivant chacune de ces entrées; il se termine par un offset sur 4 octets pointant sur l'IFD suivant; s'il n'y a pas d'IFD suivant, cet offset est égal à 0.
- Octet 0-1: 2 octets qui codent sur un entier de 16 bits le nombre d'entrées du répertoire.
-
Un groupe de douze octets (répétés n fois) décrivant chacun une entrée
de répertoire. Ces douze octets sont organisés de la façon suivante:
- Octet 0-1: Le tag ou identificateur qui permet de déterminer la fonction de ce champ
- Octet 2-3: Le type (au sens du typage des données) de ce champ.
- Octets 4-7: le nombre de valeurs du type précité.
- Octets 8-11: si la taille du type (en octets) multiplié par le nombre de valeurs est inférieur ou égal à 4, alors ce champ stocke directement la valeur correspondant à cette entrée du répertoire. Si ce n'est pas le cas, ce champ stocke l'offset vers cette valeur.
- Octets allant de A+2+B*12 à A+2+B*12+4: offset vers l'IFD suivant s'il y en a un, 0 sinon.
La liste des tags TIFF est décrite pour partie dans la norme. Il faut cependant savoir qu'il existe d"une part de très nombreuses extensions à la liste d'origine, et qu'il est même possible de définir des tags pointant sur des sous-structures d'IFD complètes n'obéissant pas complètement à la norme TIFF, comme les sous-IFD de tpe EXIF ou XMP. Nous y reviendrons plus loin.
Les types de données TIFF sont les suivants:
- 1 : BYTE. Entier non signé sur 8 bits.
- 2 : ASCII. Suite de code ASCII sur 8 bits, se terminant par un byte contenant 0 (convention venant du langage C).
- 3 : SHORT. Entier non signé sur 16 bits.
- 4 : LONG. Entier non signé sur 32 bits.
- 5 : RATIONAL. Deux entiers non signés de 32 bits, le premier représentant le numérateur et le second le dénominateur.
- 6 : SBYTE. Entier signé sur 8 bits.
- 7 : UNDEFINED. Valeur sur 8 bits dont la définition dépend du type du champ.
- 8 : SSHORT. Entier signé sur 16 bits.
- 9 : SLONG. Entier signé sur 32 bits.
- 10 : RATIONAL. Deux entiers signés de 32 bits, le premier représentant le numérateur et le second le dénominateur.
- 11 : FLOAT. Nombre en simple précision (32 bits) au format IEEE
- 12 : DOUBLE. Nombre en double précision (64 bits) au format IEEE
Nous allons maintenant détailler sur un exemple la structure d'un IFD. Nous allons reprendre un fichier TIFF généré par Photoshop et analyser l'ensemble de l'IFH et de l'IFD:
0000000 73 73 42 0 8 0 0 0 23 0 254 0 4 0 1 0 I I * nul bs nul nul nul etb nul ~ nul eot nul soh nul 0000016 0 0 0 0 0 0 0 1 3 0 1 0 0 0 0 13 nul nul nul nul nul nul nul soh etx nul soh nul nul nul nul cr 0000032 0 0 1 1 3 0 1 0 0 0 128 19 0 0 2 1 nul nul soh soh etx nul soh nul nul nul nul dc3 nul nul stx soh 0000048 3 0 3 0 0 0 34 1 0 0 3 1 3 0 1 0 etx nul etx nul nul nul " soh nul nul etx soh etx nul soh nul 0000064 0 0 1 0 0 0 6 1 3 0 1 0 0 0 2 0 nul nul soh nul nul nul ack soh etx nul soh nul nul nul stx nul 0000080 0 0 15 1 2 0 6 0 0 0 40 1 0 0 16 1 nul nul si soh stx nul ack nul nul nul ( soh nul nul dle soh 0000096 2 0 22 0 0 0 46 1 0 0 17 1 4 0 1 0 stx nul syn nul nul nul . soh nul nul dc1 soh eot nul soh nul 0000112 0 0 148 112 0 0 18 1 3 0 1 0 0 0 1 0 nul nul dc4 p nul nul dc2 soh etx nul soh nul nul nul soh nul 0000128 0 0 21 1 3 0 1 0 0 0 3 0 0 0 22 1 nul nul nak soh etx nul soh nul nul nul etx nul nul nul syn soh 0000144 3 0 1 0 0 0 128 19 0 0 23 1 4 0 1 0 etx nul soh nul nul nul nul dc3 nul nul etb soh eot nul soh nul 0000160 0 0 0 0 241 5 26 1 5 0 1 0 0 0 68 1 nul nul nul nul q enq sub soh enq nul soh nul nul nul D soh 0000176 0 0 27 1 5 0 1 0 0 0 76 1 0 0 28 1 nul nul esc soh enq nul soh nul nul nul L soh nul nul fs soh 0000192 3 0 1 0 0 0 1 0 0 0 40 1 3 0 1 0 etx nul soh nul nul nul soh nul nul nul ( soh etx nul soh nul 0000208 0 0 2 0 0 0 49 1 2 0 28 0 0 0 84 1 nul nul stx nul nul nul 1 soh stx nul fs nul nul nul T soh 0000224 0 0 50 1 2 0 20 0 0 0 112 1 0 0 188 2 nul nul 2 soh stx nul dc4 nul nul nul p soh nul nul stx 0000240 1 0 216 84 0 0 132 1 0 0 187 131 4 0 2 0 soh nul X T nul nul eot soh nul nul ; etx eot nul stx nul 0000256 0 0 92 86 0 0 73 134 1 0 48 26 0 0 100 86 nul nul \ V nul nul I ack soh nul 0 sub nul nul d V 0000272 0 0 105 135 4 0 1 0 0 0 148 112 241 5 0 0 nul nul i bel eot nul soh nul nul nul dc4 p q enq nul nul 0000288 0 0 16 0 16 0 16 0 67 97 110 111 110 0 67 97 nul nul dle nul dle nul dle nul C a n o n nul C a 0000304 110 111 110 32 69 79 83 45 49 68 115 32 77 97 114 107 n o n sp E O S - 1 D s sp M a r k 0000320 32 73 73 0 0 159 36 0 16 39 0 0 0 159 36 0 sp I I nul nul us $ nul dle ' nul nul nul us $ nul 0000336 16 39 0 0 65 100 111 98 101 32 80 104 111 116 111 115 dle ' nul nul A d o b e sp P h o t o s 0000352 104 111 112 32 67 83 50 32 87 105 110 100 111 119 115 0 h o p sp C S 2 sp W i n d o w s nul 0000368 50 48 48 55 58 49 49 58 49 49 32 48 57 58 51 54 2 0 0 7 : 1 1 : 1 1 sp 0 9 : 3 6 0000384 58 50 53 0 60 63 120 112 97 99 107 101 116 32 98 101 : 2 5 nul < ? x p a c k e t sp b e
L'en-tête (IFH) est le même que celui examiné plus haut. Il s'agit
d'un format little-endian (II), on trouve ensuite le nombre 42
(entier sur 2 octets 42 0) puis le nombre 8 (entier sur 4 octets: 8 0
0 0).
L'IFD arrive juste ensuite. Il commence par les deux octets (octet
numéro 8 et octet numéro 9) codant le
nombre d'entrées , soit 23 (séquence 23 0). A la suite de ces deux
octets se trouve 23 séquences de 12 octets; la première va de l'octet 10
à l'octet 21, la seconde de 22 à 33... etc jusqu'à la dernière entrée qui ira
de l'octet 274 à l'octet 285. L'IFD se termine par 4 octets de (de 286 à
289) contenant l'offset de l'IFD suivant. Dans notre cas, nous voyons
que ces 4 octets sont égaux à 0: il n'y a pas d'autre IFD.
Nous allons maintenant détailler les différentes entrées de l'IFD:
- Entrée 0:
- Octets 10-11: Code le tag sous la forme d'un entier de 16 bits (2 octets), soit ici la séquence (254 0) qui correspond à l'entier 254. Le tag 254 (0xfe en hexadécimal) correspond au champ NewSubfileType (voir la norme TIFF et ses extensions).
- Octets 12-13: Code le type sous la forme d'un entier de 16 bits (2 octets), soit ici la séquence (4 0) qui correspond à l'entier 4. Le type de l'objet est donc 4, ce qui correspond, nous l'avons vu plus haut, à un entier long non signé (LONG).
- Octets 14-17: Code le nombre d'objets sous la forme d'un entier de 32 bits (4 octets), soit ici la séquence (1 0 0 0) qui correspond à l'entier 1. Il y aura donc un seul entier long. La longueur totale de la donnée codée est donc de 4 (taille d'un entier long) multiplié par 1 (nombre de données codées), soit 4 octets. Cette taille étant inférieure ou égale à 4, le champ suivant va contenir directement une valeur, et non l'offset vers cette valeur.
- Octets 18-21: Code ici directement la valeur du champ (voir
cidessus) sous la
forme d'un entier de 32 bits (4 octets), soit ici la séquence (0 0 0 0) qui
correspond à l'entier 0. La valeur du champ
NewSubfileType est donc 0.
Il reste ensuite à interpréter la valeur du champ. Là aussi, cette interprétation est décrite soit dans la norme TIFF elle-même soit dans une de ses extensions. Dans le cas présent, la valeur doit être interprétée comme une séquence de 32 bits; le bit 0 indique si l'IFD courant décrit une version réduite d'une image plus importante décrite par un autre IFD du même fichier (le bit vaut alors 1) ou s'il s'agit de l'image principale (le bit vaut alors 0). Le bit 1 indique s'il s'agit d'une fichier décrivant une image d'une seule page (0) ou de plusieurs pages (1) et le bit 2 lorsqu'il vaut 1 indique qu'il s'agit du descriptif d'n masque de transparence pour une autre image TIFF. Dans le cas présent, tous les bits sont à 0: il s'agit donc d'une image principale d'une seule page.
- Entrée 1:
- Octets 22-23: Ici le tag est codé par (0 1) et correspond à l'entier 256=1x256+0 (0x100 en hexa). Il correspond au champ ImageWidth (norme TIFF).
- Octets 24-25: le type de la donnée est codée par (3 0) soit 3 qui définit un entier court non signé (SHORT).
- Octets 26-29: nombre d'objets codé par (1 0 0 0) soit 1. Il y aura donc un seul entier court. La longueur totale de la donnée codée est donc de 2 (taille d'un entier court) multiplié par 1 (nombre de données codées), soit 2 octets. Cette taille étant inférieure ou égale à 4, le champ suivant va contenir directement une valeur, et non l'offset vers cette valeur.
- Octets 30-33: Code ici directement la valeur du champ (voir
ci-dessus) sous la
forme d'un entier de 16 bits (2 octets), soit ici la séquence (0 13)
[seuls les deux premiers octets sont signifiants] qui
correspond à l'entier 13x256=3328. La valeur du champ
ImageWidth est donc 3328.
L'interprétation de ce champ est immédiate: l'image a une largeur de 3328 pixels.
- Entrée 2:
- Octets 34-35: tag codé par (1 1) soit 257 (0x101 en hexa). Correspond au champ ImageLength (norme TIFF).
- Octets 36-37: le type de la donnée est codée par (3 0) soit 3 qui définit un entier court non signé (SHORT).
- Octets 38-41: nombre d'objets codé par (1 0 0 0) soit 1. Il y aura donc un seul entier court. La taille totale est inférieure à 4, le champ suivant code directement la valeur du champ.
- Octets 42-45: séquence (128 19)
correspond à l'entier 19x256+128=4992. La valeur du champ
ImageWidth est donc 4992.
L'image a une hauteur de 4992 pixels.
- Entrée 3:
- Octets 46-47: tag codé par (2 1) soit 258 (0x102 en hexa). Correspond au champ BitsPerSample (norme TIFF).
- Octets 48-49: le type de la donnée est codée par (3 0) soit 3 qui définit un entier court non signé (SHORT).
- Octets 50-53: nombre d'objets codé par (3 0 0 0) soit 3. Il y aura donc trois entiers courts. La taille totale est égale à 2 (taille d'une entier court) multiplié par 3 (nombre de données)=6; cette taille étant supérieure à 4, le champ suivant code un offset sur la valeur du champ.
- Octets 54-57: séquence (34 1 0 0)
correspond à l'entier 1x256+34=290. Les trois entiers courts
définissant la valeur du champ BitsPerSample se trouvent donc
à l'adresse 290 du fichier.
Si nous allons maintenant à l'adresse 290, nous trouvons la séquence suivante (16 0 16 0 16 0) qui définit 3 entiers courts valant chacun 16. Nous avons donc une image avec trois couches, chaque couche étant décrite avec une précision de 16 bits par pixel.
- Entrée 4:
- Octets 58-59: tag codé par (3 1) soit 259 (0x103 en hexa). Correspond au champ Compression.
- Octets 60-61: (3 0) soit 3. Entier court non signé (SHORT).
- Octets 62-65: (1 0 0 0) soit 1 objet.
- Octets 66-69: séquence (1 0 0 0), soit 1. La valeur 1 indique que les données de l'image ne sont pas compressées.
Le principe étant maintenant compris, nous n'allons pas détailler aussi précisément les autres entrées de l'IFD. Nous allons nous contenter de les présenter dans la table suivante:
Tag (hexa) | Nom du Tag | Type | Nombre | Valeur ou offset | Valeur pointée | Interprétation |
0x106 | PhotometricInterpretation | SHORT | 1 | 0x2=2 | Type de l'image. 2=>RGB full color | |
0x10f | Make | ASCII | 6 | 296 | Canon | Fabriquant |
0x110 | Model | ASCII | 22 | 302 | Canon EOS-1Ds Mark II | Modèle |
0x111 | StripOffsets | LONG | 1 | 0x7094=28820 | Offset du début de l'image | |
0x112 | Orientation | SHORT | 1 | 0x1=1 | Orientation. | |
0x115 | SamplesPerPixel | SHORT | 1 | 0x3=3 | Nombre de couches par pixel | |
0x116 | RowsPerStrip | SHORT | 1 | 0x1380=4992 | Nombre de colonnes par bande Ici, RowsPerStrip=ImageLength Toute l'image est dans un strip |
|
0x117 | StripByteCounts | LONG | 1 | 0x5f10000=99680256 | Longueur de la (des) bande(s) On trouve bien ici: 4992x3328x3x2=99680256 |
|
0x11a | XResolution | RATIONAL | 1 | 324 | (2400000/10000) | Nombre de pixels par unité de résolution |
0x11b | YResolution | RATIONAL | 1 | 332 | (2400000/10000) | Nombre de pixels par unité de résolution |
0x11c | PlanarConfiguration | SHORT | 1 | 0x1=1 | Organisation des couches 1 => codage RGBRGBRGB 2 => codage RRR...GGG...BBB... |
|
0x128 | ResolutionUnit | SHORT | 1 | 0x2=2 | Unité de mesure 2=>Inch, 3=>cm |
|
0x131 | Software | ASCII | 28 | 340 | Adobe Photoshop CS2 Windows | Logiciel |
0x132 | DateTime | ASCII | 20 | 368 | 2007:11:11 09:36:25 | Jour et heure |
0x2bc | AdobeXMP | BYTE | 21720 | 388 | Pointeur sur les données XMP | |
0x83bb | IPTC | LONG | 2 | 22108 | 540 131074 | Données IPTC |
0x8649 | PhotoshopImageResourceBlocks | BYTE | 6704 | 22116 | Pointeur sur données privées PhotoShop | |
0x8769 | ExifIFD | LONG | 1 | 0x5f17094=99709076 | Pointeur sur sous-répertoire EXIF |
Comme nous venons de le voir, il existe de nombreuses extensions à la norme TIFF de base, généralement non documentées. Un fichier TIFF peut également contenir des champs à la norme Exif, à la norme XMP, voire à la norme JIFF.
La norme TIFF présente surtout un énorme défaut: tous les offsets sont absolus et mesurés par rapport au début du fichier. En conséquence, toute modification de la longueur d'un champ interne par un logiciel tiers oblige à recalculer la totalité des offsets. Plus grave, de nombreux champs n'étant pas documentés, il est alors impossible de savoir s'ils contiennent ou pas des offsets et comment les recalculer et il n'y a pas d'autre solution que de supprimer purement et simplement ces champs lors de la modification du fichier.
La norme CIFF était une intéressante solution à ce problème en fabriquant des champs au sein dequels les offsets étaient relatifs au début du champ lui-même. Les premiers fichiers RAW Canon (les CRW) étaient fabriqués suivant la norme CIFF, mais il semble que cette norme soit en voie d'extinction aujourd'hui.
Nous reviendrons aux fichiers TIFF, et en particuliers aux champs ExifIFD et XMP lorsque nous aurons parlé de ces normes.
Format de données Exif
La norme Exif (Exchangeable image file format) a été créé par la Japan Electronic Industries Development Association (JEIDA). La denière version (2.2) est daté d'Avril 2002. La structure des tags Exif dérive largement de la structure des fichiers TIFF. Il y a d'ailleurs un fort recouvrementr entre TIFF et Exif.
Les tags définis par le standard Exif couvrent un champ trés vaste, qui couvrent aussi bien les informations de date et d'heure, mais aussi tous les paramètres liés à l'appareil (ouverture, vitesse, focale, type de mise au point, vitesse ISO, etc...). Ils couvrent également des données de géolocalisation qui peuvent être utilisées par les appareils équipés de lecteurs GPS, ou des programmes capables d'inscrire ces données GPS en combinant des traces GPS et les informations d'heure et de date des photographies.
Nous allons maintenant parcourir le sous répertoire Exif du fichier TIFF précédent. Il se trouve à l'offset 99709076, et respecte la structure générale d'un IFD. Les deux premiers octets indiquent le nombre d'entrées n du répertoire, suivis de n séquences de 12 octets correspondant à chacune des entrées du répertoire, suivant en cela le format TIFF habituel.
Voici la séquence d'octets correspondante:
99709076 24 0 154 130 5 0 1 0 0 0 186 113 241 5 157 130 can nul sub stx enq nul soh nul nul nul : q q enq gs stx 99709092 5 0 1 0 0 0 194 113 241 5 34 136 3 0 1 0 enq nul soh nul nul nul B q q enq " bs etx nul soh nul 99709108 0 0 1 0 0 0 39 136 3 0 1 0 0 0 100 0 nul nul soh nul nul nul ' bs etx nul soh nul nul nul d nul 99709124 0 0 0 144 7 0 4 0 0 0 48 50 50 49 3 144 nul nul nul dle bel nul eot nul nul nul 0 2 2 1 etx dle 99709140 2 0 20 0 0 0 202 113 241 5 4 144 2 0 20 0 stx nul dc4 nul nul nul J q q enq eot dle stx nul dc4 nul 99709156 0 0 222 113 241 5 1 146 10 0 1 0 0 0 242 113 nul nul ^ q q enq soh dc2 nl nul soh nul nul nul r q 99709172 241 5 2 146 5 0 1 0 0 0 250 113 241 5 4 146 q enq stx dc2 enq nul soh nul nul nul z q q enq eot dc2 99709188 10 0 1 0 0 0 2 114 241 5 5 146 5 0 1 0 nl nul soh nul nul nul stx r q enq enq dc2 enq nul soh nul 99709204 0 0 10 114 241 5 7 146 3 0 1 0 0 0 5 0 nul nul nl r q enq bel dc2 etx nul soh nul nul nul enq nul 99709220 0 0 9 146 3 0 1 0 0 0 9 0 0 0 10 146 nul nul ht dc2 etx nul soh nul nul nul ht nul nul nul nl dc2 99709236 5 0 1 0 0 0 18 114 241 5 1 160 3 0 1 0 enq nul soh nul nul nul dc2 r q enq soh sp etx nul soh nul 99709252 0 0 255 255 0 0 2 160 4 0 1 0 0 0 0 13 nul nul del del nul nul stx sp eot nul soh nul nul nul nul cr 99709268 0 0 3 160 4 0 1 0 0 0 128 19 0 0 14 162 nul nul etx sp eot nul soh nul nul nul nul dc3 nul nul so " 99709284 5 0 1 0 0 0 26 114 241 5 15 162 5 0 1 0 enq nul soh nul nul nul sub r q enq si " enq nul soh nul 99709300 0 0 34 114 241 5 16 162 3 0 1 0 0 0 2 0 nul nul " r q enq dle " etx nul soh nul nul nul stx nul 99709316 0 0 1 164 3 0 1 0 0 0 0 0 0 0 2 164 nul nul soh $ etx nul soh nul nul nul nul nul nul nul stx $ 99709332 3 0 1 0 0 0 1 0 0 0 3 164 3 0 1 0 etx nul soh nul nul nul soh nul nul nul etx $ etx nul soh nul 99709348 0 0 0 0 0 0 6 164 3 0 1 0 0 0 0 0 nul nul nul nul nul nul ack $ etx nul soh nul nul nul nul nul 99709364 0 0 0 0 0 0 1 0 0 0 250 0 0 0 4 0 nul nul nul nul nul nul soh nul nul nul z nul nul nul eot nul 99709380 0 0 1 0 0 0 50 48 48 53 58 48 52 58 48 57 nul nul soh nul nul nul 2 0 0 5 : 0 4 : 0 9 99709396 32 49 53 58 51 57 58 53 55 0 50 48 48 53 58 48 sp 1 5 : 3 9 : 5 7 nul 2 0 0 5 : 0 99709412 52 58 48 57 32 49 53 58 51 57 58 53 55 0 88 140 4 : 0 9 sp 1 5 : 3 9 : 5 7 nul X ff 99709428 121 0 64 66 15 0 4 0 0 0 1 0 0 0 0 0 y nul @ B si nul eot nul nul nul soh nul nul nul nul nul 99709444 0 0 1 0 0 0 3 0 0 0 1 0 0 0 105 0 nul nul soh nul nul nul etx nul nul nul soh nul nul nul i nul 99709460 0 0 1 0 0 0 128 106 76 0 140 5 0 0 112 223 nul nul soh nul nul nul nul j L nul ff enq nul nul p _ 99709476 50 0 177 3 0 0 0 0 2 nul 1 etx nul nul nul nul
On voit donc ici que nous avons 24 entrées (séquence 24 0). La première entrée commence à l'octet 99709078 et se termine à l'octet 99709089; la dernière entrée commence à l'octet 99709356 et se termine à l'octet 99709367. La structure de chaque entrée ainsi que les principes fondamentaux de codage des données est identique à celui des fichiers TIFF.
Le principe étant le même que pour un fichier TIFF, nous allons nous contenter de décrire la valeur des tags Exif sous la forme d'un tableau.
Tag (hexa) | Nom du Tag | Type | Nombre | Valeur ou offset | Valeur pointée | Interprétation |
0x829a | ExposureTime | RATIONAL | 1 | 99709370 | (1/250) | Temps d'exposition |
0x829d | FNumber | RATIONAL | 1 | 99709378 | (4/1) | Ouverture |
0x8822 | ExposureProgram | SHORT | 1 | 0x1=1 | Programme d'exposition | |
0x8827 | ISOSpeedRating | SHORT | 1 | 0x64=100 | Sensibilité ISO | |
0x9000 | ExifVersion | UNDEFINED | 1 | 0x31323230=825373232 | Version Exif 4 octets de code ASCII: 0221 |
|
0x9003 | DateTimeOriginal | ASCII | 20 | 99709386 | 2005:04:09 15:39:57 | Date et heure de la prise de vue |
0x9004 | DateTimeDigitized | ASCII | 20 | 99709406 | 2005:04:09 15:39:57 | Date et heure de numérisation |
0x9201 | ShutterSpeedValue | SRATIONAL | 1 | 99709426 | (7965784/1000000) | Vitesse d'obturation? |
0x9202 | ApertureValue | RATIONAL | 1 | 99709434 | (4/1) | Valeur de l'ouverture |
0x9204 | ExposureBias | SRATIONAL | 1 | 99709442 | (0/1) | Modification de l'exposition |
0x9205 | MaxApertureValue | RATIONAL | 1 | 99709450 | (3/1) | Ouverture Max |
0x9207 | MeteringMode | SHORT | 1 | 0x5=5 | Mode de mesure (5=>Multi-segment) | |
0x9209 | Flash | SHORT | 1 | 0x9=9 | Flash 9=>On | |
0x920a | FocalLength | RATIONAL | 1 | 99709458 | (105/1) | Focale |
0xa001 | ColorSpace | SHORT | 1 | 0xffff=65535 | Espace de couleur 65535=>non calibré | |
0xa002 | PixelXDimension | LONG | 1 | 0xd00=3328 | Taille horizontale en pixels | |
0xa003 | PixelYDimension | LONG | 1 | 0x1380=4992 | Taille verticale en pixels | |
0xa20e | FocalPlaneXResolution | RATIONAL | 1 | 99709466 | (5008000/1420) | Résolution dans le plan focal X |
0xa20f | FocalPlaneYResolution | RATIONAL | 1 | 99709474 | (3334000/945) | Résolution dans le plan focal Y |
0xa210 | FocalPlaneResolutionUnit | SHORT | 1 | 0x2=2 | Unité de résolution 2=>inches | |
0xa401 | CustomRendered | SHORT | 1 | 0x0=0 | Mode de rendu 0=>standard | |
0xa402 | ExposureMode | SHORT | 1 | 0x1=1 | Mode d'exposition 1=>Manual | |
0xa403 | WhiteBalance | SHORT | 1 | 0x0=0 | Balance des blancs 0=>Auto | |
0xa406 | SceneCaptureType | SHORT | 1 | 0x0=0 | Mode de capture de scène 0=>Standard |
Il existe de nombreux problèmes avec la norme Exif; elle n'est d'une part plus maintenue, et aucun organisme n'assure son suivi et sa normalisation, même si elle reste un standard de-facto. D'autre part, elle ne permet pas de coder simplement les informations nécessaires pour des images dont la profondeur par plan dépasse 8 bits, etc...
Format de données XMP
Le format XMP (Extensible Metadata Plateform) est un format de métadonnée basé sur XML et RDF. Il a été lancé par Adobe Systèmes en 2001 et gagne rapidement en popularité. Son principal avantage, comme tout format dérivé de SGML, est qu'il répond à un formalisme simple: document de définition de format+texte ASCII, ce qui permet de garantir une portabilité optimale.
Il faut cependant bien remarquer que le format XMP n'est pas un format de fichier, mais un format de métadonnée. Les données XMP doivent être stockées à l'intérieur d'un format de fichier "ordinaire": cela peut-être à l'intérieur de fichier TIFF, JPEG, PNG ou même HTML, puisque la norme XMP est basée sur XML. Il existe un document d'Adobe qui détaille les méhodes "canoniques" d'inclusion de données XMP dans ces différents types de fichiers.
A l'intérieur d'un fichier TIFF les données XMP sont stockées sous la forme d'une longue chaine de caractères. Dans le cas du fichier qui nous intéresse ci-dessus ces données commencent à l'offset 388 et ont une longueur de 21720 octets.
A l'intérieur des données XMP, on retrouve plusieurs sections reprenant chacune avec une description textuelle les informations des champs TIFF, Exif, etc... Nous allons détailler rapidement les données XMP de notre fichier.
- En tête:
<?xpacketbegin="o;?"id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmetaxmlns:x="adobe:ns:meta/"x:xmptk="3.1.1-112">
- Section TIFF
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Descriptionrdf:about="" xmlns:tiff=" http://ns.adobe.com/tiff/1.0/"> <tiff:Make>Canon</tiff:Make> <tiff:Model>Canon EOS-1DsMarkII</tiff:Model> <tiff:Orientation>1</tiff:Orientation> <tiff:XResolution>2400000/10000</tiff:XResolution> <tiff:YResolution>2400000/10000</tiff:YResolution> <tiff:ResolutionUnit>2</tiff:ResolutionUnit> <tiff:NativeDigest> 256,257,258,259,262,274,277,284,530,531, 282,283,296,301,318,319,529,532,306,270,271,272, 305,315,33432; EDD80D775FDA6A8B2DC3242C626EED77 </tiff:NativeDigest> </rdf:Description>
- Section Exif
<rdf:Description rdf:about="" xmlns:exif="http://ns.adobe.com/exif/1.0/"> <exif:ExifVersion>0221</exif:ExifVersion> <exif:ExposureTime>1/250</exif:ExposureTime> <exif:ShutterSpeedValue>7965784/1000000</exif:ShutterSpeedValue> <exif:FNumber>4/1</exif:FNumber> <exif:ApertureValue>4/1</exif:ApertureValue> <exif:ExposureProgram>1</exif:ExposureProgram> <exif:DateTimeOriginal>2005-04-09T15:39:57+02:00</exif:DateTimeOriginal> <exif:DateTimeDigitized>2005-04-09T15:39:57+02:00</exif:DateTimeDigitized> <exif:ExposureBiasValue>0/1</exif:ExposureBiasValue> <exif:MaxApertureValue>3/1</exif:MaxApertureValue> <exif:MeteringMode>5</exif:MeteringMode> <exif:FocalLength>105/1</exif:FocalLength> <exif:CustomRendered>0</exif:CustomRendered> <exif:ExposureMode>1</exif:ExposureMode> <exif:WhiteBalance>0</exif:WhiteBalance> <exif:SceneCaptureType>0</exif:SceneCaptureType> <exif:FocalPlaneXResolution>5008000/1420</exif:FocalPlaneXResolution> <exif:FocalPlaneYResolution>3334000/945</exif:FocalPlaneYResolution> <exif:FocalPlaneResolutionUnit>2</exif:FocalPlaneResolutionUnit> <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>100</rdf:li> </rdf:Seq> </exif:ISOSpeedRatings> <exif:Flashrdf:parseType="Resource"> <exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode> </exif:Flash> <exif:PixelXDimension>3328</exif:PixelXDimension> <exif:PixelYDimension>4992</exif:PixelYDimension> <exif:ColorSpace>-1</exif:ColorSpace> <exif:NativeDigest>36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379, 37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988, 41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30; 712D6E204276F78A672F6369C0E9B134</exif:NativeDigest> </rdf:Description>
- Section XAP
L'acronyme XAP (Extensible Authoring Publishing) était le nom originel du standard devenu XMP. Pour des raisons de compatibilités, il a survécu dans nombre de documents XMP.
<rdf:Descriptionrdf:about="" xmlns:xap="http://ns.adobe.com/xap/1.0/"> <xap:ModifyDate>2007-11-11T09:36:25+01:00</xap:ModifyDate> <xap:Rating>0</xap:Rating> <xap:CreateDate>2007-11-11T09:36:25+01:00</xap:CreateDate> <xap:MetadataDate>2007-11-11T09:36:25+01:00</xap:MetadataDate> <xap:CreatorTool>AdobePhotoshopCS2Windows</xap:CreatorTool> </rdf:Description>
- Section Exif auxiliaire
<rdf:Description rdf:about="" xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"> <aux:LensInfo>105/1105/10/00/0</aux:LensInfo> <aux:Lens>105.0mm</aux:Lens> <aux:ImageNumber>30</aux:ImageNumber> <aux:FlashCompensation>0/1</aux:FlashCompensation> <aux:Firmware>1.1.1</aux:Firmware> </rdf:Description>
- Section Camera Raw settings
<rdf:Description rdf:about="" xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"> <crs:Version>3.7</crs:Version> <crs:RawFileName>XA6I0030.CR2</crs:RawFileName> <crs:WhiteBalance>AsShot</crs:WhiteBalance> <crs:Temperature>4650</crs:Temperature> <crs:Tint>-2</crs:Tint> <crs:Exposure>0.00</crs:Exposure> <crs:Shadows>5</crs:Shadows> <crs:Brightness>+50</crs:Brightness> <crs:Contrast>+25</crs:Contrast> <crs:Saturation>0</crs:Saturation> <crs:Sharpness>25</crs:Sharpness> <crs:LuminanceSmoothing>0</crs:LuminanceSmoothing> <crs:ColorNoiseReduction>25</crs:ColorNoiseReduction> <crs:ChromaticAberrationR>0</crs:ChromaticAberrationR> <crs:ChromaticAberrationB>0</crs:ChromaticAberrationB> <crs:VignetteAmount>0</crs:VignetteAmount> <crs:ShadowTint>0</crs:ShadowTint> <crs:RedHue>0</crs:RedHue> <crs:RedSaturation>0</crs:RedSaturation> <crs:GreenHue>0</crs:GreenHue> <crs:GreenSaturation>0</crs:GreenSaturation> <crs:BlueHue>0</crs:BlueHue> <crs:BlueSaturation>0</crs:BlueSaturation> <crs:FillLight>0</crs:FillLight> <crs:Vibrance>0</crs:Vibrance> <crs:HighlightRecovery>0</crs:HighlightRecovery> <crs:HueAdjustmentRed>0</crs:HueAdjustmentRed> <crs:HueAdjustmentOrange>0</crs:HueAdjustmentOrange> <crs:HueAdjustmentYellow>0</crs:HueAdjustmentYellow> <crs:HueAdjustmentGreen>0</crs:HueAdjustmentGreen> <crs:HueAdjustmentAqua>0</crs:HueAdjustmentAqua> <crs:HueAdjustmentBlue>0</crs:HueAdjustmentBlue> <crs:HueAdjustmentPurple>0</crs:HueAdjustmentPurple> <crs:HueAdjustmentMagenta>0</crs:HueAdjustmentMagenta> <crs:SaturationAdjustmentRed>0</crs:SaturationAdjustmentRed> <crs:SaturationAdjustmentOrange>0</crs:SaturationAdjustmentOrange> <crs:SaturationAdjustmentYellow>0</crs:SaturationAdjustmentYellow> <crs:SaturationAdjustmentGreen>0</crs:SaturationAdjustmentGreen> <crs:SaturationAdjustmentAqua>0</crs:SaturationAdjustmentAqua> <crs:SaturationAdjustmentBlue>0</crs:SaturationAdjustmentBlue> <crs:SaturationAdjustmentPurple>0</crs:SaturationAdjustmentPurple> <crs:SaturationAdjustmentMagenta>0</crs:SaturationAdjustmentMagenta> <crs:LuminanceAdjustmentRed>0</crs:LuminanceAdjustmentRed> <crs:LuminanceAdjustmentOrange>0</crs:LuminanceAdjustmentOrange> <crs:LuminanceAdjustmentYellow>0</crs:LuminanceAdjustmentYellow> <crs:LuminanceAdjustmentGreen>0</crs:LuminanceAdjustmentGreen> <crs:LuminanceAdjustmentAqua>0</crs:LuminanceAdjustmentAqua> <crs:LuminanceAdjustmentBlue>0</crs:LuminanceAdjustmentBlue> <crs:LuminanceAdjustmentPurple>0</crs:LuminanceAdjustmentPurple> <crs:LuminanceAdjustmentMagenta>0</crs:LuminanceAdjustmentMagenta> <crs:SplitToningShadowHue>0</crs:SplitToningShadowHue> <crs:SplitToningShadowSaturation>0</crs:SplitToningShadowSaturation> <crs:SplitToningHighlightHue>0</crs:SplitToningHighlightHue> <crs:SplitToningHighlightSaturation>0</crs:SplitToningHighlightSaturation> <crs:SplitToningBalance>0</crs:SplitToningBalance> <crs:ParametricShadows>0</crs:ParametricShadows> <crs:ParametricDarks>0</crs:ParametricDarks> <crs:ParametricLights>0</crs:ParametricLights> <crs:ParametricHighlights>0</crs:ParametricHighlights> <crs:ParametricShadowSplit>25</crs:ParametricShadowSplit> <crs:ParametricMidtoneSplit>50</crs:ParametricMidtoneSplit> <crs:ParametricHighlightSplit>75</crs:ParametricHighlightSplit> <crs:ConvertToGrayscale>False</crs:ConvertToGrayscale> <crs:ToneCurveName>MediumContrast</crs:ToneCurveName> <crs:ToneCurve> <rdf:Seq> <rdf:li>0,0 </rdf:li> <rdf:li>32,22</rdf:li> <rdf:li>64,56</rdf:li> <rdf:li>128,128</rdf:li> <rdf:li>192,196 </rdf:li> <rdf:li>255,255</rdf:li> </rdf:Seq> </crs:ToneCurve> <crs:CameraProfile>ACR2.4</crs:CameraProfile> <crs:HasSettings>True</crs:HasSettings> <crs:HasCrop>False</crs:HasCrop> <crs:AlreadyApplied>True</crs:AlreadyApplied> </rdf:Description>
- Section Photoshop
<rdf:Descriptionrdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"> <photoshop:SidecarForExtension>CR2</photoshop:SidecarForExtension> <photoshop:ColorMode>3</photoshop:ColorMode> <photoshop:ICCProfile>sRGBIEC61966-2.1</photoshop:ICCProfile> <photoshop:History/> </rdf:Description>
- Section XAPMM
<rdf:Descriptionrdf:about="" xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"> <xapMM:DocumentID>uuid:4DDD5E173190DC11ABB5A6B2C0E70ABC</xapMM:DocumentID> <xapMM:InstanceID>uuid:4EDD5E173190DC11ABB5A6B2C0E70ABC</xapMM:InstanceID> <xapMM:DerivedFromrdf:parseType="Resource"> <stRef:instanceID>uuid:4ADD5E173190DC11ABB5A6B2C0E70ABC</stRef:instanceID> <stRef:documentID>uuid:4ADD5E173190DC11ABB5A6B2C0E70ABC</stRef:documentID> </xapMM:DerivedFrom> </rdf:Description>
- Section Dublin Core
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:format>image/tiff</dc:format> </rdf:Description> </rdf:RDF>
- Fin
</x:xmpmeta> <?xpacketend="w"?>
Format JPEG
L'acronyme JPEG signifie Joint Photographic Experts Group, qui est le nom du groupe d'experts qui a créé le standard. Le malheur est que l'acronyme JPEG décrit à la fois le groupe d'expert, le codec de codage/compression de données et le format de fichier, dont le nom correct est JPEG Interchange Format.
Il existe également une version simplifiée du format de fichier JPEG, le format JFIF (pour JPEG File Interchange Format). Ce format est une version simplifiée du format de fichier JPEG, mais reste complètement compatible avec lui. Il faut cependant noter que, contrairement à ce qui peut être écrit à divers endroits, le format JFIF n'est pas forcément plus répandu que le format JPEG lui-même.
Nous allons nous intéresser ici au format de fichier JPEG. Nous reviendrons sur le codec JPEG plus loin dans cette page.
- Marqueurs JPEG: la structure d'un fichier JPEG est
structuré par la présence de marqueurs qui indiquent le début et la
longueur des champs. Tous les marqueurs JPEG commencent par l'octet
0xff (255) suivi d'un second octet décrivant le type du
marqueur.
Voici la table complète des marqueurs JPEG:
Marqueur (hexa) Symbole Description Marqueur de début de trame, non-différentiel, codage de Huffman 0xc0 SOF0 DCT traditionnel 0xc1 SOF1 DCT séquentiel étendu 0xc2 SOF2 DCT progressif 0xc3 SOF3 Codage sans perte de donnée (lossless) Spécification de table de Huffman 0xc4 DHT Définition de table de Huffman Marqueur de début de trame, différentiel, codage de Huffman 0xc5 SOF5 DCT séquentiel différentiel 0xc6 SOF6 DCT progressif différentiel 0xc7 SOF7 Sans perte de données (lossless), différentiel Marqueur de début de trame, non-différentiel, codage arithmétique 0xc8 JPG Réservé pour extensions JPEG 0xc9 SOF9 DCT séquentiel étendu 0xca SOF10 DCT progressif 0xcb SOF11 Codage sans perte de donnée (lossless) Spécification du conditionnement de codage arithmétique 0xcc DAC Définit le conditionnement de codage arithmétique Marqueur de début de trame, différentiel, codage arithmétique 0xcd SOF13 DCT séquentiel différentiel 0xce SOF14 DCT progressif différentiel 0xcf SOF15 Sans perte de données (lossless), différentiel Fin de l'intervalle de redémarrage 0xd0 à 0xd7 RSTm Redémarrage modulo 8 m fois Autres marqueurs 0xd8 SOI Début d'image 0xd9 EOI Fin d'image 0xda SOS Début de scan 0xdb DQT Définition de table de quantification 0xdc DNL Définition du nombre de lignes 0xdd DRI Définition de l'intervalle de redémarrage 0xde DHP Définition progression hiérarchique 0xdf EXP Extension 0xe0 à 0xef APPm Réservé pour les applications externes 0xf0 à 0xfd JPGm Réservé pour les extensions JPEG 0xfe COM Commentaire Marqueurs réservés 0x01 TEM Pour usage temporaire lors du codage arithmétique 0x02 à 0xbf RES Réservé Un certain nombre de marqueurs sont suivis immédiatement par deux octets en format big endian qui définissent la longueur du segment marqué.
- Fichier JPEG:
Voici le début d'un fichier JPEG
0000000 255 216 255 225 32 168 69 120 105 102 0 0 73 73 42 0 del X del a sp ( E x i f nul nul I I * nul 0000016 8 0 0 0 10 0 15 1 2 0 6 0 0 0 56 2 bs nul nul nul nl nul si soh stx nul ack nul nul nul 8 stx 0000032 0 0 16 1 2 0 22 0 0 0 64 2 0 0 18 1 nul nul dle soh stx nul syn nul nul nul @ stx nul nul dc2 soh 0000048 3 0 1 0 0 0 1 0 0 0 26 1 5 0 1 0 etx nul soh nul nul nul soh nul nul nul sub soh enq nul soh nul 0000064 0 0 40 2 0 0 27 1 5 0 1 0 0 0 48 2 nul nul ( stx nul nul esc soh enq nul soh nul nul nul 0 stx 0000080 0 0 40 1 3 0 1 0 0 0 2 0 0 0 49 1 nul nul ( soh etx nul soh nul nul nul stx nul nul nul 1 soh 0000096 2 0 27 0 0 0 12 2 0 0 50 1 2 0 20 0 stx nul esc nul nul nul ff stx nul nul 2 soh stx nul dc4 nul
- Structure générale: un fichier JPEG commence toujours par
un marqueur SOI (séquence 255 216, ou 0xff 0xd8 en hexa). Il
est suivi d'un ou plusieurs marqueurs codant soit des méta-données
(segments APP), soit des données d'images. Dans le cas présent, nous
trouvons un marqueur APP1 (séquence 255 225, 0xff 0xe1) suivi de deux
octets codant la longueur du segment APP1 (séquence 32 168), soit
32x256+168=8360 (nous sommes ici en format big endian).
Il faut cependant bien voir que, contrairement à un fichier TIFF, ce nombre correspond à une longueur de segment et est donc relative au début du segment, sans inclure les deux octets du marqueur. Il faut rappeler que dans le cas d'un fichier TIFF, il s'agit d'un offset absolu par rapport au début du fichier.
- Segment APP1 codant des données Exif: Dans le cas présenté
ci-dessus, le premier segment est donc un segment APP1. Comme plusieurs
types de métadonnées pouvant être stockées dans des segments APP1
(même si, de façon générale, le segment APP1 est "réservé" aux données
TIFF/EXIF), il
existe en général en début de segment APP1 un identifiant décrivant le
type des données. Ici, on trouve les 4 lettres 'Exif' suivies de deux
0 (séquence 0x0 0x0).
La suite du segment correspond exactement au format TIFF tel que décrit plus haut: deux caractères ('II' ou 'MM') décrivant le type d'endianness, deux octets contenant le "magic number" 42, puis l'offset du premier IFD (séquence 8 0 0 0), etc... Attention cependant, les offsets sont ici relatifs au début des données TIFF/EXIF elles-mêmes, c'est à dire au premier caractère 'I' ou 'M'. Il faut aussi noter que, bien que le format général des en-têtes JPEG soit en format big endian, les contenus des sous-séquences peuvent parfaitement être en format little endian.
On voit ici qu'il s'agit d'un répertoire contenant dix entrées (10 0). Le premier tag est 0x10f (séquence 15 1), qui correspond au tag Make, le type de données est 2 (séquence 2 0, ASCII), la longueur des données est 6 (séquence 6 0 0 0) et ces données se trouvent à la position 2*256+56=568, valeur à laquelle il faut rajouter 12 qui est l'offset du début du fichier TIFF dans le fichier JPEG. Si l'on regarde à la position 580:
0000576 1 0 0 0 67 97 110 111 110 0 0 0 67 97 110 111 soh nul nul nul C a n o n nul nul nul C a n o 0000592 110 32 69 79 83 45 49 68 115 32 77 97 114 107 32 73 n sp E O S - 1 D s sp M a r k sp I 0000608 73 0 0 0 50 48 48 53 58 48 52 58 48 57 32 49 I nul nul nul 2 0 0 5 : 0 4 : 0 9 sp 1
On trouve bien la chaine "Canon" suivi d'un 0.
On trouve immédiatement derrière le premier tag le tag 0x110 qui correspond au modèle de l'appareil; là aussi le type de données est 2, la longueur de la chaine 22 et sa position 2x256+64+12=588. Là encore, à la position 588 on trouve bien la chaine de caractères décrivant le modèle, etc...
Il est cependant intéressant de continuer à détailler certains des champs de ce "pseudo-fichier" TIFF. En effet nous trouvons le tag 0x8769 (séquence 105 135 en position 130) qui identifie le pointeur sur un sous-répertoire ExifIFD en position relative 136, soit 148 en absolu.
0000128 0 0 105 135 4 0 1 0 0 0 136 0 0 0 188 1 nul nul i bel eot nul soh nul nul nul bs nul nul nul < soh 0000144 0 0 0 0 25 0 154 130 5 0 1 0 0 0 108 2 nul nul nul nul em nul sub stx enq nul soh nul nul nul l stx 0000160 0 0 157 130 5 0 1 0 0 0 116 2 0 0 34 136 nul nul gs stx enq nul soh nul nul nul t stx nul nul " bs
On constate que ce sous répertoire possède quand à lui 25 entrées, possédant en fait la majorité des informations intéressantes.
Mais il y a encore plus intéressant. Après le tag 0x8769, qui était la dernière entrée du répertoire IFD principal, on constate que le champ pointant sur l'IFD suivant n'est pas nul. Il renvoie en fait sur l'adresse (relative) 1x256+188=444 (séquence 188 1 0 0), soit 456 en absolu. Si nous allons en position 456, nous découvrons un autre IFD
0000448 0 0 0 0 0 0 0 0 6 0 3 1 3 0 1 0 nul nul nul nul nul nul nul nul ack nul etx soh etx nul soh nul 0000464 0 0 6 0 0 0 26 1 5 0 1 0 0 0 220 3 nul nul ack nul nul nul sub soh enq nul soh nul nul nul \ etx 0000480 0 0 27 1 5 0 1 0 0 0 228 3 0 0 40 1 nul nul esc soh enq nul soh nul nul nul d etx nul nul ( soh 0000496 3 0 1 0 0 0 2 0 0 0 1 2 4 0 1 0 etx nul soh nul nul nul stx nul nul nul soh stx eot nul soh nul 0000512 0 0 236 3 0 0 2 2 4 0 1 0 0 0 169 28 nul nul l etx nul nul stx stx eot nul soh nul nul nul ) fs
Cet IFD comporte quand à lui 6 entrées dont la plus intéressant est situé à la position 506. Il s'agit d'un tag 0x201 (JPEGInterchangeFormat) qui pointe sur la position 3x256+236=1004 en relatif et 1016 en absolu. A la position 1016:
0001008 128 252 10 0 16 39 0 0 255 216 255 219 0 132 0 3 nul | nl nul dle ' nul nul del X del [ nul eot nul etx 0001024 2 2 3 2 2 3 3 3 3 4 3 3 4 5 8 5 stx stx etx stx stx etx etx etx etx eot etx etx eot enq bs enq
il s'agit donc d'un marqueur 255 216 identifiant le début d'un fichier JPEG intégré dans le second répertoire IFD. Ce fichier JPEG n'est rien d'autre que le "thumbnail", c'est à dire l'image réduite qui est généralement utilisée par les navigateurs de fichiers de type explorer...
Le jeu de poupée russe est donc tout à fait redoutable et montre bien la complexité des structures imbriquées TIFF/EXIF/JPEG...
- Segment APP2: le segment de données suivant se trouve à
l'offset 8360 (taille indiquée pour le segment APP1)+ 2 (taille du
marqueur SOI) + 2 (taille du marqueur APP1) = 8364. Si nous allons à
la position 8364 du fichier:
0008352 217 0 0 0 32 32 32 32 32 32 32 32 255 226 12 84 Y nul nul nul sp sp sp sp sp sp sp sp del b ff T 0008368 73 67 67 95 80 82 79 70 73 76 69 0 1 1 0 0 I C C _ P R O F I L E nul soh soh nul nul
Nous trouvons à la position 8364 la séquence 255 226 soit 0xff 0xe2 en hexa, qui correspond au marqueur APP2. Il est suivi de deux octets codant la taille du segment: 12*256+84=3156 octets. Ces 4 octets sont suivant d'une chaine de caractères décrivant le contenu du marqueur, qui est ici "ICC_PROFILE" (profil colorimétrique).
- Segment DQT:le segment suivant se trouve à la position
8364+3156+2=11522:
0011520 0 1 255 219 0 132 0 8 6 6 7 6 5 8 7 7 nul soh del [ nul eot nul bs ack ack bel ack enq bs bel bel
Le tag 255 219 (0xff 0xdb) identifie un début de table de quantification suivi de la taille (0 132, soit 132 octets). Les tables de quantification sont utilisées lors du processus de décodage des données JPEG (voir le chapitre sur ce sujet).
- Segment DHT: le segment suivant se trouve en position
11522+132+2=11656:
0011648 50 50 50 50 50 50 50 50 255 196 1 162 0 0 1 5 2 2 2 2 2 2 2 2 del D soh " nul nul soh enq
Le tag 255 196 identifie le début de la table de Huffman, suivi de la longueur de la table 1x256+162=418 octets. Les tables de Huffman servent également dans le processus de décompression de l'information JPEG.
- Segment SOF0: En position 12076 on trouve le segment SOF
(Start Of Frame)
qui indique le type de codage utilisé ainsi que les caractéristiques
principales de la compression JPEG.
0012064 232 233 234 242 243 244 245 246 247 248 249 250 255 192 0 17 h i j r s t u v w x y z del @ nul dc1 0012080 8 19 128 13 0 3 1 33 0 2 17 1 3 17 1 255 bs dc3 nul cr nul etx soh ! nul stx dc1 soh etx dc1 soh del
Le tag 255 192 identifie une compression SOF0 (baseline DCT ou DCT standard). La longueur de ce champ est 17 (0 17). Les paramètres suivants permettent d'identifier le nombre de bits par pixels (8), les dimensions de l'image 19x256+128=4992 et 13*256+0=3328, ainsi que le nombre de plan (3).
- Champ SOS: Le champ SOS (Start Of Scan) se trouve à la
position 12095:
0012080 8 19 128 13 0 3 1 33 0 2 17 1 3 17 1 255 bs dc3 nul cr nul etx soh ! nul stx dc1 soh etx dc1 soh del 0012096 218 0 12 3 1 0 2 17 3 17 0 63 0 241 58 43 Z nul ff etx soh nul stx dc1 etx dc1 nul ? nul q : +
Il est identifié par le marqueur 255 218 et la longueur de l'en-tête est de 12. Ce champ indique le début d'une zone de données d'image (dans le cas présent il n'y en a qu'une) et fournit un certain nombre de paramètres au décodeur: le nombre de composants dans le scan (3 ici), ainsi que les sélecteurs de composants de scan et les tables de décodage associées.
Les données d'image commencent immédiatement après cet en-tête. Il s'agit de données encodées par l'algorithme JPEG (quantification+normalisation+encodage de Huffman). Ces données doivent en revanche ne jamais présentées d'octets égal à 255 suivi d'un octet autre que 0 ou 255. En effet, dans ce cas, cette séquence pourrait être confondue avec un marqueur valide. Les encodeurs jpeg insèrent donc des octets nul (0) après un octet valant 255 chqaue fois que cette situation risque de se présenter.
Format JFIF
Le format JFIF (JPEG File Interchange Format) est une restriction du format JPEG. Il est totalement compatible avec le format JPEG, mais le limite sérieusement:
- L'espace de couleur est obligatoirement YCbCr
- Le fichier commence systématiquement par un marqueur SOI
- Il est immédiatement suivi par un marqueur APP0 contenant:
- 2 octets codant la longeur du segment
- 5 octets contenant la chaine "JFIF" suivi d'un 0
- 2 octets codant la version, le premier codant la révision majeure, et le second la révision mineure
- 1 octet codant les unités employés. 0: pas d'unité, 1: inch, 2: cm
- 2 octets codant la densité horizontale en pixel
- 2 octets codant la densité verticale en pixel
- 1 octet codant la taille horizontale du "thumbnail"
- 1 octet codant la taille verticale du "thumbnail"
- 3n octets contenant les valeurs RGB du "thumbnail"
- De façon optionnelle, on peut rajouter un deuxième segment APP0 contenant une extension au standard. L'identifiant de ce segment (la chaine de caractère qui suit la longueur du segment) est la chaine "JFXX" suivi d'un 0. Nous ne le détaillerons pas ici.
Exemple de fichier RAW: le format Epson ERF
Le format ERF d'Epson est l'exemple parfait du "bon élève". Il s'agit en effet d'un format TIFF absolument conforme au standard. Si nous analysons le fichier, nous trouvons un en-tête TIFF totalement normal, suivi d'un premier répertoire à 24 entrées. La première image décrite est le thumbnail.
pos:30 tag:0x100 ImageWidth type:LONG count:1 val:160 pos:42 tag:0x101 ImageLength type:LONG count:1 val:120 pos:54 tag:0x102 BitsPerSample type:SHORT count:3 offset:302 val: 8 8 8 pos:66 tag:0x103 Compression type:SHORT count:1 val:1 pos:78 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:2 pos:90 tag:0x10e ImageDescription type:ASCII count:18 offset:308 val: EPSON DSC Picture pos:102 tag:0x10f Make type:ASCII count:18 offset:326 val: SEIKO EPSON CORP. pos:114 tag:0x110 Model type:ASCII count:5 offset:344 val: R-D1 pos:126 tag:0x111 StripOffsets type:LONG count:1 val:1508 pos:138 tag:0x112 Orientation type:SHORT count:1 val:1 pos:150 tag:0x115 SamplesPerPixel type:SHORT count:1 val:3 pos:162 tag:0x116 RowsPerStrip type:LONG count:1 val:120 pos:174 tag:0x117 StripByteCounts type:LONG count:1 val:57600 pos:186 tag:0x11a XResolution type:RATIONAL count:1 offset:350 val: (72/1) pos:198 tag:0x11b YResolution type:RATIONAL count:1 offset:358 val: (72/1) pos:210 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1 pos:222 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:234 tag:0x131 Software type:ASCII count:12 offset:366 val: E04106-0200 pos:246 tag:0x132 DateTime type:ASCII count:20 offset:378 val: 2006:11:25 10:10:33
Il s'agit d'une image de taille 160x120, stocké en format RGB (PhotometricInterpretation=2) avec 8 bits par couche (BItsPerSample 8 8 8), sans aucune compression (Compression=1). L'image est stocké de façon contigue (RowsPerStrip=120=ImageLength) et l'on vérifie bien que StripByteCounts = 57600 = 160x120x3 = ImageWidth x ImageLength x SamplesPerPixel.
Cette première image est suivie d'une seconde:
pos:1316 tag:0x100 ImageWidth type:LONG count:1 val:3040 pos:1328 tag:0x101 ImageLength type:LONG count:1 val:2024 pos:1340 tag:0x102 BitsPerSample type:SHORT count:1 val:12 pos:1352 tag:0x103 Compression type:SHORT count:1 val:32769 pos:1364 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:32803 pos:1376 tag:0x111 StripOffsets type:LONG count:1 val:59108 pos:1388 tag:0x115 SamplesPerPixel type:SHORT count:1 val:1 pos:1400 tag:0x116 RowsPerStrip type:LONG count:1 val:2024 pos:1412 tag:0x117 StripByteCounts type:LONG count:1 val:9844736 pos:1448 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1 pos:1460 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:1472 tag:0x828d CFARepeatPatternDim type:SHORT count:2 val:2 2 pos:1484 tag:0x828e CFAPattern type:BYTE count:4 val:0 1 1 2
Nous avons là l'image principale d'une taille de 3040x2024. Il y a 12 bits par pixel (BitsPerSample), mais une seule couche (SamplesPerPixel=1), ce qui est parfaitement normal. L'image est stockée de façon contigue (RowsPerStrip=ImageLength). Le mode de compression utilisé est propriétaire (Compression=32769, valeur spécifique Epson). Il faut cependant remarquer qu'il ne s'agit pas vraiment d'une compression à proprement parlé, puisque le nombre d'octets stockés (9844736) est supérieur à la valeur obtenue en stockant simplement les données (3040x2024x12/8=9229440). PhotometricInterpretation=32803, ce qui indique qu'il s'agit d'une image issue d'une mosaïque Bayer. Les tags CFARepeatPattern et CFAPattern décrivent le type de matrice Bayer utilisé (ordonnancement des filtres RGB). Ici la matrice est entièrement déterminée par une matrice 2x2 (CFARepeatPattern=2 2) et il s'agit d'une matrice ((R G),(G B)) (CFARepeatPatternDim= 0 1 1 2).
Ce champ IFD est suivi d'un répertoire ExifIFD contenant de nombreux champs "classiques" mais contenant aussi un champ MakerNote.
pos:548 tag:0x927c MakerNote type:UNDEFINED count:586 offset:708
Les champs MakerNote sont réservés aux fabricants. Ils contiennent des informations propriétaires, qui ne sont pas supposées être décodables...
Exemple de fichier RAW: le format Canon CR2
Le format CR2 Canon est lui-aussi globalement semblable au format
TIFF, et il en respecte la structure générale. En revanche, il
contient de nombreux tags non standards, et l'utilisation de certains
tags n'est pas conforme à la norme.
L'en-tête TIFF est conforme à la norme, mais différent des en-têtes
traditionnels. Il se compose en effetd de 16 octets au lieu de 8; les
8 premiers sont les 8 octets "standards", mais les 8 suivants sont différents:
0000000 73 73 42 0 16 0 0 0 67 82 2 0 148 204 10 0 I I * nul dle nul nul nul C R stx nul dc4 L nl nul
Les octets numéro 8 et 9 sont les caractères 'C' et 'R', qui identifient un fichier Canon Raw, les octets 10 et 11 identifient les versions majeures (2) et mineures (0) du format CR; les 4 octets suivants donnent l'offset de stockage de l'image "brute" (ici 707732).
La suite de la structure est beaucoup plus complexe. En effet, les fichiers CR2 contiennent plusieurs sous-images. La première (IFD1) décrite est la suivante:
pos:26 tag:0x100 ImageWidth type:SHORT count:1 val:1536 pos:38 tag:0x101 ImageLength type:SHORT count:1 val:1024 pos:50 tag:0x102 BitsPerSample type:SHORT count:3 offset:190 val: 8 8 8 pos:62 tag:0x103 Compression type:SHORT count:1 val:6 pos:74 tag:0x10f Make type:ASCII count:6 offset:196 val: Canon pos:86 tag:0x110 Model type:ASCII count:22 offset:202 val: Canon EOS-1Ds Mark II pos:98 tag:0x111 StripOffsets type:LONG count:1 val:10084 pos:110 tag:0x112 Orientation type:SHORT count:1 val:8 pos:122 tag:0x117 StripByteCounts type:LONG count:1 val:392372 pos:134 tag:0x11a XResolution type:RATIONAL count:1 offset:234 val: (72/1) pos:146 tag:0x11b YResolution type:RATIONAL count:1 offset:242 val: (72/1) pos:158 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:170 tag:0x132 DateTime type:ASCII count:20 offset:250 val: 2005:04:09 15:39:57
Nous n'allons pas à nouveau détailler tous les champs. Il s'agit ici d'une image de taille 1536x1024 sur 3 plans RGB de 8 bits, stocké de façon contigue, et compressé par un algorithme JPEG (Compression=6).
Cette première image est suivi d'un sub-segment ExifIFD qui contient la majorité des champs standards plus un sous-segment MakerNote qui contient un grand nombre de tags non standards Canon (la signification de ces segments peut-être partiellement trouvés dans les documents cités en annexe de cette page). C'est dans ce segment que se trouve la première description de l'image brute principale. Nous ne détaillerons que 3 de ses champs:
pos:496 tag:0xa002 PixelXDimension type:SHORT count:1 val:4992 pos:508 tag:0xa003 PixelYDimension type:SHORT count:1 val:3328 pos:974 tag:0xe0 UnknownTag type:SHORT count:17 offset:2814 val: 34 5108 3349 1 1 108 19 5099 3346 0 0 0 0 0 0 0 0
Les deux premiers tags fixent les dimensions "théoriques" de l'image. Le tag 0xe0 décrit les caractéristiques du capteur de l'appareil; les chiffres 5108 et 3349 décrivent la taille véritable du capteur, qui ne sont pas égales à la dimension de l'image. En revanche, ce sont ces dimensions qui sont utilisées pour interpréter la dimension de l'image RAW qui a été stocké!
A la suite de ces segments descriptifs se trouve un nouvel IFD (IFD2):
pos:402466 tag:0x201 JPEGInterchangeFormat type:LONG count:1 val:402486 pos:402478 tag:0x202 JPEGInterchangeFormatLngth type:LONG count:1 val:10190
Cet IFD contient donc un fichier JPEG directement inclus dans le fichier CR2.
Derrière cet IFD se trouve un autre IFD (IFD3) décrivant une autre image:
pos:412686 tag:0x100 ImageWidth type:SHORT count:1 val:384 pos:412698 tag:0x101 ImageLength type:SHORT count:1 val:256 pos:412710 tag:0x102 BitsPerSample type:SHORT count:3 offset:412814 val: 8 8 8 pos:412722 tag:0x103 Compression type:SHORT count:1 val:6 pos:412734 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:2 pos:412746 tag:0x111 StripOffsets type:LONG count:1 val:412820 pos:412758 tag:0x115 SamplesPerPixel type:SHORT count:1 val:3 pos:412770 tag:0x116 RowsPerStrip type:SHORT count:1 val:256 pos:412782 tag:0x117 StripByteCounts type:LONG count:1 val:294912 pos:412794 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1
Il s'agit cette fois-ci d'une image de dimension 384x256, avec 3 plans et 8 bits par plan. Curieusement, la compression indiquée est 6 (JPEG) alors que l'image n'est pas compressé (384 x 256 x 3 = 294912 = StripByteCounts). Il s'agit clairement d'une déviation, volontaire ou involontaire, du standard TIFF.
Nous en arrivons maintenant au dernier IFD (IFD4) qui est relativement court:
pos:707742 tag:0x103 Compression type:SHORT count:1 val:6 pos:707754 tag:0x111 StripOffsets type:LONG count:1 val:707816 pos:707766 tag:0x117 StripByteCounts type:LONG count:1 val:14319750 pos:707778 tag:0xc5d8 UnknownTag type:LONG count:1 val:1 pos:707790 tag:0xc5e0 UnknownTag type:LONG count:1 val:3 pos:707802 tag:0xc640 RawStripping type:SHORT count:3 offset:707810 val: 2 1680 1748
Il s'agit donc de l'image RAW elle-même. Elle est stockée de façon contigue et contient 14319750 octets. Elle est compressée suivant un algorithme de type JPEG (en fait, un algorithme semblable à du JPEG lossless, mais qui n'est pas exactement du JPEG lossless). Le tag RawStripping indique que l'image a été découpée en trois bandes dont les tailles respectives sont 1680 deux fois et 1748 une fois (on vérifie bien que 1680+1680+1748 = 5108 = la taille du capteur), avant d'être compressée.
En conclusion, le format CR2 reprend globalement la structure TIFF avec quelques déviations au standard, mais il est surtout relativement fouilli, puisqu'il ne contient pas moins de 3 images en plus de l'image RAW, dans 3 formats différents et avec des tailles différentes!
Format Nikon NEF
Le format Nikon NEF est lui aussi un format TIFF au niveau de sa
structure générale. Comme le format CR2 Canon il contient des
extensions à la norme et plusieurs images sont stockés dans le fichier
en plus de l'image "RAW". Les formats RAW Nikon sont reputés comme
déviants fortement du standard TIFF. En ce qui concerne ceux que j'ai
pu observés, ils étaient tout à fait dans la norme.
Il semble (et une
polémique a éclaté à ce sujet entre Adobe et Nikon) que le format de
certains
champs propriétaires (en particulier ceux codant la balance des
blancs) ne soient pas livrés, ou n'aient pas été livrés même aux
développeurs professionnels comme Adobe, Nikon protégeant ainsi son
propre logiciel de développement RAW, NikonCapture.
Le fichier commence par un premier IFD décrivant une image 160x120 avec 3 plans de 8 bits chacun pour un résultat (non compressé) occupant un espace de 57600 octets.
pos:18 tag:0xfe NewSubfileType type:LONG count:1 val:1 pos:30 tag:0x100 ImageWidth type:LONG count:1 val:160 pos:42 tag:0x101 ImageLength type:LONG count:1 val:120 pos:54 tag:0x102 BitsPerSample type:SHORT count:3 offset:326 val: 8 8 8 pos:66 tag:0x103 Compression type:SHORT count:1 val:1 pos:78 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:2 pos:90 tag:0x10e ImageDescription type:ASCII count:11 offset:332 val: pos:102 tag:0x10f Make type:ASCII count:6 offset:364 val: NIKON pos:114 tag:0x110 Model type:ASCII count:6 offset:388 val: E8400 pos:126 tag:0x111 StripOffsets type:LONG count:1 val:56560 pos:138 tag:0x112 Orientation type:SHORT count:1 val:1 pos:150 tag:0x115 SamplesPerPixel type:SHORT count:1 val:3 pos:162 tag:0x116 RowsPerStrip type:LONG count:1 val:120 pos:174 tag:0x117 StripByteCounts type:LONG count:1 val:57600 pos:186 tag:0x11a XResolution type:RATIONAL count:1 offset:402 val: (300/1) pos:198 tag:0x11b YResolution type:RATIONAL count:1 offset:410 val: (300/1) pos:210 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1 pos:222 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:234 tag:0x131 Software type:ASCII count:10 offset:418 val: E8400v1.5 pos:246 tag:0x132 DateTime type:ASCII count:20 offset:450 val: 2007:10:19 01:15:57 pos:258 tag:0x14a SubIFDs type:LONG count:2 offset:470 val:
Ce premier IFD est suivi de deux sous IFD. Le premier décrit une image JPEG (taille 640x480) et contient un sous IFD JPEG décrivant cette image.
pos:914 tag:0xfe NewSubfileType type:LONG count:1 val:1 pos:926 tag:0x103 Compression type:SHORT count:1 val:6 pos:938 tag:0x11a XResolution type:RATIONAL count:1 offset:1006 val: (300/1) pos:950 tag:0x11b YResolution type:RATIONAL count:1 offset:1014 val: (300/1) pos:962 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:974 tag:0x201 JPEGInterchangeFormat type:LONG count:1 val:114160 Start SubJPEG 1712 Pour usage temporaire lors du codage arithmétique - TEM 1826 Réservé pour les extensions JPEG - JPG12 length=8738 15601 Définition de table de Huffman - DHT length=31 th=0 tl=1 15634 Définition de table de Huffman - DHT length=181 th=1 tl=1 15817 Définition de table de Huffman - DHT length=31 th=0 tl=0 15850 Définition de table de Huffman - DHT length=181 th=1 tl=0 16033 Définition de table de quantification - DQT length=67 Pq=1 Tq=10 16102 Définition de table de quantification - DQT length=67 Pq=0 Tq=10 16171 SOF0 - DCT traditionnel length=17 p=8 y=640 x=480 nf=3 c=0 h=2 v=1 tq=0 c=1 h=1 v=1 tq=1 c=2 h=1 v=1 tq=1 16190 Début de scan - SOS length=12 Ns=3 (0: Cs=0 Td=0 Ta=0) (1: Cs=1 Td=1 Ta=1) (2: Cs=2 Td=1 Ta=1) Ss=0 Se=63 Ah=0 Al=0 53917 Fin d'image - EOI End SubJPEG pos:986 tag:0x202 JPEGInterchangeFormatLngth type:LONG count:1 val:213913 pos:998 tag:0x213 YCbCrPositionning type:SHORT count:1 val:2
Le second sous IFD décrit l'image RAW elle-même. Il s'agit ici d'une image 3280x2454 sur 1 plan et 12 bits par pixel. Le codage est propriétaire, mais on peut constater qu'il n'y a pas de compression de données (3280x2454x12/8=12073680). La matrice Bayer suit un format ((B,G),(G,R)), suivant la description des tags CFA.
pos:1032 tag:0xfe NewSubfileType type:LONG count:1 val:0 pos:1044 tag:0x100 ImageWidth type:LONG count:1 val:3280 pos:1056 tag:0x101 ImageLength type:LONG count:1 val:2454 pos:1068 tag:0x102 BitsPerSample type:SHORT count:1 val:12 pos:1080 tag:0x103 Compression type:SHORT count:1 val:1 pos:1092 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:32803 pos:1104 tag:0x111 StripOffsets type:LONG count:1 val:597488 pos:1116 tag:0x112 Orientation type:SHORT count:1 val:1 pos:1128 tag:0x115 SamplesPerPixel type:SHORT count:1 val:1 pos:1140 tag:0x116 RowsPerStrip type:LONG count:1 val:2454 pos:1152 tag:0x117 StripByteCounts type:LONG count:1 val:12073680 pos:1164 tag:0x11a XResolution type:RATIONAL count:1 offset:1244 val: (300/1) pos:1176 tag:0x11b YResolution type:RATIONAL count:1 offset:1252 val: (300/1) pos:1188 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1 pos:1200 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:1212 tag:0x828d CFARepeatPatternDim type:SHORT count:2 val:2 2 pos:1224 tag:0x828e CFAPattern type:BYTE count:4 val:2 1 1 0 pos:1236 tag:0x9217 SensingMethod type:SHORT count:1 val:2
Ce dernier sous-IFD est suivi d'un IFD Exif décrivant les principales caractéristiques de l'image.
pos:570 tag:0x829a ExposureTime type:RATIONAL count:1 offset:722 val: (10/601) pos:582 tag:0x829d FNumber type:RATIONAL count:1 offset:730 val: (49/10) pos:594 tag:0x8822 ExposureProgram type:SHORT count:1 val:2 pos:606 tag:0x9003 DateTimeOriginal type:ASCII count:20 offset:738 val: 2007:10:19 01:15:57 pos:618 tag:0x9004 DateTimeDigitized type:ASCII count:20 offset:758 val: 2007:10:19 01:15:57 pos:630 tag:0x9204 ExposureBias type:SRATIONAL count:1 offset:778 val: (0/10) pos:642 tag:0x9205 MaxApertureValue type:RATIONAL count:1 offset:786 val: (35/10) pos:654 tag:0x9207 MeteringMode type:SHORT count:1 val:5 pos:666 tag:0x9209 Flash type:SHORT count:1 val:25 pos:678 tag:0x920a FocalLength type:RATIONAL count:1 offset:794 val: (216/10) pos:690 tag:0x927c MakerNote type:UNDEFINED count:52657 offset:1260 val: count=52657. Too long to print pos:702 tag:0xa300 FileSource type:UNDEFINED count:1 val:3 pos:714 tag:0xa302 CFAPattern type:UNDEFINED count:8 offset:802 val: 0 2 0 2 5 3 1 4
Format Pentax PEF
Le format PEF est lui aussi à la norme TIFF, et il la respecte de façon relativement rigoureuse. Le fichier commence par un premier IFD qui décrit l'image RAW. On constate qu'il s'agit d'un codage propriétaire et que l'image est compressée.
pos:18 tag:0x100 ImageWidth type:LONG count:1 val:3936 pos:30 tag:0x101 ImageLength type:LONG count:1 val:2624 pos:42 tag:0x102 BitsPerSample type:SHORT count:1 val:12 pos:54 tag:0x103 Compression type:SHORT count:1 val:65535 pos:66 tag:0x106 PhotometricInterpretation type:SHORT count:1 val:32803 pos:78 tag:0x10f Make type:ASCII count:20 offset:242 val: PENTAX Corporation pos:90 tag:0x110 Model type:ASCII count:20 offset:262 val: PENTAX K10D pos:102 tag:0x111 StripOffsets type:LONG count:1 val:85452 pos:114 tag:0x112 Orientation type:SHORT count:1 val:1 pos:126 tag:0x115 SamplesPerPixel type:SHORT count:1 val:1 pos:138 tag:0x116 RowsPerStrip type:LONG count:1 val:2624 pos:150 tag:0x117 StripByteCounts type:LONG count:1 val:10712048 pos:162 tag:0x11a XResolution type:RATIONAL count:1 offset:282 val: (72/1) pos:174 tag:0x11b YResolution type:RATIONAL count:1 offset:290 val: (72/1) pos:186 tag:0x11c PlanarConfiguration type:SHORT count:1 val:1 pos:198 tag:0x128 ResolutionUnit type:SHORT count:1 val:2 pos:210 tag:0x131 Software type:ASCII count:24 offset:298 val: K10D Ver 1.20 pos:222 tag:0x132 DateTime type:ASCII count:20 offset:322 val: 2007:06:24 11:01:28
Ce premier IFD est suivi d'un sous-IFD Exif qui décrit les caractéristiques principales de l'image.
Format DNG
Références
- Norme TIFF version 6
- Draft du standard TIFF-EP
- Une copie locale de la documentation de l'ensemble des tags reconnus par l'excellent logiciel de Phil Harvey exiftool. La page originale (à consulter de préférence car elle est probablement plus à jour) est ici.
- Description des tags Exif et de certains tags (MakerNotes) propriétaires. Il s'agit d'une partie de la documentation de exifutils. Attention, certains tags décrits sont en hexa et d'autres en octal...
- Extension TIFF pour le codage JPEG et LZW
- Norme DNG (extension TIFF)
- Norme Exif version 2.2
- Spécifications XMP
- Document d'Adobe décrivant les méthodes canoniques d'inclusions de données XMP dans différents formats de fichiers.
- IPTC4 XMP Core
- Draft du Dublin Core NISO standard Z39.85-2007
- The Ressource Document Format (RDF) definition
- Standard JPEG (recommandation ITU T81)
- Norme JFIF version 1.02
- Article de 1991 par Wallace posant les bases du JPEG
- Norme DCF (Design rule for Camera File system)
- Norme CIFF
Le téléchargement ou la reproduction des documents et photographies
présents sur ce site sont autorisés à condition que leur origine soit
explicitement mentionnée et que leur utilisation
se limite à des fins non commerciales, notamment de recherche,
d'éducation et d'enseignement.
Tous droits réservés.
Dernière modification: 21:00, 20/03/2024