**BMP** (ад англ.: Bitmap Picture) — фармат захоўвання растравых малюнкаў, распрацаваны кампаніяй Microsoft.
Файлы фармату BMP могуць мець пашырэнні .bmp, .dib і .rle

З фарматам BMP працуе вялікая колькасць праграм, бо яго падтрымка інтэгравана ў аперацыйныя сістэмы Windows і OS/2.
Акрамя таго, даныя гэтага фармату ўключаюцца ў дваічныя файлы рэсурсаў RES і ў PE-файлы.

У дадзеным фармаце можна захоўваць толькі аднаслаёвыя растры.
На кожны піксель ў розных файлах можа прыходзіцца розная колькасць біт (глыбіня колеру).
Microsoft прапануе бітнасці 1, 2, 4, 8, 16, 24, 32, 48 і 64.
У бітнасцях 8 і ніжэй, колер паказваецца з індэксам табліцы колераў (палітры), а пры большых — непасрэдным значэннем.
Колер жа ў любым выпадку можна задаць толькі ў каляровай мадэлі RGB (як пры непасрэдным ўказанні ў пікселі, так і ў табліцы колераў), але ў битностях 16 і 32 можна атрымаць Grayscale з глыбінёй да 16 і 32 біт адпаведна.
Частковая празрыстасць рэалізавана альфа-каналам розных бітнасцяў, але пры гэтым празрыстасць без градацый можна ўскосна атрымаць RLE-кадзіраваннем.

У большасці выпадкаў пікселі захоўваюцца ў выглядзе адносна простага двухмернага масіва.
Для бітнасцей 4 і 8 даступна RLE-кадзіраванне, якое можа паменшыць іх памер.
Фармат BMP таксама падтрымлівае ўбудаванне даных у фарматах JPEG і PNG.
Але апошняе, хутчэй, больш прызначана не для кампактнага захоўвання, а для абыходу абмежаванняў архітэктуры GDI, якая не прадугледжвае прамую працу з відарысамі, адметнымі ад фарматаў BMP.

У апошніх версіях фармату BMP таксама з’явіліся магчымасці па кіраванні колерам.
У прыватнасці, можна паказваць канчатковыя кропкі, вырабляць гама-карэкцыю і ўбудоўваць каляровыя профілі ICC.

DIB і DDB
---------

Пры выкарыстанні фармату DIB (англ.: Device Independent BitmapDevice Independent Bitmap, апаратна-незалежны растр) праграміст можа атрымаць доступ да ўсіх элементаў структур, якія апісваюць малюнак, пры дапамозе звычайнага паказальніка.
Але гэтыя дадзеныя не выкарыстоўваюцца для непасрэднага кіравання экранам, так як яны заўсёды захоўваюцца ў сістэмнай памяці, а не ў спецыялізаванай відэапамяці.
Фармат пікселя ў аператыўнай памяці можа адрознівацца ад таго фармату, які павінен заносіцца ў відэапамяць для індыкацыі пункту такога ж колеру.
Напрыклад, у DIB-фармаце можа выкарыстоўвацца 24 біта для задання пікселя, а графічны адаптар у гэты момант можа працаваць у рэжыме HiColor з каляровай глыбінёй 16 біт.
Пры гэтым ярка-чырвоная кропка ў апаратна-незалежным фармаце будзе задавацца трыма байтами 0000FF16, а ў відэапамяці — словам F80016.
Пры капіяванні малюнка на экран сістэма будзе марнаваць дадатковы час на пераўтварэнне кодаў колеру з 24-бітнага фармату ў фармат відэабуфера.

Фармат DDB (англ.: Device Dependent BitmapDevice Dependent Bitmap, апаратна-залежны растр) заўсёды змяшчае каляровыя коды, якія супадаюць з кодамі відэабуфера, але ён можа захоўвацца як у сістэмнай, так і ў відэапамяці.
У абодвух выпадках ён змяшчае толькі коды колеру ў тым фармаце, які забяспечыць перасылку выявы з АЗП у відэапамяць пры дапамозе простага капіявання.

Унутраная будова
----------------

Афіцыйную інфармацыю па фармаце BMP можна знайсці ў MSDN або даведцы Microsoft Windows SDK (можа ісці ў камплекце з некаторымі IDE).
У файле WinGDI.h ад кампаніі Microsoft ёсць усе аб’явы на мове C++, якія тычацца дадзенага фармату.
У дадзены артыкул жа не былі ўключаны аб’явы тыпаў, так як ад гэтага яна можа быць занадта грувасткай.
Да таго ж афіцыйныя аб’явы некаторыя распрацоўшчыкі могуць палічыць нязручнымі і таму іх запатрабаванасць сумніўная.
Калі вам спатрэбяцца арыгінальныя імёны канстант, структур, тыпаў і іх палёў, то яны ўсе ёсць у тэксце гэтага артыкула.

Максімальны памер непадзельных вочак (выключаючы поля бітавых структур): 32 біта і таму фармат можна класіфікаваць як 32-бітны.
Выключэннем могуць быць 64-бітныя пікселі, але іх значэнні каналаў можна апрацоўваць і 16-бітнымі словамі.
Парадак байт у 16-бітныя і 32-бітных вочках паўсюль ад малодшага да старэйшага (little-endian).
Цэлыя лікі запісваюцца ў прамым кодзе, са знакам — у дадатковым.
Калі параўноўваць з апаратнымі архітэктурамі, то парадак байт і фармат лікаў адпавядае x86.

У дадзенай артыкуле для ўказанні тыпаў выкарыстоўваюцца імёны тыпаў WinAPI як у дакументацыі Microsoft.
Акрамя спецыфічных (апісаныя асобна ў тэксце артыкула) можна сустрэць чатыры лікавых тыпу:

* BYTE — 8-бітнае беззнакавае цэлае.
* WORD — 16-бітнае беззнакавае цэлае.
* DWORD — 32-бітнае беззнакавае цэлае.
* LONG — 32-бітнае цэлае са знакам.

У фармаце Windows Bitmap пад структурамі разумеецца блок з ідучымі запар вочкамі рознага фіксаванага памеру, у якіх ёсць ўмоўныя імёны (ёсць у многіх мовах праграмавання), а не што-то складаней (напрыклад, паток каманд адвольнага памеру).

У некаторых элементаў фармату паказаная версія Windows, пачынаючы з якой ён падтрымліваецца.
Гаворка ідзе ў першую чаргу аб асноўных бібліятэках WinAPI такіх як gdi32.dll, shell32.dll, user32.dll і kernel32.dll.
Іншыя кампаненты аперацыйнай сістэмы (напрыклад, GDI+, .NET, DirectX) могуць мець іншыя больш шырокія магчымасці.

### Агульная структура

Дадзеныя ў фармаце BMP складаюцца з трох асноўных блокаў рознага памеру:

1. Загаловак з структуры BITMAPFILEHEADER і блока BITMAPINFO. Апошні змяшчае:
	1. Інфармацыйныя поля.
	2. Бітавыя маскі для здабывання каляровых значэнняў каналаў (апцыянальныя).
	3. Табліца колераў (апцыянальная).
2. Каляровы профіль (апцыянальны).
3. Піксельныя дадзеныя.

Пры захоўванні ў файле усе загалоўкі ідуць з самага першага байта.
Піксельныя дадзеныя могуць знаходзіцца на адвольнай пазіцыі ў файле (яна паказваецца ў поле OffBits структуры BITMAPFILEHEADER), у тым ліку і ў выдаленні ад загалоўкаў.
Апцыянальны каляровай профіль з’явіўся ў версіі 5 і ён таксама можа свабодна размяшчацца, але яго пазіцыя паказваецца ад пачатку BITMAPINFO (у поле ProfileData).

У аператыўнай памяці (напрыклад, пры ўзаемадзеянні з WinAPI-функцыямі GDI) з загалоўкаў выключаецца структура BITMAPFILEHEADER.
Пры гэтым Microsoft рэкамендуе размяшчаць каляровай профіль адразу за загалоўкамі ў адзіным блоку.
Піксельныя дадзеныя могуць мець адвольнае размяшчэнне ў памяці і іх адрас паказваецца ў параметрах працэдур.
У любым выпадку рэкамендуецца ў памяці ўсе блокі змяшчаць па адрасах кратных чатыром: у загалоўках ёсць 32-бітныя ячэйкі, а да піксельных дадзеных такое патрабаванне паказана ў дакументацыі.
Гэта патрабаванне справядліва толькі для аператыўнай памяці: пры захоўванні ў файле яго прытрымлівацца не абавязкова.

### BITMAPFILEHEADER

BITMAPFILEHEADER — 14-байтная структура, якая размяшчаецца ў самым пачатку файла.
Звярніце ўвагу на тое, што з самага пачатку структуры збіваецца выраўноўванне вочак.
Калі для вас яно важна, то ў аператыўнай памяці дадзены загаловак размяшчайце па цотных адрасах, якія не кратныя чатыром (тады 32-бітныя ячэйкі трапяць на выравненные пазіцыі).

| Пастаў.
(hex) | Памер
(байты) | Імя | Тып WinAPI | Апісанне |
| --- | --- | --- | --- | --- |
| 00 | 2 | bfType | WORD | Адзнака для адрознення фармату ад іншых (сігнатура фармату). Можа змяшчаць адзінае значэнне 4D4216/424D16 (little-endian/big-endian). |
| 02 | 4 | bfSize | DWORD | Памер файла ў байтах. |
| 06 | 2 | bfReserved1 | WORD | Зарэзерваваны і павінны змяшчаць нуль. |
| 08 | 2 | bfReserved2 | WORD |
| 0A | 4 | bfOffBits | DWORD | Становішча піксельных дадзеных адносна пачатку дадзенай структуры (у байтах). |

Сігнатура фармату пры праглядзе змесціва файла тэкстам у дваічным рэжыме выглядае як пара ASCII-знакаў «BM».

### BITMAPINFO

BITMAPINFO ў файле ідзе адразу за BITMAPFILEHEADER.
Адрас гэтага блока ў памяці напрамую таксама перадаецца некаторых функцый WinAPI (напрыклад, SetDIBitsToDevice або CreateDIBitmap).
Акрамя гэтага, гэты жа блок выкарыстоўваецца ў фарматах значкоў і курсораў Windows, але ў дадзенай артыкуле гэты момант не разглядаецца (гл. асобныя апісання гэтых фарматаў).
Дадзеная структура з’яўляецца асноўнай і апісальнай у фармаце BMP і таму калі проста згадана імя поля, то гаворка ідзе пра поле ў дадзенай структуры.

