home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Intermedia 1998 January
/
inter1_98.iso
/
www
/
rozi
/
GIF.ZIP
/
SHOWGIF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-01-12
|
9KB
|
353 lines
{ ======== Program u╛ywa niestandardowego sterownika VESA.BGI ========== }
{$r-,i-}
unit ShowGif;
interface
var
ModeNum:byte; {numer trybu graficznego}
function setSvgaMode:integer;
procedure Gifka(x,y:word;name:string);
implementation
uses dos,crt,graph;
const max=4096;
type
RodzajMapyKolorow=(globalny,lokalny);
prologGIF = record
naglowek:array [1..6] of char;
szerokoscEkranu:word;
wysokoscekranu:word;
PoleBitowe:byte;
KolorTla:byte;
PixelAspectRatio:byte;
end;
tablicaKolorow=array[globalny..lokalny,0..255]of record
czerwony,zielony,niebieski:byte;
end;
opisObrazu=record
odkolumny:word;
odlinii:word;
szerokoscObrazu:word;
WysokoscObrazu:word;
polebitowe:byte;
end;
var
prolog:prologGIF;
opisobr:opisObrazu;
mapakolorow:rodzajMapyKolorow;
bitownakolor:byte;
LiczbaKolorow:array[globalny..lokalny] of word;
jestmapa:array[globalny..lokalny] of boolean;
przeplatany,koniec:boolean;
zostalobitow:shortint;
liczbabitow,odilubitow:byte;
indeksbufora,indeksdanych,ilebajtow:word;
poziom,odpoziomu,poziomstosu:word;
poprzednikod,aktualnykod:word;
koniecdanych,nowy:word;
tymczasowy,zatrzask:word;
linie,maxX,maxY,xEkr,Yekr:word;
xp,yp:word; {wspóêrz⌐dne pocz}
etykieta:byte;
st,tr:integer;
naekran:procedure(kolor:byte);
nazwaZbioru:string;
zbiorGIF:file;
Kolory:tablicakolorow;
slownik:array[0..max] of record
poziom:word;
dana:byte;
end;
stos:array[0..1024]of byte;
bufor:array [0..32767] of byte; {buf. odczytu z dysku}
r:registers;
{ ============PREZENTACJA PUNKTOW NA EKRANIE============ }
{$f+}
procedure naEkran1 (kolor:byte);
begin
if(xekr>maxx) then begin xEkr:=0; inc(yekr); end;
if(yekr>maxy) then yekr:=0;
if(xekr<maxx) and (yekr<maxy) then
putpixel (xEkr+xp,yEkr+yp,kolor);
inc (xekr);
end;
procedure naEkran2(kolor:byte); {obraz przeplatany}
const yInc:array[1..5] of byte=(8,8,4,2,1);
yLin:array[1..5] of byte=(0,4,2,1,0);
begin
if(xekr>maxx)then begin
xekr:=0;
inc(yekr,yinc[linie]);
if (yekr>maxy) then begin
inc(linie);
yekr:=ylin[linie];
end;
end;
if (xekr<maxx) and (yekr<maxy) then
putpixel(Xekr+xp,yekr+yp,kolor);
inc(xekr);
end;
function setSvgaMode:integer;
begin
setSvgaMode:=ModeNum; {numer trybu graficznego}
end;
{$f-}
{=======0====POBIERANIE DANYCH ZE ZBIORU GIF=====================}
function wezBajt:byte;
begin
if (indeksbufora>=ilebajtow) then begin
blockread(zbiorGIF,bufor,sizeof(bufor),ilebajtow);
if (ilebajtow=0) then begin wezbajt:=0;exit; end;
indeksbufora:=0;
end;
wezbajt:=bufor[indeksbufora];
inc(indeksbufora);
end;
procedure wezBlok(var v;ile:word);
var W:word;
begin
if ile>ilebajtow then w:=ilebajtow else w:=ile;
move (bufor[indeksbufora],v,w);
dec (ile,w);
inc(indeksbufora,w);
if (indeksbufora>=ilebajtow) then begin
blockread (zbiorgif,bufor,sizeof(bufor),ilebajtow);
if (ilebajtow=0) then exit;
indeksbufora:=0;
end;
move(bufor[indeksbufora],v,ile);
inc(indeksbufora,ile);
end;
function wezBajtDanych:word;
begin
if (indeksdanych=0) then indeksdanych:=wezbajt;
if (indeksdanych>=1) then begin
wezbajtdanych:=wezbajt;
dec(indeksdanych);
end
else wezbajtdanych:=max+1;
end;
function wezKod (ilebitow:byte):word;
const maska:array[1..8] of byte=($01,$03,$07,$0f,$1f,$3f,$7f,$ff);
var trzebabitow,ile:byte;
kod:word;
begin
trzebabitow:=ilebitow;
kod:=0;
while (trzebabitow>0) do begin
if (zostalobitow<=0) then
begin
zatrzask:=wezbajtdanych;
if zatrzask>max then begin wezkod:=koniecdanych;exit;end;
zostalobitow:=8;
end;
if (trzebabitow>=zostalobitow) then ile:=zostalobitow
else ile:=trzebabitow;
kod:=kod or ((zatrzask and maska[ile]) shl (ilebitow-trzebabitow));
zatrzask:=zatrzask shr ile;
dec(trzebabitow,ile);
dec(zostalobitow,ile);
end;
wezkod:=kod;
end;
{===================== DEKOMPRESJA OBRAZU ======================}
procedure inicjuj;
begin
liczbabitow:=odilubitow+1;
poziom:=1 shl odilubitow;
nowy:=poziom; koniecdanych:=poziom+1;
inc (poziom,2);
odpoziomu:=poziom;
end;
procedure rozpakuj;
var c:char;
begin
indeksdanych:=0;
poziomstosu:=0;
zostalobitow:=0;
odilubitow:=wezbajt;
if odilubitow=0 then exit;
fillchar(slownik,sizeof(slownik),0);
inicjuj;
aktualnykod:=wezkod(liczbabitow);
while (aktualnykod<>koniecdanych) do begin
if (aktualnykod=nowy) then begin
inicjuj;
aktualnykod:=wezkod(liczbabitow);
slownik[poziom-1].dana:=aktualnykod;
poprzednikod:=aktualnykod;
naekran(aktualnykod);
end
else begin
tymczasowy:=aktualnykod;
if (aktualnykod>=poziom) then {1}
begin
aktualnykod:=poprzednikod;
stos[poziomstosu]:=slownik[poziom-1].dana;
inc (poziomstosu);
end;
while (aktualnykod>=odpoziomu) do {2}
begin
stos[poziomstosu]:=slownik[aktualnykod].dana;
aktualnykod:=slownik[aktualnykod].poziom;
inc (poziomstosu);
end;
stos[poziomstosu]:=aktualnykod; {3}
inc(poziomstosu);
while (poziomstosu>0) do
begin
dec(poziomstosu);
naekran (stos[poziomstosu]);
end;
slownik[poziom].poziom:=poprzednikod; {4}
slownik[poziom].dana:=aktualnykod;
inc(poziom);
poprzednikod:=tymczasowy;
if (poziom shr liczbabitow>0) and (liczbabitow<12) then inc(liczbabitow); {*}
end;
if keypressed then begin koniec:=true; exit; end;
aktualnykod:=wezkod(liczbabitow);
end;
aktualnykod:=wezkod(liczbabitow);
end;
{=============== POBIERANIE POSZCZEGOLNYCH BLOKOW ==============}
procedure ominrozszerzenie;
var b:byte;
s:string;
begin
b:=wezbajt; {pobranie etykiety bez jej interpretacji}
b:=wezbajt; {pobranie dlugosci bloku}
while (b>0) do
begin
wezblok(s,b);
b:=wezbajt;
end;
end;
procedure wezprolog;
var b:byte;
begin
wezblok(prolog,sizeof(prolog));
b:=prolog.polebitowe;
jestmapa[globalny]:=(b and $80>0);
liczbakolorow[globalny]:=1 shl (b and $07+1);
bitownakolor:=(b and $7f) shr 4+1;
end;
procedure wezopisobrazu;
var b:byte;
begin
wezblok(opisobr,sizeof(opisobr));
b:=opisobr.polebitowe;
jestmapa[lokalny]:=(b and $80>0);
liczbakolorow[lokalny]:=1 shl (b and $07+1);
przeplatany:=(b and $40>0);
maxx:=opisobr.szerokoscObrazu-1;
maxy:=opisobr.wysokoscObrazu-1;
end;
procedure wezkolory;
var f,ile:word;
plik:text;
begin
ile:=liczbakolorow[mapakolorow];
ile:=ile*3;
wezblok(kolory[mapakolorow],ile);
end;
procedure definiujKolory;
var w:word;
reg:registers;
begin
for w:=0 to liczbakolorow[mapakolorow]-1 do
with kolory[mapakolorow][w] do
begin
czerwony:=czerwony shr 2;
zielony:=zielony shr 2;
niebieski:=niebieski shr 2;
end;
reg.ax:=$1012;
reg.bx:=0;
reg.cx:=liczbakolorow[mapakolorow];
reg.es:=seg(kolory);
reg.dx:=ofs(kolory[mapakolorow]);
intr($10,reg);
end;
procedure Gifka;
begin
nazwazbioru:=name;
xp:=x;yp:=y;
xekr:=x;yekr:=y;
assign(zbiorgif,nazwazbioru);
reset (zbiorgif,1);
if (ioresult<>0) then exit;
ilebajtow:=0;
indeksbufora:=0;
wezprolog;
{ if prolog.szerokoscekranu>prolog.wysokoscekranu then
begin
if prolog.szerokoscekranu<320 then modeNum:=0;
if (prolog.szerokoscekranu>320) and (prolog.szerokoscekranu<=640) then modeNum:=2;
if (prolog.szerokoscekranu>640) and (prolog.szerokoscekranu<=800) then modeNum:=3;
if (prolog.szerokoscekranu>800) then modeNum:=4;
end;
if prolog.szerokoscekranu<prolog.wysokoscekranu then begin
if prolog.wysokoscekranu<200 then modeNum:=0;
if (prolog.wysokoscekranu>200) and (prolog.wysokoscekranu<480) then modeNum:=2;
if (prolog.wysokoscekranu>480) and (prolog.wysokoscekranu <600) then modeNum:=3;
if (prolog.wysokoscekranu>600) then modeNum:=4;
end;}
with prolog do
if (naglowek<>'GIF87a') and (naglowek<>'GIF89a') then begin
close(zbiorgif);
writeln ('Zbior nie jest zgodny z formatem GIF !');
exit;
end;
mapakolorow:=globalny;
if jestmapa[globalny] then wezkolory;
{ st:=installUserDriver('VESA',@setsvgamode);
st:=detect;
initgraph(st,tr,'');}
koniec:=false;
repeat
etykieta:=wezbajt;
case etykieta of
$2c:begin
wezopisObrazu;
if przeplatany then begin linie:=1; naekran:=naekran2; end
else naekran:=naekran1;
if jestmapa[lokalny] then
begin
mapakolorow:=lokalny;
wezkolory;
end;
definiujkolory;
xEkr:=0; yEkr:=0;
rozpakuj;
mapakolorow:=globalny;
end;
$21:ominrozszerzenie;
0,$3b:koniec:=true;
end;
until koniec;
setcolor (white);
close(zbiorGIF);
end;
end.