// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak // upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev) // Format /* [ FRAME ] [CHUNK] !pozor delka je 3 bajtova (tj 16MB) 0 - PRADNY CHUNK 1 - LZW FULL SCREEN 2 - MGIF DELTA 3 - HICOLOR PALETE 4 - SOUND TRACK 5 - TEXT TRACK 6 - MGIF COPY 7 - SOUND INIT Popis Chunku: PRAZDNY_CHUNK - muze obsahovat soukrome informace LZW_FULL_SCREEN - ihned za hlavickou nasleduje LZW komprimovany obrazek v rozliseni 320x180 256 barev MGIF_DELTA - cely blok je LZW komprimovany. Po dekomprimace blok obsahuje dva druhy informaci. Prvni DWORD je ofset od pocatku dat ktery ukazuje na zacatek graficke informace. Po tomto DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte) Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte) Po tomto bytu je nutne prenest presne tolik slov z grafickeho bloku na obrazovku. Dvojice bajtu se opakuji dokud ani jeden z nich nema nejvyssi 2 bity nastavene. Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre- skocit. (nula=zadny). HICOLOR PALETTE - Prvni byte znamena pocet aktivnich barev. Pak nasleduje paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem beznym paletam je v tom ze neni treba v palete udrzovat barvy, ktere uz na obrazovce jsou, protoze zmena palety se neprojevi na jiz zobrazenem obrazku. SOUND_TRACK - Kazdy frame obsahuje zvukovou stopu. Je to RAW format. Pro verzi MGIF97 zde je zvukova informace ulozena ve zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana na 50% jako MUS. TEXT_TRACK - Navic je ve mozne ve frame umistit textovou zpravu (titulek) Prvni WORD udava dobu zobrazeni (pocet frame). Pote nasleduje text zakoncen znakem 0; MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem tvaru(tj 57600byte); */ #include #include #include #include #include #include #include "lzw.h" #include #include #include #include #include //#include //#include #include #define MGIF "MGIF" #define MGIF_Y "97" #define VER 0x100 #define MGIF_EMPTY 0 #define MGIF_LZW 1 #define MGIF_DELTA 2 #define MGIF_PAL 3 #define MGIF_SOUND 4 #define MGIF_TEXT 5 #define MGIF_COPY 6 #define MGIF_SINIT 7 char konec=0; void *bufpos; long vals_save=0x80008000; typedef struct mgif_header { char sign[4]; char year[2]; char eof; word ver; long frames; word snd_chans; int snd_freq; short ampl_table[256]; short reserved[32]; }; struct mgif_header gh; int mgf; int chunks; word hipal[256]; char open_mgf_file(char *filename) { mgf=open(filename,O_BINARY | O_RDONLY); if (mgf==-1) return 1; read(mgf,&gh,sizeof(gh)); vals_save=0; bufpos=NULL; return 0; } void close_mgf_file() { close(mgf); } void load_frame(void *f) { long frame_head; long frame_size; read(mgf,&frame_head,4); chunks=frame_head & 0xff; frame_size=frame_head>>8; read(mgf,f,frame_size); } void load_lzw_frame(void *p,void *temp) { reinit_lzw(); lzw_decode(p,temp); } void display_copy(char *temp) { char *c; int i,j; word *w,ww; c=temp; w=lbuffer+60*640; for(i=0;i<180;i++) { for(j=0;j<320;j++) { ww=hipal[*c]; // w[640]=ww; *w++=ww; // w[640]=ww; *w++=ww; c++; } w+=640; } //showview(0,0,640,360); } void display_delta(char *temp) { char *graph,*contr,sk; int i,j,k; word *w,ww; contr=temp; graph=contr+*(long *)contr; contr+=4;graph+=4; for(i=0;i<180;i++) { w=lbuffer+1280*(i+30);sk=1; while ((*contr & 0xc0)!=0xc0) if (sk) { w+=(*contr++)*4;sk=!sk; } else { k=*contr++*2; for(j=0;j>8;p+=4; switch(a) { case MGIF_LZW: case MGIF_DELTA:load_lzw_frame(p,temp);frmode=a;break; case MGIF_PAL:memcpy(hipal,p,siz);break; case MGIF_COPY:temp=p;frmode=a;break; case MGIF_SOUND:sound=p;ssize=siz;break; } p+=siz; } if (sound!=NULL) { while (test_next_frame(bufpos,ssize)); bufpos=sound_decompress(sound,bufpos,ssize,&gh.ampl_table); } else delay(50); if (banking) switch (frmode) { case MGIF_LZW: case MGIF_COPY:show_full_interl_bank(temp,(word *)(60*2048),hipal);break; case MGIF_DELTA:show_delta_interl_bank(temp,(word *)(60*2048),hipal);break; } else switch (frmode) { case MGIF_LZW: case MGIF_COPY:show_full_interl_lfb(temp,lbuffer+60*640,hipal);break; case MGIF_DELTA:show_delta_interl_lfb(temp,lbuffer+(60)*640,hipal);break; } } extern int test_counter; void play_frames() { int x; void *f,*temp; f=getmem(65536); temp=getmem(65536); for(x=0;x2) { sscanf(argv[2],"%d",&a); sscanf(argv[3],"%x",&b); sscanf(argv[4],"%d",&c); sscanf(argv[5],"%d",&d); } else sound_detect(&a,&b,&c,&d); set_mixing_device(a,22050,b,c,d); start_mixing();delay(10); init_lzw_compressor(8); curcolor=0x0; bar(0,0,639,479);showview(0,0,0,0); do if (open_mgf_file(argv[1])) konec=1; else { play_frames(); close_mgf_file(); } while (!konec); done_lzw_compressor(); stop_mixing(); closemode(); }