Блок BITMAPINFO складаецца з трох частак:

1. Структура з інфармацыйнымі палямі.
2. Бітавыя маскі для здабывання каляровых значэнняў каналаў (прысутнічаюць не заўсёды).
3. Табліца колераў (прысутнічае не заўсёды).

Пра бітавыя маскі і табліцу колераў глядзіце ніжэй у асобных раздзелах.
Тут далей пойдзе апісанне структуры з інфармацыйнымі палямі.

У момант напісання гэтага артыкула структура з інфармацыйнымі палямі мела чатыры версіі: CORE, 3, 4 і 5 (абазначэнні версій прыведзены ўмоўныя у рамках дадзенага артыкула для кароткасці).
Для кожнай версіі Microsoft абвясціла чатыры асобныя структуры з рознымі імёнамі палёў.
У дадзеным артыкуле пры згадванні поля, якое прысутнічае ў некалькіх структурах, бярэцца агульная для ўсіх структур частка ў канцы імя (напрыклад, BitCount замест bcBitCount, biBitCount, bV4BitCount або bV5BitCount).
Версію структуры можна вызначыць па першай 32-бітнай вочку (WinAPI-тып DWORD), якая змяшчае яе памер у байтах (беззнаковым цэлым).
Версія CORE адрозніваецца ад усіх сваёй кампактнасцю і выкарыстаннем выключна 16-бітных беззнаковых палёў.
Астатнія тры змяшчаюць ідэнтычныя ячэйкі, да якіх у кожнай новай версіі дадаваліся новыя.

Ніжэй прадстаўлена аглядная табліца па інфармацыйных структурах:

| Версія | Памер
(байты) | Імя структуры | Версія Windows 9x/NT | Версія Windows CE/Mobile | Заўвагі |
| --- | --- | --- | --- | --- | --- |
| CORE | 12 | BITMAPCOREHEADER | 95/NT 3.1 і старэй | CE 2.0/Mobile 5.0 і старэй | Змяшчае толькі шырыню, вышыню і бітнасць растру. |
| 3 | 40 | BITMAPINFOHEADER | 95/NT 3.1 і старэй | CE 1.0/Mobile 5.0 і старэй | Змяшчае шырыню, вышыню і битность растру, а таксама фармат пікселяў, інфармацыю аб каляровай табліцы і дазволе. |
| 4 | 108 | BITMAPV4HEADER | 95/NT 4.0 і старэй | не падтрымліваецца | Асобна вылучаныя маскі каналаў, дададзеная інфармацыя аб каляровым прасторы і гаме. |
| 5 | 124 | BITMAPV5HEADER | 98/2000 і старэй | не падтрымліваецца | Дададзена ўказанне пераважнай стратэгіі адлюстравання і падтрымка профіляў ICC. |

З-за ідэнтычнасці палёў у версіях 3, 4 і 5 можа здацца, што полем Памер можна рэгуляваць колькасць палёў, прыбіраючы непатрэбныя.
У рэчаіснасці гэта не карэктна, так як тут памер гуляе ролю версіі (у версіі CORE хоць і таксама ідэнтычныя паля, але іншага памеру і тыпу).
Ніхто не гарантуе, што вам не могуць трапіцца загалоўкі меншых або вялікіх памераў з іншым наборам палёў.
Тым не менш, Adobe Photoshop можа пры захаванні файлаў BMP запісваць структуры інфармацыйных палёў з памерамі 52 і 56 байт.
Па сутнасці гэта зрэзаная 4-я версія, якая змяшчае толькі біты маскі каналаў (56 байт — версія з альфа-каналам).

#### 16-бітныя інфармацыйныя паля (версія CORE)

Звярніце ўвагу на тое, што тут паля шырыні і вышыні змяшчаюць бяззнакавыя цэлыя, у той час як 32-бітныя структуры захоўваюць значэнні са знакам.

| Пазіцыя
у файле
(hex) | Пазіцыя
у структуры
(hex) | Памер
(байты) | Імя | Тып WinAPI | Апісанне |
| --- | --- | --- | --- | --- | --- |
| 0E | 00 | 4 | bcSize | DWORD | Памер дадзенай структуры ў байтах, які паказвае таксама на версію структуры (тут павінна быць значэнне 12). |
| 12 | 04 | 2 | bcWidth | WORD | Шырыня (bcWidth) і вышыня (bcHeight) растру ў пікселях. Паказваюцца цэлым лікам без знака. Значэнне 0 не дакументавана. |
| 14 | 06 | 2 | bcHeight | WORD |
| 16 | 08 | 2 | bcPlanes | WORD | У BMP дапушчальна толькі значэнне 1. Гэта поле выкарыстоўваецца ў значках і курсорах Windows. |
| 18 | 0A | 2 | bcBitCount | WORD | Колькасць біт на піксель (спіс падтрымоўваных глядзіце ў асобным раздзеле ніжэй). |

#### 32-бітныя інфармацыйныя паля (версіі 3, 4 і 5)

У табліцы ніжэй поля прадстаўленыя аглядна.
Падрабязную інфармацыю вы можаце знайсці ў раздзелах далей.

| Пазіция
ў файле
(hex) | Пазіцыя
ў структуры
(hex) | Памер
(байты) | Імя
(версіі 3/4/5) | Тып WinAPI | Описание |
| --- | --- | --- | --- | --- | --- |
| 0E | 00 | 4 | biSize
bV4Size
bV5Size | DWORD | Пазмер дадзенай структуры ў байтах, які паказвае таксама на версію структуры (гл. табліцу версій вышэй). |
| 12 | 04 | 4 | biWidth
bV4Width
bV5Width | LONG | Шырыня растра ў пікселях. Паказваецца цэлым лікам са знакам. Ноль і адмоўныя не дакументаваныя. |
| 16 | 08 | 4 | biHeight
bV4Height
bV5Height | LONG | Целы лік са знакам, які змяшчае два параметра: вышыня растра ў пікселях (абсалютнае значэнне ліку) і парадак следавання радкоў у двумерных масівах (знак ліка). Нулявоя значэнне не дакументаванае. |
| 1A | 0C | 2 | biPlanes
bV4Planes
bV5Planes | WORD | У BMP дапушчальна толькі значэнне 1. Гэтае поле выкарыстоўваецца ў значках і курсорах Windows. |
| 1C | 0E | 2 | biBitCount
bV4BitCount
bV5BitCount | WORD | Колькасць біт на піксель (спіс падтрымліваемых глядзіце ў асобным раздзеле ніжэй). |
| 1E | 10 | 4 | biCompression
bV4V4Compression
bV5Compression | DWORD | Паказвае на спосаб захоўвання пікселей (гл. у раздзеле ніжэй). |
| 22 | 14 | 4 | biSizeImage
bV4SizeImage
bV5SizeImage | DWORD | Памер піксельных дадзеных у байтах. Можа быць абнулено калі захоўванне ажыццяўляецца двумерным масівам. |
| 26 | 18 | 4 | biXPelsPerMeter
bV4XPelsPerMeter
bV5XPelsPerMeter | LONG | Колькасць пікселей на метр па гарызанталі і вертыкалі (гл. раздзел «Разрозненне выявы» дадзенага артыкула). |
| 2A | 1C | 4 | biYPelsPerMeter
bV4YPelsPerMeter
bV5YPelsPerMeter | LONG |
| 2E | 20 | 4 | biClrUsed
bV4ClrUsed
bV5ClrUsed | DWORD | Памер табліцы колераў у ячэйках. |
| 32 | 24 | 4 | biClrImportant
bV4ClrImportant
bV5ClrImportant | DWORD | Колькасць ячэек ат пачатку табліцы колераў до апошней, якая выкарыстоўваецца (уключаючы яе саму). |
| Даданыя ў версіі 4 |
| Пазіцыя
ў файле
(hex) | Пазіцыя
ў структуры
(hex) | Памер
(байты) | Імя
(версии 4/5) | Тып WinAPI | Апісанне |
| 36 | 28 | 4 | bV4RedMask
bV5RedMask | DWORD | Бітавыя маскі для выняцця значенняў каналаў: інтэнсіўнасць чырвонага, зялёнага, сіняга і значэнне альфа-канала. |
| 3A | 2C | 4 | bV4GreenMask
bV5GreenMask | DWORD |
| 3E | 30 | 4 | bV4BlueMask
bV5BlueMask | DWORD |
| 42 | 34 | 4 | bV4AlphaMask
bV5AlphaMask | DWORD |
| 46 | 38 | 4 | bV4CSType
bV5CSType | DWORD | Выгляд каляровай прасторы. |
| 4A | 3C | 36 | bV4Endpoints
bV5Endpoints | CIEXYZTRIPLE | Значэнне гэтых чатырох палей бярэтся ва ўвагу толькі калі поле CSType змяшчае 0 (LCS\_CALIBRATED\_RGB). Тады канчатковыя кропкі і значэнні гамы для трох каляровых кампанент паказваюцца ў гэтых палях. |
| 6E | 60 | 4 | bV4GammaRed
bV5GammaRed | DWORD |
| 72 | 64 | 4 | bV4GammaGreen
bV5GammaGreen | DWORD |
| 76 | 68 | 4 | bV4GammaBlue
bV5GammaBlue | DWORD |
| Даданыя ў версіі 5 |
| Пазіцыя
ў файле
(hex) | Пазіцыя
ў структуры
(hex) | Памер
(байты) | Імя | Тып WinAPI | Апісанне |
| 7A | 6C | 4 | bV5Intent | DWORD | Перавагі пры рэндэрынге растра. |
| 7E | 70 | 4 | bV5ProfileData | DWORD | Срушэнне ў байтах каляровага профілю ад пачатку BITMAPINFO (гл. таксама раздзел «Каляровы профиль» ніжэй у гэтым артыкуле). |
| 82 | 74 | 4 | bV5ProfileSize | DWORD | Калі ў BMP непасрэдна ўключаецца каляровы профіль, то тут паказваецца ягоны памер ў байтах. |
| 86 | 78 | 4 | bV5Reserved | DWORD | Зарэзервавана і павінна быць абнулено. |

### Бітнасць выявы (поле BitCount)

