CtEncodeImpl.mesa
Copyright Ó 1988, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, July 3, 1992 1:30 pm PDT
Glassner, November 14, 1990 4:52 pm PST
DIRECTORY Basics, CtBasic, CtEncode, FS, ImagerSample, IO, Rope, SF;
CtEncodeImpl: CEDAR PROGRAM
IMPORTS Basics, CtBasic, FS, ImagerSample, IO
EXPORTS CtEncode
~ BEGIN
ROPE:    TYPE ~ Rope.ROPE;
STREAM:   TYPE ~ IO.STREAM;
Box:    TYPE ~ CtBasic.Box;
RGB:    TYPE ~ CtBasic.RGB;
SampleMap:  TYPE ~ CtBasic.SampleMap;
SampleMaps:  TYPE ~ CtBasic.SampleMaps;
SampleBuffer: TYPE ~ ImagerSample.SampleBuffer;
Run Length Encoding Operations
Error: PUBLIC ERROR [reason: ROPE] = CODE;
WriteEncoded: PUBLIC PROC [maps: SampleMaps, fileName: ROPE] ~ {
IF maps = NIL OR (maps.bpp # 8 AND maps.bpp # 24)
THEN Error["Bad map"]
ELSE {
color: BOOL ← maps.bpp = 24;
r, g, b, bw: ImagerSample.SampleBuffer;
out: STREAMFS.StreamOpen[fileName, $create];
redGrn: SampleMap;
IF color
THEN {
redGrn ← CtBasic.GetRedGrn[maps[0].map];
r ← ImagerSample.NewSamples[maps.w];
g ← ImagerSample.NewSamples[maps.w];
b ← ImagerSample.NewSamples[maps.w];
}
ELSE bw ← ImagerSample.NewSamples[maps.w];
IO.PutByte[out, IF color THEN 1 ELSE 0];
IO.PutHWord[out, Basics.HFromCard16[maps.x]];
IO.PutHWord[out, Basics.HFromCard16[maps.y]];
IO.PutHWord[out, Basics.HFromCard16[maps.w]];
IO.PutHWord[out, Basics.HFromCard16[maps.h]];
FOR y: NAT IN [maps.y..maps.y+maps.h) DO
IF color
THEN {
WriteRGBRun: PROC ~ INLINE {
IO.PutByte[out, run];
IO.PutByte[out, rgb.r];
IO.PutByte[out, rgb.g];
IO.PutByte[out, rgb.b];
};
run: NAT ← 1;
rgb: RGB;
ImagerSample.GetSamples[redGrn, [y, 2*maps.x], [0, 2], r, 0, maps.w];
ImagerSample.GetSamples[redGrn, [y, 2*maps.x+1], [0, 2], g, 0, maps.w];
ImagerSample.GetSamples[maps[1].map, [y, maps.x], [0, 1], b, 0, maps.w];
rgb ← [r[0], g[0], b[0]];
FOR x: NAT IN (0..maps.w) DO
temp: RGB ← [r[x], g[x], b[x]];
IF temp = rgb AND run # 255 THEN {run ← run+1; LOOP};
WriteRGBRun[];
rgb ← temp;
run ← 1;
REPEAT
FINISHED => WriteRGBRun[];
ENDLOOP;
}
ELSE {
WriteBWRun: PROC ~ INLINE {
IO.PutByte[out, run];
IO.PutByte[out, val];
};
run: NAT ← 1;
val: CARDINAL;
ImagerSample.GetSamples[maps[0].map, [y, maps.x], [0, 1], bw, 0, maps.w];
val ← bw[0];
FOR x: NAT IN (0..maps.w) DO
temp: CARDINAL ← bw[x];
IF temp = val AND run # 255 THEN {run ← run+1; LOOP};
WriteBWRun[];
val ← temp;
run ← 1;
REPEAT
FINISHED => WriteBWRun[];
ENDLOOP;
};
ENDLOOP;
IO.Close[out];
};
};
ReadEncoded: PUBLIC PROC [fileName: ROPE, maps: SampleMaps ¬ NIL]
RETURNS [SampleMaps]
~ {
in: STREAM ¬ FS.StreamOpen[fileName ! FS.Error => Error[error.explanation]];
r, g, b, bw: ImagerSample.SampleBuffer;
bpp: CARDINAL ¬ IF IO.GetByte[in] = 0 THEN 8 ELSE 24;
xOrigin: CARDINAL ¬ Basics.Card16FromH[IO.GetHWord[in]];
yOrigin: CARDINAL ¬ Basics.Card16FromH[IO.GetHWord[in]];
w: CARDINAL ¬ Basics.Card16FromH[IO.GetHWord[in]];
h: CARDINAL ¬ Basics.Card16FromH[IO.GetHWord[in]];
CtBasic.ClipMaps[maps, maps.x, maps.y, maps.x+w, maps.y+h];
IF maps = NIL
THEN maps ¬ CtBasic.CreateMaps[bpp, xOrigin, yOrigin, w, h]
ELSE CtBasic.ClipMaps[maps, xOrigin, yOrigin, w, h];
IF bpp = 24
THEN {
r ¬ ImagerSample.NewSamples[maps.w];
g ¬ ImagerSample.NewSamples[maps.w];
b ¬ ImagerSample.NewSamples[maps.w];
}
ELSE bw ¬ ImagerSample.NewSamples[maps.w];
FOR y: NAT IN [maps.y..maps.y+maps.h) DO
IF bpp = 8
THEN {
x: NAT ¬ 0;
WHILE x < w DO
run: CARDINAL ¬ IO.GetByte[in];
val: CARDINAL ¬ IO.GetByte[in];
FOR n: NAT IN [x..x+run) DO bw[n] ¬ val; ENDLOOP;
x ¬ x+run;
REPEAT FINISHED =>
ImagerSample.PutSamples[maps[0].map, [y, maps.x], [0, 1], bw, 0, maps.w];
ENDLOOP;
}
ELSE {
x: NAT ¬ 0;
WHILE x < w DO
run: CARDINAL ¬ IO.GetByte[in];
rgb: RGB ¬ [IO.GetByte[in], IO.GetByte[in], IO.GetByte[in]];
FOR n: NAT IN [x..x+run) DO
r[n] ¬ rgb.r;
g[n] ¬ rgb.g;
b[n] ¬ rgb.b;
ENDLOOP;
x ¬ x+run;
REPEAT FINISHED => {
ImagerSample.PutSamples[maps[0].map, [y, maps.x], [0, 1], r, 0, maps.w];
ImagerSample.PutSamples[maps[1].map, [y, maps.x], [0, 1], g, 0, maps.w];
ImagerSample.PutSamples[maps[2].map, [y, maps.x], [0, 1], b, 0, maps.w];
};
ENDLOOP;
};
ENDLOOP;
RETURN[maps];
};
END.