home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
C!T
/
C!T10_93
/
PCX
/
PCX.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1993-08-09
|
13KB
|
353 lines
program PCX_Viewer;
{ Turbo Pascal versie 6.0 of hoger
Auteur: Th.M. Hupkens }
uses Crt, Graph, Dos, All_In;
{ Als u All_In aanroept, dan kunt u het pad naar de BGI-drivers vervangen
door een dummy pad. U heeft de BGI-drivers dan verder niet meer nodig.
All_In linkt alleen de benodigde drivers in: ATT, HERC, CGA, EGAVGA }
{$R- Geen controle op arraygrenzen e.d }
{$I- Geen controle op Invoer/Uitvoer}
{$S- Geen controle op stack overschreiding }
const BufferLengte = $FFFE;
{ BufferLengte bepaalt hoeveel bytes in één keer worden ingelezen.
De maximaal toegestane waarde is $FFFE. }
type PcxType = Object
Kenmerk, Versie: byte;
Gecomprimeerd: boolean;
BitsPerPixel: byte;
Raam: Record Links, Boven, Rechts, Onder: word End;
HorResolutie, VerResolutie: word;
Kleuren: array[0..15] of Record Rood, Groen, Blauw: byte End;
Reserve: byte;
AantalVlakken: byte;
AantalBytesPerLijn: word;
PaletInformatie: word;
ReserveArray: array[1..58] of byte;
procedure ToonHeaderInfo;
procedure LaatZien;
procedure Zet16Kleuren;
End;
ArByte = array[0..$FFFE] of byte;
const Mode13: boolean = false; Klaar: boolean = false;
var Herhaal, Teller, j, m, x, y, MaxX, MaxY, Vlak: word;
VGAScherm: array[0..199, 0..319] of byte absolute $A000:0;
PCX: PCXType;
GraphDriver, GraphMode: integer;
Buffer, Lijn: ^ArByte;
Bestand: string;
Palet: PaletteType;
PCX_Bestand: File;
Procedure SetVideoMode(VideoMode: byte);
var Regs: Registers;
Begin
Regs.AX := VideoMode;
Intr($10, Regs)
End;
Procedure LeesBuffer;
var BufSize: word;
Begin
Klaar := Klaar or EOF(PCX_Bestand);
BlockRead(PCX_Bestand, Buffer^, SizeOf(Buffer^), BufSize)
End;
Procedure Lees256Kleuren;
{ Leest het kleurenstaartje van het PCX-Bestand en stelt deze kleuren
vervolgens in.
De procedure SetRGBPalette uit de unit graph kan niet gebruikt worden,
omdat deze alleen werkt als het beeldscherm via InitGraph in
grafische mode is gezet. Sommige VGA's wachten bij elke verandering van
het palet op een verticale terugslag. Dit kost veel te veel tijd,
daarom worden hier in één keer het hele palet gezet. }
var Registers: Dos.Registers;
Kleuren256: array[0..255] of Record Rood, Groen, Blauw: byte End;
PaletNr, ID: byte;
Begin
Seek(PCX_Bestand, FileSize(PCX_Bestand) - 769); { Zoek positie van ID }
ID := 0;
BlockRead(PCX_Bestand, ID, 1); { Lees alleen ID in }
If ID = 12 then With Registers do Begin
BlockRead(PCX_Bestand, Kleuren256, 768);
For PaletNr := 0 to 255 do With Kleuren256[PaletNr] do Begin
Rood := Rood shr 2; Groen := Groen shr 2; Blauw := Blauw shr 2
End;
AX := $1012;
BX := 0; { Begin bij register nummer 0 }
CX := 256; { Lees alle 256 kleurenregisters in }
ES := Seg(Kleuren256);
DX := Ofs(Kleuren256);
Intr($10, Registers)
End;
Seek(PCX_Bestand, SizeOf(PCX)) { Zet positie bestand weer achter de header }
End;
Procedure LeesPCXHeader(Naam: string);
Begin
If Pos('.', Naam) = 0 then Naam := Naam + '.PCX';
Assign(PCX_Bestand, Naam);
Reset(PCX_Bestand, 1); { Open bestand en kies recordgrootte 1 }
IF IOResult <> 0 then Begin
WriteLn('Bestand niet gevonden. Druk op Enter.');
ReadLn; Halt End;
BlockRead(PCX_Bestand, PCX, SizeOf(PCX))
End;
Procedure Increment;
Begin
If Teller < BufferLengte then Inc(Teller)
else Begin
Teller := 0;
LeesBuffer
End
End;
Procedure PCXType.ToonHeaderInfo;
var AantalKleuren: LongInt;
Begin
ClrScr;
If Kenmerk <> $0A then Begin
WriteLn('Geen PCX-formaat'); Close(PCX_Bestand); ReadLn; Halt End;
Case Versie of
0: Write('Versie 2.5');
2: Write('Versie 2.8 met palet');
3: Write('Versie 2.8 zonder palet');
5: Write('Versie 3.0')
else Write('Onbekende versie') End;
WriteLn;
With Raam do Begin
WriteLn('Raam links-boven: (', Links, ', ', Boven, ')');
WriteLn('Raam rechts-onder: (', Rechts, ', ', Onder, ')');
Dec(Rechts, Links);
Dec(Onder, Boven) End;
WriteLn('Aantal vlakken: ', AantalVlakken);
WriteLn('Aantal bits per beeldpunt: ', BitsPerPixel);
WriteLn('Aantal bytes per lijn: ', AantalBytesPerLijn);
AantalKleuren := LongInt(1) shl (AantalVlakken * BitsPerPixel);
WriteLn('Aantal kleuren: ', AantalKleuren);
If AantalVlakken = 3 then Begin
WriteLn('Dit is een 24-bits bestand.');
If GraphDriver = VGA then
WriteLn('Het wordt in 16 grijstinten weergegeven.')
else Begin
WriteLn('Het kan niet op uw scherm worden weergegeven.');
Halt End End;
If AantalKleuren = 16 then
For j := 0 to 15 do With Kleuren[j] do Begin
Write(Rood shr 2: 5, Groen shr 2: 5, Blauw shr 2: 5);
WriteLn(' EGA_palet: ', (Rood shr 7) shl 2
+ (Groen shr 7) shl 1 + (Blauw shr 7)
+ ((Rood shr 6) and 1) shl 5
+ ((Groen shr 6) and 1) shl 4
+ ((Blauw shr 6) and 1) shl 3: 5) End
End;
Procedure PCXType.Zet16Kleuren;
Begin
If GraphDriver = EGA then
For j := 0 to 15 do With Kleuren[j] do
SetPalette(j, (Rood shr 7) shl 2 + (Groen shr 7) shl 1
+ (Blauw shr 7) + ((Rood shr 6) and 1) shl 5
+ ((Groen shr 6) and 1) shl 4
+ ((Blauw shr 6) and 1) shl 3)
else If GraphDriver = VGA then Begin
GetPalette(Palet);
For j := 0 to 15 do With Palet, Kleuren[j] do
SetRGBPalette(Colors[j], Rood shr 2,
Groen shr 2, Blauw shr 2)
End;
End;
Procedure PCXType.LaatZien;
Begin
With Raam do Begin
If (GraphDriver = VGA) and (AantalVlakken = 1)
and (BitsPerPixel = 8) then Begin
{ Kies videomode 13 hex (320 x 200, 256 kleuren): }
SetVideoMode($13);
Mode13 := true;
MaxX := 319; MaxY := 199;
Lees256Kleuren End
else Begin
If (BitsPerPixel = 2) or ((AantalVlakken = 2) and (Onder < 200)) then
If GraphDriver <> HercMono then Begin
GraphDriver := CGA; GraphMode := CGAC1 End;
If (GraphDriver = VGA) and (AantalVlakken = 4)
and (Rechts = 639) and (Onder <= 349) then GraphMode := VGAMed;
{ Waarschijnlijk EGAMode, niet met zekerheid vast te stellen.
Als het getoonde plaatjes uitgerekt is in de hoogte,
maak hier dan <tijdelijk> van: GraphMode := VGAHi }
{
Als u NIET All_In gebruikt dan moet in de volgende opdracht het op uw
computer van toepassing zijnde pad naar de BGI-drivers staan!
}
InitGraph(GraphDriver, GraphMode, ' '{'C:\TP7\BGI'});
MaxX := GetMaxX; MaxY := GetMaxY
End;
If Rechts < MaxX then MaxX := Rechts;
If Onder < MaxY then MaxY := Onder
End; { With Raam do... }
x := 0; y := 0;
Teller := 0;
LeesBuffer;
Case AantalVlakken of
1: Case BitsPerPixel of
1: { Monochroom }
While not (Klaar or KeyPressed) do Begin
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do
For j := 7 downto 0 do Begin
If 1 shl j and Buffer^[Teller] <> 0 then
If x <= MaxX then PutPixel(x, y, White);
Inc(x) End;
If x shr 3 >= AantalBytesPerLijn then Begin
x := 0; Inc(y);
If y > MaxY then Klaar := true End;
Increment
End;
{ Einde Monochroom }
2: { CGA 4 kleuren }
While not (Klaar or KeyPressed) do Begin
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do Begin
For j := 0 to 3 do
PutPixel(x shl 2 + j, y, Buffer^[Teller] shr (2 * (3 - j)) and 3);
Inc(x);
If x >= AantalBytesPerLijn then Begin
x := 0;
Inc(y);
If y > MaxY then Klaar := true End
End; { For m := 1 to Herhaal ... }
Increment
End; { While not Klaar ... }
{ Einde CGA 4-kleuren (1 vlak) }
4: { 16 Kleuren: N.b. Geen documentatie over gevonden ! }
Begin
Zet16Kleuren;
While not (Klaar or KeyPressed) do Begin
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do Begin
PutPixel(x shl 1, y, Buffer^[Teller] shr 4);
PutPixel(x shl 1 + 1, y, Buffer^[Teller] and 15);
Inc(x);
If x >= AantalBytesPerLijn then Begin
x := 0;
Inc(y);
If y > MaxY then Klaar := true End
End; { For m := 1 to Herhaal ... }
Increment
End { While not Klaar ... }
End;
{ Einde 16 kleuren (1 vlak ) }
8: { 256 kleuren }
While not (Klaar or KeyPressed) do Begin
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do Begin
If x <= MaxX then
If Mode13 then VGAScherm[y, x] := Buffer^[Teller]
else PutPixel(x, y, Buffer^[Teller]);
Inc(x) End; { For m := 1 to Herhaal }
If x >= AantalBytesPerLijn then Begin
x := 0; Inc(y);
If y > MaxY then Klaar := true End;
Increment
End { While not Klaar }
{ Einde 256 kleuren }
End; { Case BitsPerPixel }
3: Begin { GraphDriver moet VGA zijn, maar dat is al eerder gecontroleerd! }
GetPalette(Palet);
For j := 0 to 15 do With Palet do
SetRGBPalette(Colors[j], 2 + j shl 2, 2 + j shl 2, 2 + j shl 2);
Vlak := 0;
GetMem(Lijn, AantalBytesPerLijn);
FillChar(Lijn^, AantalBytesPerLijn, 0);
repeat
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do Begin
If Vlak = 1 then Inc(Lijn^[x], Buffer^[Teller] shr 1)
else Inc(Lijn^[x], Buffer^[Teller] shr 2);
Inc(x);
If x >= AantalBytesPerLijn then Begin
x := 0; Inc(Vlak);
If Vlak = AantalVlakken then Begin
Vlak := 0;
For j := 0 to MaxX do PutPixel(j, y, Lijn^[j] shr 4);
FillChar(Lijn^, AantalBytesPerLijn, 0);
Inc(y); If y > MaxY then Klaar := true End
End
End;
Increment
until Klaar or KeyPressed
End;
2,
4: Begin
If AantalVlakken = 4 then Zet16Kleuren;
Vlak := 0;
GetMem(Lijn, MaxX + 1);
FillChar(Lijn^, MaxX + 1, 0);
repeat
If Buffer^[Teller] and $C0 = $C0 then Begin
Herhaal := Buffer^[Teller] - $C0;
Increment End
else Herhaal := 1;
For m := 1 to Herhaal do Begin
For j := 7 downto 0 do Begin
If 1 shl j and Buffer^[Teller] > 0 then
If x <= MaxX then Inc(Lijn^[x], 1 shl Vlak);
Inc(x) End;
If x >= AantalBytesPerLijn shl 3 then Begin
x := 0; Inc(Vlak);
If Vlak = AantalVlakken then Begin
Vlak := 0;
For j := 0 to MaxX do PutPixel(j, y, Lijn^[j]);
FillChar(Lijn^, MaxX + 1, 0);
Inc(y); If y > MaxY then Klaar := true End
End
End;
Increment
until Klaar or KeyPressed;
End
End (* Case AantalVlakken of *)
End;
Begin
If ParamCount = 0 then Begin
Write('Geef naam van PCX bestand: ');
ReadLn(Bestand) End
else Bestand := ParamStr(1);
DetectGraph(GraphDriver, GraphMode);
LeesPCXHeader(Bestand);
PCX.ToonHeaderInfo;
ReadLn;
GetMem(Buffer, BufferLengte);
PCX.LaatZien;
Write(#7); { Klein belletje }
ReadLn;
If Mode13 then TextMode(LastMode)
else CloseGraph;
Close(PCX_Bestand)
End.