Поле BitCount змяшчае колькасць біт, якое прыходзіцца на кожны піксель.
Калі там указана выдатнае ад нуля значэнне, то гэта і ёсць рэальная бітнасць.
Нулявое ж змесціва поля BitCount паказваецца калі пікселі захоўваюцца ў фармаце JPEG ці PNG.
Тады сапраўдная бітнасць будзе вызначацца ўжо гэтымі фарматамі.
Бітнасці чыста BMP фармату прадстаўлены ў табліцы ніжэй:

| Біт | Байт | BITMAPINFO | RLE | Маскі каналаў | Патрымка праграмным забеспячэннем |
| --- | --- | --- | --- | --- | --- |
| CORE | 3, 4, 5 | Windows 9x и NT | Windows CE и Mobile | GDI+ и .NET |
| 1 | ⅛ | Так | Так | Не | Не | Так | Так | Так |
| 2 | ¼ | Так | Так | Не | Не | Не | Так | Не |
| 4 | ½ | Так | Так | Так | Не | Так | Так | Так |
| 8 | 1 | Так | Так | Так | Не | Так | Так | Так |
| 16 | 2 | Не | Так | Не | Так | Так | Так | Так |
| 24 | 3 | Так | Так | Не | Не | Так | Так | Так |
| 32 | 4 | Не | Так | Не | Так | Так | Так | Так |
| 48 | 6 | Не | Так | Не | Не | Не | Не | Так |
| 64 | 8 | Не | Так | Не | Не | Не | Не | Так |

Заўвагі да табліцы:
  

1. У калонцы «BITMAPINFO» пазначана падтрымка бітнасцей толькі з боку Microsoft.
  

2. Windows CE 1.0 і 1.01 падтрымлівае толькі бітнасці 1 і 2.
  

3. GDI+ версіі 1.0 16-бітныя каляровыя каналы ўмее толькі счытваць, адразу перакладаючы іх у 8-бітныя.

У бітнасцях 8 і ніжэй колер пікселя паказваецца індэксам ў табліцы колераў, у вышэйшых: непасрэдным значэннем у каляровай мадэлі RGB.
Альфа-канал апцыянальна можа быць дададзены ў битностях 16 і 32.
У бітнасці 64 ён прысутнічае перманентна.

У табліцы прадстаўлены толькі бітнасці, якія дакументавала карпарацыя Microsoft.
Сам фармат не змяшчае ніякіх прынцыповых абмежаванняў на выкарыстанне якіх-небудзь не згаданых тут бітнасцяў.

1-бітныя BMP-файлы з чыста чорным (скінуты біт) і белым (усталяваны біт) колерамі называюць манахромнымі.
Такія файлы звычайна выкарыстоўваюцца ў якасці масак для іншых растраў.
Магчыма вам пастаянна трапляліся на вочы менавіта такія 1-бітныя растры.
У рэчаіснасці фармат Windows Bitmap не накладвае ніякіх абмежаванняў на тое, якія колеры будуць выкарыстоўвацца для кожнага з значэнняў біт.

Вы можаце таксама сустрэць наступныя назвы бітнісцяў: CGA для дзвюх біт, EGA для чатырох, HiColor (HighColor) для 16 біт, TrueColor для 24-х і 32-ух біт з паўпразрыстасцю, DeepColor для вялікіх бітнасцяў і, магчыма, іншыя.
Гэтыя назвы з’явіліся ў перыяд развіцця каляровых растравых дысплеяў і ставяцца больш да іх глыбіні колеру.
Да моманту напісання гэтага артыкула (2014-ы год) такія назвы ўжо даўно не выкарыстоўваюцца з-за моцнага распаўсюджвання 24-бітных прылад (замест гэтага проста паказваецца глыбіня колеру ў бітах або іх колькасць).
А BMP-файлы ў меншай бітнасці захоўваюцца ў большай ступені не для адлюстравання на CGA або EGA-прыладах, а для кампактнасці па параўнанні з 24-бітнымі і 32-бітнымі фарматамі калі выкарыстоўваецца малую колькасць колераў.

### Поле Compression

Для кожнай групы бітнасцяў выкарыстоўваюцца асобныя абмежаваныя значэнні Compression, але ў сукупнасці іх значэнні ўнікальныя.
Microsoft дакументавала наступныя значэнні (у табліцы пазначаны імёны канстант ад гэтай карпарацыі):

| Значэнне | Імя канстанты | Дастасавальна
да BitCount | Захоўванне пікселяў | Знак Height | Версія Windows |
| --- | --- | --- | --- | --- | --- |
| 9x/NT | CE |
| 0 | BI\_RGB | любым акрамя нуля | двухмерных масіў | +/− | 95/NT 3.1 | CE 1.0 |
| 1 | BI\_RLE8 | 8 | ПЛОШЧЫ-кадаваньне | + | 95/NT 3.1 | (не подд.) |
| 2 | BI\_RLE4 | 4 | ПЛОШЧЫ-кадаваньне | + | 95/NT 3.1 | (не подд.) |
| 3 | BI\_BITFIELDS | 16 і 32 | двухмерных масіў з маскамі каляровых каналаў | +/− | 95/NT 3.1 | CE 2.0 |
| 4 | BI\_JPEG | 0 | ва ўбудаваным JPEG-файле |  ?/− | 98/2000 | (не подд.) |
| 5 | BI\_PNG | 0 | ва ўбудаваным PNG-файле |  ?/− | 98/2000 | (не подд.) |
| 6 | BI\_ALPHABITFIELDS | 16 і 32 | двухмерных масіў з маскамі каляровых і альфа-канала | +/− | (не подд.) | .NET 4.0 |

### Табліца колераў

Табліца колераў з’яўляецца часткай блока BITMAPINFO і можа выкарыстоўвацца ў двух выпадках:

1. Яна абавязкова прысутнічае пры бітнасцях 8 і ніжэй, у якіх колер пікселяў задаецца індэксам ячэйкі з яе.
2. Пры бітнасцях 8 і вышэй, у якіх колер паказваецца непасрэдным значэннем, табліца прысутнічае калі выкарыстоўваецца загаловак не CORE-версіі, у якога поле ClrUsed змяшчае не нулявое значэнне. Тут яна задзейнічаецца ўжо для аптымізацыі колераў пры працы з прыладамі, якія выкарыстоўваюць палітры (як менавіта вырабляецца аптымізацыя ў дакументацыі не сказана).

Пазіцыя табліцы колераў паказваецца ад яго пачатку блока BITMAPINFO.
Па змаўчанні яна ідзе адразу за інфармацыйнай структурай (яе беззнаковый памер у байтах можна прачытаць з першага 32-бітнага поля).
Але паміж структурай з палямі і каляровай табліцай могуць ісці четырехбайтные бітаў маскі для здабывання каляровых каналаў (тычыцца толькі битностей 16 і 32).
Яны там знаходзяцца толькі калі выкарыстоўваецца інфармацыйная структура 3-яй версіі (Size = 40) і поле Compression змяшчае 3 (BI\_BITFIELDS) або 6 (BI\_ALPHABITFIELDS).
Тады да памеру інфармацыйных палёў трэба дадаць 12 (пры значэнні BI\_BITFIELDS) або 16 байт (калі паказана BI\_ALPHABITFIELDS).
Атрымліваецца 6 варыянтаў размяшчэння табліцы:

| Версія
загалоўка | Пазіцыя (hex) | Заўвагі |
| --- | --- | --- |
| У файле | У BITMAPINFO |
| CORE | 1A | 0C | маскі каналаў не падтрымліваюцца |
| 3 | 36 | 28 | Compression не змяшчае 3 або 6 |
| 42 | 34 | Compression = 3 (BI\_BITFIELDS) |
| 46 | 38 | Compression = 6 (BI\_ALPHABITFIELDS) |
| 4 | 7A | 6C | маскі каналаў ўбудаваныя
у інфармацыйныя поля |
| 5 | 8A | 7B |

Колькасць вочак у табліцы вызначаецца па палях BitCount і ClrUsed.
Пры бітнасцях 8 і ніжэй максімальная колькасць вочак у табліцы прымаецца за 2*бмтнасць*: 2 у аднабітным растры, 4 у двухбітным, 16 у 4-охбітным і 256 у 8-бітным.
У дадзеных бітнасцях табліца заўсёды змяшчае гэта максімальную колькасць вочак калі выкарыстоўваецца загаловак версіі CORE (Size = 12) або калі ў іншых версіях поле ClrUsed змяшчае 0.
Ва ўсіх астатніх выпадках, незалежна ад бітнасці, у табліцы знаходзіцца столькі вочак, колькі паказана ў поле ClrUsed.

Сама ж табліца ўяўляе сабой аднамерны масіў, які можа змяшчаць ячэйкі трох тыпаў:

1. 32-бітная структура **RGBQUAD**. Прымяняецца, калі ў BITMAPINFO выкарыстана інфармацыйная структура версіі 3, 4 ці 5. У самой жа структуры RGBQUAD паказваецца колер у мадэлі RGB ў чатырох байтавых вочках (усе маюць WinAPI-тып BYTE): rgbBlue (сіні), rgbGreen (зялёны), rgbRed (чырвоны) і rgbReserved (зарэзерваваная і павінна быць абнулена).
2. 24-бітная структура **RGBTRIPLE**. Ўжываецца калі BITMAPINFO пачынаецца са структуры BITMAPCOREHEADER. RGBTRIPLE складаецца з трох байтавых вочак (WinAPI-тып BYTE), у якіх паказваецца колер у мадэлі RGB: rgbtBlue (сіні), rgbtGreen (зялёны) і rgbtRed (чырвоны).
3. 16-бітныя індэксы колераў (бяззнакавыя цэлыя лікі) у бягучай лагічнай палітры кантэксту прылады (сістэмныя аб’екты Windows GDI). Гэты выгляд даступны толькі падчас выканання праграмы. Фармат BMP не падтрымлівае відавочнае ўказанне, што выкарыстоўваецца такая табліца і таму сама праграма паведамляе WinAPI-функцыі пра гэта ў спецыяльных параметрах (як правіла канстантай DIB\_PAL\_COLORS).

Ва ўсёй табліцы могуць быць задзейнічаны не ўсе ячэйкі і ў полі ClrImportant змяшчаецца колькасць вочак ад пачатку табліцы да апошняй якая выкарыстоўваецца (уключаючы яе саму).
Змесціва 0 поля ClrImportant паказвае на тое, што выкарыстоўваецца ўся табліца.
Задзейнічаныя ячэйкі лепш размяшчаць у самым пачатку табліцы і рэкамендуецца пры гэтым адсартаваць іх па змяншэнні ступені важнасці (на выпадак, калі прыйдзецца паменшыць іх колькасць).

