Knihovna pro uchování informací o animaci, která je rozdělena na navzájem nesouvisející framy. Každý frame může obsahovat několik bloků.
Knihovní funkce pro práci s formátem buran využívají strukturu TBuran
.
O datech struktury TBuran uživatel této knihovny nemusí nic vědět.
Další pomocnou strukturou je TBuran_dir
, která slouží (mimo jiné)
k předávání informací o právě načteném bloku dat:
typedef struct TBuran_dir { int typ, off, siz; }TBuran_dir;
V typ
je typ dat bloku a v siz
je velikost bloku v bytech.
Velikost typu dat v bloku není pro knihovnu
nikterak zajímavá.
Knihovna vlastně nic neví (ani nepotřebuje vědět) o typu dat v bloku.
Přesto je použita následující konvence: spodních
16 bitů typu má význam délky typu, horních 16 je pak již rozlišovacích.
TBuran* buran_open(char *path, char *mode)
vytvoří strukturu TBuran
. Argumenty path
a mode
jsou
obdobně jako ve fopen(3)
. Tedy path
je jméno otevíraného souboru,
mode
je jedno z "rb"
pro čtení, nebo "wb"
pro zápis.
TBuran* buran_open_by_file(FILE *f)
obdoba s tím rozdílem, že soubor f
je již otevřen v příslušném módu.
int buran_seek(TBuran *bur, int offset, int mode)
posun po buranu bur
, offset je v závislosti na mode
buď od
začátku (SEEK_SET
), nebo relativně k současné pozici (SEEK_CUR
).
TBuran_dir *buran_read(TBuran *bur, int typ, int nty)
načtení nty
'ého bloku typu typ
. Pokud bude typ==0
,
jde o nty
blok bez ohledu na typ.
V případě neúspěchu je vrácená hodnota NULL
.
Při úspěchu ukazuje na TBuran_dir
, ve které
jsou obsaženy informace o načteném bloku.
unsigned char *buran_buff(bur);
vrátí ukazatel na buffer s místem, kde jsou data bloku. Je nutné si jej přetypovat.
TBuran_dir *dir; float *points; /* chci všechny bloky s body (POINT)*/ for(i=0; NULL != (dir = buran_read(bur, BUR_TYP_POINT, i); i++) { points = (float*)buran_buff(bur); ... dělej něco s polem `points' }
int buran_write(TBuran *bur, int bur_typ, int siz, void * buff)
Zapíše blok typu bur_typ
, na který ukazuje buff
velikosti (v bytech ) siz
.
int buran_write_init(TBuran *bur, int bur_typ)
Připraví burana pro postupný zápis bloku typu typ
. Ekvivalentní
buran_write(bur, bur_typ, 0, 0);
int buran_write_add(TBuran *b, int siz, void *buff)
Přidání dat k posledně zapsanému bloku dat. Velikost dat je siz
a nacházejí se na buff
.
int buran_flush(TBuran *b)
Konec zadávání tohoto framu. Je potřeba zavolat po ukončení sypání dat do jednoho framu.
int buran_printf(TBuran *bur, char *format, ...)
Zapiš logovací hlášku (typ BUR_TYP_LOG
). Argumenty format
a ...
jsou stejné jako u printf(3)
.
Příklad ukazuje, jak je možné uložit 10 framů, v každém jsou dva bloky(logovací hláška a blok pět bodů):
TBuran *bur = buran_open("look.bur", "wb"); float point[3] = { 1, 0 , 0}; /* deset obrázků */ for(int frame = 0; frame < 10; frame++) { /* v každém pět bodů */ buran_init(bur, BUR_TYP_POINT); for(i = 5; i--;) { /* přidej jeden bod */ buran_add(bur, sizeof(float)* 3, point); point[2] += 0.5; /* ``výpočet'' bodu */ } /* zapiš poznámku k tomu framu */ buran_printf(bur, "Poznámka k framu %i\n", frame); /* ukonči zadávání tohoto framu */ buran_flush(bur); }
Podrobný popis formátu buran
Celý soubor je rozdělen na framy. Fram má následující struktru: nejprve je hlavička framu. Ta je dlouhá 3 inty. V prvním je tzv magické číslo (hodnota pro kontrolu, zda nejde o porušenou strukturu souboru). Následuje offset následujícího a předcházejícího framu.
Následuje adresář bloků ve framu. Každá položka se skládá opět ze tří intů. První je typ bloku. Druhý je offset začátku dat odpovídajícího bloku. Offset se počítá od konce adresáře. A konečně třetí položka je délka bloku dat.
Pokud jsou všechny položky nulové, jde o poslední položku adresáře.
Následují data framu.
Knihovna nepomýšlí na korekci různých typu endianit (byte-orderů).
Proto soubor není přenositelný mezi platformami různých endianů. Jinými
slovy: číst data můžeme jen na endiánech na kterých tato data vznikala.
Taktéž zřejmě budou problémy s přenosem souboru mezi platformami s
různými hodnotami sizeof(int)
.