home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Intermedia 1998 January
/
inter1_98.iso
/
www
/
rozi
/
GIF.ZIP
/
GIF.PAS
next >
Wrap
Pascal/Delphi Source File
|
1997-01-12
|
9KB
|
360 lines
{$r-,i-}
program ShowGif;
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;
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;
r:registers;
{PROCEDURE putPixel (x,y:word;c:byte);
assembler;
asm
mov ax,$a000
mov es,ax
mov dx,y
mov di,x
xchg dh,dl
add di,dx dla trybu 320x200x256
shr dx,2 wÆåczyì $g+
add di,dx
mov al,c
mov es:[di],al
end;
procedure putpixel(x,y,k:word);
var ekran:array [0..199,0..319] of byte absolute $a000:0;
begin
if (x>319) or (y>199) then exit;
ekran[y,x]:=k;
end;}
{ ============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,yEkr,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,yekr,kolor);
inc(xekr);
end;
function setSvgaMode:integer;
begin
setSvgaMode:=2; {numer trybu graficznego}
end;
{$f-}
{===========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);
repeat until keypressed;
while keypressed do c:=readkey;
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;
begin
if(paramcount=0) then
begin
write('Podaj nazwe zbioru => ');
readln(nazwazbioru);
end
else nazwazbioru:=paramstr(1);
if (pos('.',nazwazbioru)=0) then nazwazbioru:=nazwazbioru+'.GIF';
assign(zbiorgif,nazwazbioru);
reset (zbiorgif,1);
if (ioresult<>0) then exit;
ilebajtow:=0;
indeksbufora:=0;
wezprolog;
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('c:\tp\bgi\vga256',@setsvgamode);
{r.ax:=$0013;
intr($10,r); dla 320x200x256}
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;
{r.ax:=$003;
intr($10,r); dla 320x200x256 }
closegraph;
close(zbiorGIF);
end.