前言:本站為你精心整理了FLIC動畫文件播放程序設計范文,希望能為你的創作提供參考價值,我們的客服老師可以幫助你提供個性化的參考范文,歡迎咨詢。
Autodesk公司的三維動畫設計軟件3DS在我國已廣泛使用,其良好的性能為計算機專家和藝術家所肯定。其動畫存儲文件flic也給系統提供了存儲和顯示的方便。下面具體分析FLIC文件的格式及播放程序的設計。
一、FLIC文件格式的概述
FLIC文件事實上是對一個靜止畫面序列的描述,連續顯示這一序列便可在上產生動畫效果。FLIC文件結構簡潔,彈出速度快,雖然每種基色最多只有256級灰度,圖像深度只有8位,但使用起來很方便。
FLIC文件有兩種類型:FLI文件和FLC文件。FLC文是FLI文件的進一步發展,它采用更高效的壓縮技術,且其分辨率也不僅限于320×200。我們在PC上經常使用的FLI文件,因為它和VGA的320×200×256顯示相匹配。
FLIC文件采取的壓縮技術原理就是僅保存前一幀中改變的部分。這樣占的空間小,彈出速度快。FLIC文件的結果可分為3個層次:文件層、幀層和塊層。文件層給出了FLIC文件的基本特征。幀層定義了幀的緩沖和塊中塊的數目。塊層包括塊的大小、類型和實際數據。這樣的層次結構很容易實現,特別是可以增加塊的類型以滿足新的需要,同時無需涉及原定義。
二、各層頭的結構
1.FLI文件格式的結構定義
①文件頭的結構定義
文件頭長度為80H字節,其C語言結構定義如下
/*flifilehedaerstruct*/
typedefstruct{
unsignedlongfli-size;/*00H:文件總長度*/
unsignedintmagic;/*04H:文件格式,FLC=AF12;
FLI=AF11;*/
unsignedintframes-number;/*06H:FLIC的幀數*/
unsignedintscreen-width;/*08H:屏幕寬度*/
unsignedintscreen-height;/*0AH:屏幕高度*/
unsignedintunuserd;/*0CH:保留未用*/
unsignedintflags;/*0EH:標志=0003*/
unsignedintspeed;/*10H:幀間播放速度單位*/
unsignedlongnext;/*12H:置為0*/
unsignedlongfrit;/*16H:置為0*/
unsignedcharfli-expand[102];/*1AH:保留作擴展用=0*/
}FLIHEAD;
②幀頭的結構定義
幀頭長度為10H字節,其C語言結構定義如下:
/*framesheaderstruct*/
typedefstruct{
unsignedlongsize-frame;/*00H:幀大小,包括本幀頭*/
unsignedintmagic;/*04H:幀標識字=0F1FAH*/
unsignedintchunks;/*06H:本幀塊數*/
unsignedcharexpand[8];/*08H:保留未用=0*/
}FRAMESHEAD;
③塊頭的結構定義
塊頭長度為6H字節,其C語言結構定義如下:
/*chunkheaderstruct*/
typedefstruct{
unsignedlongsize-chunk;/*00H:塊大小*/
unsignedtype-chunk;/*04H:塊類型*/
}CHUNKHEAD;
2.FLC文件格式的結構定義
文件頭長度為80H字節,其C語言結構定義如下:
/*flifileheaderstruct*/
typedefstruct{
unsignedlongfli-size;/*00H:文件總長度*/
unsignedintmagic;/*04H:文件格式,FLC=AF12;
FLI=AF11;*/
unsignedintframes-number;/*06H:FLIC的幀數*/
unsignedintscreen-width;/*08H:屏幕寬度*/
unsignedintscreen-height;/*0AH:屏幕高度*/
unsignedintdepth;/*0CH:圖像深度*/
unsignedintflags;/*0EH:標志=0003*/
unsignedintspeed;/*10H:幀間播放速度單位
FLC=1ms,FLI=1/70s*/
unsignedintreserved-1;/*14H:保留未用*/
unsignedlongcreatetime;
unsignedlongcreator;
unsignedlongupdatetime;
unsignedlongupdater;
unsignedintaspectx;/*創建文件時的顯示屏幕像素大小的縱橫比,VGA320×200
unsignedintaspecty;為6∶5*/
unsignedcharreserved-2[0x26];/*保留未用,=0*/
unsignedlongoffsetframel;/*50H:第一幀畫面相對于文件
開始的偏移*/
unsignedlongoffsetframe2;/*54H:第二幀畫面相對于文件
開始的偏移*/
unsignedcharreserved-3[0x28];/*保留未用=0*/
}FLIHEAD;
FLC的幀頭和塊頭的結構定義和FLI文件格式的定義相同。
每塊的數據緊接在FLIC文件頭的后面。對于不同的塊類型有不同的數據含義,下面就不同的塊類型分別介紹,這是設計播放FLIC動畫文件程序的關鍵之所在。
三、塊類型的含義
FLIC格式文件中的塊類型有許多種,每一種類型都有不同的定義,因此我們必須對每一種類型作出準確的分析。由于動畫格式FLIC圖像文件的塊類型具有極強的可擴展性,在此我們只介紹幾種常見的塊類型。
1.類型04H
為每基色256級灰度的彩色調色板信息表FLIC-COLOR,其第一個字為需調色的調色子塊數(一個字),緊接其后的是需調色的相應各塊的數據定義:
字節含義
第一字節:跳色數,在本塊中的需要跳過的顏色數(字節)。
第二字節:調色數,本塊中有多少種顏色需要改變,當調色數為0時指調256色。初始時當前色號為零。
其后的字節:以三字節為一組,是需要改調色的相應的RGB值。
通常FLIC圖像文件的頭一幀的第一塊數據便是該類型(或0BH類塊)。在程序設計中我們定義了一個256色的調色板數組:
charpalette[768];
用于完成調色板的初始化工作。
2.類型07H
該類型數據以字節為基礎,只適用于.FLC文件,處理對第一幀圖像的改變情況較為適用。它含有本幀圖像對于上與幀圖像的改變部分。
這種塊類型是一種最常用的、最復雜的塊類型,一般除了第一幀外后面的各幀通常采用這種塊類型進行行數據壓縮存儲。它的描述如下:
字節含義
(1)第一個字:需要改變的行的數量
(2)第二個字開始:是具體需要改變的數據本身。每一行是進行單獨的壓縮的,這種技術的采用大大壓縮了.FLC文件長度。它的具體定義為:可選字、小塊數及小塊的值。①可選字:
當高位=11時,低位部分為跳行數。該字可以有多個,其跳行數相加。當高位=10時,低位部分內容為當前行的最后一個字節。(作為本行的結束標志)。②小塊數:當高位=00時,此字表示小塊數的值。③小塊:第一個字節:跳列數。第二個字節:小塊類型:當該值為正時:表示要從塊中搬到圖像中的像素(字)個數N,其后就是N個連續的像素數據;當該值為負時:它的絕對值N表示要重復從塊中搬到圖像中的像素(字)的次數,其后就是那個像素的數據
。第三個字節:塊中的圖像數據(字)。
3.類型0BH
與類型04H類似,它與VGA的13H模式相匹配。
4.類型0CH
與類型07H類似,但它以字節為基礎,通常用于.FLI文件
字節含義
(1)第一個字:從屏幕上方開始和上一幀相同的行數即本幀中第一行要改變的行號。例如:如果有一個改變(運動)僅僅只是在屏幕的底部,那么此時該字值為199(VGA320×200)。
(2)第二個字:需要改變的行的數量。
(3)第三個字以后:是具體需要改變的數據本身。每一行是進行單獨的壓縮的,這種技術的采用大大壓縮了.FIC文件長度。它的具體定義為:小塊數及塊的值。
①小塊數:此字表示小塊的個數值,它是本行中含有小塊的個數。當小塊數=0時,說明本行和上一行相同,不用進行重新處理。
②小塊:第一個字節:跳列數。第二個字節:小塊類型:當該值為正時:表示要從塊中搬到圖像中的像素(字節)個數N,其后就是N個連續的像素數據;當該值為負時:它的絕對值N表示要重復從塊中搬到圖像中的像素(字節)的次數,其后就是那個像素的數據。第三個字節:
塊中的圖像數據。
5.類型0DH
該類型沒有數據,該幀的所有像素值都為0。在實際應用中通常它只產生在當用戶使用3DS創建一個新的FLIC文件中的第一幀。
6.類型0FH
該類型用于壓縮圖像,通常只用于第一幀。它采用了Run-Length壓縮方法。該方法與類型07H及0CH中的行數據壓縮方法是相似的。只是在該方法中正負號的定義與類型07H和0CH恰好相反。
字節含義
(1)第一字節本行中小塊數。
(2)第二字節小塊的具體內容。
①第一字節:小塊類型:當該值為負時:它的絕對值表示要搬到圖像中的像素(字節)個數,其后就是數據;當該值為正時,表示要將下一個像素復制到圖像中的次數,該像素(字節)緊隨其后。
②第二個字節:塊中的圖像數據。
7.類型10H
這種類型不進行壓縮,塊中的數據個數一定為圖像的長寬相乘。這種類型在實際應用中一般不用。
下面具體討論播放程序的C語言程序設計方法,本文中的程序是針對.FLI格式的動畫文件而進行的程序設計。讀者如果要播放.FIC格式的動畫文件,只需根據.FIC文件格式的具體定義,并參照下面的程序設計方法即可設計出相應的程序。
四、程序設計
1.第一幀圖像的播放程序
voidFirst-Frame(Video-Mem,fli-fp)
char*Video-Mem;
FILE*fli-fp;
{
intLine-PacketNumber
intSize-Count=0
intScreen-Char;
longSereen-Count=0L;
memset(Video-Mem,0,60000);
do{
Line-PacketNumber=fgetc(fli-fp);
while(Line-PacketNumber--)
{
Size-Count=fgetc(fli-fp);
if((Size-COUNT&0X80)==0X80
{
Size-Count=(256-Size-Count);
while(Size-Count--)
{
Screen-Count++;
Sereen-Char=fgete(fli-fp);
*Video-Mem++=Screen-Char;
}
}
else
{
Sereen-Char=fgete(fli-fp);
while(Size-Count--
{
Screen-Count++;
*Video-Mem++=Sereen-Char;
}
}
}
}while(Screen-Count<64000);
}
2.FLI后續各幀圖像的播放程序
voidOther-Frame(Video-Mem,Fli-fp,Update-LineNumber)
char*Video-Mem;
FILE*Fli-fp;
intUpdate-LineNumber;
{
intSize-Count=0,Skip-Col=0;
intUpdate-LineCount=0;
intScreen-Char;
intNumber-Packet;
char*Video-p;
while(Update-LineCount<Update-LineNumber)
{
Video-p=Video-Mem;
Number-Packet=fgetc(Fli-fp)
Update-LineCount++;
while(Number-Packet--)
{
Skip-Col=fgete(Fli-fp);
Video-Mem=Video-Mem+Skip-Col;
Size-Count=fgetc(Fli-fp);
if((Size-Count&0x80)==0x80)
{
Size-Count=256-Size-Count;
Screen-Char=fgetc(Fli-fp);
while(Size-Count--)*Video-Mem++=Sereen-Char;
}
else
{
while(Size-Count--){
Screen-Char=fgetc(Fli-fp);
*Video-Mem++=Screen-Char;
}
}
}
Video-Mem=Video-p+320;
}
}
3.播放程序的調用及其它幾個子程序
voidTransmit-Fli(Fli-fp)
FILE*Fli-fp;
{
intNUmber-Chunk;
if(fread((unsignedchar*)&header,1,sizeof(FLIHEAD),Fli-fp)
==sizeof(FLIHEAD))
if(header,magie|=0xAF11)
{
printf("NotanFLIfile/n");
exit(0);
}
if(fread((unsignedchar*)*frame-head,1,
sizeof(FRAMESHEAD),Fli-fp)==sizeof(FRAMESHEAD));
if(frame-head,magic=0xF1FA)
{
printf("ReadinganErroeFLIfile\n");
exit(0);
}
if(fread((unsignedchar*)&chunk-head,1,
sizeof(CHUNKHEAD),Fli-fp)==sizeof(CHUNKHEAD));
if(fread(&NUmber-Chunk,1,sizeof(int),Fli-fp)==sizeof(int));
else{
printf("ErrorreadingFli\n");
exit(0);
}
fgetc(Fli-fp);fgetc(Fli-fp);
if(fread(&palette,1,sizeof(palette),Fli-fp)==768);
else{
printf("ErrorreadingFli\n");
exit(0);
}
if(fread((unsignedchar*)&chunk-head,1,
sizeof(CHUNKHEAD),Fli-fp)==sizeof(CHUNKHEAD));
else{
printf("ErrorreadingFli\n");
exit(0);
}
ShowFli-Frame(Fli-fp);
fclose(Fli-fp);
}
voidShowFli-Frame(Fli-fp)
FILE*Fli-fp;
{
longFrame-DataAddress;
intFirst-UpdateLine,End-UpdateLine;
intFrame-Number=2,Adjust-Char=0;
init();
setvgapalette(palette);
First-Frame(MK-FP(0x0a000,0x0),Fli-fp);
Frame-DataAddress=ftell(Fli-fp);
while(Frame-Number<=header,frames-number-1)
{
Frame-DataAddress=ftell(Fli-fp);
Adjust-Char=fgetc(Fli-fp);
if(Adjust-Char|=0)fseek(Fli-fp,-1L,SEEK-CUR);
if(fread((unsignedchar*)&frame-head,1,
sizeof(FRAMESHEAD),Fli-fp)==sizeof(FRAMESHEAD));
if(frame-head,magic|=0xFIFA)exit(0);
if(frame-head,chunks|=0)
{
if(fread((unsignedchar*)&chunk-head,1,
sizeof(CHUNKHEAD),Fli-fp)==sizeof(CHUNKHEAD));
if(fread(&First-UpdateLine,1,sizeof(int),Fli-fp)
==sizeof(int));
else{
printf("ErrorreadingFli/n");
exit(0);
}
if(fread(&End-UpdateLine,1,sizeof(int),Fli-fp)
==sizeof(int));
else{
prinft("ErrorreadingFli/n");
exit(0);
}
Other-Frame(MK-FP(0x0a000,First-UpdateLine*320),Fli-fp,
End-UpdateLine);
}
Frame-Number++;
}
}
voidvideo-init()
{
unionREGSr;
r.x.ax=0x0013;
int86(0x10,&r,&r);
}
voidvideo-text()
{
unionREGSr;
r.x.ax=0x0003;
int86(0x10,&r,&r);
}
setvgapalette(p)
char*p;
{
unionREGSr;
structSREGSsr;
inti;
for(i=0;i<768;++i)*(p+i)=*(p+i)>>1;
r.x.ax=0x1012;
r.x.bx=0;
r.x.cx=256;
r.x.dx=FP-OFF(p);
sr.es=FP-SEG(p);
int86x(0x10,&r,&r,&sr);
}
本文主要論述了三維動畫設計軟件3DS中的動畫存儲文件FLIC的存儲方式及針對FLI格式文件的播放程序的C語言設計方法。對于工作在高分辨率方式下的動畫文件的播放程序的C程序設計,我們也可以通過同樣的方法進行設計??傊疚闹皇翘峁┙o讀者一種最基本的設計方法,為以后的進一步擴充提供了可能。