Ф а р м а т м а л ю н к а B M P

Арыгінал даступны на сайце Paul Bourke


Увядзенне

Файлы BMP сыходзяць у мінулае (але ўсё яшчэ часта выкарыстоўваюцца) фармат файла для гістарычнай (але ўсё яшчэ часта выкарыстоўваецца) аперацыйнай сістэмы пад назвай “Windows”. Выявы BMP могуць вар’іравацца ад чорна і белага (1 біт на піксель) да 24-бітнага колеру (16,7 мільёна колераў). Хоць выявы можна сціснуць, гэта рэдка выкарыстоўваецца на практыцы і тут мы не будзем разглядаць гэта падрабязна.

Структура

Файл BMP складаецца з 3 альбо 4 частак, як паказана на дыяграме справа. Першая частка – гэта загаловак, за ім ідзе інфармацыйны раздзел, калі малюнак індэксуецца колерам, то вынікае палітра, і апошні з усіх – гэта даныя пікселя. Размяшчэнне даных малюнка адносна sart файла змяшчаецца ў загалоўку. Такая інфармацыя, як шырыня і вышыня малюнка, тып сціску, колькасць колераў, змяшчаецца ў інфармацыйным загалоўку.

Загаловак

Загаловак складаецца з наступных палёў. Звярніце ўвагу, што мы мяркуем, што кароткі int складае 2 байта, int 4 байта, і доўгі int 8 байт. Далей мы мяркуем, што парадак байтаў як для тыповых (Intel) машын. Даўжыня загалоўка складае 14 байт.

typedef struct {
   unsigned short int type;                 /* Magic identifier            */
   unsigned int size;                       /* File size in bytes          */
   unsigned short int reserved1, reserved2;
   unsigned int offset;                     /* Offset to image data, bytes */
} HEADER;

Карыснымі палямі ў гэтай структуры з’яўляюцца тып поля (павінна быць “BM”), якое з’яўляецца простай праверкай таго, што гэта, верагодна, будзе законным BMP-файлам, , і поле зрушэння, якое дае колькасць байт да атрымання
фактычных даных пікселя (гэта адносна да пачатку файла). Звярніце ўвагу, што гэтая структура не кратна 4-м байтам для тых машын / кампілятараў, якія могуць размяркаваць гэта,  гэтыя машыны звычайна будуць размяшчаць гэтую структуру ад 2 байт да 16, што прывядзе да выраўноўвання будучых выклікаў fread ().

Інфармацыя

Даныя інфармацыі пра выявы, якія вынікаюць далей, складаюць 40 байт у даўжыню, гэта апісана ў структуры, прыведзенай ніжэй.Поля, якія прадстаўляюць найбольшую цікавасць, прадстаўленыя шырынёй і вышынёй малюнка, колькасцю біт на піксель (павінна быць 1, 4, 8 ці 24), лікам плоскасцяў (тут мяркуецца 1) і тыпам сціску (мяркуецца, што тут 0).

typedef struct {
   unsigned int size;               /* Header size in bytes      */
   int width,height;                /* Width and height of image */
   unsigned short int planes;       /* Number of colour planes   */
   unsigned short int bits;         /* Bits per pixel            */
   unsigned int compression;        /* Compression type          */
   unsigned int imagesize;          /* Image size in bytes       */
   int xresolution,yresolution;     /* Pixels per meter          */
   unsigned int ncolours;           /* Number of colours         */
   unsigned int importantcolours;   /* Important colours         */
} INFOHEADER;

Ніжэй прыведзены тыпы сціску, якія падтрымліваюцца BMP:

  • 0 - no compression
  • 1 - 8 bit run length encoding
  • 2 - 4 bit run length encoding
  • 3 - RGB bitmap with mask
Толькі тып 0 (тут не будзе абмяркоўвацца кампрэсія).

24-бітныя даныя выявы

Самыя простыя дадзеныя для чытання – гэта 24-бітныя сапраўдныя каляровыя выявы. У гэтым выпадку даныя выявы вынікаюць адразу пасля загалоўка інфармацыі, гэта значыць няма каляровай палітры. Ён складаецца з трох байт на піксель у парадку b, g, r. Кожны байт дае насычанасць для гэтага каляровага кампанента, 0 для чорнага і 1 для белага (цалкам насычанага).

Індэксаваныя даныя пра колер

Калі малюнак індэксуецца колерам, то адразу пасля загалоўка інфармацыі з’явіцца табліца з колерамі infoheader.ncolours, кожны па 4 байта. Першыя тры байта адпавядаюць кампанентам b, g, r, апошні байт зарэзерваваны / нявыкарыстаны, але, відавочна, можа прадстаўляць альфа-канал. Для 8-бітных малюнкаў шэрага колеру гэты каляровы індэкс, як правіла, будзе проста рампам шэрага адцення. Калі вы робіце сумы …. тады даўжыня загалоўка плюс даўжыня інфармацыйнага блока плюс 4 разы колькасці колераў палітры, якое павінна адпавядаць зрушэнню дадзеных малюнка. Іншымі словамі

14 + 40 + 4 * infoheader.ncolours = header.offset

Зыходны код

Вось крыніца, прадстаўленая Michael Sweet, BITMAP.H, BITMAP.C, і BMPVIEW.C.

І некаторыя прыклады майго кода, parse.c і на прыклад 24-бітны rgb BMP файл для тэставання. Звярніце ўвагу, што ні адзін з гэтых сегментаў кода не будзе апрацоўваць усе тыпы файлаў BMP, у прыватнасці, яны не апрацоўваюць сціснутыя файлы BMP. Яны павінны стаць добрай адпраўной кропкай для сустрэтых варыянтаў і для тых, хто хоча пісаць файлы, сумяшчальныя з BMP. З іншага боку, калі ў вас ёсць ці напісаны лепшы апрацоўшчык BMP, то вы можаце падаць тут заяўку для яго дадання.

Уклад Адама Маеўскага, які запісвае па адным біце ў піксельным файле BMP: pf1bit_bmp.c.
Змены ў pf1bit_bmp.c паводле “aleksisto”: mypf1bit_bmp.c
Уклад Гаральда Ходзінса для выпраўлення байтавай упакоўкі, неабходнай для некаторых кампілятараў: bitmap2.h.