~
BEGIN
Device: TYPE ~ ImagerDevice.Device;
Data: TYPE ~ REF DataRep;
DataRep:
TYPE ~
RECORD [
msg: IO.STREAM,
tab: RefTab.Ref, -- to avoid putting them out more than once
nameRoot: ROPE,
counter: CARD ¬ 0,
sourceFileName: ROPE,
page: INT ¬ 0
];
RopeFromFactoredTransformation:
PROC [f: ImagerTransformation.FactoredTransformation]
RETURNS [
ROPE] ~ {
fRope: ROPE ¬ NIL;
n: INT ¬ 0;
IF f.t # [0, 0] THEN {n ¬ n + 1; fRope ¬ IO.PutFR["%g %g TRANSLATE", [real[f.t.x]], [real[f.t.y]]]};
IF f.r2 # 0 THEN {n ¬ n + 1; fRope ¬ IO.PutFR["%g ROTATE %g", [real[f.r2]], [rope[fRope]]]};
IF f.s # [1, 1]
THEN {
n ¬ n + 1;
IF f.s.x = f.s.y
THEN {
fRope ¬ IO.PutFR["%g SCALE %g", [real[f.s.x]], [rope[fRope]]];
}
ELSE {
fRope ¬ IO.PutFR["%g %g SCALE2 %g", [real[f.s.x]], [real[f.s.y]], [rope[fRope]]];
};
};
IF f.r1 # 0 THEN {n ¬ n + 1; fRope ¬ IO.PutFR["%g ROTATE %g", [real[f.r1]], [rope[fRope]]]};
IF fRope = NIL THEN {n ¬ n + 1; fRope ¬ "1 SCALE"};
FOR i:
INT
IN [1..n)
DO
fRope ¬ Rope.Concat[fRope, " CONCAT"];
ENDLOOP;
RETURN [fRope]
};
GetScanOrder:
PROC [pa: ImagerPixelArray.PixelArray]
RETURNS [ImagerTransformation.Transformation] ~ {
r: Imager.Rectangle ~ ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]];
RETURN [ImagerTransformation.PostTranslate[pa.m, [-r.x, -r.y]]]
};
DoPixelArray:
PROC [device: Device, pa: ImagerPixelArray.PixelArray, m: ImagerTransformation.Transformation, mask:
BOOL, colorOperator: ImagerColor.ColorOperator, remarks:
ROPE] ~ {
data: Data ~ NARROW[device.data];
res: RasterEncodingStandardIO.RES ~ NEW[RasterEncodingStandardIO.RESRep];
fileName: ROPE ¬ NARROW[RefTab.Fetch[x: data.tab, key: pa].val];
scanOrder: ImagerTransformation.Transformation ~ GetScanOrder[pa];
f: ImagerTransformation.FactoredTransformation ~ ImagerTransformation.Factor[m: ImagerTransformation.PostScale[ImagerTransformation.Cat[ImagerTransformation.Invert[scanOrder], pa.m, m], 0.001]];
fRope: ROPE ~ RopeFromFactoredTransformation[f];
normPA: ImagerPixelArray.PixelArray ¬ NEW[ImagerPixelArray.PixelArrayRep ¬ pa];
normPA.m ¬ scanOrder;
remarks ¬ Rope.Cat[fRope, " as ", remarks, " on page ", IO.PutFR1["%g", [integer[data.page]]]];
IF fileName #
NIL
THEN {
IO.PutF[data.msg, "Repeat of %g: %g\n", [rope[fileName]], [rope[remarks]]];
RETURN
};
IF mask THEN res.maskImage ¬ normPA ELSE res.colorImage ¬ normPA;
IF colorOperator #
NIL
AND colorOperator.chromatic
THEN {
res.header ¬ "Interpress/Xerox/3.0/RasterEncoding/1.0 ";
};
res.colorOperator ¬ colorOperator;
fileName ¬ IO.PutFR["%g-%g.res", [rope[data.nameRoot]], [cardinal[data.counter]]];
data.counter ¬ data.counter + 1;
res.imageProperties ¬ Prop.Put[propList: res.imageProperties, key: $name, val: Rope.Cat["Extracted from ", data.sourceFileName, ": ", remarks]];
res.imageProperties ¬ Prop.Put[propList: res.imageProperties, key: $creationTime, val: IO.PutFR1["%g", [time[BasicTime.Now[]]]]];
IF f.s.x/f.s.y
IN [0.999..1.001]
THEN {
res.imageScale.x ¬ res.imageScale.y ¬ f.s.x;
};
RasterEncodingStandardIO.Write[fileName: fileName, res: res];
fileName ¬ FS.FileInfo[name: fileName].fullFName;
[] ¬ RefTab.Insert[x: data.tab, key: pa, val: fileName];
IO.PutF[data.msg, "%g: %g\n", [rope[fileName]], [rope[remarks]]];
};
ExtractSetColor:
PROC [device: Device, color: ImagerColor.Color, viewToDevice: ImagerTransformation.Transformation] ~ {
WITH color
SELECT
FROM
color: ImagerColor.SampledColor => {
DoPixelArray[device: device, pa: color.pa, m: color.um, mask: FALSE, colorOperator: color.colorOperator, remarks: "Sampled Color"]
};
color: ImagerColor.SampledBlack => {
DoPixelArray[device: device, pa: color.pa, m: color.um, mask: FALSE, colorOperator: NIL, remarks: IF color.clear THEN "Clear Sampled Black" ELSE "Sampled Black"]
};
ENDCASE => NULL;
device.state.allow ¬ [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE]
};
ExtractMaskBoxes:
PROC [device: Device, bounds:
SF.Box, boxes:
SF.BoxGenerator] ~ {
};
deviceClass: ImagerDevice.DeviceClass ~
NEW [ImagerDevice.DeviceClassRep ¬ [
SetColor: ExtractSetColor,
MaskBoxes: ExtractMaskBoxes
]];
ExtractMaskPixel:
PROC [context: Imager.Context, pa: ImagerPixelArray.PixelArray] ~ {
DoPixelArray[device: ImagerRaster.GetDevice[context], pa: pa, m: ImagerBackdoor.GetT[context], mask: TRUE, colorOperator: NIL, remarks: "Mask"];
};
class: ImagerPrivate.Class ~ CreateClass[];
CreateClass:
PROC
RETURNS [ImagerPrivate.Class] ~ {
class: ImagerPrivate.Class ~ ImagerRaster.CreateClass[type: $ExtractPixelArrays];
class.MaskPixel ¬ ExtractMaskPixel;
RETURN [class]
};
CreateContext:
PROC [data: Data]
RETURNS [Imager.Context] ~ {
deviceParm: ImagerDevice.DeviceParm ~ ImagerDevice.MakeDeviceParm[
class: deviceClass, sSize: NAT.LAST, fSize: NAT.LAST, scanMode: [slow: right, fast: up], surfaceUnitsPerInch: [25.4, 25.4], surfaceUnitsPerPixel: 1
];
context: Imager.Context ~ ImagerRaster.Create[class: class, deviceClass: deviceClass, deviceParm: deviceParm, data: data, pixelUnits: FALSE];
RETURN [context];
};
GetFileNameToken:
PROC [stream:
IO.
STREAM]
RETURNS [rope:
ROPE ¬
NIL] = {
FileNameTokenBreak:
PROC [char:
CHAR]
RETURNS [
IO.CharClass] = {
IF char = '← THEN RETURN [break];
IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
rope ¬ stream.GetTokenRope[FileNameTokenBreak ! IO.EndOfStream => CONTINUE].token;
};
OutputRoot:
PROC [inputName:
ROPE]
RETURNS [
ROPE] ~ {
cp: FS.ComponentPositions;
[inputName, cp] ¬ FS.ExpandName[inputName];
RETURN [Rope.Substr[inputName, cp.base.start, cp.base.length]];
};
Command: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
ENABLE
FS.Error => {
result ¬ $Failure;
msg ¬ error.explanation;
IF error.group = user THEN CONTINUE;
};
stream: IO.STREAM ~ IO.RIS[cmd.commandLine];
inputName: ROPE ¬ GetFileNameToken[stream];
Log: InterpressInterpreter.LogProc ~ {
IO.PutRope[cmd.err, "IP Log: "];
IO.PutRope[cmd.err, explanation];
IO.PutRope[cmd.err, "\n"];
};
IF inputName =
NIL
THEN RETURN[result: $Failure, msg: cmd.procData.doc]
ELSE {
fullFName: ROPE ~ FS.FileInfo[inputName].fullFName;
master: InterpressInterpreter.Master ~ InterpressInterpreter.Open[fullFName, Log];
data: Data ¬ NEW[DataRep ¬ [msg: cmd.out, tab: RefTab.Create[], nameRoot: OutputRoot[fullFName], sourceFileName: fullFName]];
context: Imager.Context ¬ CreateContext[data];
IO.PutF1[cmd.out, "Input file is %g . . .\n", [rope[fullFName]]];
FOR i:
INT
IN [1..master.pages]
DO
data.page ¬ i;
InterpressInterpreter.DoPage[master: master, page: i, context: context, log: Log, copy: 1];
ENDLOOP;
IO.PutF[cmd.out, "%g image%g extracted.\n", [cardinal[data.counter]], [rope[IF data.counter#1 THEN "s" ELSE ""]]];
InterpressInterpreter.Close[master: master];
};
};
Commander.Register[key: "IPImageExtract", proc: Command, doc: "Writes one RES (Raster Encoding Standard) file for each sampled image in the specified Interpress file"];
Commander.Register[key: "InterpressImageExtract", proc: Command, doc: "Writes one RES (Raster Encoding Standard) file for each sampled image in the specified Interpress file"]