### Маскі для здабывання каляровых значэнняў каналаў

Калі бітнісць выявы 16 або 32, то могуць быць пазначаны 32-бітныя маскі для здабывання каляровых каналаў.
Гэта звязана з тым, што 16 не кратна тром і таму біты могуць быць размеркаваны рознымі спосабамі.
У 32-бітных малюнках з-за зручнасці выкарыстоўваюць 8-бітныя каналы і таму падтрымка для іх можа здацца залішняй.
У рэчаіснасці тут маска дае магчымасць ўключыць/адключыць альфа-канал або ўсталяваць зручны вам парадак прытрымлівання кампанент, а не толькі рэгуляваць іх дазвол.
Пры ўжыванні масак вочка пікселя счытваецца цалкам як адпаведнае машыннае слова ў litte-endian.

Наяўнасць бітавых масак залежыць ад версіі інфармацыйных палёў структуры BITMAPINFO і палі Compression ў ёй.
Для версіі CORE адвольныя маскі пазначыць нельга, так як там адсутнічае поле Compression і асобныя поля масак.
У астатніх версіях каляровыя маскі задзейнічаюцца калі Compression змяшчае 3 (BI\_BITFIELDS).
Маска альфа-канал выкарыстоўваецца заўсёды ў версіях 4 і 5.
Так як Windows CE не падтрымлівае гэтыя дзве версіі, у якіх для яе ёсць спецыяльнае поле, для трэцяй версіі было ўведзена значэнне 6 (BI\_ALPHABITFIELDS) поля Compression, якое дадае адразу каляровыя маскі і маску альфа-канала (падтрымліваецца пачынаючы з Windows CE .NET 4.0).

Становішча бітавых масак фіксавана незалежна ад версіі загалоўка: 36h ва ўсім файле або 28h ад пачатку блока BITMAPINFO.
У версіях 4 і 5 на гэтым месцы размяшчаюцца прызначаныя спецыяльна для іх поля.
У версіі 3 бітаў маскі павінны размяшчацца адразу за інфармацыйнымі палямі і такім чынам яны дакладна трапляюць на пазіцыі адпаведных палёў у старэйшых версіях.
Звярніце ўвагу на тое, што ў трэцяй версіі пры наяўнасці масак зрушваецца табліца колераў на 12 або 16 байт наперад, размяшчаючыся адразу за імі.
4-байтные маскі колераў ідуць у парадку чырвоная, зялёная, сіняя.
Маска альфа-канала размяшчаецца ўжо за імі.

У дакументацыі Microsoft да бітавых масак ўжываецца толькі адно абавязковае патрабаванне: кожная маска павінна быць бесперапыннай.
Пра выпадак перасячэння масак там сказана, што пажадана гэтага не рабіць.
Microsoft таксама кажа аб тым, што не абавязкова задзейнічаць усе біты пікселя.
Якія-небудзь патрабаванні да змесціва невыкарыстоўваемых біт адсутнічаюць.

Звярніце ўвагу на тое, што ніхто не гарантуе, што могуць быць выкарыстаны маскі шырэй 8 біт.
І нічога не сказана пра выпадак, калі ў якога-небудзь канала будзе нулявая маска (напрыклад, калі ён сапраўды не выкарыстоўваецца).
Тут магчымая сітуацыя калі нулявыя маскі будуць ва ўсіх кампанентаў і застанецца адзін альфа-канал (які пры гэтым можа заняць усе біты).
Нулявую маску каляровага канала можна трактаваць двума спосабамі: яго значэнне прымаецца за нуль або жа пры прамалёўцы пікселі гэтага канала не закранаюцца.
Калі ўзяць першы варыянт інтэрпрэтацыі з адзіным альфа-каналам, то альфа-канал, па сутнасці, будзе задаваць ступень зачернения пікселя.
Акрамя нявызначаных варыянтаў ёсць таксама і цікавы.
Так як перасячэння не забароненыя, то можна ўсе каналы выставіць на адну пазіцыю і тым самым атрымаць Grayscale.

Некаторы ПЗ мае абмежаваны набор падтрымоўваных бітавых масак.
У табліцы ніжэй прыведзены даступныя варыянты ў такіх абмежаваных асяроддзях:

| Бітнасць | \* | Значэнні масак (hex) | Падтрымка ў ПА |
| --- | --- | --- | --- |
| Чырвоны | Зялёны | Сіні | Альфа | Невыкарыстоўваныя | Windows 9x | GDI+ і .NET |
| 16 | (a) | 7C00 | 03E0 | 001F | 0000 | 8000 | Так | Так |
| 7C00 | 03E0 | 001F | 8000 | 0000 | Не | Так |
| F800 | 07E0 | 001F | 0000 | 0000 | Так | Так |
| (b) | FFFF | FFFF | FFFF | 0000 | 0000 | Не | Так |
| 32 | (a) | 00FF:0000 | 0000:FF00 | 0000:00FF | 0000:0000 | FF00:0000 | Так | Так |
| 00FF:0000 | 0000:FF00 | 0000:00FF | FF00:0000 | 0000:0000 | Не | Так |

Заўвагі да табліцы:
  

(a) Гэтыя наборы выкарыстоўваюцца па змаўчанні ў бітнасцях 16 і 32, калі маскі для здабывання колераў не зададзеныя.
  

(b) Гэты набор масак па сваёй сутнасці рэалізуе 16-бітны Grayscale.

### Піксельныя дадзеныя

У файле пра становішча піксельных дадзеных можна даведацца з поля OffBits структуры BITMAPFILEHEADER.
Падчас выканання прыкладанне захоўвае адрас піксельных дадзеных там, дзе зручней.
У дакументацыі Microsoft таксама згадваюцца так званыя пакетныя (англ. *packed*) битмапы, якія паказваюцца адным адрасам блока BITMAPINFO.
У такіх бітмапаў піксельныя дадзеныя ідуць адразу за загалоўкам (уключаючы акрамя інфармацыйных палёў бітаў маскі і табліцу колераў).

Памер піксельных дадзеных у байтах запісваецца ў полі SizeImage структуры BITMAPINFO.
Туды запісваюцца менавіта «сырой» памер таго бесперапыннага блока, які змяшчае дадзеныя для фарміравання пікселяў (незалежна ад фармату), а не які-небудзь распакаваць.
Па змаўчанні гэта поле абавязкова павінна змяшчаць актуальнае значэнне, так як па ім можна дакладна даведацца, колькі менавіта байт трэба лічыць з файла для атрымання пікселяў.
Тым не менш, дапушчальна змяшчаць у гэтым полі нуль пры захоўванні пікселяў двухмернымі масівамі (калі поле Compression змяшчае значэнне 0 (BI\_RGB), 3 (BI\_BITFIELDS) або 6 (BI\_ALPHABITFIELDS)).
Тады памер пікселяў пры неабходнасці можна адносна хутка разлічыць зыходзячы з бітнасці, шырыні і вышыні растру.

У фармаце Windows Bitmap даступна тры спосабу захоўвання пікселяў (гл. таксама раздзел «Поле Compression» дадзенага артыкула):

1. Двухмерны масіў.
2. RLE-кадаваньне (толькі для битностей 4 і 8).
3. У фарматах JPEG ці PNG.

У падпадзелах далей асобна апісаны кожны з іх.

#### Указанне колеру і значэння альфа-канала

Для ўказанні колеру пры захоўванні ў фармаце BMP незалежна ад спосабу заданні выкарыстоўваюцца толькі бяззнакавыя цэлыя лікі.
Сам жа колер пікселя можа задавацца двума спосабамі:

1. Індэксам ў табліцы колераў (пры бітнастях 8 і ніжэй).
2. Непасрэдным значэннем у каляровай мадэлі RGB (пры бітнасцях вышэй 8).

Другі мэтазгодна выкарыстоўваць, калі набор колераў даволі вялікі або непрадказальны (напрыклад, падчас апрацоўкі малюнка).
Першы ж спосаб забяспечвае як кампактную кампаноўку пры малым наборы колераў, так і некаторы зручнасць ў кіраванні выкарыстоўваюцца колерамі (дастаткова змяніць значэнне колеру ў палітры).
У самой табліцы колераў паказваюцца або 16-бітныя бяззнакавыя індэксы ў сістэмнай палітры (гл. раздзел «Табліца колераў» у дадзеным артыкуле), або жа ў RGB як у пікселі, але выключна 8-бітнымі значэннямі каналаў.

Індэкс ў табліцы колераў — гэта нумар ячэйкі ў ёй ад пачатку табліцы (выкарыстоўваецца бесперапынная нумарацыя, пачынаючы з нуля).
Для кожнай бітнасці максімальны індэкс прынцыпова абмежаваны значэннем 2*бітнасць* − 1.
У рэчаіснасці ж ён абмежаваны яшчэ і колькасцю элементаў у табліцы (падрабязнасці ў раздзеле «Табліца колераў» дадзенага артыкула).
Microsoft не дакументавала паводзіны ў выпадку калі ўказваецца індэкс за межамі табліцы, але GDI у гэтым выпадку бярэ чорны колер.

У битностях вышэй за 8 колер пікселя паказваецца непасрэдна ў каляровай мадэлі RGB: асобна паказваецца ўзровень чырвонага колеру, зялёнага і сіняга.
Нулявое значэнне любога з каналаў азначае поўнае адсутнасць адпаведнага адцення, а максімальнае: поўнае яго прысутнасць.
Дазвол жа значэнняў каналаў пераменнае і ў кожнай бітнасці яно сваё (канкрэтныя значэнні глядзіце ў раздзеле пра захоўванне пікселяў ў двухмернай масіве гэтага артыкула).
Пры гэтым у бітнасцях 16 і 32 можа быць зададзена не толькі адвольнае дазвол, але і індывідуальнае для кожнага канала (напрыклад, 5 біт для чырвонай і сіняй, але 6 біт для зялёнай).
Нягледзячы на вялікую колькасць варыянтаў заданні дазволу значэнняў, у дакументацыі Microsoft не сказана як вырабляць змена дазволу значэння.
З-за гэтага ў розных вытворцаў праграмнага забеспячэння могуць атрымлівацца розныя вынікі пры змене бітнасці.

