CBitmapReaderImpl.mesa
Copyright Ó 1991 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, May 2, 1991 2:46:56 pm PDT
Christian Jacobi, May 3, 1991 5:52 pm PDT
DIRECTORY
Ascii, Convert, ImagerSample, IO, Rope, CBitmapReader;
CBitmapReaderImpl: CEDAR PROGRAM
IMPORTS Ascii, Convert, ImagerSample, IO, Rope
EXPORTS CBitmapReader =
BEGIN
Error: PUBLIC ERROR [explanation: REF] = CODE;
Err: PROC [rt: REF TEXT] = {
ERROR Error[Rope.FromRefText[rt]]
};
ScanNum: PROC [stream: IO.STREAM] RETURNS [val: INT] = {
We are assuming correct file written by program and dont check for errors
Hex: PROC [stream: IO.STREAM] RETURNS [i: INT] = {
ch: CHAR ¬ IO.GetChar[stream];
IF Ascii.Digit[ch]
THEN RETURN [ORD[ch]-ORD['0]]
ELSE RETURN [ORD[ch]-ORD['a]+10]
};
low, high: INT;
ch: CHAR ¬ IO.GetChar[stream];
WHILE ch#'x DO ch ¬ IO.GetChar[stream] ENDLOOP;
high ¬ Hex[stream];
low ¬ Hex[stream];
RETURN [high*16+low];
};
FromStream: PUBLIC PROC [stream: IO.STREAM] RETURNS [sm: ImagerSample.RasterSampleMap, hotSpot: ImagerSample.Vec ¬ [0, 0]] = {
ENABLE {
Convert.Error => Err["format"];
IO.Error => Err["format"];
};
line: Rope.ROPE; pos: INT; width, height: INT;
--width
line ¬ IO.GetLineRope[stream];
pos ¬ Rope.FindBackward[line, "←width"];
IF pos<0 THEN Err["width not found"];
width ¬ Convert.IntFromRope[Rope.Substr[line, pos+6]];
--height
line ¬ IO.GetLineRope[stream];
pos ¬ Rope.FindBackward[line, "←height"];
IF pos<0 THEN Err["height not found"];
height ¬ Convert.IntFromRope[Rope.Substr[line, pos+7]];
--eventual hotspot
line ¬ IO.GetLineRope[stream];
pos ¬ Rope.FindBackward[line, "←x←hot"];
IF pos>=0 THEN {
hotSpot.f ¬ Convert.IntFromRope[Rope.Substr[line, pos+6]];
line ¬ IO.GetLineRope[stream];
pos ¬ Rope.FindBackward[line, "←y←hot"];
IF pos<0 THEN Err["hottspot not found"];
hotSpot.s ¬ Convert.IntFromRope[Rope.Substr[line, pos+6]];
line ¬ IO.GetLineRope[stream];
};
--real stuff
sm ¬ ImagerSample.NewSampleMap[box: [min: [0, 0], max: [s: height, f: width]], bitsPerLine: (width+63) / 64 * 64]; --alignment for sparc
ImagerSample.Clear[sm];
FOR s: INT IN [0..height) DO
nextNum: INT; availablebits: INT ¬ 0;
FOR f: INT IN [0..width) DO
IF availablebits<=0 THEN {
nextNum ¬ ScanNum[stream]; availablebits ¬ 8;
};
IF (nextNum MOD 2)#0 THEN ImagerSample.Put[sm, [s: s, f: f], 1];
nextNum ¬ nextNum/2; availablebits ¬ availablebits-1;
ENDLOOP;
ENDLOOP;
};
END.