GIF

GIF je skratka od Graphics Interchange Format a je výtvorom firmy Compuserve Inc. Compuserve dovoľuje neobmedzené použitie tohto formátu s podmienkou, že ich uvediete ako autora formátu. Na druhej strane, kompresia použitá v tomto formáte (LZW), už bola predmetom niekoľkých súdnych sporov. Čítanie a uchovávanie grafických súborov komprimovaných LZW algoritmom je povolené, ale na druhej strane tvorba softvéru, ktorý vie zapisovať pomocou LZW kompresie, je nelegálna.

Organizácia súboru

Formát GIF sa veľmi líši od bežných bitmapových formátov. Skladá sa zo série dátových blokov a subblokov. Tento formát je schopný uchovávať dáta s bitovou hĺbkou od 1 do 8 bitov. Tiež je schopný ukladať viacej obrázkov naraz.

Existujú dve verzie tohto formátu. Pôvodná verzia má označenie 87a, neskoršia verzia 89a. V novšej verzii bola pridaná schopnosť hlavne ukladať text a grafiku v jenom súbore.

GIF87a

Táto verzia, ako hovorí jej názov, bola vytvorená v roku 1987. Každý súbor začína vždy hlavičkou a popisom logickej obrazovky. Za ním môže nasledovať globálna tabuľka farieb.

Hlavička

Hlavička je dlhá vždy šesť bajtov a slúži iba na identifikovaniu súbora. Popis logicikej obrazovky sa dá označiť za druhú hlavičku.

typedef struct _GifHeader {
	// Header				
	BYTE[3]	Signature;			/* označenie, vždy ("GIF") */
	BYTE[3]	Version;        	/* verzia, ("87a", alebo "89a") */
	// screen descriptor (popis logickej obrazovky)
	WORD	ScreenWidth;    	/* šírka obrázka v bodoch */
	WORD	ScreenHeight;   	/* výška obrázka v bodoch */
	BYTE	Packed;    			/* informácia o obrazovej a farebnej mape */
	BYTE	BackGroundColor;	/* index farby pozadia */
	BYTE	AspectRatio;		/* pomer strán obrázka */
} GIFHEAD;	
			
Signature
je tri bajty dlhá a obsahuje znaky GIF. Týmito znakmi sú označené všetky súbory tohto typu.
Version
je tiež tri bajty dlhá a obsahuje verziu GIFu. Ako bolo spomenuté, v súčastnosti existujú dve rôzne verzie a to 87a a 89a

Popis logickej obrazovky

ScreenWidth, ScreenHeight
obsahujú minimálnu veľkosť obrazovky, pri ktorej je možné zobraziť celý obrázok.
Packed
obsahuje štyri subpolia
Tabuľka: Popis položiek poľa PACKED v logickej obrazovke
BitPopis
0-1veľkosť globálnej tabuľky farieb
3návestie triedenie farieb
4-6farebná rozlišovacia schopnosť
7návestie globálnej tabuľky farieb
Veľkosť globálnej tabuľky farieb má vždy správnu veľkosť a to aj vtedy, keď žiadna tabuľka nenásleduje. Ak je návestie triedenie farieb nastanené na 1, potom sú farby v globálnej tabuľke farieb utriedené od najdôležitejšej k najmenej. Počet bitov pôvodnej farebnej palety je hodnota uložená vo farebnej rozlišovacej schopnosti zvýšenej o jedna. Ak sa v súbore nachádza globálna paleta farieb, potom návestie globálnej tabuľky farieb je nastavené na 1, inak je tam 0. Globálna tabuľka farieb, ak sa v súbore nachádza, vždy následuje za popisom logickej obrazovky.
BackgroundColor
obsahuje index hodnoty v globálnej tabuľke farieb pre vyfabenie rámiku a pozadia obrázka.
AspecRatio
obsahje pomer strán obrázka. Ak sa tu nachádza 0, pomer je nedefinovaný.