Пры непасрэдным заданні колеру пікселя акрамя значэнняў RGB фармат Windows Bitmap апцыянальна дазваляе яшчэ задаць значэнні **альфа-канала**.
У плане бітнасці і кадаванні значэнняў ён ідэнтычны каляровым каналам: у яго адвольная бітнасць і выкарыстоўваюцца бяззнакавыя цэлыя.
Што ж тычыцца супастаўлення значэнняў, то нуль адпавядае поўнай празрыстасці, а максімальны даступны лік — поўнай запоўненасці.

#### Двухмерны масіў

У двухмерным масіве можна захоўваць пікселі любой бітнасці.
Пры такім спосабе захоўвання поле Compression змяшчае значэнне 0 (BI\_RGB), 3 (BI\_BITFIELDS) або 6 (BI\_ALPHABITFIELDS).
Калі выкарыстоўваецца загаловак версіі CORE, то пікселі ў любым выпадку захоўваюцца толькі двухмерным масівам.

У дадзенай кампаноўцы пікселі растру запісваюцца аднапіксельными гарызантальнымі палоскамі, якія Microsoft у сваёй дакументацыі часта называе «*scans*» (у беларускай мове найбольш блізкае слова: *радкі*).
У памяці гэтыя шэрагі запісваюцца па-парадку, але пры станоўчым Height: пачынаючы з самага ніжняга (англ.: bottom-up bitmapbottom-up bitmap), а пры адмоўным: з самага верхняга (англ.: top-down bitmaptop-down bitmap).
Унутры кожнага гарызантальнага радка пікселі запісваюцца строга толькі ад левага да правага.
Пікселі менш 8 біт размяшчаюцца ў байтах, запаўняючы біты ад старэйшых да малодшых, у выніку чаго шаснаццатковы/двайковыя лікавыя значэнні пікселяў больш падобныя на выводны малюнак.
Калі битность 16 або 32, то апрацоўка ажыццяўляецца суцэльнымі машынамі словамі аналагічнага памеру з парадкам біт ад малодшага да старэйшага (little-endian).
**Шэрагі, незалежна ад памеру вочак, абавязкова павінны дапаўняцца нулямі да кратнага чатыром байтам памеру**.
З-за гэтага, пры некратной шырыні малюнка, у канцы шэрагаў могуць аказвацца невыкарыстоўваныя біты або цэлыя байты.
Але дзякуючы гарантаванай кратнасці памеру шэрагу, апрацоўку можна вырабляць 8-мі, 16-ці або 32-бітнымі машынамі словамі, па выбары.
І ў Microsoft яшчэ прасочваецца наступная тэндэнцыя ў бітнасцях больш за 8: кампанент сіні (сіні колер) размяшчаецца ў малодшых бітах/першае байтах, Green (зялёны) у наступных, а Red (чырвоны) старэй/далей за ўсіх, і калі ёсць альфа-канал, то ён знаходзіцца ў самых старэйшых бітах/апошніх байтах.

Дыяграма ніжэй адлюстроўвае размяшчэнне пікселяў ў **бітнасцях менш за 8**:

|  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Біты | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 біт | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 2 біта | 0 | 1 | 2 | 3 |
| 4 біта | 0 | 1 |

У **бітнасцях 16** і **32** пікселі апрацоўваюцца машыннымі словамі аналагічнага памеру (мяркуецца парадак байт little-endian), якіх прымяняюцца бітаў маскі каналаў.
Калі індывідуальныя бітавыя маскі не зададзеныя, то структура будзе наступная.
Пры 16 біт на кожны канал адводзіцца па 5 біт.
Сіні размяшчаецца ў малодшых бітах (маска 001F16), зялёны на пазіцыі 5 (маска 03E016), чырвоны: пачынаючы з 10-га біта (маска 7C0016), а старэйшы застаўся біт 15 не выкарыстоўваецца.
Калі выкарыстоўваецца бітнасць 32, то па змаўчанні на кожны канал адводзіцца ўжо па байце (8 біт).
Кампаненты размяшчаюцца аналагічна: сіні ў малодшых бітах (маска 0000:00FF16), зялёны пачынаючы з біта 8 (маска 0000:FF0016), чырвоны пачынаецца з біта 16 (маска 00FF:000016), а старэйшы байт не выкарыстоўваецца (ён выкарыстоўваецца ў якасці альфа-канала, толькі калі гэта прама паказаць).
Так як мяркуецца чытанне ў парадку байта little-endian, то калі чытаць значэнні з памяці па-байтова, яны будуць размяшчаць у такім жа парадку (сіні будзе ісці першым).

Пры **бітнасці 24** на кожны канал прыходзіцца па байце, а ў **битностях 48** і **64**: па 16-бітнаму машыннай слове.
Ва ўсіх трох выпадках у памяці каляровыя кампаненты ідуць у парадку: сіні, зялёны, чырвоны.
У 64-бітных BMP за колерамі дадаткова варта 16-бітны альфа-канал.
Калі захочаце 64-бітны піксель апрацаваць суцэльным машынным словам, то ў little-endian сіні апынецца ў малодшых 16 бітах, а альфа-канал: у старэйшых.
Зялёны, адпаведна, будзе побач да чырвоным, а сіні — побач з альфа.
І можна заўважыць, што ў 24-ох бітах фармат пікселя адпавядае структуры RGBTRIPLE з табліцы колераў.

#### RLE-кадаваньне

Прымяненне RLE-кадавання кампаніяй Microsoft дакументавана толькі для бітнасцяў 4 і 8.
Пры яе выкарыстанні ў BITMAPINFO поле Compression павінна змяшчаць 2 (BI\_RLE4) пры бітнасці 4 або 1 (BI\_RLE8) з васьмібітнымі пікселямі.
Вышыня растру пры гэтым павінна быць пазначана станоўчым лікам.

У фармаце Windows Bitmap RLE-кадаваньне можна параўнаць з прамалёўкай простымі камандамі.
Прамалёўка пачынаецца з *левага ніжняга* пікселя (будзьце больш уважліва: у растрах ў цэлым больш звыкла можа быць верхні правы) і ажыццяўляецца направа і ўверх.
Пікселі за межамі памеру растру не прамалёўваюцца (аб гэтым у дакументацыі не сказана, але GDI праяўляе такое паводзіны).
Інструкцыі RLE дазваляюць перарываць прамалёўку гарызанталі, усёй выявы, а таксама перамяшчаць курсор прамалёўкі на іншую пазіцыю.
У выніку некаторыя пікселі могуць апынуцца не замаляванымі.
Фармат не прадугледжвае колеру для незарисованных пікселяў, у дакументацыі нічога пра іх не сказана, а сістэмныя функцыі проста не чапаюць незафарбаваныя пікселі.
Так як няма важкай прычыны ў пачатку зафарбоўваць прастакутнік пад растрам нявызначаным колерам, то можна казаць аб тым, што RLE ўскосна падтрымлівае празрыстасць.

Фарміраванне выявы пры RLE-кадаванні ажыццяўляецца камандамі.
Кожная каманда абавязкова павінна пачынацца з цотнага адрасу (выраўненыя на 16-бітную мяжу).
Існуе пяць каманд, якія вызначаюцца парай байт:

| Байт 1
(hex) | Байт 2
(hex) | Апісанне |
| --- | --- | --- |
| 01..FF | 00..FF | Пачынаючы з бягучай пазіцыі і далей направа прамаляваць столькі пікселяў, колькі паказана ў першым байце. Значэнні для пікселяў бяруцца з другога байта. У 8-бітных BMP ўвесь байт цалкам з’яўляецца значэннем. У 4-бітных з яго па-чарзе бярэцца спачатку старэйшы, а потым малодшы ніббл (чацвёрка біт). |
| 00 | 00 | Перамясціць курсор у пачатак (самае лева) наступнай (верхняй) гарызанталі. |
| 00 | 01 | Спыніць прамалёўку (дасягнуты канец). |
| 00 | 02 | Перамясціць курсор направа і ўверх на названыя ў наступных двух байтах значэнні. У першым наступным байце змяшчаецца значэнне для гарызантальнага зруху, а ў наступным — для вертыкальнага. Абодва значэнні: цэлыя бяззнакавыя ліку (налева і ўніз зрушыць нельга). |
| 00 | 03..FF | З бягучай пазіцыі і далей направа замаляваць пікселі значэннямі, якія ідуць пасля гэтай пары байт. У другім байце каманды змяшчаецца колькасць пікселяў, якое трэба зафарбаваць (менавіта пікселяў, а не байт). У 8-бітным выданні бярэцца паток байт як ёсць. У 4-бітным счытваецца ўжо нибблы: старэйшыя 4 біты з байта для першага пікселя, малодшыя 4 біты — для наступнага, і так з наступных байт. Гэты паток можа скончыцца няцотных колькасцю байт, а каманды патрабуюць 16-бітнага выраўноўвання. Калі гэта адбылося, то дапісваецца дадатковы байт (яго змесціва значэння не мае). |

Калі дасягаецца правы край гарызанталі, то на наступную пераклад не вырабляецца.
Таму трэба спецыяльна ўстаўляць каманду заканчэння шэрагу.
І як відаць з табліцы, набор каманд не дазваляюць рухацца ўніз або вярнуцца назад у гарызанталі.
Таму можна спыняць прамалёўку калі будзе дасягнуты верхні край.

#### Ўбудаванне дадзеных у фарматах JPEG і PNG

Пачынаючы з версій Windows 98/ME і 2000/XP сістэмныя функцыі дазваляюць захоўваць пікселі ў фарматах JPEG і PNG.
Пра ступень падтрымкі гэтых двух фарматаў сістэмай нічога не вядома.

Для ўбудавання JPEG ці PNG трэба ў BITMAPINFO абнуліць поле BitCount, а ў Compression паказаць значэнне 4 (BI\_JPEG) або 5 (PI\_PNG).
Значэнне поля SizeImage у дадзеным выпадку будзе роўна памеры JPEG ці PNG-файл, які ўбудоўваецца на месца піксельных дадзеных як ёсць.
Шырыня ж з вышынёй у загалоўку паказваюцца ўжо для раскадаваць малюнка.
Пра знак поля Height менавіта для гэтага выпадку ў дакументацыі наўпрост нічога не сказана, але мяркуючы па ўсім трэба запісваць адмоўнае значэнне.

### Разрозненне выявы

