Grafické formáty ve znamení Unixu

30. 11. 2006
Doba čtení: 12 minut

Sdílet

Dnešní část seriálu o grafických formátech je věnována čtveřici velmi jednoduchých rastrových formátů, které mají svůj původ na Unixových systémech. Jedná se o formáty PBM, PGM, PPM a PAM. V současnosti se s těmito formáty můžeme setkat v mnoha aplikacích, ve kterých slouží jako prostředek pro úschovu rastrových obrázků.

Obsah

1. Úvodní informace o rastrových formátech P[BGPA]M
2. PBM – Portable Bitmap File Format (textová verze)
3. PBM – Portable Bitmap File Format (binární verze)
4. PGM – Portable GrayMap File Format (textová verze)
5. PGM – Portable GrayMap File Format (binární verze)
6. PPM – Portable PixelMap File Format (textová verze)
7. PPM – Portable PixelMap File Format (binární verze)
8. PAM – Portable Arbitrary Map
9. Obsah dalšího pokračování tohoto seriálu

1. Úvodní informace o rastrových formátech P[BGPA]M

Rastrové grafické formáty PBM, PGM, PPM a PAM se od všech dříve popisovaných formátů odlišují v jedné podstatné vlastnosti – vznikly na Unixových systémech a ne pro potřeby ukládání obrázků na počítačích řady PC (dnes jsou tyto formáty samozřejmě používány i na dalších platformách). Unixový původ je na těchto formátech znát, zejména jejich téměř absolutní nezávislost na použitých hardwarových prostředcích (nenastávají například prakticky žádné problémy s little vs. big endian, zejména u textových verzí formátů), přítomnost magického čísla (jednoznačné identifikace formátu) na začátku souboru, použití textových hlaviček, dostupnost dokumentace ve formě manuálových stránek apod.

Není také použita žádná metoda komprimace rastrových dat, protože na tuto činnost jsou v unixových systémech (ale i jinde) určeny dnes již téměř standardní prostředky typu gzip, bzip, bzip2 apod., běžné bývalo i použití starodávného filtru compress (ten byl mimochodem zatížen stejným patentem jako GIF), takže samotné grafické formáty nebylo nutné zbytečně komplikovat – obrázek bylo možné přes rouru zkomprimovat či naopak dekomprimovat. Popisované grafické formáty existují ve dvou variantách – textové (označované běžně jako ASCII či Plain) a binární (označovaná jako Raw). Rozdíl mezi těmito dvěma variantami (včetně předností a záporů) je zřejmý:

  1. V případě textové varianty jsou vytvářeny cca čtyřikrát větší soubory, takto uložené obrázky jsou však velmi snadno zpracovatelné i programovými prostředky, které jsou primárně určeny pro zpracování textových souborů (mezi tyto prostředky patří například sh, awk, sed, Perl a Tcl). I vytváření textové varianty je v některých případech jednodušší, mnohdy postačuje přesměrování standardního výstupu aplikace do souboru s následným přidáním hlavičky. Vytvořené textové soubory jsou bez problémů přenositelné téměř jakýmkoli protokolem (včetně sedmibitových e-mailů bez nutnosti použití base-64, apod). Délka řádku je stanovena na maximálně 70 znaků, což dovoluje zpracování jakýmkoli textovým editorem.
  2. Binární varianta těchto grafických formátů (raw) přináší dvě přednosti: menší velikost souboru v porovnání s variantou textovou a snadné načtení rastrového obrázku (uloženého za hlavičkou) pomocí jednoho příkazu, například funkce fread() ze standardní céčkové knihovny. Samotný zápis obrázku je dokonce jednodušší než zápis souboru typu TGA (jde také o soubor s velmi jednoduchou strukturou), a to zejména z toho důvodu, že není potřeba brát ohled na endianitu dané architektury ani zarovnání datových struktur; obojí nám odstíní céčkovská knihovna. Pro čtení či zápis hlavičky je možné použít funkce typu scanf() a printf().