Globálna tabuľka farieb

Je to séria trojbajtových čísiel, kde každá trojica obsahuje hodnotu červenej, zelenej a modrej zložky pre danú farbu.

typedef struct _GifColorTable {
	BYTE	Red;	/* červená zložka farby */
	BYTE	Green;	/* selená zložka farby	*/
	BYTE	Blue;	/* modrá zložka farby */
} GIFCOLORTABLE;
			
Počet položiek v globálnej palete je vždy mocninou čísla 2. Maximálne číslo je 256 a jeho veľkosť v bajtoch sa dá zistiť následujúcim výpočtom: velkost_tabulky = 3 * (1L << (velkost_globalnej_tabulky_farieb + 1))

Ak sa v súubore táto tabuľka nenachádza, potom má každý obrazok svoju lokálnu tabuľku farieb, ktorú používa namiesto globálnej.

Lokálny popis obrázku

typedef struct _GifImageDescriptor {
	BYTE	Separator;	/* Indetifikátor */
	WORD	Left;		/* súradnica X obrázku na obrazovke */
	WORD	Top;		/* súradnica Y obrázku na obrazovke	*/
	WORD	Height;		/* šírka obrázku v bodoch */
	WORD	Width;		/* výška obrázku v bodoch */
	BYTE	Packed;		/* inromácia o obrazovej a farebnej mape */
} GIFIMGDESC;
			
Separator
obsahuje hodnotu 2Ch, ktorousa signalizuje začiatok bloku.
Left, Top
sú súradnice ľavého horného rohu bodu obázku v bodoch na logickej obrazovke.
Width, Height
označujú veľkosť obrázka v bodoch.
Packed
Tabuľka: Popis položky PACKED v lokálnom obrázku
BitPopis
0lokálna tabuľka farieb
1prekladané (interlaced) dáta
2triedenie farieb
3-4vyhradené
5-7veľkosť lokálnej tabuľky farieb
Všetky položky majú rovnaký význam ako pri logickej obrazovke. Význam prekladaných dát bude vysvetlený v ďalšej sekcii. Položka lokálna tabuľka farieb indikuje prítomnosť lokálnaje palety pre lokálny obrázok. Ak je táto hodnota nulová, je nulová aj hodnota v poli veľkosť lokálnej tabuľky farieb.

Lokálna tabuľka farieb

Platí pre ňu to isté ako pre globálnu tabuľku farieb. Následuje hneď za popisom lokálneho obrázku. Na výpočet jej veľkosti sa používa veľkosť lokánej tabuľky farieb.

Obrazové dáta

Súbory GIF sa nedajú veľmi komprimovať pomocou archivačných programov ako ZIP, RAR. Dôvodom je v metóde uloženia obrazových dát, ktoré sú komprimované pomocou kompresie LZW.

GIF ukladá svoje dáta ako sériu subblokov. Každý dátový subblok začína počítadlom, ktorého hodnota je v rozmedzí od 1-255 a indikuje počet dátových bajtov v subbloku. Za počitadlom následujú dátové toky, ktoré sú ukončené hodnotou 0. Každý subblok musí byť čítaný osobitne a posielaný dekóderu. Tiež sa tu nesleduje, kde končia, prípadne začínajú skanovacie riadky, tazkže sa môže stať, že prechod na nový riadok nastane niekde uprosted bloku.

Samotný formát dekódovaných dát je pomerne jednoduchý. Každý bod v dekódovanom skanovacom riadku je index do globálnej alebo lokálnej palety.

Skanovacie riadky sú obvykle ukladané za sebou, začínajúc prvým riadkom a končiac posledným. Formát GIF podporuje však aj prekladanú (interlaced) metódu. Použitá prekladaná metóda je štvorprechodová. Prvý prechod začína na riadku 0 a kóduje každý ôsmi riadok. Druhý začina na štvrtom riadku a tiež kóduje každý ôsmi riadok. Posledné dva prechody kódujú každý druhý riadok a začínajú na druhom a prvom riadku. Ak teda máme 16 skanovacích riadkov, potom ich budeme v prekladanom režime dekódovať v poradí: 0,8,4,12,2,6,10,14,1,3,5,7,9,11,13,15.

