PCX-Bilder in Pascal -------------------- Nachdem Ihr sicherlich die Theorieabhandlung der PCX-Bilder gele- sen habt, geht es nun gleich weiter mit der Umsetzung in die Praxis mit Pascal. Das folgende Programm liest ein 320x200x256-PCX-Bild ein und bringt es auf den Bildschirm. Eine h”here Aufl”sung ist zwar auch machbar, doch ein wenig komplizierter, wenn man kein passenden BGI-Aufsatz hat. In der n„chsten Ausgabe von STOD drfte wohl (wenn ich gengend Zeit finde) auch ein wenig zu dem Thema ste- hen. Nun aber zum Programm. Obwohl es eigentlich nicht n”tig ist, berprfe ich trotzdem am Anfang des Programms, ob es sich ber- haupt um ein PCX-Bild handelt (erstes Byte muá '0A' sein). Den Rest des Headers bergehe ich einfach mal. Dann werden 30000 Byte aus der Datei gelesen. Die tats„chliche Anzahl der gelesenen Bytes werden von der Prozedur 'BlockRead' in 'GeleseneBytes' zu- rckgeliefert. Der Rest des Programms, das meiner Meinung nach gengend dokumentiert ist, l„át sich nach dem Schema beschreiben, das auch schon im allgemein abgefaáten Text steht: Sollte die Z„hlvariable 'Index' einen Werte ungleich 0 beinhalten, so wird das n„chste Byte sooft in den Videospeicher geschrieben, wie es Index vorschreibt. Andernfalls wird das n„chste Byte daraufhin berprft, ob es ein Z„hlbyte ist (Byte AND $C0 = $C0). Ist das der Fall, wird das Byte in Index gespeichert, und es geht wieder von vorne los. Sollte es nicht so sein, repr„sentiert das jetzige Byte einen einzelnen Pixel und wird in den Videospeicher bertra- gen. Danach geht's ebenfalls von vorne los. Zum Schluá der Prozedur wird dann noch die Palette gesetzt, die sich am Ende der Datei befindet. Die Prozedur: PROCEDURE PCX(PCXFile:STRING); VAR PCX : FILE; Daten : ^BYTE; DatenMem : POINTER; Pal,ScreenPos,Pos,Index, Wiederholung,GeleseneBytes : WORD; BEGIN ASSIGN(PCX,PCXFile); {$I-} RESET(PCX,1); IF IOResult <> 0 THEN Exit; {$I+} GetMem(Daten,30000); {Bytes reservieren} DatenMem := Daten; {Anfangsadresse merken} BlockRead(PCX,Daten^,128,GeleseneBytes); {Header lesen} IF Daten^ <> $0A THEN BEGIN {PCX-Kennung vorhanden?} Close(PCX); {Nein: Prozedur verlassen} Exit; END; Index := 0; ScreenPos := 0; REPEAT BlockRead(PCX,Daten^,30000,GeleseneBytes); {Bytes lesen} Pos := 0; WHILE (Pos < GeleseneBytes) AND (ScreenPos <= 64000) DO BEGIN {Solange Daten noch brig sind, und nicht schon alle Pixel gesetzt sind} IF Index > 0 THEN BEGIN {Wiederholungsbyte?} FOR Wiederholung := 1 TO Index DO BEGIN {Ja: } MEM[$A000:ScreenPos] := Daten^; {Schreibe Farbe sooft, wie {Index besagt} Inc(ScreenPos); END; Index := 0; {Nein: Index auf null} END ELSE IF (Daten^ AND $C0) = $C0 THEN Index := Daten^ AND $3F {Wenn Byte = Z„hlbyte, dann Index := Byte} ELSE BEGIN {Sonst: } MEM[$A000:ScreenPos] := Daten^; {Schreibe Byte in Video- speicher - Einzelfarbe} Inc(ScreenPos); END; Inc(Pos); Inc(Daten); END; Daten := DatenMem; {Ursprngliche Adresse herstellen} UNTIL GeleseneBytes = 0; Seek(PCX,FileSize(PCX)-769); {Auf 769. Byte vor Ende setzen} BlockRead(PCX,Daten^,769); {769 Byte lesen} IF Daten^ = $0C THEN BEGIN {Paletten-Erkennung?} Inc(Daten); {Auf Anfang der Farbtabelle setzen} FOR Pal := 1 TO 768 DO BEGIN Daten^ := Daten^ SHR 2; {Paletteneintr„ge durch 4 teilen} Inc(Daten); END; Dec(Daten,768); {Wieder auf Anfang setzen} ASM MOV BX,0 MOV CX,256 MOV AX,1012h LES DX,Daten INT 10h {Palette eintragen} END; END; Daten := DatenMem; {Daten wieder auf ursprngliche Adresse setzen} FreeMem(Daten,30000); {Speicher wieder freigeben} Close (PCX); END; Tja, soviel zu dieser Prozedur. Das Listing muá (natrlich!) nicht abgeschrieben werden, sondern befindet sich in dem Ver- zeichnis 'SOURCES' im STOD-Pfad. Eine Demo-Prog wird da eventuell auch noch zu finden sein - schaut Euch mal ein wenig um. Und wie immer: Sollten noch irgendwelche Fragen oder Verbes- serungsvorschl„ge vorhanden sein ---> her damit! Kemil