Nyní mi zbývá vysvětlit, proč se jedná o čtyři formáty a ne o formát jediný. Důvod je pochopitelný – již z koncovky souboru s rastrovým obrázkem (v případě PBM, PGM a PPM) je možné poznat, jakou bitovou hloubku a tím i maximální počet barev má daný obrázek. Také samotná hlavička obrázku i jeho interní struktura může být mnohem jednodušší. Poslední ze čtveřice, tj. formát PAM, se v tomto ohledu poněkud odlišuje, protože se jedná o ideového následníka PBM, PGM a PPM, který do jedné struktury souboru integruje mnoho různých formátů pixelů. V následující tabulce jsou sepsány názvy všech dnes popisovaných formátů, včetně bitové hloubky obrázků (bpp – bits per pixel). Z bitové hloubky je možné odvodit i maximální počet barev zobrazitelných v jednom obrázku.

Koncovka souboru Typ Bpp Počet barev
PBM Portable Bitmap File Format 1 2 (černá a bílá)
PGM Portable GrayMap File Format 8 256 odstínů šedi (základ)
16 max. 65536 odstínů šedi max.
PPM Portable PixelMap File Format 24 16777216
48 max. 2814749767106­56 max.
PAM Portable Arbitrary Map 1–24 2–16777216

Všechny čtyři formáty jsou v dokumentaci (například k ImageMagicku či Netpbm) souhrnně označované jako PNM. V tomto případě se však nejedná o žádný konkrétní formát, pouze o zkrácený výpis všech zkratek. Jinými slovy, na grafický rastrový soubor s koncovkou PNM bychom měli narazit pouze v případě, že se interně jedná o PBM, PGM či PPM (to se jednoduše pozná z hlavičky, ve které je uloženo magické číslo). Vzhledem ke zmatkům ohledně PNM jsem si proto dovolil v názvu této kapitoly použít regulární výraz.

2. PBM – Portable Bitmap File Format (textová verze)

Náš popis Unixových rastrových grafických formátů začneme tím nejjednodušším. Jedná se o formát PBM, což je zkratka sousloví Portable Bitmap File Format. Do tohoto grafického formátu je možné ukládat pouze černo-bílé obrázky (takzvané pérovky), které obsahují pouze zcela černé a čistě bílé pixely. Obrázek neobsahuje žádné informace o barvové paletě, proto není možné černou a bílou barvu žádným způsobem změnit, jak tomu bylo například u „černo-bílého“ PCX, GIFu či PNG. Jak jsme si již řekli v první kapitole, může být rastrový obrázek uložen buď v textové (ASCII) podobě, nebo v binárním tvaru. Nejprve si popíšeme textovou variantu PBM a poté variantu binární.

Textová varianta souborů typu PBM má velmi jednoduchou strukturu. Na začátku se nachází magické číslo, které je sestaveno z ASCII znaků „P1“. Za těmito znaky se nachází některý z „bílých“ znaků – konec řádku, mezera, tabulátor apod. (těchto znaků může být použito i více). Následně je v textové podobě uloženo horizontální rozlišení, tj. počet pixelů na obrazovém řádku, a po další sekvenci bílých znaků vertikální rozlišení, tj. počet obrazových řádků. Následuje poslední sekvence bílých znaků, za nimiž jsou již uložena rastrová data:

P1 (bílé znaky)
šířka (bílé znaky)
výška (bílé znaky)
rastrová data 

V souboru se mohou nacházet i řádky s poznámkou, ty začínají znakem „#“ (zde je patrná souvislost se shellem). Poznámka by se sice měla nacházet pouze před řádkem se specifikací šířky obrázku, ale viděl jsem i soubory, kde se poznámka nacházela i za tímto řádkem, proto je dobré při načítání souboru poznámky odstraňovat všude.

