<<>> <> <> <> <> <<>> 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] = { <> 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.