Для супастаўлення беспамерных пікселяў з матэрыяльнымі памерамі выкарыстоўваюцца поля XPelsPerMeter і YPelsPerMeter.
У гэтых палях цэлым лікам паказваецца колькі ў дадзеным малюнку пікселяў прыпадае на адзін лінейны метр, асобна па гарызанталі (XPelsPerMeter) і вертыкалі (YPelsPerMeter).
Microsoft абвясціла гэтыя два поля лікавым тыпам са знакам, але ў дакументацыі нічога не сказана пра адмоўныя значэнні.
Пра значэнне нуль таксама нічога не сказана, але лагічней яго прымаць за няпэўны дазвол, калі яно невядома, ці не мае значэння.

Разрозненнне часта паказваецца з прывязкай не да метрычных памернастях, а ў кропках на цалю (DPI/PPI).
Для перакладу туды і назад цаля прымаецца роўным 25,4 мм (англійская цаля).
Матэматычныя формулы для перакладу пікселі/цалю (PPI) у пікселі/метр (PPM) і наадварот:

{\displaystyle }
{\displaystyle }
Калі цікавіць дакладны цэлалікавы пераклад, то выходзяць наступныя выразы:

`*PPM* = (*PPI* * 5000 + 64) / 127`
`*PPI* = (*PPM* * 127 + 2500) / 5000`
Пасля іх акругленне будзе выраблена да бліжэйшага цэлага.
Калі хочаце акругленне ўніз, то не дадавайце палову дзельніка.
Калі хочаце ўверх, то дадавайце паменшаны на адзінку дзельнік.

Ніжэй прадстаўлены загадзя вылічаныя значэнні PPM для некаторых PPI/DPI:

* 96 ppi ≈ 3780 ppm (для манітораў ў Microsoft)
* 72 ppi ≈ 2835 ppm (Apple для манітораў)
* 150 dpi ≈ 5906 ppm
* 300 dpi ≈ 11811 ppm
* 600 dpi ≈ 23622 ppm

### Каляровая прастора

У інфармацыйных палях асноўным полем задавалым каляровае прастору з’яўляецца поле CSType.
Дапушчальныя яго значэнні прыведзены ў табліцы ніжэй:

| Значэнне | Версія
BITMAPINFO | Імя канстанты | Апісанне |
| --- | --- | --- | --- |
| Hex | Тэкст |
| 0 | (няма) | 4 | LCS\_CALIBRATED\_RGB | Карэкціроўка зыходзячы з значэнняў Endpoints, GammaRed, GammaGreen і GammaBlue. |
| 73524742 | 'sRGB' | 4 | LCS\_sRGB | Выкарыстоўваецца каляровая прастора sRGB. |
| 57696E20 | 'Win ' | 4 | LCS\_WINDOWS\_COLOR\_SPACE | Сістэмнае прастору па змаўчанні (sRGB). |
| 4C494E4B | 'LINK' | 5 | PROFILE\_LINKED | Каляровай профіль у адным файле. |
| 4D424544 | 'MBED' | 5 | PROFILE\_EMBEDDED | Уключаны ў дадзены файл каляровай профіль. |

Microsoft абвясціла значэнні канстант не лікавымі значэннямі, а тэкставымі з чатырох знакаў.
У дадзеным выпадку коды знакаў фарміруюць байты 32-бітнага значэння (ASCII-код самага правага сімвала з’яўляецца малодшым байце, код самага левага — старэйшым).
Пры праглядзе дваічнага змесціва файла ў выглядзе тэксту такія значэнні ў кадоўцы ASCII будуць адлюстроўвацца задам-наперад (напрыклад, «KNIL», а не «LINK»).

#### Канчатковыя кропкі і значэнне гамы

Фармат Windows Bitmap дазваляе вырабляць колеракарэкцыя указаннем канчатковых кропак для чырвонага, зялёнага і сіняга колераў, а таксама значэнняў гамы.
Для гэтага поле CSType павінна змяшчаць значэнне 0 (LCS\_CALIBRATED\_RGB).
Карэкціруючыя ж значэнні запісваюцца ў палі Endpoints, GammaRed, GammaGreen і GammaBlue (пры іншых значэннях CSType гэтыя чатыры поля ігнаруюцца).

36-байтное поле EndPoints з’яўляецца структурай CIEXYZTRIPLE, якая складаецца з трох палёў ciexyzRed (канчатковая кропка чырвонага), ciexyzGreen (кропка зялёнага) і ciexyzBlue (сіняя).
Гэтыя тры палі, у сваю чаргу, таксама з’яўляюцца структурамі CIEXYZ з трыма палямі ciexyzX, ciexyzY і ciexyzZ тыпу FXPT2DOT30.
PXPT2DOT30 — гэта 32-бітнае беззнаковое лік з фіксаванай коскі, у якога 2 старэйшых біта адводзяцца пад цэлую частку, а 30 малодшых — пад дробную.

Значэнне гамы запісваецца ў адпаведныя палі для кожнага каляровага канала асобна: GammaRed (чырвоны), GammaGreen (зялёны) і GammaBlue (сіні).
У аб’яве інфармацыйных структур Microsoft паказала ў дадзеных палёў тып DWORD.
У гэты ж час у файле WinGDI.h ёсць больш падыходнае аб’яву тыпу FXPT16DOT16 (на аснове тыпу long), які ўяўляе сабой 32-бітнае беззнаковое лік з дробавай часткай у малодшых 16 бітах і цэлай — у 16 старэйшых.
Варта адзначыць, што ў MSDN на старонках пра структуры BITMAPV4HEADER і BITMAPV5HEADER толькі гэта і сказана.
У артыкуле ж пра структуру LOGCOLORSPACE сказана, што ў яе ў аналагічных палях павінны быць абнуленыя старэйшы і малодшы байт (па сутнасці замест фармату 16.16 выкарыстоўваецца фармат 8.8, які размяшчаецца ў сярэдзіне 32-бітнай ячэйкі).

Ніжэй прыведзены значэнні названых вышэй чатырох палёў у адпаведнасці з каляровым прасторай sRGB:

| Поле | Значэнне |
| --- | --- |
| Дробавую | Hex |
| EndPoints.ciexyzRed.ciexyzX | 0,64 | 28F5C28F |
| EndPoints.ciexyzRed.ciexyzY | 0,33 | 151EB852 |
| EndPoints.ciexyzRed.ciexyzZ | 0,03 | 01EB851F |
| EndPoints.ciexyzGreen.ciexyzX | 0,30 | 13333333 |
| EndPoints.ciexyzGreen.ciexyzY | 0,60 | 26666666 |
| EndPoints.ciexyzGreen.ciexyzZ | 0,10 | 06666666 |
| EndPoints.ciexyzBlue.ciexyzX | 0,15 | 0999999A |
| EndPoints.ciexyzBlue.ciexyzY | 0,06 | 03D70A3D |
| EndPoints.ciexyzBlue.ciexyzZ | 0,79 | 328F5C29 |
| GammaRed
GammaGreen
GammaBlue | 2,20 | 0002199A |

#### Каляровы профіль

У файле BMP пры неабходнасці можа быць паказаны каляровы профіль як непасрэдным уключэннем, так і спасылкай на іншы файл.
Профілі з’явіліся ў пятай версіі BMP, і пакуль толькі тут ёсць спецыяльныя для іх поля.
Падтрымліваюцца жа каляровыя профілі толькі ў фармаце ICC.

Пры выкарыстанні каляровых профіляў ў першую чаргу трэба пазначыць наступныя значэнні поля CSType:

* 4C494E4B16 (PROFILE\_LINKED) — калі выкарыстоўваецца профіль у адным файле.
* 4D42454416 (PROFILE\_EMBEDDED) — калі профіль непасрэдна ўбудоўваецца ў BMP.

У любым выпадку ў поле ProfileData адзначаецца зрушэнне профілю ў байтах ад пачатку блока BITMAPINFO.
Калі убудаваны профіль, то ў ProfileSize трэба паказаць яго памер у байтах (калі ён падключаецца, то гэта поле павінна быць абнуленае).
Незалежна ад варыянту, Microsoft рэкамендуе размяшчаць профіль пры захоўванні ў файле за піксельнымі дадзенымі, а ў аператыўнай памяці пры ўзаемадзеянні з WinAPI-функцыямі: адразу за загалоўкам.

Фармат ICC ў сваім загалоўку выкарыстоўвае пераважна 32-бітныя або кратныя гэтаму памеры ячэйкі.
Зыходзячы з гэтага, калі профіль непасрэдна ўключаецца ў BMP, то ў аператыўнай памяці яго рэкамендуецца захоўваць па кратнаму чатырох байтам адрасе.

Калі знешні профіль, то замест яго змесціва ў BMP разьмяшчаецца тэкставая радок з шляхам да файла.
Ён абавязкова павінен быць у однобайтовой кадоўцы Windows 1252 (стандартная кадоўка для заходнееўрапейскіх моў) і заканчвацца нулявым байтам.
Пра падзельнікі кампанентаў шляху ў дакументацыі нічога не сказана, і таму, хутчэй за ўсё, можна выкарыстоўваць як левыя слэшы «\», так і «правыя» «/».
Шлях жа можа быць як у адносным, так і поўным і сеткавым.
І так як ва ўказанні шляху выкарыстоўваецца однобайтовая кадоўка, то гэтую радок у аператыўнай памяці выраўноўваць не абавязкова.

#### Перавагі пры рэндэрынгу

**Перавагі пры рэндэрынгу** (англ.: rendering intentsrendering intents) былі ўведзеныя Міжнародным канцорцыумам па колеры (International Color Consortium) і вызначаюць прыярытэты ў выпадку, калі пры пераходзе з каляровага подпространство, падтрымоўванага адным прыладай (англ.: gamutgamut), у подпространство іншага, у малюнку выкарыстаны колеру, адсутныя ў мэтавым.
Таксама ёсць вызначэнне ад ICC, якое вызначаецца перавагі пры рэндэрынгу як стыль супастаўлення каляровых значэнняў з аднаго описателя выявы ў іншае (арыгінал на англійскай мове: *«style of mapping colour values from one image description to another»*).
Карпарацыя Microsoft ўключыла ў фармат BMP спецыяльнае поле Intent, якое можа прымаць значэнні цалкам па спецыфікацыі ICC.
Таму за падрабязнай інфармацыі звяртайцеся да дакументацыі кансорцыума, апошнюю версію якой можна спампаваць з сайта color.org.
У Microsoft ж гэтыя перавагі коратка апісаны ў артыкуле «Rendering Intents» на MSDN.