Trailer

Trailer je jediný bajt dát, ktorý je uložený ako posledný znak v súbore. Jeho hodnota je 3Bh. Musí byť v každom súbore.

GIF89a

Táto verzia bola zverejnen8 roku 1989. Formát je veľmi podobný formátu GIF87a. Obsahuje naviac niekoľko nových rozširujúcich blokov.

Blok rozšírenia grafiky

Informácie, ktorá tento blok obsahuje, slúžia na modifikáciu dát vykresľovacieho bloku, ktorý za ním bezprostredne nasleduje. Môže modifikovať bitmapu aj textové pole.

typedef struct _GifGraphicsControlExtension {
	BYTE	Identifier;	/* identifikátor, vždy 21h */
	BYTE	Label;		/* názov tohto rozšírenia, vždy F9h */
	BYTE	BlockSize;	/* veľkosť ostatných polí, vždy 04h */
	BYTE	Packed;		/* metóda, pomocou ktorej sa bude pracovať s grafikou */
	WORD	DelayTime;	/* pauza v desatinách sekundy */
	BYTE	ColorIndex;	/* index prehľadnosti farby */
	BYTE	Terminator;	/* terminátor bloku, vždy 0 */
} GIFGRAPHICSCONTROL
			
Identifier
obsahuje hodnotu 21h a iba identifikuje začiatok tohto rozšírenia.
Label
má hodnotu F9h a identifikuje tento blok rozšírenia.
BlockSize
obsahuje počet bajtov ďalších polí, teda polí Packed, DelayTime a ColorIndex
Packed
Tabuľka: Popis položky PACKED v bloku rozšírenia grafiky
BitPopis
0priehľadná farba
1užívateľov vstup
2-4manipulácia s grafikou
5-7rezervované
Ak je nastavená priehľadná farba na 1, potom položka ColorIndex obsahuje index farby do palety, ktorá je priehľadná. Ak je hodnota pri užívateľom vstupe, má sa proces zastaviť a čakať na užívateľov vstup (klávesnica, myš). Manipulácia s grafikou určuje, čo sa stane s obrazovými dátami po ich zobrazení. Môže nadobúdať hodnoty 00h (metóda nie je špecifikovaná), 01h (nechať dáta nezmenené) ,02h (prepísať ich farbou pozadia) a 04h (prepísať ich predchádzajúcimi dátami).
DelayTime
určuje v desatinách sekundy čas, za ktorý má prezentácia pokračovať. Pokiaľ je očakávaný aj užívateľov vstup, potom sa v prezentácii pokračuje, keď nastane jedna zo situácii (vyprší čas, alebo užívateľ zadá vstup).
ColorIndex
obsahuje index farby v palete, ktorá sa má zobrazovať ako priehľadná.
Terminator
označuje koniec tohto bloku. Jeho hodnota je 0.

Blok rozšírenia štandardného text

Verzia GIF89a môže vďaka tomuto bloku uchovávať okrem bitmapových dát aj textovú informáciu. Táto je potom ako grafika zobrazená na obrazovke.

Takýchto blokov môže byť v súbore neobmedzene veľa. Každý takýto blok má definovaný raster s jeho príslušnými údajmi (výška , šírka a umiestnenie). Tiež je popísaná veľkosť jednej bunky tohto rastra. V každej bunke môže byť iba jeden znak.

