home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
572
/
upkpcx.pas
< prev
Wrap
Pascal/Delphi Source File
|
1992-11-19
|
6KB
|
201 lines
(* Unité Pk PCX
modeaff = 1 256 couleurs
modeaff = 2 16 couleurs
modeaff = 3 2 couleurs
*)
unit upkpcx;
interface
uses dos,graph,crt;
type type_entete=record
manu,vers,compr,prof :byte;
x1,y1,x2,y2,x0,y0 :word;
pal :array[0..47]of byte;
res,plan :byte;
bpl,pinfo,xecr,yecr :word;
blanc :array[0..53]of byte;
end;
var pcx_info : type_entete;
pcx_pal : array[0..767]of byte;
function pcx_ouvre(nom:string):integer;
procedure pcx_affiche(gx,gy, x,y,xx,yy:integer);
procedure pcx_palette;
procedure pcx_ferme;
implementation
var pcx_buff : array[0..32770] of byte;
pcx_mode : integer;
lapal : longint;
taille,ibuff : word;
f : file;
nomfichier : string;
modeaff : integer;
b : byte;
i : integer;
car : char;
function itoa(n:longint;p:integer):string;
var t:string;
begin
str(n:p, t); itoa:=t;
end;
procedure erreur(msg:string);
begin
restorecrtmode;
writeln('***ERREUR***');
writeln(msg);
writeln;
halt(1);
end;
procedure pcx_bloc;
begin
blockread(f,pcx_buff,32768,taille);
ibuff:=0;
end;
function pcx_ouvre(nom:string):integer;
begin
{$i-}
assign(f,nom); reset(f,1); if ioresult<>0 then halt(1);
{$i+}
blockread(f,pcx_info,128);
modeaff:=0;
if pcx_info.plan=1 then if pcx_info.prof=8 then modeaff:=1
else modeaff:=3;
if pcx_info.plan=4 then modeaff:=2;
case modeaff of
2: move(pcx_info.pal, pcx_pal, 16*3);
1: begin
seek(f,filesize(f)-769); { palette suffixée }
blockread(f,b,1);
if b=12 then blockread(f,pcx_pal,768);
end;
end;
for i:=0 to 767 do pcx_pal[i]:=pcx_pal[i]shr 2; { sur 6 bits }
pcx_ouvre:=modeaff;
end;
procedure pcx_affiche(gx,gy, x,y,xx,yy:integer);
var n : byte;
i : integer;
cx,cy,rep,xy : word; { x,y, xx,yy : rect à visu }
video, maxy : word;
leplan : word;
lesplans : array[0..3]of byte;
maxx,octetecran : integer;
mx,my : integer;
procedure vgaplan(n:integer);
begin
port[$3c4]:=2; port[$3c5]:=n;
end;
procedure pcx_aff(n:integer);
begin
if (y<=cy)and(cy<=yy)and(x<=cx)and(cx<=xx)then
if modeaff=1 then
putpixel(gx+cx,gy+cy,n)
else
mem[$a000:(gy+cy)*octetecran+cx+gx]:=n;
inc(cx);
if cx>=maxx then
case modeaff of
1 : begin cx:=0; inc(cy); if cy>yy then cy:=maxy; end;
3 : begin cx:=0; inc(cy); if cy>yy then cy:=maxy; end;
2 : begin cx:=0; inc(leplan);
if leplan=4 then begin
leplan:=0; inc(cy); if cy>=yy then cy:=maxy; end;
vgaplan(lesplans[leplan]);
end;
end; {case modeaff}
end;
begin
if xx<0 then xx:=pcx_info.x2-pcx_info.x1+1;
if yy<0 then yy:=pcx_info.y2-pcx_info.y1+1;
mx:=getmaxx; my:=getmaxy;
if gx+x>=mx then erreur('X Début sort de l''écran !');
if gy+y>=my then erreur('Y Début sort de l''écran !');
if gx+xx>mx then xx:=mx-gx; { fin sort de l'écran }
if gy+yy>my then yy:=my-gy;
if gx+x<0 then x:=-gx; { début pas encore dans l'écran }
if gx+y<0 then y:=-gy;
if (modeaff=2)or(modeaff=3) then begin
gx:=gx div 8; x:=x div 8; xx:=xx div 8; { x: octet en octet }
end;
cy:=0; cx:=0; maxy:=pcx_info.y2-pcx_info.y1+1;
lesplans[0]:= 1; lesplans[1]:= 2; lesplans[2]:= 4; lesplans[3]:= 8;
leplan:=0;
case modeaff of
3:begin
vgaplan(1+2+4+8);
maxx:=pcx_info.bpl;
octetecran:=(getmaxx+1)div 8; { 800*600->100 640*480->80 }
end;
2:begin
vgaplan(lesplans[leplan]);
maxx:=pcx_info.bpl;
octetecran:=(getmaxx+1)div 8;
end;
1:begin
maxx:=pcx_info.x2-pcx_info.x1+1; { largeur image }
if (maxx mod 2)=1 then erreur('La largeur doit être un nombre PAIR !');
octetecran:=getmaxx+1; {320 640 800 1024}
end;
end;
seek(f,128);
pcx_bloc;
{-----------------------------------------------début décodage----------}
while cy < maxy do begin
if taille<=0 then pcx_bloc;
n:=pcx_buff[ibuff]; inc(ibuff); dec(taille);
if (n and $c0)=$c0 then begin
rep:= n and $3f;
if taille<=0 then pcx_bloc;
n:=pcx_buff[ibuff]; inc(ibuff); dec(taille);
for i:=1 to rep do pcx_aff(n);
end else pcx_aff(n);
end;
{-----------------------------------------------fin décodage----------}
vgaplan(1+2+4+8);
end;
procedure pcx_palette;
var i,n :integer;
b :byte;
regs :registers;
begin
case modeaff of
2:
for i:=0 to 15 do begin
setpalette(i,i);
setrgbpalette(i,pcx_pal[i*3],pcx_pal[i*3+1],pcx_pal[i*3+2])
end;
1:begin
regs.ah := $10; regs.al := $12;
regs.es := seg(pcx_pal); regs.dx := ofs(pcx_pal);
regs.bx := 0; regs.cx := $100;
intr($10, regs)
end;
end; { case of }
end;
procedure pcx_ferme;
begin
close(f);
end;
begin
end.