Formát uložení rastrových dat v textových souborech typu PBM je velmi jednoduchý, ale také neúsporný. Každý pixel je představován jednou ASCII číslicí „0“ nebo „1“, číslice jsou od sebe odděleny jedním nebo více bílými znaky. Maximální délka řádku je stanovena na 70 znaků (snadné zpracování v textových editorech, jednodušší bufferování apod.). Barvy pixelů jsou uloženy opačně, než bychom mohli očekávat: bílý pixel má hodnotu „0“, černý pixel hodnotu „1“.

Následuje ukázka začátku souboru, který obsahuje známý obrázek Lenny, u nějž bylo pomocí ditheringu dosaženo snížení barev na černou a bílou. Celková velikost souboru dosáhla 132744 bytů, přičemž rastrová data mají pouze 256×256/8=8192 bytů. Zde je patrná značná nehospodárnost, která však nemusí být na škodu v případě, že se obrázky vytváří s účelem jejich dalšího zpracování (například konverze pomocí již zmíněné utility ImageMagick a Netpbm). Na výpisu si všimněte, že konvertor – v tomto případě IrfanView– nedodržel doporučenou délku řádku:

P1
# Created by IrfanView
256 256
0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0
1 1 0 1 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1
1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 1
1 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1
# následuje dalších 1637 řádků rastrových dat 

Celý obrázek uložený v textovém formátu PBM si můžete stáhnout z tohoto odkazu.

3. PBM – Portable Bitmap File Format (binární verze)

Binární varianta souboru typu PBM se v mnohém podobá variantě textové. Hlavička souboru má stejnou strukturu, pouze se změnilo magické číslo, které je nyní zadáno dvojicí znaků „P4“ a nikoli „P1“. Za hlavičkou následují binárně uložená rastrová data, přičemž v každém bytu jsou uloženy barvy osmi pixelů. Logika kódování černé a bílé barvy zůstává zachována: bílá barva pixelu je reprezentována bitem s nulovou hodnotou a černá barva pixelu bitem s hodnotou jedničkovou (patrně díky chybě v interních funkcích však některé programy kódy barev negují). V jednom souboru typu binární PBM se může nacházet několik obrázků, není to však obvyklé a mnohé aplikace nemusí takové soubory korektně zpracovat. Formát hlavičky:

P4 (bílé znaky)
šířka (bílé znaky)
výška (bílé znaky)
rastrová data 

Obrazové řádky jsou v souboru uloženy sekvenčně za sebou, pouze se musí zaručit, aby každý obrazový řádek končil na hranici celého bytu. Prakticky to znamená pouze to, že posledních 1 až 7 bitů na každém obrazovém řádku nemusí být využito, což však délku souboru při reálném použití nijak drasticky nezvětší (maximálně o počet bytů, který odpovídá počtu obrazových řádků v rastrovém obrázku). Ukažme si příklad rastrových dat uložených v binárním PBM. Opět se jedná o ditherovaný obrázek Lenny, který má nyní velikost 8226 bytů (včetně podpisu konverzního programu). Čistá rastrová data mají velikost 8192 bytů, rozdíl (8226–8192=34 bytů) činí pouhá čtyři procenta. Pro obrázky s větším rozlišením se režie ještě více snižuje.

P4
# Created by IrfanView
256 256
# následují rastrová data, zde pro ilustraci převedena do hexadecimálního kódu
08 51 50 03 ff ff ff fe dd b6 db 56 b5 b6 b5 d5
5a d7 6d 57 da 90 92 90 51 00 0f fb 7f f5 6e f9
01 04 00 15 ff ff fe d7 6b 6d ad b5 aa db dd 6e
ed b5 bb ff e4 0a 44 2a 84 00 0f af b7 5f bb b0
... 

Pro testovací účely si můžete stáhnout binární verzi PBM obrázku Lenny.

4. PGM – Portable GrayMap File Format (textová verze)

