-- VersatectoPacked.mesa - April 1980
-- Replacement versatec module to generate packed bitmap files
-- Updated: July 21, 1981 11:08 AM by R. Pasco

--file format:
--
1st word: # bits per scanline
--
<scanline>s
--where <scanline> is runlength encoded in bytes:
--
<high order 4 bits = length-1; low order 4 bits = pattern>

DIRECTORY
InlineDefs: FROM "InlineDefs" USING [LongCOPY, HighByte, LowByte],
StreamDefs: FROM "StreamDefs" USING [StreamHandle, NewByteStream, Write,
Append],
SystemDefs: FROM "SystemDefs" USING [AllocateHeapNode, FreeHeapNode],
VersatecDefs: FROM "VersatecDefs";

Versatec: PROGRAM
IMPORTS InlineDefs, StreamDefs, SystemDefs
EXPORTS VersatecDefs =
BEGIN OPEN InlineDefs, StreamDefs, SystemDefs;

StartVersatecPlot: PUBLIC PROCEDURE[fileName: STRING, width,height: CARDINAL] =
BEGIN
ScanLineBits ← ((width+3)/4)*4;
ScanLineLength ← (width+15)/16;
ScanLine ← AllocateHeapNode[ScanLineLength];
LineNumber ← 0;
Stream ← NewByteStream[fileName, Write + Append];
Stream.put[Stream,HighByte[ScanLineBits]];
Stream.put[Stream,LowByte[ScanLineBits]];
END;

EndVersatecPlot: PUBLIC PROCEDURE =
BEGIN
FreeHeapNode[ScanLine];
Stream.destroy[Stream];
END;

Word: TYPE = POINTER TO WordRecord;
WordRecord: TYPE = MACHINE DEPENDENT RECORD [n1,n2,n3,n4: [0..15]];


WriteVersatecLine: PUBLIC PROCEDURE [line: LONG POINTER, nBytes: CARDINAL] =
BEGIN
word: Word ← ScanLine;
nCount: INTEGER ← 0;
nBits: INTEGER ← 0;
byte,pattern,nybble: INTEGER;
GetNybble: PROC RETURNS[nybble: INTEGER] =
BEGIN
nCount ← nCount + 1;
nBits ← nBits + 4;
SELECT nCount FROM
1=> nybble ← word.n1;
2=> nybble ← word.n2;
3=> nybble ← word.n3;
4=> {nybble ← word.n4;
word ← word + 1;
nCount ← 0;
};
ENDCASE;
END;
LongCOPY[line, ScanLineLength, ScanLine];
byte ← pattern ← GetNybble[];
WHILE nBits<ScanLineBits DO
nybble ← GetNybble[];
IF nybble=pattern THEN
{IF byte<360B THEN byte ← byte+16
ELSE
{Stream.put[Stream,byte];
byte ← nybble;
};
}
ELSE
{Stream.put[Stream,byte];
byte ← pattern ← nybble;
};
ENDLOOP;
Stream.put[Stream,byte];
LineNumber ← LineNumber + 1;
END;

Stream: StreamHandle;
ScanLine: POINTER ← NIL;
ScanLineLength: CARDINAL;
ScanLineBits: INTEGER;
LineNumber: CARDINAL;

-- *** START CODE ***

END.