Il formato "FLIC" è stato inventato da Jim Kent per l'Autodesk Animator, ed in poco tempo è
diventato praticamente uno standard per quanto riguarda le animazioni generate su PC. Nonostante oggi ci siano
formati senz'altro più evoluti ed in grado di supportare anche una colonna sonora che accompagni l'animazione,
come per esempio l'AVI di Windows o il MPEG, il formato FLIC è tutt'altro che superato.
C'è da dire che i FLIC non sono in diretta competizione con gli AVI, i MPEG o altri formati del genere,
perché questi ultimi sono stati sviluppati per trattare immagini reali digitalizzate, provenienti per lo
più da telecamera o videoregistratore, mentre i FLIC contengono di solito immagini rese direttamente su
PC con programmi di rendering o raytracing, oppure disegnate a mano.
Il grande vantaggio dei FLIC nei confronti dei formati sopra citati è senz'altro la sua semplicità.
Scrivere un player di FLIC, infatti, è tutt'altro che difficile, e magari può servire ad arricchire
la presentazione dei propri programmi. Tra l'altro questa pratica è abbastanza diffusa anche in prodotti
"commerciali", per esempio andando a guardare in mezzo ai "resource" di Ultima Underworld II
si scopre che la bellissima introduzione è appunto un FLIC.
Vediamo allora quali sono le idee alla base dei FLIC. Un'animazione fluida e plausibile richiede che lo schermo
sia aggiornato circa 25/30 volte al secondo (anche se si hanno risultati apprezzabili già con 12/15 frame
per secondo). Su PC, purtroppo, gli accessi alla memoria video sono molto lenti, anche sulle SVGA più veloci
siamo ancora molto lontani dai tempi di accesso delle normali RAM. Inoltre è la CPU che deve scrivere in
memoria video, e nel fare questo ruba spesso tempo ad altri compiti. Paradossalmente, il modo migliore per usare
una VGA è... usarla il meno possibile!
Dovendo fare i conti anche con la lunghezza del file che contiene l'animazione, non c'è quindi da stupirsi
se nei FLIC un frame (un "fotogramma") non viene quasi mai memorizzato per intero: solo le parti differenti
dal frame precedente vengono compresse e salvate nel file. Si ottiene così il duplice scopo di ridurre la
lunghezza del file e aumentare la velocità di esecuzione, minimizzando gli accessi a video.
Un file di tipo FLIC è strutturato nel modo seguente:
Header Prefix chunk Settings chunk Position chunk Frame 1 chunk Postage stamp Color data Pixel data Frame 2 chunk Color data Pixel data ... Ring frame chunk Color data Pixel data |
Come si vede, è una gerarchia di oggetti chiamati "chunk". Un chunk contiene la propria dimensione,
il proprio tipo e i dati necessari per interpretarlo. In questo modo è possibile aggiungere nuovi chunk
ed estendere il formato senza che programmi già esistenti ne risentano, perché questi ultimi semplicemente
ignorano i chunk che non conoscono.
Andiamo ora ad analizzare come è organizzato l'header ed i vari tipi di chunk.
L'header principale si trova naturalmente all'inizio del file ed è lungo 128 byte. La sua struttura e' riportata
in figura 1.2: dato che quest'ultima è differente per i .FLI ed i .FLC, la cosa migliore da fare nel caso
si incontri un .FLI è modificarne l'header rendendolo compatibile con quello di un file .FLC.
Offset Dim. (bytes) Nome Descrizione 0 (00h) 4 size lunghezza dell'intero file 4 (04h) 2 type tipo di file 6 (06h) 2 frames numero di frame presenti 8 (08h) 2 width larghezza dell'immagine in pixel 10 (0Ah) 2 height altezza dell'immagine in pixel 12 (0Ch) 2 depth numero di bit per pixel, vale sempre 8 14 (0Eh) 2 flags flags, vale di solito 0003h 16 (10h) 4 speed intervallo di tempo tra un frame e l'altro 20 (14h) 2 reserved 22 (16h) 4 created data e ora di creazione del file 26 (1Ah) 4 creator (*) 30 (1Eh) 4 updated data e ora dell'ultima modifica al file 34 (22h) 4 updater (*) 38 (26h) 2 aspectx (**) 40 (28h) 2 aspecty (**) 42 (2Ah) 38 reserved 80 (50h) 4 oframe1 offset del primo frame 84 (54h) 4 oframe2 offset del secondo frame 88 (58h) 40 reserved |
(*) I campi "creator" e "updater" vengono riempiti da Animator Pro con il numero di serie
del programma che ha creato il file e quello del programma che l'ha modificato per ultimo. Per i .FLC creati da
altre applicazioni questo campo contiene 0.
(**) I campi "aspectx" e "aspecty" descrivono lo schermo su cui è stato creata l'animazione.
Su quello schermo un rettangolo largo "aspectx" pixel e alto "aspecty" pixel appare quadrato.
Vediamo in dettaglio alcuni dei campi più importanti:
Type
Specifica il formato del file: AF11h per i FLI e AF12h per gli FLC. Nel caso dei FLI, i campi dell'header dall'offset
20 (14h) in poi non hanno significato.
Frames
Il numero di frame presenti. In effetti il file contiene un ulteriore frame, detto ring frame, che collega l'ultimo
frame con il secondo. Il ring frame è necessario perché spesso il primo frame è molto lungo
e lento da visualizzare, dato che contiene l'intera palette di colori e le informazioni necessarie a costruire
la prima schermata per intero. Dopo l'ultimo frame, quindi, invece di ritornare al primo si legge il ring frame
e si salta poi al secondo frame.
Speed
E' l'intervallo di tempo che deve trascorrere tra un frame e l'altro, cioè la velocità di riproduzione.
Nei FLI questa velocità viene espressa, chissà perché, in 70-esimi di secondo, mentre negli
FLC è in millisecondi.
OFrame1 e OFrame2
Contengono gli offset rispettivamente del primo e del secondo frame, relativi all'inizio del file (solo per gli
FLC). L'offset del primo frame è necessario perché dopo l'header si possono trovare dei dati aggiuntivi
(il prefix chunk) inseriti dal programma che ha creato l'animazione, mentre l'offset del secondo frame, da usare
insieme al ring frame, può essere calcolato a partire dall'offset del primo.
Un frame chunk contiene tutte le informazioni necessarie a visualizzare un singolo "fotogramma" dell'animazione.
La sua struttura è molto semplice:
Offset Dim. (bytes) Nome Descrizione 0 (00h) 4 length lunghezza del frame 4 (04h) 2 type tipo di frame, sempre F1FAh 6 (06h) 2 chunks numero di chunks contenuti nel frame 8 (08h) 8 reserved 16 (10h) length-16 ... dati |
In effetti la struttura descritta sopra non è altro che un "contenitore" per i dati veri e propri, che vengono memorizzati dentro ulteriori blocchi che chiameremo semplicemente chunk. Un frame può contenere uno o più chunk, ed ad ogni chunk è associata una particolare azione, come pulire lo schermo, aggiornare la palette e così via.
Un chunk è composto dal breve header descritto in figura 1.4, immediatamente seguito dai dati ad esso necessari.
Offset Dim. (bytes) Nome Descrizione 0 (00h) 4 length lunghezza del chunk 4 (04h) 2 type tipo di chunk 6 (06h) length-6 ... dati |
Ci sono diversi tipi di chunk, e se il programma che sta visualizzando un FLIC incontra un chunk di tipo sconosciuto
non deve interrompere l'esecuzione, ma "saltare" tutto il chunk, di cui conosce la lunghezza, e passare
al prossimo.
Ed ecco finalmente l'elenco dei chunk che si possono incontrare.
Type 4 (COLOR_256: palette a 256 livelli)
I dati sono organizzati in blocchi (packet). La prima word dopo l'header contiene il numero di packet nel chunk. Un packet ha la seguente struttura:
byte indice del colore da aggiornare, relativo all'indice corrente byte numero di colori da aggiornare ... 3 byte di informazione (R,G,B) per ogni colore da aggiornare
All'inizio l'indice del colore vale 0. Per ogni packet presente si aggiorna innanzitutto l'indice sommandogli
il primo byte del packet. Il numero di colori si trova nel secondo byte: il valore 0 indica che ci sono 256 colori.
Per ogni colore infine si hanno tre byte che forniscono il valore delle componenti: rosso, verde e blu rispettivamente.
Ogni componente può andare da 0 a 255, quindi bisogna dividere il valore per 4 prima di poterlo inserire
nella palette della VGA, che dispone di soli 6 bit per componente.
Type 7 (DELTA_FLC)
E' il tipo di chunk usato nei file FLC per descrivere le differenze rispetto al frame precedente, compresse con
il metodo RLE (word-oriented).
La prima word dopo l'header contiene il numero di linee da aggiornare. Ogni linea inizia con una word (control
word) il cui significato dipende dal valore dei due bit più significativi, come indicato in figura 1.5.
Bit 15 | Bit 14 | Descrizione |
0 | 0 | La word contiene il numero di packet presenti nella linea ed è subito seguita dal primo packet. Il numero di packet può essere 0 |
1 | 0 | Il byte meno significativo contiene il colore dell'ultimo pixel della linea nelle immagini con larghezza dispari. Questa word è sempre seguita da una word che contiene il numero di packet. |
1 | 1 | Questa word indica il numero di linee da saltare, pari al suo valore assoluto, ed è seguita da un'altra control word. |
Come abbiamo visto i FLIC sono strutturati in modo ragionevolmente semplice, e la loro struttura permette di espandere
facilmente il formato per tenerlo al passo con i tempi, basta aggiungere nuovi tipi di chunk.
Per fornire un esempio concreto di come leggere ed interpretare un FLIC, allegati a questo articolo ci sono diversi
file: FLIP.EXE è un piccolo player di FLIC che funziona con una normale VGA in modalità 320x200 a
256 colori, e FLIP.PAS, scritto in Turbo Pascal e Assembler, è il sorgente di FLIP.EXE. Infine CFLIC.ZIP
contiene sorgenti ed eseguibile per un player di FLIC scritto in C proprio da Jim Kent.
Nota: questo articolo è stato pubblicato su SBDI (Sound Blaster Digest Italia, una rivista elettronica) ma non ricordo quando. Il file porta la data di Marzo 1994.
Copyright (c) 2005 Alessandro Scotti. All rights reserved.
Home :: Computer Programming |