Dalším popisovaným formátem je PGM, neboli Portable GrayMap. Jak již název tohoto formátu napovídá, je do něj možné ukládat šedobílé (grayscale) obrázky. Tyto obrázky neobsahují barvovou paletu, práce s nimi je tedy velmi jednoduchá. PGM však přináší oproti běžným monochromatickým obrázkům jedno významné rozšíření – je možné specifikovat maximální hodnotu pixelu, která je považována za čistě bílou. Také samotné hodnoty pixelů jsou ukládány jinak, než je tomu v ostatních formátech, protože je na ně aplikována gamma korekce s hodnotou γ=2.2:

P2 (bílé znaky)
šířka (bílé znaky)
výška (bílé znaky)
maximální hodnota pixelu (bílé znaky)
rastrová data 

Textová varianta souboru PGM začíná magickou sekvencí, což je dvojice znaků „P2“. Za touto sekvencí následuje jeden či více bílých znaků, šířka obrázku v pixelech, opět jeden či více bílých znaků, výška obrázku v pixelech, obligátní oddělovač a maximální hodnota intenzity pixelu. Ta musí být menší než 216=65536 (toto číslo také odpovídá celkovému počtu odstínů šedi, které je možné v obrázku použít). Většina aplikací zde ponechává hodnotu 255, pixely tedy mohou obsahovat intenzitu v rozmezí 0..255. Následují rastrová data, což jsou číselné hodnoty, které jsou od sebe oddělené bílými znaky, minimálně jednou mezerou, tabulátorem či znakem pro konec řádku.

Následuje ukázka začátku souboru obsahujícího obrázek Lenny uložený v monochromatické podobě. Celý ukázkový soubor si můžete stáhnout zde.

P2
# Created by IrfanView
256 256
255
160 160 161 162 161 161 159 157 158 158 157 155 155 154 153 154 154
156 160 163 166 169 171 173 172 168 165 161 154 145 128 110 97
# následují hodnoty dalších pixelů 

5. PGM – Portable GrayMap File Format (binární verze)

Binární varianta souborů typu PGM je do značné míry ovlivněna tím, že maximální intenzita pixelů může nabývat hodnot z rozsahu 0 až 216-1. Pokud je maximální intenzita menší než 256 (0 až 28-1), je každý pixel v binárním souboru uložený jako jeden byte, v opačném případě jsou pro hodnotu pixelu vyhrazeny dva byty. Dvoubytový formát však některé prohlížeče nedokáží korektně načíst, proto se většinou setkáme pouze s formátem jednobytovým. Hlavička binární verze PGM je podobná hlavičce textové (ASCII, plain) verze, ovšem s tím rozdílem, že magické číslo je nastaveno na hodnotu „P5“ a nikoli na „P2“. Hlavička tedy vypadá následovně:

P5 (bílé znaky)
šířka (bílé znaky)
výška (bílé znaky)
maximální hodnota pixelu (bílé znaky)
rastrová data v binárním tvaru 

Ukázka obrázku Lenny převedeného do odstínů šedi je uložena zde.

6. PPM – Portable PixelMap File Format (textová verze)

Soubory typu PPM neboli Portable PixelMap umožňují práci s obrázky v truecolor formátu používajících barvový model RGB. Zatímco většina „truecolor“ formátů pracuje s maximálním množstvím 256×256×256=1­6777216 barev, u PPM je možné použít až neuvěřitelných 65536×65536×6­5536=281474976710656 barevných odstínů (ovšem délka těchto souborů je také neuvěřitelná :-). Hlavička textové varianty formátu PPM má tvar:

P3 (bílé znaky)
šířka (bílé znaky)
výška (bílé znaky)
maximální hodnota barvové složky pixelu (bílé znaky)
rastrová data v textovém tvaru 

Barvové složky pixelů jsou uloženy s gamma faktorem nastaveným na 2,16, ovšem některé materiály zmiňují gamma faktor=2,2. Ne­korektně napsané aplikace předpokládají, že mezi intenzitou barvové složky a její hodnotou je lineární vztah, takto vzniklé obrázky však postrádají kontrast v oblasti vyšších intenzit a také se snižuje dynamika (to vadí zejména u obrázků, které jsou již původně nekvalitní, například příliš tmavé či světlé). Následuje ukázka začátku souboru s truecolor obrázkem Lenny:

