home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Club Elmshorn Atari PD
/
CCE_PD.iso
/
mac
/
0300
/
CCE_0385.ZIP
/
CCE_0385.PD
/
SAVE_IMG
/
GEMIMAGE.I
< prev
next >
Wrap
Text File
|
1991-06-29
|
7KB
|
214 lines
IMPLEMENTATION MODULE GemImage;
(* Modul zur Erzeugung von gepackten GEM-Image-Files
Version 1.0, vom 29.6.1991, (c) by JauTeam
Erstellt von: Peter Oleski und Christian Felsch
mit : MegaMax Modula 2, Vers. 4.1
Anfragen : E-Mail Christian Felsch @HH (Maus Hamburg)
*)
FROM Binary IMPORT WriteBlock, WriteByte;
FROM Files IMPORT File, Close, Access, Create, ReplaceMode;
FROM SYSTEM IMPORT CAST, ADDRESS;
TYPE bits = SET OF [0..7];
DatenForm = (schwarz,weiss,muster,bitstr,nix);
IMGHeader = RECORD (* der IMG-Header
version, gemäß DRI *)
kopflaenge,
farbebenen,
musterlaenge,
pixelbreite,
pixelhoehe,
bildbreite,
bildhoehe :CARDINAL;
END(*RECORD*);
CONST Weiss = bits{};
Schwarz = bits{0..7};
VAR Image : File;
bild : POINTER TO ARRAY [0..MaxLCard] OF bits; (* Zeiger auf das Bild *)
Zeile,
GleicheZeilen,
ModeAnzahl,
BytesProZeile,
LastBildByte : LONGCARD;
LastMode : DatenForm;
PROCEDURE ZeilenGleich(zeile:LONGCARD): BOOLEAN; (* vergleicht zwei auf- *)
VAR pos,start,ende: LONGCARD; (* einander folgende Zeilen *)
(* auf Gleiheit *)
BEGIN
start:=zeile * BytesProZeile;
ende:=start + BytesProZeile-1;
pos:=start;
WHILE (pos+BytesProZeile <= LastBildByte) AND (pos<ende)
AND (bild^[pos] = bild^[pos+BytesProZeile]) DO
INC(pos);
END(*FOR*);
RETURN (pos=ende);
END ZeilenGleich;
PROCEDURE Solid(farbe: bits; byte: LONGCARD):BOOLEAN; (* testet byte auf weiss *)
(* oder schwarz *)
BEGIN
RETURN (bild^[byte]=farbe);
END Solid;
PROCEDURE IstMuster(last,byte: LONGCARD):BOOLEAN; (* testet 4 byte auf *)
(* muster *)
BEGIN
IF byte+3 <= last THEN
RETURN ((bild^[byte] = bild^[byte+2]) AND (bild^[byte+1] = bild^[byte+3]));
ELSE
RETURN FALSE;
END(*IF*);
END IstMuster;
PROCEDURE Speichern(mode:DatenForm; byte:LONGCARD); (* zählt wie oft ein *)
VAR daten: bits; (* gleicher Mode vorkommt *)
p : LONGCARD; (* und speichert diesen *)
BEGIN
IF (mode = LastMode) THEN
INC(ModeAnzahl);
ELSE
IF ModeAnzahl > 0 THEN
CASE LastMode OF
schwarz:WHILE ModeAnzahl > 127 DO
WriteByte(Image,$FF); (* 127 schwarze Bytes *)
DEC(ModeAnzahl,127);
END(* WHILE *);
daten:=CAST(bits,ModeAnzahl);
INCL(daten,7);
WriteByte(Image,daten);|
weiss :WHILE ModeAnzahl > 127 DO
WriteByte(Image,$7F); (* 127 weiße Bytes *)
DEC(ModeAnzahl,127);
END(* WHILE *);
daten:=CAST(bits,ModeAnzahl);
EXCL(daten,7);
WriteByte(Image,daten);|
muster :WriteByte(Image,$0); (* Muster geht bis max 4080 *)
WriteByte(Image,CHR(ModeAnzahl)); (* Punkte breit *)
WriteByte(Image,bild^[byte-2]);
WriteByte(Image,bild^[byte-1]);|
bitstr :WHILE ModeAnzahl > 255 DO (* ungepackt speichern *)
WriteByte(Image,$80);
WriteByte(Image,$FF);
FOR p:=0 TO 254 DO
WriteByte(Image,bild^[byte-ModeAnzahl+p]);
END(*FOR*);
DEC(ModeAnzahl,255);
INC(byte,256);
END;(* while *)
WriteByte(Image,$80);
WriteByte(Image,CHR(ModeAnzahl));
FOR p:=0 TO ModeAnzahl-1 DO
WriteByte(Image,bild^[byte-ModeAnzahl+p]);
END(*FOR*);|
END(*CASE*);
LastMode:=mode;
ModeAnzahl:=1;
ELSE
LastMode:=mode;
INC(ModeAnzahl);
END(*IF*);
END(*IF*);
END Speichern;
PROCEDURE ScanZeileZerlegen(zeile: LONGCARD); (* zerlegt eine Zeile *)
VAR start,ende,pos: LONGCARD; (* in Modes *)
BEGIN
ModeAnzahl:=0;
LastMode:=nix;
start:=zeile * BytesProZeile;
ende:=start + BytesProZeile - 1;
pos:=start;
WHILE pos <= ende DO
IF Solid(Schwarz,pos) THEN
Speichern(schwarz,pos);
ELSIF Solid(Weiss,pos) THEN
Speichern(weiss,pos);
ELSIF IstMuster(ende,pos) THEN
Speichern(muster,pos);
INC(pos);
ELSE
Speichern(bitstr,pos);
END(*IF*);
INC(pos);
END(*WHILE*);
Speichern(nix,pos);
END ScanZeileZerlegen;
PROCEDURE MakeHeader(hdr: SmallHeader; name: ARRAY OF CHAR):BOOLEAN;
VAR bigHdr: IMGHeader; (* speichert den kompletten *)
(* Header ab *)
BEGIN
WITH bigHdr DO
version :=hdr.version;
kopflaenge :=8;
farbebenen :=1;
musterlaenge:=2;
pixelbreite :=hdr.pixelbreite;
pixelhoehe :=hdr.pixelhoehe;
bildbreite :=hdr.bildbreite;
bildhoehe :=hdr.bildhoehe;
END(*WITH*);
IF bigHdr.bildbreite > 4080 THEN
RETURN FALSE;
ELSE;
Create(Image,name,writeOnly,replaceOld);
WriteBlock(Image,bigHdr);
RETURN TRUE;
END(*IF*);
END MakeHeader;
PROCEDURE BitImageSpeichern(data:ADDRESS; header: SmallHeader;
filename: ARRAY OF CHAR):BOOLEAN;
BEGIN
bild:=data;
IF MakeHeader(header,filename) THEN
BytesProZeile:= header.bildbreite DIV 8;
LastBildByte:=(LONG(header.bildbreite) * LONG(header.bildhoehe) DIV 8)-1;
Zeile:=0;
GleicheZeilen:=1;
WHILE Zeile < LONG( header.bildhoehe) DO
IF (ZeilenGleich(Zeile)) AND (GleicheZeilen < 255) THEN
INC(GleicheZeilen); (* test auf VRC *)
ELSIF GleicheZeilen<>1 THEN
WriteByte(Image,$0);
WriteByte(Image,$0);
WriteByte(Image,$FF);
WriteByte(Image,CHR(GleicheZeilen));
ScanZeileZerlegen(Zeile);
GleicheZeilen:=1;
ELSE
ScanZeileZerlegen(Zeile);
END(*IF*);
INC(Zeile);
END(*WHILE*);
Close(Image);
RETURN TRUE;
ELSE
RETURN FALSE;
END(*IF*);
END BitImageSpeichern;
END GemImage.