PressImageExtractImpl.mesa
Michael Plass, April 25, 1984 12:15:33 pm PST
DIRECTORY
AIS, Basics, Commander, CountedVM, Convert, FS, IO, PressReader, Rope, PressPrinter;
PressImageExtractImpl: CEDAR PROGRAM
IMPORTS AIS, Commander, CountedVM, Convert, FS, IO, PressReader, Rope, PressPrinter ~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
bytesPerPage: NAT ~ 512; -- as per press file format.
ExtractImages: PROC [inputName, outputNameRoot: ROPE, msg: IO.STREAM] ~ TRUSTED {
pressFile: PressReader.Handle ← PressReader.OpenPressFile[inputName];
aisNum: INT ← 0;
DoPage: PROC [pageNumber: INT] RETURNS [ok: BOOLEANTRUE] = TRUSTED {
PageProc: PressReader.PageProc = TRUSTED {
EntityProc: PressReader.EntityProc = TRUSTED { -- Xe, Ye, fontSet
xe: INT ← entityTrailer.Xe;
ye: INT ← entityTrailer.Ye;
x: INT ← xe;
y: INT ← ye;
lastShowX, lastShowY: INT ← -1;
hue: REAL ← 0.0;
saturation: REAL ← 1.0;
brightness: REAL ← 0.0;
skipAlternative, inAlternative: BOOLFALSE;
reposition: BOOLEANFALSE;
showCharactersProc: PressReader.ShowCharactersProc = TRUSTED {
NULL;
}; -- showCharactersProc
fontProc: PressReader.FontProc = TRUSTED {
NULL;
};
positionProc: PressReader.PositionProc = TRUSTED {
IF skipAlternative THEN RETURN;
IF opCode = setX THEN x ← xe + value
ELSE y ← ye + value;
reposition ← TRUE;
};
spacingProc: PressReader.SpacingProc = TRUSTED {
NULL;
};
spaceProc: PressReader.SpaceProc = TRUSTED {
NULL;
};
colorProc: PressReader.ColorProc = TRUSTED {
IF skipAlternative THEN RETURN;
SELECT opCode FROM
setHue => NULL;
setSaturation => NULL;
setBrightness => NULL;
ENDCASE => ERROR;
};
showRectangleProc: PressReader.ShowRectangleProc = TRUSTED {
NULL;
};
alternativeProc: PressReader.AlternativeProc = TRUSTED {
IF (types = 0) AND (elBytes = 0) AND (dlBytes = 0) THEN
inAlternative ← skipAlternative ← FALSE
ELSE IF inAlternative THEN skipAlternative ← TRUE
ELSE inAlternative ← TRUE;
};
showObjectProc: PressReader.ShowObjectProc = TRUSTED {
NULL;
}; -- showObjectProc
outputName: ROPE;
showDotsOpCode: ROPE;
thecode, thedots, thelines: INTINT.FIRST;
SetCoding: PressReader.SetCodingProc ~ {
thecode ← code;
thedots ← dots;
thelines ← lines;
};
themode: NATNAT.LAST;
SetMode: PressReader.SetModeProc ~ {
themode ← mode;
};
passdots, displaydots, passlines, displaylines: INTINT.FIRST;
SetWindow: PressReader.SetWindowProc ~ {
passdots ← pd;
displaydots ← dd;
passlines ← pl;
displaylines ← dl;
};
thewidth, theheight: INTINT.FIRST;
SetSize: PressReader.SetSizeProc ~ {
thewidth ← width;
theheight ← height;
};
DotsFollow: PressReader.DotsFollowProc ~ {
scanMode: AIS.ScanMode ← SELECT themode FROM
2 => ru,
3 => rd,
6 => lu,
7 => ld,
9 => ul,
8 => ur,
13 => dl,
12 => dr,
ENDCASE => rd;
raster: AIS.Raster ← NEW[AIS.RasterPart ← [
scanCount: thelines,
scanLength: thedots,
scanMode: scanMode,
bitsPerPixel: thecode,
linesPerBlock: -1,
paddingPerBlock: 65535
]];
ais: AIS.FRef ← AIS.CreateFile[name: outputName, raster: raster];
window: AIS.WRef ← AIS.OpenWindow[ais];
words: INT ← (thedots*MAX[thecode, 1]+Basics.bitsPerWord-1)/Basics.bitsPerWord;
vm: CountedVM.Handle ← CountedVM.Allocate[words];
buffer: AIS.Buffer ← [length: words, addr: vm.Pointer];
msg.PutF[" ← Page %g ", IO.int[pageNumber]];
msg.PutF[" %g[x: %g, y: %g, w: %g, h: %g]", IO.rope[showDotsOpCode], IO.int[x], IO.int[y], IO.int[thewidth], IO.int[theheight]];
IF brightness # 0.0 THEN msg.PutF[", hue: %g, sat: %g, brt: %g", IO.real[hue], IO.real[saturation], IO.real[brightness]];
FOR lineno: INT IN [0..thelines) DO
[] ← dots.file.UnsafeGetBlock[[base: buffer.addr, startIndex: 0, count: words*2]];
window.UnsafeWriteLine[buffer, lineno];
ENDLOOP;
AIS.CloseFile[ais];
};
showDotsProc: PressReader.ShowDotsProc = TRUSTED {
IF NOT skipAlternative THEN {
showDotsOpCode ← IF opCode = showDots THEN "showDots" ELSE "showDotsOpaque";
aisNum ← aisNum + 1;
outputName Rope.Cat[outputNameRoot, "-", Convert.RopeFromInt[aisNum], ".ais"];
msg.PutRope[FS.ExpandName[outputName].fullFName];
pressFile.GetDots[[
setCoding: SetCoding,
setMode: SetMode,
setWindow: SetWindow,
setSize: SetSize,
dotsFollow: DotsFollow
]];
msg.PutChar['\n];
};
}; -- showDotsProc
pressFile.GetCommands[PressReader.CommandProcs[
showCharactersProc: showCharactersProc,
fontProc: fontProc,
positionProc: positionProc,
spacingProc: spacingProc,
spaceProc: spaceProc,
colorProc: colorProc,
showRectangleProc: showRectangleProc,
alternativeProc: alternativeProc,
showObjectProc: showObjectProc,
showDotsProc: showDotsProc
]];
}; -- EntityProc
pressFile.GetPage[EntityProc];
}; -- PageProc
SkipFonts: PressReader.FontDirectoryProc = TRUSTED {
ok ← FALSE;
};
pressFile.GetParts[pageNumber, PageProc, SkipFonts];
}; -- DoPage
pageNumber: INT ← 1;
WHILE DoPage[pageNumber] DO
pageNumber ← pageNumber + 1;
ENDLOOP;
pressFile.ClosePressFile[];
}; -- ExtractImages
Break: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = '← THEN RETURN [break];
IF char = ' OR char = '  OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
FindFullName: PROC [inputName: ROPE] RETURNS [ROPE] ~ {
fullFName: ROPENIL;
fullFName ← FS.FileInfo[inputName ! FS.Error => CONTINUE].fullFName;
IF fullFName = NIL OR NOT PressPrinter.IsAPressFile[fullFName] THEN {
IF inputName.Find[".press", 0, FALSE] = -1 THEN {
inputName ← inputName.Concat[".press"];
};
fullFName ← FS.FileInfo[inputName].fullFName;
};
RETURN [fullFName]
};
FileNameRoot: PROC [inputName: ROPE] RETURNS [ROPE] ~ {
fullFName: ROPENIL;
cp: FS.ComponentPositions;
[fullFName, cp] ← FS.ExpandName[inputName];
RETURN [fullFName.Substr[cp.base.start, cp.base.length]];
};
PressImageExtractCommand: Commander.CommandProc ~ {
stream: IO.STREAMIO.RIS[cmd.commandLine];
GetToken: PROC RETURNS [rope: ROPE] = {
rope ← NIL;
rope ← stream.GetTokenRope[Break ! IO.EndOfStream => CONTINUE].token;
};
inputName: ROPE ← GetToken[];
inputName ← FindFullName[inputName ! FS.Error => {
IF error.group = user THEN {cmd.out.PutRope[error.explanation]; cmd.out.PutChar['\n]; GOTO Quit} ELSE REJECT
}];
ExtractImages[inputName, FileNameRoot[inputName], cmd.out];
cmd.out.PutRope["Done.\n"];
IF GetToken[].Length # 0 THEN {cmd.out.PutRope["(Ignored: "]; cmd.out.PutRope[cmd.commandLine.Substr[stream.GetIndex]]; cmd.out.PutRope[")\n"]};
EXITS Quit => NULL
};
Commander.Register["PressImageExtract", PressImageExtractCommand, "Recover the sampled image portions of a press file"];
END.