Перавагу паказваецца ў поле Intent блока BITMAPINFO і даступныя толькі з 5-й версіяй інфармацыйных палёў.
Значэнні ж могуць быць наступнымі:

| Значэнне | Імя канстанты
для BMP | Назва
ICC | Назва
Microsoft | Канстанта
з файла Icm.h | Канстанта
для DEVMODE |
| --- | --- | --- | --- | --- | --- |
| 1 | LCS\_GM\_BUSINESS | saturation | Graphic | INTENT\_SATURATION (2) | DMICM\_SATURATE (1) |
| 2 | LCS\_GM\_GRAPHICS | media-relative colorimetric | Proof | INTENT\_RELATIVE\_COLORIMETRIC (1) | DMICM\_COLORIMETRIC (3) |
| 4 | LCS\_GM\_IMAGES | perceptual | Picture | INTENT\_PERCEPTUAL (0) | DMICM\_CONTRAST (2) |
| 8 | LCS\_GM\_ABS\_COLORIMETRIC | ICC-absolute colorimetric
(relative colometric) | Match | INTENT\_ABSOLUTE\_COLORIMETRIC (3) | DMICM\_ABS\_COLORIMETRIC (4) |

Microsoft для дадзенай характарыстыкі абвясціла як мінімум тры набору канстант, якія адрозніваюцца сваімі значэннямі і выкарыстоўваюцца ў розных месцах.
Тут яны прыведзены на выпадак, калі вам трэба будзе хутка іх супаставіць.
Значэнні канстант з прэфіксам «INTENT\_» цалкам супадаюць з тымі значэннямі, якія выкарыстоўваюцца ў файлах профіляў ICC.
Канстанты з прэфіксам «DMICM\_» абвешчаныя ў файле WinGDI.h для структуры DEVMODE.
Канстанты «LCS\_GM\_», якія выкарыстоўваюцца ў BMP, абвешчаныя там жа і прызначаныя ў першую чаргу для структуры LOGCOLORSPACE.
Ёсць таксама назвы для уласцівасцяў друкарак.
Яны аналагічныя тым, што ў калонцы «Назва Microsoft», але з «Графіка» і «Pictures».

За значэнне па змаўчанні, якое ў першую чаргу падыходзіць для фатаграфій і малюнкаў, можна прымаць 4 (LCS\_GM\_IMAGES).
У такім якасці рэкамендуе яго як Microsoft, так і ICC.

Прыклад праграмы на C
---------------------

Наступная праграма адкрывае 24 бітны BMP файл у вакне XWindow, глыбіня колеру павінна складаць 32 біта, на меншай колераперадачы не працуе, так як гэта ўскладняе прыклад:

```
/\* Компилируется строкой: cc -o xtest xtest.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm \*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include "bitmap.h" /\* Тут вызначэнні загалоўкаў BMP як было апісана вышэй у гэтым артыкуле (структуры павінны быць спакаваныя на 2 байты!) \*/

static XImage \*CreateImageFromBuffer(Display\*, unsigned char \*, int, int);

main(int argc, char \*argv[])
{
 Display \*dis;
 Window win;/\* Наша акно \*/
 XEvent event;/\* Падзеі \*/
 GC gc;/\* Графічны кантэкст \*/

 XImage \*image;
 int n, width, height, fd, size;
 unsigned char \*data;
 BITMAPFILEHEADER bmp;
 BITMAPINFOHEADER inf;
 char\* buf;

 if (argc < 2) {
 perror("use: xtest file.bmp\n");
 exit(1);
 }

 if ((fd = open(argv[1], O\_RDONLY)) == -1) {
 printf("Error open bitmap\n");
 exit(1);
 }

 read(fd, &bmp, sizeof(BITMAPFILEHEADER));
 read(fd, &inf,sizeof(BITMAPINFOHEADER));

 width = inf.biWidth;
 height = inf.biHeight;

 if ((dis = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
 printf("Can’t connect X server:%s\n", strerror(errno));
 exit(1);
 }

 win = XCreateSimpleWindow(dis, RootWindow(dis, DefaultScreen(dis)), 0, 0, width, height, 5,
 BlackPixel(dis, DefaultScreen(dis)), WhitePixel(dis, DefaultScreen(dis)));

 XSetStandardProperties(dis, win, argv[1], argv[0], None, argv, argc, NULL);
 gc = DefaultGC(dis, DefaultScreen(dis));

 /\* Часам у структуры гэтае месца не запоўнена \*/
 if(inf.biSizeImage == 0) {
 /\* Вылічым памер \*/
 size = width \* 3 + width % 4;
 size = size \* height;
 } else {
 size = inf.biSizeImage;
 }
 
 buf = malloc(size);
 if(buf == NULL) {
 perror("malloc");
 exit(1);
 }
 printf("size =%d байтов выделено\n", size);

 /\* Змесцімся на пачатак самага відарыса \*/
 lseek(fd, bmp.bfOffBits, SEEK\_SET);

 /\* Чытаем у буфер \*/
 n = read(fd, buf, size);
 printf("size =%d байт прачытана\n", n);

 image = CreateImageFromBuffer(dis, buf, width, height);

 /\* Выдалім буфер - ён нам больш не патрэбен \*/
 free(buf);

 XMapWindow(dis, win);
 XSelectInput(dis, win, ExposureMask | KeyPressMask);
 while (1) {
 XNextEvent(dis, &event);
 if (event.xany.window == win) {
 switch (event.type) {
 case Expose:
 XPutImage(dis, win, gc, image, 0, 0, 0, 0, image->width, image->height);
 break;

 case KeyPress:
 if (XLookupKeysym(&event.xkey, 0) == XK\_q) {
 XDestroyImage(image);
 XCloseDisplay(dis);
 close(fd);
 exit(EXIT\_SUCCESS);
 }
 break;

 default:
 break;
 }
 }
 }
}

/\* Стварае Ximage з файла BMP, бо відарыс BMP захоўваецца первернутым - у цыкле гэта выпраўляецца \*/ 
XImage \*CreateImageFromBuffer(Display \* dis, unsigned char \*buf, int width, int height)
{
 int depth, screen;
 XImage \*img = NULL;
 int i, j;
 int numBmpBytes;
 size\_t numImgBytes;
 int32\_t \*imgBuf;
 int ind = 0;
 int line;
 int temp;
 int ih, iw; /\* Нумары радка і слупка для адлюстравання \*/
 int new\_ind; /\* Новы індэкс \*/

 screen = DefaultScreen(dis);
 depth = DefaultDepth(dis, screen);
 temp = width \* 3;
 line = temp + width % 4; /\* Даўжыня радка з улікам выраўноўвання \*/
 numImgBytes = (4 \* (width \* height));
 imgBuf = malloc(numImgBytes);

 /\* Памер, адведзены на BMP у файле з улікам выраўноўвання \*/
 numBmpBytes = line \* height;
 for (i = 0; i < numBmpBytes; i++) {
 unsigned int r, g, b;

 /\* Прапускаем padding \*/
 if (i >= temp && (i % line) >= temp)
 continue;
 
 b = buf[i];
 i++;
 g = buf[i];
 i++;
 r = buf[i];

 
 /\* Вылічаем новы індэкс для адлюстравання па вертыкалі \*/
 iw = ind % width;
 ih = ind / width;
 new\_ind = iw + (height — ih — 1) \* width;
 
 imgBuf[new\_ind] = (r | g << 8 | b << 16) << 8;
 ind++;
 }

 img = XCreateImage(dis, CopyFromParent, depth, ZPixmap, 0, (char \*) imgBuf, width, height, 32, 0);
 XInitImage(img);

 /\* Парадак бітаў і байтаў на PC павінен быць такім \*/
 img->byte\_order = MSBFirst;

 img->bitmap\_bit\_order = MSBFirst;
 return img;
}

```

Гл. таксама
-----------

* ICO (фармат файлаў) — роднасны памер ад Microsoft для захоўвання значкоў і курсору мышы.

Зноскі
------

1. ↑   Праверана 3 лютага 2021.
2. 1 2   Праверана 7 верасня 2016.
3. ↑   Праверана 7 верасня 2016.
4. ↑  *S. Leonard* Windows Image Media Types — IETF, 2016. — 12 p. — doi:10.17487/RFC7903<a href='https://wikidata.org/wiki/Track:Q47481673'></a><a href='https://wikidata.org/wiki/Track:Q217082'></a>
5. ↑   Праверана 14 кастрычніка 2016.
6. ↑   Праверана 14 кастрычніка 2016.
7. ↑  Евченко А. И. OpenGL и DirectX. Программирование графики (Для профессионалов), 2006 г. Стр. 183.
8. ↑  См. раздел «Remarks» статьи «BITMAPV5HEADER structure» на MSDN.
9. ↑  См. раздел «Remarks» в статье «BITMAPINFO structure» на MSDN.
10. ↑  См. статью «Bitmap Header Types» в MSDN.
11. ↑  Информация о версиях взята из справки по Microsoft Windows SDK, идущая в комплекте с Microsoft Visual Studio 2008 и Embarcadero RAD Studio 2010 (раздел «Requirements» в статьях про данные структуры).
12. ↑  См. разделы «Requirements» в статьях «BITMAPCOREHEADER» и «BITMAPINFOHEADER» применительно к Windows Mobile 6.5 на MSDN.
13. ↑  Імя поля «bV4V4Compression» з падвоеным «V4» паказана ў дакументацыях і аб’яве структуры ў файле WinGDI.h (глядзіце, напрыклад, «BITMAPV4HEADER structure» на MSDN.).
14. ↑  Microsoft аб’явіла паля Gamma\* з типом DWORD, но пры гэтым у GDI ёсць спецыяльнй для такіх палей тып FXPT16DOT16.
15. ↑  См. раздел «Remarks» в статье BITMAPINFOHEADER (рубрика «Windows Mobile 6.5») на MSDN.
16. ↑  См. раздел «Remarks» в статье «Image Pixel Format Constants» (рубрика «GDI+») на MSDN.
17. ↑  В MSDN в самом начале раздела «Remarks» страницы структуры BITMAPV5HEADER есть предложение *«If bV5Height is negative, indicating a top-down DIB, bV5Compression must be either BI\_RGB or BI\_BITFIELDS.»* (перевод: *«Если bV5Height отрицательный, обозначая DIB вида сверху-вниз, то bV5Compression должен быть либо BI\_RGB, либо BI\_BITFIELDS»*). Здесь возможно не уточнили, что это касается только RLE-кодирования, так как в одном из примеров прорисовки JPEG-растра указывается именно отрицательная высота (ищите строку «bmi.bmiHeader.biHeight» в статье «Testing a Printer for JPEG or PNG Support» на MSDN).
18. ↑  Будьте внимательны.
В MSDN в статье «BITMAPINFOHEADER»
для Windows Mobile 6.5 в описании к полю biClrUsed есть предложение
*«If biBitCount equals 16 or 32, the optimal color palette starts immediately following the three DWORD masks.»*
(перевод: «*Если biBitCount равно 16 или 32, то оптимальная цветовая палитра начинается следуя сразу за тремя DWORD-масками*»).
В этой же статье выше, в описании к полю biCompression сказано *«Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks…»*
и ниже аналогичное с *«consists of four DWORD color masks»* (переводы: *«Указывает, что битмап не сжат и что таблица цветов состоит из трёх цветовых DWORD-масок»*
и «*состоит из четырёх цветовых DWORD-масок*»).
Аналогичная информация содержится в статье «BITMAPINFOHEADER structure» для Windows 9x/NT.
Всё это можно интерпретировать так, что в битности 16 и 32 за информационными полями (структурой BITMAPINFOHEADER) обязательно присутствуют три 32-битных маски для извлечения значений цветовых каналов.
При этом если Compression содержит 3 (BI\_BITFIELDS) или 6 (BI\_ALPHABITFIELDS), то за ними добавляется ещё три или четыре аналогичных маски,
которые в свою очередь занимают таблицу цветов делая невозможным использование 16-битных индексов оптимальных цветов в логической палитре
(возможно при этом в поле biClrUsed нужно записать значение 6 или 8, а в biClrImportant обязательно 0, чтобы дополнительные маски случайно не обработались как индексы в палитре).
  

