-- File: PressNetDecompressor.mesa: Routines for decompresing a compressed image.
-- Last edited: February 24, 1982 10:23 AM By: GWilliams
-- Deleted reporting.

DIRECTORY
InlineDefs USING [BITOR, BITSHIFT, BITXOR],
--IODefs USING[CR, WriteChar, WriteString],
MiscDefs USING [CallDebugger, SetBlock],
PressCompressDefs USING[Color, NibbleSpecType, NibbleRunSpec, remTable, NibbleRange],
PressNetDefs,
SegmentDefs USING[DataSegmentHandle, DefaultBase, DeleteDataSegment, NewDataSegment, SegmentAddress];
PressNetDecompressor: PROGRAM
IMPORTS InlineDefs, --IODefs,-- MiscDefs, PressCompressDefs, SegmentDefs
EXPORTS PressCompressDefs
=
BEGIN OPEN InlineDefs, --IODefs,-- MiscDefs, PressCompressDefs, SegmentDefs;

--Globals for the sink process

destA, destB: POINTER TO ARRAY OF WORD;
destASeg, destBSeg: DataSegmentHandle;
pos: CARDINAL;
--remember next position to fill in output scan.
curNibble, destLoc: CARDINAL;
scanLineLength: CARDINAL;
nibbleSz, nibblesPerScan, arrayLength: CARDINAL;
atomCt, runCt: CARDINAL;
OpenDecompressor: PUBLIC PROCEDURE [scanLen, nibbleSize: CARDINAL]=
BEGIN

atomCt ← runCt ← 0;
arrayLength ← scanLen + 1;
nibbleSz ← nibbleSize;
scanLineLength ← scanLen -1;
destASeg ← NewDataSegment[DefaultBase, (arrayLength+255)/256];
destA ← SegmentAddress[destASeg];
destBSeg ← NewDataSegment[DefaultBase, (arrayLength+255)/256];
destB ← SegmentAddress[destBSeg];
destLoc ← curNibble ← 0;
pos ← nibbleSz - 1;--the first 7-bit byte ends 6 bits into first word from left.
nibblesPerScan ← ((scanLineLength*16)/nibbleSize) + 1;
SetBlock[destA, 0, arrayLength];
SetBlock[destB, 0, arrayLength];
END;
--of OpenDecompressor

NextLine: PUBLIC PROC[]=
--XOR the data and check against the original scan line
BEGIN
i: CARDINAL;
pos ← nibbleSz-1;--the first 7-bit byte ends 6 bits into first word from left.
destLoc ← 0;
curNibble ← 0;
--now can decompress into "A"
FOR i IN [0..scanLineLength] DO destA[i] ← BITXOR[destA[i], destB[i]]; ENDLOOP;
--and zero out B so we can BITOR into it without fear
SetBlock[destB, 0, arrayLength];
END;

CompareLines
: PUBLIC PROC[original: POINTER TO ARRAY OF WORD] RETURNS [same: BOOLEAN ← TRUE]=
BEGIN
i: CARDINAL;

FOR i IN [0..scanLineLength)
DO
IF original[i] # destA[i] THEN EXIT;

REPEAT
FINISHED => RETURN[TRUE];
ENDLOOP;
same ← FALSE;
CallDebugger["Data discrepency."L];

END;
--of CompareLines

GetNibble
: PUBLIC PROC[nib: NibbleRunSpec]=
--this is called to sink nibble specifications from PressNetCompressor
BEGIN
i: CARDINAL;

plunkNibble: PROC[nibb: WORD] =
BEGIN
SELECT pos FROM
6=> {destB[destLoc] ← BITOR[BITSHIFT[nibb, 9], destB[destLoc]]; pos ← 13};
13=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 2], destB[destLoc]]; pos ← 4};
4=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -5], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 11], destB[destLoc]]; pos ← 11};
11=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 4], destB[destLoc]]; pos ← 2};
2=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -3], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 13], destB[destLoc]]; pos ← 9};
9=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 6], destB[destLoc]]; pos ← 0};
0=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -1], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 15], destB[destLoc]]; pos ← 7};
7=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 8], destB[destLoc]]; pos ← 14};
14=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 1], destB[destLoc]]; pos ← 5};
5=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -6], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 10], destB[destLoc]]; pos ← 12};
12=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 3], destB[destLoc]]; pos ← 3};
3=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -4], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 12], destB[destLoc]]; pos ← 10};
10=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 5], destB[destLoc]]; pos ← 1};
1=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, -2], destB[destLoc]];
destLoc ← destLoc+ 1; destB[destLoc] ← BITOR [BITSHIFT[nibb, 14], destB[destLoc]]; pos ← 8};
8=>{destB[destLoc] ← BITOR[BITSHIFT[nibb, 7], destB[destLoc]]; pos ← 15};
15=>{destB[destLoc] ← BITOR[nibb, destB[destLoc]]; destLoc ← destLoc+ 1; pos ← 6};
ENDCASE;
END;--plunkNibble

WITH nib SELECT FROM
run => {runCt ← runCt + 1;
FOR i IN [1..nibbleCt]
DO
curNibble ← curNibble + 1;
--IF curNibble > nibbleTot THEN ERROR[];
plunkNibble[(IF color = white THEN remTable[nibbleSz] ELSE 0)]
ENDLOOP};
atom => {atomCt ← atomCt + 1;
curNibble ← curNibble + 1;
--IF curNibble > nibbleTot THEN ERROR[];
plunkNibble[thisNibble]};
ENDCASE;

END;
--of GetNibble

CloseDecompressor
: PUBLIC PROC []=
BEGIN
DeleteDataSegment[destASeg];
DeleteDataSegment[destBSeg];
destA ← destB ← NIL;
END;


END. -- PressNetDecompressor.mesa
-- Created: February 22, 1982 10:10 AM By: GWilliams
-- Last edited: February 23, 1982 4:34 PM By: GWilliams
-- Compiling