LES IMAGES BMP
Généralité
Les BMP sont des fichiers contenant des images. Il existe 4 codage de couleurs courament utilisés
- Monochrome codé avec 1 bit par pixel
- 16 couleurs codé avec 4 bits par pixel
- 256 couleurs codé avec 8 bits par pixel
- 16 777 216 couleurs codé avec 24 bits par pixel
Mais il existe aussi d'autres codages qui sont gérés par très peut de logiciels
- 65536 couleurs codé avec 16 bits par pixel
- 4 294 967 296 couleurs codé avec 32 bits par pixel
Ses deux versions peuvent être lues par quelque logiciels mais la majorité ne peuvent pas les enregistrer corectement il vont les convertir en 24 bits par pixel.
Il existe aussi quelques variantes avec les images étendues dans les quelles on trouve plusieurs fois la même image mais à des zooms différents, ses images sont utilisées comme texture dans les jeux.
Entête
Les images BMP ont une structure bien spécifique, lorsque l'on ouvre un BMP avec un éditeur hexadécimal on va trouver trois ou quatre parties selon le fichier.
Le tableau suivant d'écrit ces structures.
Adresse | Taille | Données |
$0000 | 2 | Signature toujours égale à 'BM' |
$0002 | 4 | Taille du fichier en octet |
$0006 | 4 | Toujours à zéro |
$000A | 4 | Adresse pointant sur les données de l'image |
$000E | 4 | Taille de la seconde partie de l'entête |
$0012 | 4 | Largeur de l'image |
$0016 | 4 | Hauteur de l'image |
$001A | 2 | Nombre de plan utilisé |
$001C | 2 | Nombre de bit par pixel |
$001E | 4 | Type de compression |
$0022 | 4 | Taille des données de l'image |
$0026 | 4 | Résolution horizontale en pixel par mètre |
$002A | 4 | Résolution verticale en pixel par mètre |
$002E | 4 | Nombre de couleurs utilisées |
$0032 | 4 | Nombre de couleurs importantes |
$0036 | | début des donnée image ou début de la palette de couleur |
Dans la première partie $0000 à $000A il y a les information sur le fichier.
- $0000 deux octets contenant toujours 'BM' indiquant que le fichier ouvert est bien un BMP.
- $0002 quatre octets indiquant la taille du fichier. Dans certain cas très rare la valeur ne correspond pas à la taille réel du fichier.
- $0006 quatre octets toujours à $00.
- $000A quatre octets qui nous donnent l'adresse à partir de la quelle se trouvent les données de l'image.
Dans la seconde partie $000E à $0032 il y a toutes les informations sur l'image.
- $000E quatre octets indiquant la taille de cette deuxième partie.
- $0012 quatre octets contenant la largeur de l'image en pixel.
- $0016 quatre octets contenant la hauteur de l'image en pixel.
- $001A deux octets indiquant le nombre de plan utilisé, dans les nombreux tests que j'ai fait je n'ai vu qu'un seul plan.
- $001C deux octets indiquant le nombre de bits par pixel utilisé pour coder l'image.
- $001E quatre octets indiquant le type de compression utilisé, 0 pas de compression, 1 compression de type RLE8, 2 compression de type RLE4.
- $0022 Quatre octets indiquant la taille (en octets) des données images, il arrive parfois que cette valeur soit à zéro.
dans ce cas il faut le calculer cela donne (H*L*nb bit par pixel)*8.
Palette de couleur
Dans la troisième partie à partir de $0036 il y a la palette de couleur si l'image est encodée avec huit bits par pixel ou moins.
Cette palette est composée de X fois quatre octets en fonction du nombre de couleur utilisé.
En monochrome elle fera donc huit octets, 64 octets pour le mode 16 couleurs et enfin 1024 octets en 256 couleurs.
Le tableau suivant nous montre cette structure.
$0036 | Niveau de bleu de la couleur n°0 |
$0037 | Niveau de vert de la couleur n°0 |
$0038 | Niveau de rouge de la couleur n°0 |
$0039 | $00 |
$003A | Niveau de bleu de la couleur n°1 |
$003B | Niveau de vert de la couleur n°1 |
$003C | Niveau de rouge de la couleur n°1 |
$003D | $00 |
$003E | ... |
Donc en chargeant la palette dans un tableau de quatre octets par ligne on obtiens cette structure
$00 | Couleur n°0 |
$01 | Couleur n°1 |
$03 | Couleur n°3 |
... | ... |
Par la suite il reste à lire les données images et de pointer sur la ligne du tableau pour avoir la couleur.
Les données
Dans la dernière partie se trouvent les données de l'image, la première valeur, sur 1 ou 32 bits, correspond au premier pixel de la dernière ligne de l'image.
Les données sont effectivement stockées de la dernière ligne à la première. Pour les modes 16, 24 ou 32 bits les informations de la couleur sont inversées on à BVR au lieu de RVB il faut donc faire une inversion du Rouge et du Bleu.
Les images particuliéres
Au cours de mais recherche sur les BMP utilisé dans certain jeux j'ai trouvé quelque cas de codage singulier.
Il semble que DirectX les gére très bien.
Quand une image est codé en 16 bits par pixel on peut avoir les cas suivants:
- Sur les 16 bits 4 vont être dédié au masque aplha, 4 pour le bleu, 4 pour le vert et 4 pour le rouge.
- Sur les 16 bits 1 va être dédié au masque aplha, 5 pour le bleu, 5 pour le vert et 5 pour le rouge.
- Sur les 16 bits 5 pour le bleu, 6 pour le vert et 5 pour le rouge. dans ce cas il n'y a pas de masque alpha, mais il peut y avoir d'autres cas
- Compression DXT1
- Compression DXT2
- Compression DXT3
- Compression DXT4
- Compression DXT5
Il est possible aussi qu'il y ait plusieur fois la même images à des zooms différents, On à ainsi pour une image de 256*256 les zooms suivants :
128*128, 64*64, 32*32, 16*16, 8*8, 4*4, 2*2 et 1*1.
Ces images ditent étendue ne fonctionnent qu'avec des images carrées.
Si on lit une image étendue sans tenir compte de sa hauteur on obtien ceci
Après traitement on obtient ceci