typedef struct _GifPlainTextExtension {
	BYTE	Identifier; 	/* identifikátor, vždy 21h */
	BYTE    Label;      	/* názov tohto rozšírenia, vždy 01h */
	BYTE 	BlockSize;	/* veľkosť bloku rozšírenia	*/
	WORD	TextGridLeft;	/* X-ová pozícia textového rámčeka v bodoch	*/
	WORD	TextGridTop;	/* Y-ová pozícia textového rámčeka v bodoch	*/
	WORD	TextGridWidth;	/* šírka textového rámčeka bodoch	*/
	WORD	TextGridHeight;	/* výška textového rámčeka v bodoch	*/
	BYTE	CelWidth;	/* šírka pola v bodoch	*/
	BYTE	CelHeight;	/* výška pola v bodoch	*/
	BYTE	TextFgColor;	/* farba textu (index)	*/
	BYTE	TextBgColor;	/* farba pozadia (index) */
	BYTE	*PlainTextData;	/* vlastný ASCII text */
	BYTE	Terminator;	/* terminátor bloku, vždy 0	*/
} GIFPLAINTEXT
			
Identifier
obsahuje hodnotu 21h a iba identifikuje začiatok tohto rozšírenia.
Label
má hodnotu 01h a identifikuje tento blok rozšírenia.
BlockSize
obsahuje hodnotu 0Ch, čo je počet bajtov ďalších polí.
TextGridLeft, TextGridTop, TextGridWidth, TextGridHeight
definujú umiestnenie textového rámčeka vzhľadom na logickú obrazovku ,teda súradnice 0,0, ktorá sa nachádza vľavo hore.
CelWidth, CelHeight
veľkosť jednej bunky, do ktorej sa má znak nakresliť.
TextFgColor, TextBgColor
obsahujú index farby do globálnej tabuľky farieb, ktorý určuje farbu textu, prípadne farbu pozadia.
PlainTextData
obsahuje vlastnú textovú informáciu, ktorá má byť vykreslená ako grafika. Pole obsahuje jeden alebo viacej subblokov. Každý subblok začína bajtom, ktorý určuje jeho dĺžku, teda počet znakov. Počet dátových subblokov v tomto poli je neobmedzený.
Terminator
označuje koniec tohto bloku. Jeho hodnota je 0. Táto hodnota sa dá tiež chápať ako začiatok subbloku s dĺžkou 0.

Blok rozšírenia pre aplikáciu

typedef struct _GifApplicationExtension {
	BYTE	Identifier;			/* identifikátor, vždy 21h */
	BYTE 	Label;				/* názov tohto rozšírenia, vždy FFh */
	BYTE	BlockSize;			/* veľkosť bloku rozšírenia, vždy 0Bh */
	CHAR	IdApplication[8];	/* identifikátor aplikácie	*/	
	BYTE	AuthentCode[3];		/* oprávňovací kód aplikácie */
	BYTE	*ApplicationData;	/* pointer na subbloky príslušných dát	*/
	BYTE	Terminator;			/* terminátor bloku, vždy 0	*/
} GIFAPPLICATION;
			
Toto rozšírenie nebudem vôbec vysvetľovať, pretože nie je nevyhnutné pre zobrazovanie dát. Pre možnosť dekódovanie tohto bloku len spomenie, že pole ApplicationData má rovnakú štruktúru ako pole PlainTextData v textovom rozšírení.

Blok rozšírenia komentára

Do tohto bloku sa dajú ukladať ľudsky čitateľné texty maximálnej dĺžky 255 znakov. Takýchto blokov sa môže v súbore vyskytovať neobmedzene veľa. Tieto dáta nie sú určené pre zobrazovanie, ale iba pre človeka, ktorý skúma daný súbor.

typedef struct _GifCommentExtension {
	BYTE	Indetifier;		/* identifikátor, vždy 21h */
	BYTE	Label;			/* názov tohto rozšírenia, vždy FEh */
	BYTE	*CommentData;	/* pointer na subbloky komentových dát	*/
	BYTE	Terminator;		/* terminátor, vždy 0 */
}