В действительно всё несколько иначе.
19. ↑  В документации MSDN на странице «Bitmap Header Types» есть предложение
*«Bitmaps that are 1, 4, or 8 bpp must have a color table with a maximum size based on the bpp.»*
(перевод: *«Битмапы с битностью 1, 4 или 8 должны содержать таблицу цветов с максимальным соответствующим битности размером.»*).
Это явно ошибка и писавший применил условия структуры CORE, у которой действительно должен быть максимум
(см. раздел «Remarks» в статье «BITMAPCOREINFO structure»),
ко всем остальным версиям структур.
В другой статье «BITMAPINFO structure» про таблицу цветов сказано
*«The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.»*
(перевод: *«количество элементов в массиве зависит от значений полей biBitCount и biClrUsed структуры BITMAPINFOHEADER»*),
а в статьях структур версий 3, 4, 5
(см. например, «BITMAPV5HEADER structure»)
в описании поля BitCount везде написано
*«the bmiColors member of BITMAPINFO contains up to 256 entries»*
(аналогично про другие битности; перевод фразы: *«член bmiColors BITMAPINFO содержит до 256 элементов»*).
20. ↑  См. например, описания к битностям 16 и 32 у поля bV5BitCount в статье «BITMAPV5HEADER structure» на MSDN.
21. ↑  На MSDN и справке Microsoft Windows SDK в статье «BITMAPINFOHEADER structure» в описании значения 16 поля biBitCount есть сбивающее с толку предложение *«All the bits in the pixel do not have to be used.»* (перевод: «*Не задействовать все биты в пикселе*»). Это опечатка (написали «have» вместо «need»), которая отсутствует в аналогичном блоке в статье про пятую версию (в четвёртой это предложение отсутствует).
22. ↑  Данная информация есть в справке по Microsoft Windows SDK, которая идёт в комплекте вместе с крупными IDE.
23. ↑  См. «Image Pixel Format Constants» про GDI+ в MSDN.
24. ↑  См. «PixelFormat Enumeration» про .NET Framework 1.1 в MSDN.
25. ↑  См. раздел «Remarks» в статье «BITMAPINFO» на MSDN.
26. ↑  В документации (например, в статье «BITMAPV5HEADER structure» на MSDN) сказано, что нулевой размер можно указывать при значении 0 (BI\_RGB) поля Compression. Очевидно, что это применимо и к значениям 3 (BI\_BITFIELDS) и 6 (BI\_ALPHABITFIELDS), так как они вносят различие лишь во внутреннюю структуру пикселей, а не в их размер.
27. ↑  По своей сути один-в-один как в структуре RGBQUAD, которая используется в таблице цветов.
28. ↑  На MSDN в статье «BITMAPV4HEADER structure» упоминается только одно значение поля CSType (LCS\_CALIBRATED\_RGB).
Полный список доступных значений для версий 4 и 5 можно посмотреть в статье «Using Structures in WCS 1.0».
29. ↑  Здесь после «Win» идёт ещё пробел.
30. ↑  Использование такого стиля значений констант только в поле CSType является скорее всего результатом влияния спецификации ICC, у которой в файлах цветовых профилей 32-битным меткам (англ.: tagstags) значения выданы аналогично.
31. ↑  См. раздел «Remarks» в статье «LOGCOLORSPACE Structure» на MSDN.
32. ↑  Числа взяты из стандарта «A Standard Default Color Space for the Internet — sRGB». Все значения округлялись вверх если был установлен самый первый отброшенный права бит.
33. ↑  С обнулённым младшим байтом будет значение 00001A0016 (округлено вверх).
34. ↑  Описание данного формата есть в спецификации ICC.1:2010, ссылка на которую есть в конце данной статьи.
35. ↑  См. раздел «Remarks» статьи «BITMAPV5HEADER structure» на MSDN.
36. ↑  См. статью «Using Structures in WCS 1.0» на MSDN.
37. ↑  См. раздел «7.2 Profile header» в спецификации ICC.1:2010.
38. ↑  Определение дано в спецификации ICC.1:2010 в разделе 3.1.27 на стр. 21.
39. ↑  В версии 4.3 спецификации (последняя на момент написания статьи) данная тема широко освещается в разделах «0.4 Rendering intents» (во вступлении; стр. 8), «6.2 Rendering intent» (в основном содержимом; стр. 26) и «D.6 Discussion of colorimetric intents» (в приложениях; стр. 109).
40. ↑  Сопоставления констант взяты из файла Icm.h (закомментированный блок прямо над объевлениями констант «INTENT\_»).
41. ↑  См. раздел «7.2.15 Rendering intent field (bytes 64 to 67)» спецификации ICC.
42. ↑  См. раздел «Picture Intent» в статье «Rendering Intents» на MSDN.
43. ↑  В спецификации внизу страницы 41.

Крыніцы і літаратура
--------------------

### Microsoft (MSDN і SDK)

Microsoft Windows SDK — камплект для распрацоўшчыкаў, які ўключае ў сябе даведку і ўключаюцца файлы на мове C++. Па тэме дадзенага артыкула актуальныя файлы WinGDI.h і Icm.h, з якіх былі ўзятыя ў першую чаргу значэнні канстант.
Апошнюю версію дадзенага камплекта можна бясплатна спампаваць з сайта Microsoft (у дадзеным артыкуле выкарыстоўваліся версіі 6.0 і 7.1).

У Microsoft няма асобнай спецыяльнай дакументацыі менавіта па фармаце BMP.
Але яго структуры і іншыя элементы апісаны ў рамках падсістэмы GDI.
Гэта апісанне ёсць у даведцы, якая ўключаецца ў вышэйзгаданае SDK, а таксама на MSDN.
Прычым у апошнім яна прысутнічае для розных платформаў і незалежна ў даведцы па Visual Studio.
У большасці выпадкаў там прадстаўлена ідэнтычная інфармацыя, але ў некаторых месцах можа быць трохі больш фактаў (напрыклад, у даведцы SDK больш інфармацыі аб падтрымцы Windows).

Асноўная інфармацыю знаходзіцца ў даведцы па GDI, якая адносіцца да платформах Windows 9x і NT.
Спасылкі на старонкі гэтага раздзелу, якія адносяцца толькі да фармату, а не да WinAPI-функцый працы з ім:

* «Bitmap Classifications» — апісанне апаратна-залежных і апаратна-незалежных бітмапаў.
* «Bitmap Storage» — агульнае апісанне фармату файла BMP.
* «Bitmap Header Types» — агляд па версіях загалоўкаў BMP.
* «Bitmap Compression» — апісанне RLE-кадавання.
* «Bitmap Structures» — раздзел з апісаннямі структур з палямі. Для зручнасці прамыя спасылкі на ключавыя:
	+ BITMAPFILEHEADER
	+ BITMAPCOREHEADER
	+ BITMAPINFOHEADER
	+ BITMAPV4HEADER
	+ BITMAPV5HEADER

У платформаў Windows Compact 2013 (CE 6.0) і Mobile 6.5 ёсць толькі апісання трох структур, але ў дачыненні да дадзеных платформах:

* BITMAPFILEHEADER
* BITMAPCOREHEADER
* BITMAPINFOHEADER

Спасылкі на іншыя старонкі з MSDN, якія адносяцца да фармату BMP:

* «Image Pixel Format Канстант» — канстанты фарматаў пікселяў GDI+.
* «PixelFormat Enumeration» — апісанне значэнняў пералічваецца, тыпу PixelFormat для .NET Framework 1.1 (самая ранняя версія).
* «Using Structures in WCS 1.0» — пра якія выкарыстоўваюцца ў кіраванні колерам у Windows структуры.
* «Rendering Intents» — апісанне пераваг пры рэндэрынгу.

### Іншыя

У спецыфікацыі ICC па кіраванні колерам можна знайсці інфармацыю аб каляровых профілях (у тым ліку аб фармаце файлаў ICC), а таксама аб перавагах рэндэрынгу.
Гэтую спецыфікацыю можна спампаваць з афіцыйнага сайта кансорцыума color.org.
У момант напісання артыкула апошняй версіяй была 4.3 (снежань 2010).
Прамыя спасылкі на PDF з сайта ICC:

* Тэхнічныя характарыстыкі ICC.1:2010 (Profile version 4.3.0.0) «Image technology colour management — Architecture, profile format, and data structure».
* Errata да спецыфікацыі (выяўленыя памылкі і памылкі друку; апублікаваныя 24 верасня 2013 года).