BMP
фармат графічнага файла From Wikipedia, the free encyclopedia
Remove ads
BMP (ад англ.: Bitmap Picture) — фармат захоўвання растравых выяў, распрацаваны кампаніяй Microsoft, падтрымка якога інтэгравана ў аперацыйныя сістэмы Windows і OS/2. Файлы фармату BMP могуць мець пашырэнні .bmp, .dib і .rle
Артыкул вымагае праверкі арфаграфіі Удзельнік, які паставіў шаблон, не пакінуў тлумачэнняў. |
У гэтым фармаце можна захоўваць толькі аднаслаёвыя растры.
Фармат дазваляе задаваць для розных файлаў розную глыбіню колеру (колькасць біт колеру на піксель). Microsoft прапануе бітнасці 1, 2, 4, 8, 16, 24, 32, 48 і 64. У бітнасцях 8 і ніжэй, колер паказваецца з індэксам табліцы колераў, а пры большых — непасрэдным значэннем. Колер можна задаць толькі ў каляровай мадэлі RGB (як пры непасрэдным ўказанні ў пікселі, так і ў табліцы колераў), але ў бітнасцях 16 і 32 можна атрымаць адценні шэрага колеру з глыбінёй да 16 і 32 біт адпаведна. Частковая празрыстасць рэалізавана альфа-каналам розных бітнасцяў, але пры гэтым празрыстасць без градацый можна ўскосна атрымаць RLE-кадзіраваннем. У большасці выпадкаў пікселі захоўваюцца ў выглядзе адносна простага двухмернага масіва. Для бітнасцей 4 і 8 даступна RLE-кадзіраванне, якое можа паменшыць іх памер.
Фармат BMP таксама падтрымлівае ўбудаванне даных у фарматах JPEG і PNG. Але апошняе, хутчэй, больш прызначана не для кампактнага захоўвання, а для абыходу абмежаванняў архітэктуры GDI, якая не прадугледжвае прамую працу з відарысамі у фарматах, адрозных ад фармату BMP.
У апошніх версіях фармату BMP таксама з’явіліся магчымасці па кіраванні колерам. У прыватнасці, можна паказваць канчатковыя кропкі, вырабляць гама-карэкцыю і ўбудоўваць каляровыя профілі ICC.
Remove ads
DIB і DDB
Пры выкарыстанні фармату DIB (англ.: Device Independent Bitmap — апаратна-незалежная бітавая карта) праграміст можа атрымаць доступ да ўсіх элементаў структур, якія апісваюць малюнак, пры дапамозе звычайнага ўказальніка. Але гэтыя даныя не выкарыстоўваюцца для непасрэднага кіравання экранам, так як яны заўсёды захоўваюцца ў сістэмнай памяці, а не ў спецыялізаванай відэапамяці.
Фармат пікселя ў аператыўнай памяці можа адрознівацца ад таго фармату, які павінен заносіцца ў відэапамяць для індыкацыі пункту такога ж колеру. Напрыклад, у DIB-фармаце можа выкарыстоўвацца 24 біта для задання пікселя, а графічны адаптар у гэты момант можа працаваць у рэжыме HiColor з каляровай глыбінёй 16 біт. Пры гэтым ярка-чырвоная кропка ў апаратна-незалежным фармаце будзе задавацца трыма байтами 0000FF16, а ў відэапамяці — словам F80016. Пры капіяванні малюнка на экран сістэма будзе марнаваць дадатковы час на пераўтварэнне кодаў колеру з 24-бітнага фармату ў фармат відэабуфера.
Фармат DDB (англ.: Device Dependent Bitmap — апаратна-залежная бітавая карта) заўсёды змяшчае каляровыя коды, якія супадаюць з кодамі відэабуфера, але ён можа захоўвацца як у сістэмнай, так і ў відэапамяці. У абодвух выпадках ён змяшчае толькі коды колеру ў тым фармаце, які забяспечыць перасылку выявы з АЗП у відэапамяць пры дапамозе простага капіявання[7].
Remove ads
Унутраная будова
Афіцыйную інфармацыю па фармаце 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 складаюцца з трох асноўных блокаў рознага памеру:
- Загаловак з структуры BITMAPFILEHEADER і блока BITMAPINFO. Апошні змяшчае:
- Інфармацыйныя поля.
- Бітавыя маскі для здабывання каляровых значэнняў каналаў (апцыянальныя).
- Табліца колераў (апцыянальная).
- Каляровы профіль (апцыянальны).
- Піксельныя даныя.
Пры захоўванні ў файле ўсе загалоўкі ідуць з самага першага байта.
Піксельныя даныя могуць знаходзіцца на адвольнай пазіцыі ў файле (яна паказваецца ў поле OffBits структуры BITMAPFILEHEADER), у тым ліку і ў выдаленні ад загалоўкаў. Апцыянальны каляровай профіль з’явіўся ў версіі 5 і ён таксама можа свабодна размяшчацца, але яго пазіцыя паказваецца ад пачатку BITMAPINFO (у поле ProfileData).
У аператыўнай памяці (напрыклад, пры ўзаемадзеянні з WinAPI-функцыямі GDI) з загалоўкаў выключаецца структура BITMAPFILEHEADER.
Пры гэтым Microsoft рэкамендуе размяшчаць каляровай профіль адразу за загалоўкамі ў адзіным блоку[8].
Піксельныя даныя могуць мець адвольнае размяшчэнне ў памяці і іх адрас паказваецца ў параметрах працэдур.
У любым выпадку рэкамендуецца ў памяці ўсе блокі змяшчаць па адрасах кратных чатыром: у загалоўках ёсць 32-бітныя ячэйкі, а да піксельных даных такое патрабаванне паказана ў дакументацыі[9].
Гэта патрабаванне справядліва толькі для аператыўнай памяці: пры захоўванні ў файле яго прытрымлівацца не абавязкова.
BITMAPFILEHEADER
BITMAPFILEHEADER — 14-байтная структура, якая размяшчаецца ў самым пачатку файла. Звярніце ўвагу на тое, што з самага пачатку структуры збіваецца выраўноўванне вочак.
Калі для вас яно важна, то ў аператыўнай памяці гэты загаловак размяшчайце па цотных адрасах, якія не кратныя чатыром (тады 32-бітныя ячэйкі трапяць на выравненные пазіцыі).
Сігнатура фармату пры праглядзе змесціва файла тэкстам у дваічным рэжыме выглядае як пара ASCII-знакаў «BM».
BITMAPINFO
BITMAPINFO ў файле ідзе адразу за BITMAPFILEHEADER. Адрас гэтага блока ў памяці напрамую таксама перадаецца некаторых функцый WinAPI (напрыклад, SetDIBitsToDevice або CreateDIBitmap).
Акрамя гэтага, гэты жа блок выкарыстоўваецца ў фарматах значкоў і курсораў Windows, але ў гэтым артыкуле гэты момант не разглядаецца (гл. асобныя апісання гэтых фарматаў).
Гэта структура асноўная і апісальная ў фармаце BMP і таму калі проста згадана імя поля, то гаворка ідзе пра поле ў гэтай структуры.
Блок BITMAPINFO складаецца з трох частак:
- Структура з інфармацыйнымі палямі.
- Бітавыя маскі для здабывання каляровых значэнняў каналаў (прысутнічаюць не заўсёды).
- Табліца колераў (прысутнічае не заўсёды).
Пра бітавыя маскі і табліцу колераў глядзіце ніжэй у асобных раздзелах. Тут далей пойдзе апісанне структуры з інфармацыйнымі палямі.
У момант напісання гэтага артыкула структура з інфармацыйнымі палямі мела чатыры версіі[10]: CORE, 3, 4 і 5 (абазначэнні версій прыведзены ўмоўныя у рамках гэтага артыкула для кароткасці).
Для кожнай версіі Microsoft абвясціла чатыры асобныя структуры з рознымі імёнамі палёў.
У гэтым артыкуле пры згадванні поля, якое прысутнічае ў некалькіх структурах, бярэцца агульная для ўсіх структур частка ў канцы імя (напрыклад, BitCount замест bcBitCount, biBitCount, bV4BitCount або bV5BitCount).
Версію структуры можна вызначыць па першай 32-бітнай вочку (WinAPI-тып DWORD), якая змяшчае яе памер у байтах (беззнаковым цэлым).
Версія CORE адрозніваецца ад усіх сваёй кампактнасцю і выкарыстаннем выключна 16-бітных беззнаковых палёў. Астатнія тры змяшчаюць ідэнтычныя ячэйкі, да якіх у кожнай новай версіі дадаваліся новыя.
Ніжэй прадстаўлена аглядная табліца па інфармацыйных структурах:
Праз ідэнтычнасць палёў у версіях 3, 4 і 5 можа здацца, што полем Памер можна рэгуляваць колькасць палёў, прыбіраючы непатрэбныя.
У рэчаіснасці гэта не карэктна, так як тут памер гуляе ролю версіі (у версіі CORE хоць і таксама ідэнтычныя паля, але іншага памеру і тыпу).
Ніхто не гарантуе, што вам не могуць трапіцца загалоўкі меншых або вялікіх памераў з іншым наборам палёў.
Тым не менш, Adobe Photoshop можа пры захаванні файлаў BMP запісваць структуры інфармацыйных палёў з памерамі 52 і 56 байт.
Па сутнасці гэта зрэзаная 4-я версія, якая змяшчае толькі біты маскі каналаў (56 байт — версія з альфа-каналам).
16-бітныя інфармацыйныя паля (версія CORE)
Звярніце ўвагу на тое, што тут паля шырыні і вышыні змяшчаюць бяззнакавыя цэлыя, у той час як 32-бітныя структуры захоўваюць значэнні са знакам.
32-бітныя інфармацыйныя паля (версіі 3, 4 і 5)
У табліцы ніжэй поля прадстаўленыя аглядна.
Падрабязную інфармацыю вы можаце знайсці ў раздзелах далей.
Бітнасць выявы (поле BitCount)
Поле BitCount змяшчае колькасць біт, якое прыходзіцца на кожны піксель.
Калі там указана выдатнае ад нуля значэнне, то гэта і ёсць рэальная бітнасць.
Нулявы ж змест поля BitCount паказваецца калі пікселі захоўваюцца ў фармаце JPEG ці PNG.
Тады сапраўдная бітнасць будзе вызначацца ўжо гэтымі фарматамі.
Бітнасці чыста BMP фармату прадстаўлены ў табліцы ніжэй:
Заўвагі да табліцы:
1. У калонцы «BITMAPINFO» пазначана падтрымка бітнасцей толькі з боку Microsoft.
2. Windows CE 1.0 і 1.01 падтрымлівае толькі бітнасці 1 і 2[15].
3. GDI+ версіі 1.0 16-бітныя каляровыя каналы ўмее толькі счытваць, адразу перакладаючы іх у 8-бітныя[16].
У бітнасцях 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 дакументавала наступныя значэнні (у табліцы пазначаны імёны канстант ад гэтай карпарацыі):
Табліца колераў
Табліца колераў з’яўляецца часткай блока BITMAPINFO і можа выкарыстоўвацца ў двух выпадках:
- Яна абавязкова прысутнічае пры бітнасцях 8 і ніжэй, у якіх колер пікселяў задаецца індэксам ячэйкі з яе.
- Пры бітнасцях 8 і вышэй, у якіх колер паказваецца непасрэдным значэннем, табліца прысутнічае калі выкарыстоўваецца загаловак не CORE-версіі, у якога поле ClrUsed змяшчае не нулявое значэнне. Тут яна задзейнічаецца ўжо для аптымізацыі колераў пры працы з прыладамі, якія выкарыстоўваюць палітры (як менавіта вырабляецца аптымізацыя ў дакументацыі не сказана).
Пазіцыя табліцы колераў паказваецца ад яго пачатку блока BITMAPINFO.
Па змаўчанні яна ідзе адразу за інфармацыйнай структурай (яе беззнаковый памер у байтах можна прачытаць з першага 32-бітнага поля).
Але паміж структурай з палямі і каляровай табліцай могуць ісці четырехбайтные бітаў маскі для здабывання каляровых каналаў (тычыцца толькі битностей 16 і 32).
Яны там знаходзяцца толькі калі выкарыстоўваецца інфармацыйная структура 3-яй версіі (Size = 40) і поле Compression змяшчае 3 (BI_BITFIELDS) або 6 (BI_ALPHABITFIELDS).
Тады да памеру інфармацыйных палёў трэба дадаць 12 (пры значэнні BI_BITFIELDS) або 16 байт (калі паказана BI_ALPHABITFIELDS)[18].
Атрымліваецца 6 варыянтаў размяшчэння табліцы:
Колькасць вочак у табліцы вызначаецца па палях BitCount і ClrUsed.
Пры бітнасцях 8 і ніжэй максімальная колькасць вочак у табліцы прымаецца за 2бмтнасць: 2 у аднабітным растры, 4 у двухбітным, 16 у 4-охбітным і 256 у 8-бітным.
У гэтых бітнасцях табліца заўсёды змяшчае гэта максімальную колькасць вочак калі выкарыстоўваецца загаловак версіі CORE (Size = 12) або калі ў іншых версіях поле ClrUsed змяшчае 0.
Ва ўсіх астатніх выпадках, незалежна ад бітнасці, у табліцы знаходзіцца столькі вочак, колькі паказана ў поле ClrUsed[19].
Сама ж табліца ўяўляе сабой аднамерны масіў, які можа змяшчаць ячэйкі трох тыпаў:
- 32-бітная структура RGBQUAD. Прымяняецца, калі ў BITMAPINFO выкарыстана інфармацыйная структура версіі 3, 4 ці 5. У самой жа структуры RGBQUAD паказваецца колер у мадэлі RGB ў чатырох байтавых ячэйках (усе маюць WinAPI-тып BYTE): rgbBlue (сіні), rgbGreen (зялёны), rgbRed (чырвоны) і rgbReserved (зарэзерваваная і павінна быць абнулена).
- 24-бітная структура RGBTRIPLE. Ўжываецца калі BITMAPINFO пачынаецца са структуры BITMAPCOREHEADER. RGBTRIPLE складаецца з трох байтавых вочак (WinAPI-тып BYTE), у якіх паказваецца колер у мадэлі RGB: rgbtBlue (сіні), rgbtGreen (зялёны) і rgbtRed (чырвоны).
- 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 да бітавых масак ўжываецца толькі адно абавязковае патрабаванне: кожная маска павінна быць бесперапыннай.
Пра выпадак перасячэння масак там сказана, што пажадана гэтага не рабіць[20].
Microsoft таксама кажа аб тым, што не абавязкова задзейнічаць усе біты пікселя[21].
Якія-небудзь патрабаванні да змесціва невыкарыстоўваемых біт адсутнічаюць.
Звярніце ўвагу на тое, што ніхто не гарантуе, што могуць быць выкарыстаны маскі шырэй 8 біт.
І нічога не сказана пра выпадак, калі ў якога-небудзь канала будзе нулявая маска (напрыклад, калі ён сапраўды не выкарыстоўваецца).
Тут магчымая сітуацыя калі нулявыя маскі будуць ва ўсіх кампанентаў і застанецца адзін альфа-канал (які пры гэтым можа заняць усе біты).
Нулявую маску каляровага канала можна трактаваць двума спосабамі: яго значэнне прымаецца за нуль або жа пры прамалёўцы пікселі гэтага канала не закранаюцца.
Калі ўзяць першы варыянт інтэрпрэтацыі з адзіным альфа-каналам, то альфа-канал, па сутнасці, будзе задаваць ступень зачернения пікселя.
Акрамя нявызначаных варыянтаў ёсць таксама і цікавы.
Як перасячэнні не забаронены, то можна ўсе каналы выставіць на адну пазіцыю і тым самым атрымаць Grayscale.
Некаторы ПЗ мае абмежаваны набор падтрымоўваных бітавых масак.
У табліцы ніжэй прыведзены даступныя варыянты ў такіх абмежаваных асяроддзях:
Заўвагі да табліцы:
(a) Гэтыя наборы выкарыстоўваюцца па змаўчанні ў бітнасцях 16 і 32, калі маскі для здабывання колераў не зададзеныя.
(b) Гэты набор масак па сваёй сутнасці рэалізуе 16-бітны Grayscale.
Піксельныя даныя
У файле пра становішча піксельных даных можна даведацца з поля OffBits структуры BITMAPFILEHEADER.
Падчас выканання прыкладанне захоўвае адрас піксельных даных там, дзе зручней.
У дакументацыі Microsoft таксама згадваюцца так званыя пакетныя (англ. packed) битмапы, якія паказваюцца адным адрасам блока BITMAPINFO.
У такіх бітмапаў піксельныя даныя ідуць адразу за загалоўкам (уключаючы акрамя інфармацыйных палёў бітаў маскі і табліцу колераў)[25].
Памер піксельных даных у байтах запісваецца ў полі SizeImage структуры BITMAPINFO.
Туды запісваюцца менавіта «сырой» памер таго бесперапыннага блока, які змяшчае даныя для фарміравання пікселяў (незалежна ад фармату), а не які-небудзь распакаваць.
Па змаўчанні гэта поле абавязкова павінна змяшчаць актуальнае значэнне, так як па ім можна дакладна даведацца, колькі менавіта байт трэба лічыць з файла для атрымання пікселяў.
Тым не менш, дапушчальна змяшчаць у гэтым полі нуль пры захоўванні пікселяў двухмернымі масівамі (калі поле Compression змяшчае значэнне 0 (BI_RGB), 3 (BI_BITFIELDS) або 6 (BI_ALPHABITFIELDS)[26]).
Тады памер пікселяў пры неабходнасці можна адносна хутка разлічыць зыходзячы з бітнасці, шырыні і вышыні растру.
У фармаце Windows Bitmap даступна тры спосабу захоўвання пікселяў (гл. таксама раздзел «Поле Compression» гэтага артыкула):
- Двухмерны масіў.
- RLE-кадаваньне (толькі для бітнасцей 4 і 8).
- У фарматах JPEG ці PNG.
У падраздзелах далей асобна апісаны кожны з іх.
Указанне колеру і значэння альфа-канала
Для ўказанні колеру пры захоўванні ў фармаце BMP незалежна ад спосабу заданні выкарыстоўваюцца толькі бяззнакавыя цэлыя лікі. Сам жа колер пікселя можа задавацца двума спосабамі:
- Індэксам ў табліцы колераў (пры бітнастях 8 і ніжэй).
- Непасрэдным значэннем у каляровай мадэлі 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 bitmap), а пры адмоўным: з самага верхняга (англ.: top-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), а старэйшы байт не выкарыстоўваецца (ён выкарыстоўваецца ў якасці альфа-канала, толькі калі гэта прама паказаць)[27].
Як мяркуецца чытанне ў парадку байта 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-бітную мяжу).
Існуе пяць каманд, якія вызначаюцца парай байт:
Калі дасягаецца правы край гарызанталі, то на наступную пераклад не вырабляецца.
Таму трэба спецыяльна ўстаўляць каманду заканчэння шэрагу.
І як відаць з табліцы, набор каманд не дазваляюць рухацца ўніз або вярнуцца назад у гарызанталі.
Таму можна спыняць прамалёўку калі будзе дасягнуты верхні край.
Убудаванне даных у фарматах 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) і наадварот:
Калі цікавіць дакладны цэлалікавы пераклад, то выходзяць наступныя выразы:
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.
Дапушчальныя яго значэнні прыведзены ў табліцы ніжэй:
Microsoft абвясціла значэнні канстант не лікавымі значэннямі, а тэкставымі з чатырох знакаў[30].
У гэтым выпадку коды знакаў фарміруюць байты 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-бітнай ячэйкі)[31].
Ніжэй прыведзены значэнні названых вышэй чатырох палёў у адпаведнасці з каляровым прасторай sRGB[32]:
Каляровы профіль
У файле BMP пры неабходнасці можа быць паказаны каляровы профіль як непасрэдным уключэннем, так і спасылкай на іншы файл.
Профілі з’явіліся ў пятай версіі BMP, і пакуль толькі тут ёсць спецыяльныя для іх поля.
Падтрымліваюцца жа каляровыя профілі толькі ў фармаце ICC[34][35].
Пры выкарыстанні каляровых профіляў ў першую чаргу трэба пазначыць наступныя значэнні поля CSType:
- 4C494E4B16 (PROFILE_LINKED) — калі выкарыстоўваецца профіль у адным файле.
- 4D42454416 (PROFILE_EMBEDDED) — калі профіль непасрэдна ўбудоўваецца ў BMP.
У любым выпадку ў поле ProfileData адзначаецца зрушэнне профілю ў байтах ад пачатку блока BITMAPINFO.
Калі убудаваны профіль, то ў ProfileSize трэба паказаць яго памер у байтах (калі ён падключаецца, то гэта поле павінна быць абнуленае). Незалежна ад варыянту, Microsoft рэкамендуе размяшчаць профіль пры захоўванні ў файле за піксельнымі данымі, а ў аператыўнай памяці пры ўзаемадзеянні з WinAPI-функцыямі: адразу за загалоўкам[36].
Фармат ICC ў сваім загалоўку выкарыстоўвае пераважна 32-бітныя або кратныя гэтаму памеры ячэйкі[37].
Зыходзячы з гэтага, калі профіль непасрэдна ўключаецца ў BMP, то ў аператыўнай памяці яго рэкамендуецца захоўваць па кратнаму чатырох байтам адрасе.
Калі знешні профіль, то замест яго змесціва ў BMP разьмяшчаецца тэкставая радок з шляхам да файла.
Ён абавязкова павінен быць у однобайтовой кадоўцы Windows 1252 (стандартная кадоўка для заходнееўрапейскіх моў) і заканчвацца нулявым байтам.
Пра падзельнікі кампанентаў шляху ў дакументацыі нічога не сказана, і таму, хутчэй за ўсё, можна выкарыстоўваць як левыя слэшы «\», так і «правыя» «/».
Шлях жа можа быць як у адносным, так і поўным і сеткавым.
І так як ва ўказанні шляху выкарыстоўваецца однобайтовая кадоўка, то гэтую радок у аператыўнай памяці выраўноўваць не абавязкова.
Перавагі пры рэндэрынгу
Перавагі пры рэндэрынгу (англ.: rendering intentsrendering intents) былі ўведзеныя Міжнародным канцорцыумам па колеры (International Color Consortium) і вызначаюць прыярытэты ў выпадку, калі пры пераходзе з каляровага подпространство, падтрымоўванага адным прыладай (англ.: gamutgamut), у подпространство іншага, у малюнку выкарыстаны колеру, адсутныя ў мэтавым.
Таксама ёсць вызначэнне ад ICC, якое вызначаецца перавагі пры рэндэрынгу як стыль супастаўлення каляровых значэнняў з аднаго апісацеля выявы ў іншае (арыгінал на англійскай мове: «style of mapping colour values from one image description to another»)[38].
Карпарацыя Microsoft ўключыла ў фармат BMP спецыяльнае поле Intent, якое можа прымаць значэнні цалкам па спецыфікацыі ICC.
Таму за падрабязнай інфармацыі звяртайцеся да дакументацыі кансорцыума, апошнюю версію якой можна спампаваць з сайта color.org[39].
У Microsoft ж гэтыя перавагі коратка апісаны ў артыкуле «Rendering Intents» на MSDN.
Перавагу паказваецца ў поле Intent блока BITMAPINFO і даступныя толькі з 5-й версіяй інфармацыйных палёў.
Значэнні ж могуць быць наступнымі:
Microsoft для гэтай характарыстыкі абвясціла як мінімум тры набору канстант, якія адрозніваюцца сваімі значэннямі і выкарыстоўваюцца ў розных месцах[40].
Тут яны прыведзены на выпадак, калі вам трэба будзе хутка іх супаставіць.
Значэнні канстант з прэфіксам «INTENT_» цалкам супадаюць з тымі значэннямі, якія выкарыстоўваюцца ў файлах профіляў ICC[41].
Канстанты з прэфіксам «DMICM_» абвешчаныя ў файле WinGDI.h для структуры DEVMODE.
Канстанты «LCS_GM_», якія выкарыстоўваюцца ў BMP, абвешчаныя там жа і прызначаныя ў першую чаргу для структуры LOGCOLORSPACE.
Ёсць таксама назвы для уласцівасцяў друкарак. Яны аналагічныя тым, што ў калонцы «Назва Microsoft», але з «Графіка» і «Pictures».
За значэнне па змаўчанні, якое ў першую чаргу падыходзіць для фатаграфій і малюнкаў, можна прымаць 4 (LCS_GM_IMAGES).
У такой якасці рэкамендуе яго як Microsoft[42], так і ICC[43].
Remove ads
Прыклад праграмы на 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;
}
Remove ads
Гл. таксама
- ICO (фармат файлаў) — роднасны памер ад Microsoft для захоўвання значкоў і курсору мышы.
Зноскі
Літаратура
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads