Le fichier BitMap de Windows
Les fichiers de ce type possèdent généralement une extension .BMP ou .DIB.
Ces fichiers contiennent une image. Généralement, l'image n'est pas compressée. Par conséquent, ces fichiers peuvent bien vite occuper énormément de place.
Il est possible d'enregistrer dans ces fichiers des images de différentes tailles et d'un nombre de couleurs plus ou moins important.
Il faut donc stocker toutes ces informations dans ces fichiers afin de pouvoir réafficher l'image correctement plus tard.
Pb. endianness
suivant la plateforme utilisée.
Le fichier commence donc par un en-tête. Cet en-tête est une structure de type BITMAPFILEHEADER.
Nom | Type | Désignation |
bfType | UINT | Contient les caractères "BM". Sert de contrôle lors de la relecture du fichier. |
bfSize | DWORD | Taille totale du fichier. |
bfReserved1 | UINT | Réservé et à 0 |
bfReserved2 | UINT | Réservé et à 0 |
bfOffbits | DWORD | Décalage entre le premier octet de l'image et le début du fichier. |
Comme on peut le voir, il n'y a pas d'informations sur comment est composée
l'image.
Il y a donc un autre en-tête pour ces informations:
Il s'agit là aussi d'une structure qui est de type BITMAPINFOHEADER:
Nom | Type | Désignation |
biSize | DWORD | Taille de la structure BITMAPINFOHEADER en octets |
biWidth | LONG | Largeur du bitmap en pixels |
biHeight | LONG | Hauteur du bitmap en pixels |
biPlanes | WORD | Fixé à 1. |
biBitCount | WORD | Nombre de bits qui compose la couleur par pixel (1,4,8 ou 24). |
biCompression | DWORD | Schéma de compactage (0 pour aucun) |
biSizeImage | DWORD | Taille de l'image en octets (utile uniquement si compacté) |
biXPelsPerMeter | LONG | Résolution horizontale en pixel par mètre |
biYPelsPerMeter | LONG | Résolution verticale en pixel par mètre |
biClrUsed | DWORD | Nombre de couleurs utilisées dans l'image |
biClrImportant | Nombre de couleurs importantes dans l'image |
Après biBitCount,
les informations ne sont pas forcément présentes dans le fichier.
On pourra alors considérer que ces champs sont à 0 (valeurs par
défauts !)
si biClrUsed est
positionné à 1, 4 ou 8, cela signifie que cet en-tête sera
suivi d'un autre en-tête composé d'une palette de couleurs.
Les couleurs indiquées dans cette palette seront à affecter à
un registre de couleur dont le numéro de ce registre correspond à
la position des informations sur la couleur dans la palette.
La structure de la couleur étant la suivante:
Nom | Type | Désignation |
rgbBlue | Byte | intensité du bleu |
rgbGreen | Byte | vert |
rgbRed | Byte | rouge |
rgbReserved | Byte | réservé |
(Voir ici pourquoi un codage aussi bizarre des composantes rouge, vert et bleu...)
L'ensemble de ces structures compose la palette...
Ainsi la couleur à associer à un registre n (avec n commençant à 0) sera la couleur indiquée dans la palette à la position n * taille de la structure RGBQUAD.
Le nombre de structures RGBQUAD va varier suivant le nombre de bits de couleur
par pixel: 2 pour 1 bit, 16 pour 4 bits et 256 pour 8 bits.
On peut aussi retrouver le nombre de structures dans biClrUsed si celui-ci n'est
pas NULL.
Le pixel représentant alors le registre de couleur utilisé.
Pour un bitmap 16 couleurs, le premier pixel de chaque ligne est représenté
par les 4 bits de poids fort du premier octet. La valeur trouvée correspondant
à la position de la couleur dans la palette.
Pour un bitmap de 256 octets, l'octet représentant alors à la
position de la couleur dans la palette.
Pour un bitmap de 24 bits, 3 octets représentent directement les valeurs RVB. Il n'y a pas de table de couleurs sauf si biClrUsed n'est pas nul.
le codage RVB se
fera là aussi BVR !!!
L'image commencera donc après toutes ces structures. La taille d'une ligne de l'image devant être un multiple de quatre, il est possible que des octets soient ajoutés à la fin chaque ligne pour permettre cela.
Enfin, chose plutôt
drôle, la première ligne lue est en fait la dernière ligne
de l'image, la seconde et en fait l'avant dernière, etc...
L'explication:
Sur un moniteur, le faisceau d'électrons part pour afficher une image à l'écran d'en haut à gauche de celui-ci, pour terminer en bas à droite.
Ce qui nous donne comme repère habituellement utilisé pour afficher une image ou une animation:
Or Windows utilise un repère orthonormé tout ce qu'il y a de plus classique:
D'où l'image
inversée.
L'image n'est pas systèmatiquement
inversée. Dans le cas des textures
dans OpenGL, le repère utilisé
étant identique à celui utilisé dans un fichier bitmap,
l'image sera alors immédiatement dans le bon sens !
si biSize vaut 12,
alors il s'agit d'un bitmap supporté par OS/2. Dans ce cas, nous ne lisons
pas une structure BITMAPINFOHEADER mais une structure BITMAPCOREHEADER
typedef struct tagBITMAPCOREHEADER {
DWORD bcSize;
WORD bcWidth;
WORD bcHeight;
WORD bcPlanes;
WORD bcBitCount;
} BITMAPCOREHEADER, *PBITMAPCOREHEADER;
Avec:
Nom | Désignation |
bcSize | Nombre d'octets de la structure |
bcWidth | Largeur de l'image en pixel |
bcHeight | Hauteur de l'image en pixel |
bcPlanes | Nombre de plan (doit être à 1) |
bcBitCount | Nombre de bit par pixel (1, 4, 8 ou 24) |
BITMAPCOREHEADER étant une sous structure de BITMAPCOREINFO
typedef struct _BITMAPCOREINFO {
BITMAPCOREHEADER bmciHeader;
RGBTRIPLE bmciColors[1];
} BITMAPCOREINFO, *PBITMAPCOREINFO;
avec BITMAPCOREHEADER que nous venons de présenter.
RGBTRIPLE bmciColors[1]: Tableau de définition des couleurs.
Pour trouver la palette de couleur
pColor = ((LPBYTE) pBitmapCoreInfo + (WORD) (pBitmapCoreInfo -> bcSize))
Le principe restant le même...