Hallo!
Für meine eigenen Zwecke brauche ich einen einfachen PCX-Decoder.
Das ist eigentlich nichts wirklich besonderes, aber ich habe das Vorgehen, fest ausgerichtet auf 320x200 Pixel und 256 Farben, einmal in einer Pascal-Unit umgesetzt und mir Mühe gegeben, das ganze in Assembler so knapp und optimal wie möglich zu halten. Vielleicht ist es für den ein oder anderen ja interessant.
Grüße,
Zatzen
Code: Alles auswählen
{$G+}
Unit PCX;
(* PCX File Format Decoder Version 1 by Zatzen 15 Jan 2022 *)
(* only supports a fixed frame of 320x200 Pixels and 256 indexed colors *)
(* data must be RLE encoded *)
(* currently only works for PCX files not bigger than 65656 bytes *)
(****************************)
(* Example Program / Usage: *)
(****************************)
(* load_PCX('NAMENLOS.PCX');*)
(* decode_pcxdata; *)
(* MCGA; *)
(* set_palette_256; *)
(* display_image; *)
(* release_memory; *)
(* REPEAT UNTIL KeyPressed; *)
(* TextMode_3; *)
(****************************)
INTERFACE
Procedure Load_PCX(fn: String);
Procedure decode_pcxdata;
Procedure set_palette_256;
Procedure MCGA;
Procedure TextMode_3;
Procedure display_image;
Procedure release_memory;
IMPLEMENTATION
Var
pcxdata_src: Pointer;
pcxdata_upk: Pointer;
pcxdata_siz: WORD;
Procedure load_PCX(fn: String);
Var
f: File;
begin
Assign(f, fn);
Reset(f, 1);
pcxdata_siz := FileSize(f) - 128;
GetMem(pcxdata_src, pcxdata_siz);
Seek(f, 128);
BlockRead(f, pcxdata_src^, pcxdata_siz);
Close(f);
ASM (* shift palette data from 8 to 6 bits *)
LES DI, pcxdata_src
ADD DI, pcxdata_siz
SUB DI, 768
MOV BX, 767
@LOOP:
MOV AL, ES:[DI+BX]
SHR AL, 2
MOV ES:[DI+BX], AL
DEC BX
JNS @LOOP
END;
end;
Procedure unpak_pcx; ASSEMBLER;
ASM
XOR CX, CX
MOV DX, DS
LES DI, pcxdata_upk
LDS SI, pcxdata_src
MOV BX, 64000
@LOOP:
LODSB
CMP AL, 192
JB @SKIP { Anm: Wenn jemand eine schnellere Methode sieht als CMP möge er sich melden! }
AND AL, 63
MOV CL, AL
LODSB
SUB BX, CX
REP STOSB
JMP @SKIP2
@SKIP:
STOSB
DEC BX
@SKIP2:
JNZ @LOOP
MOV DS, DX
END;
Procedure decode_pcxdata;
begin
GetMem(pcxdata_upk, 64000);
unpak_pcx;
end;
Procedure set_palette_256; ASSEMBLER;
ASM
MOV AX, 01012H
XOR BX, BX
MOV CX, 256
LES DX, pcxdata_src
ADD DX, pcxdata_siz
SUB DX, 768
INT 10H
END;
Procedure MCGA; ASSEMBLER;
ASM
MOV AX, 013H
INT 010H
END;
Procedure TextMode_3; ASSEMBLER;
ASM
MOV AX, 003H
INT 010H
END;
Procedure display_image; ASSEMBLER;
ASM
MOV DX, DS
MOV AX, 0A000H
MOV ES, AX
XOR DI, DI
LDS SI, pcxdata_upk
MOV CX, 32000
REP MOVSW
MOV DS, DX
END;
Procedure release_memory;
begin
FreeMem(pcxdata_src, pcxdata_siz);
FreeMem(pcxdata_upk, 64000);
end;
begin
end.