P3
# Created by IrfanView
256 256
255
224 136 122 224 136 122 224 136 124 

Celková délka tohoto souboru je 728410 bytů, v paměti zabere celá pixmapa pouze 256×256×3=196608 bytů, nárůst tedy činí 370%! To je daň za použití transparentního a přenositelného obrázku.

7. PPM – Portable PixelMap File Format (binární verze)

Binární forma souborů typu PPM nepřináší nic převratného. V hlavičce se změnilo magické číslo na „P6“ (textová varianta má „P3“) a pixely jsou podle nastavené maximální hodnoty (0 až 216) uloženy buď pomocí trojice bytů RGB, nebo jako šestice RRGGBB. Celková délka souboru v případě trojice bytů na pixel (24 bpp) odpovídá nekomprimovanému TGA či BMP. V případě plnobarevného obrázku Lenny má soubor délku 196646 bytů, což je oproti čistému rastrovému obrázku (256×256×3=196608) pouze nepatrné zvýšení.

Ani při práci s binárním formátem nesmíme zapomenout na gamma faktor, který má hodnotu 2,16. Pro maximální hodnotu barvových složek do 256 (maximálně 16 milionů barev) je většinou vhodnější provádět gamma korekci pomocí vyhledávací tabulky (look-up table), pro větší maximální hodnoty však velikost tabulky narůstá a proto se používají sice pomalejší, ale paměťově zcela nenáročná konverzní funkce. Při požadavku na rychlé (a poněkud nepřesné) náhledy se také používá aproximace gamma funkce (což je exponenciála a při inverzní transformaci logaritmická funkce) dvojicí lineárních úseků.

8. PAM – Portable Arbitrary Map

Soubory typu PAM, neboli Portable Arbitrary Map nebo také Portable AnyMap nabízí rozšíření schopností původních tří unixových bitmapových formátů, tj. PBM, PGM a PPM. Zatímco původní formáty měly předepsaný formát pixelů a podle obsahu hlavičky i bitovou hloubku, je u formátu PAM situace poněkud odlišná. Jak formát pixelů, tak i význam kódování barev je možné zjistit z hlavičky. Struktura hlavičky se také změnila, protože každá její položka je zapsána i spolu se svým názvem, který je od hodnoty oddělen mezerou. Obecný formát hlavičky je následující:

P7
WIDTH šířka (bílé znaky)
HEIGHT výška (bílé znaky)
DEPTH bitová_hloubka (bílé znaky)
MAXVAL maximální hodnota pixelu (bílé znaky)
TUPLTYPE typ n-tice představující pixel (bílé znaky)
ENDHDR
rastrová data v binárním tvaru 

Význam většiny položek (WIDTH, HEIGHT, DEPTH a MAXVAL) je zřejmý. Položka ENDHDR ukončuje hlavičku, za touto položkou již následují rastrová data. Nejzajímavější je položka TUPLTYPE (nikoli TUPLETYPE, názvy totiž mohou mít maximálně osm znaků), pomocí které se předepisuje, jaký formát bude mít n-tice obsahující hodnoty jednotlivých pixelů. Je definováno několik obecně použitelných formátů n-tic; ty jsou vypsány v následující tabulce:

ict ve školství 24

Označení n-tice Význam
BLACKANDWHITE odpovídá binárnímu formátu PBM
GRAYSCALE odpovídá binárnímu formátu PGM
RGB odpovídá binárnímu formátu PPM
BLACKANDWHITE_ALPHA černo-bílé obrázky s průhledností
GRAYSCALE_ALPHA monochromatické obrázky s průhledností
RGB_ALPHA plnobarevné obrázky s průhledností

9. Obsah dalšího pokračování tohoto seriálu

V následující části tohoto seriálu se již začneme zabývat další velmi populární skupinou rastrových grafických formátů – jedná se o formáty využívající ztrátovou komprimaci, mezi něž patří například známý formát JFIF (JPEG).

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.