ConvertToRastersImpl.mesa
Copyright Ó 1987, 1988 by Xerox Corporation. All rights reserved.
Maureen Stone, May 26, 1989 5:08:11 pm PDT
Doug Wyatt, April 12, 1988 7:18:34 pm PDT
Tow, March 13, 1989 7:13:16 pm PST
Takes an Interpress Master and generates color correct rasters
DIRECTORY
ConvertToRasters, Imager, Interpress, ImagerSmoothContext, ImagerSmoothContextExtras, ImagerSample, ImagerPixel, Rope, PrintColor, ImagerBackdoor, CedarProcess, VM, ConvertRasterObject, SF, ImagerPixelArray, ImagerInterpress, ImagerColor, ImagerBox, ImagerColorFns, ImagerTransformation, ImagerMaskCapture, VMSideDoor;
ConvertToRastersImpl: CEDAR PROGRAM
IMPORTS Interpress, ImagerSmoothContext, ImagerPixel, ImagerSmoothContextExtras, Imager, ImagerBackdoor, CedarProcess, VM, ConvertRasterObject, Rope, ImagerPixelArray, ImagerInterpress, ImagerColor, ImagerColorFns, ImagerTransformation, ImagerMaskCapture, ImagerBox, VMSideDoor
EXPORTS ConvertToRasters
~ BEGIN OPEN ConvertToRasters;
ROPE: TYPE ~ Rope.ROPE;
Context: TYPE ~ Imager.Context;
PixelMap: TYPE ~ ImagerPixel.PixelMap;
ColorCorrection: TYPE = PrintColor.ColorCorrection;
Interpress to Rasters
Convert: PUBLIC PROC [action: PROC[Imager.Context], rasterSpec: RasterSpec, proc: RasterProc] RETURNS [nBands: NAT] = {
pm: PixelMap ← NIL;
inch: REAL = 0.0254; -- inches->meters conversion factor
nLines: NAT ~ rasterSpec.sSize;
line: NAT ← 0;
stop: BOOLEANFALSE;
ctx: Context;
samplesPerPixel: NATSELECT rasterSpec.type FROM
rgb => 3, gray => 1, cmyk => 4, ENDCASE => ERROR;
pixels: ImagerPixel.PixelBuffer ← ImagerPixel.ObtainScratchPixels[samplesPerPixel, rasterSpec.fSize];
CedarProcess.SetPriority[background];
nBands ← 1;
WHILE line<nLines DO
do: PROC = {action[ctx]};
bandSize, bandLines: NAT;
DO  --allocate may fail. If so, do it in bands.
failed: BOOLEANFALSE;
bandSize ← (nLines+nBands-1)/nBands;
bandLines ← MIN[bandSize, nLines-line];
rasterSpec.sSize ← bandSize;
IF VM.PagesForWords[INT[rasterSpec.sSize]*rasterSpec.fSize/BITS[WORD]*samplesPerPixel] > VMSideDoor.rmPages/4
THEN failed ← TRUE
ELSE [ctx, pm] ← CreateContext[rasterSpec, pm, 1 ! VM.CantAllocate => {failed ← TRUE; CONTINUE}];
IF failed THEN {
nBands ← nBands+1;
ctx ← NIL;
}
ELSE EXIT;
ENDLOOP;
Imager.TranslateT[ctx, [0,(line-nLines+bandSize)]];
Imager.DoSave[ctx, do];
FOR j: NAT IN [0..bandLines) DO
ImagerPixel.GetPixels[self: pm, initIndex: [s: j, f: 0], delta: [s: 0, f: 1],
pixels: pixels, start: 0, count: rasterSpec.fSize];
IF proc[pixels] THEN {stop ← TRUE; EXIT};
ENDLOOP;
IF stop THEN EXIT;
line ← line+bandLines;
ENDLOOP;
ImagerPixel.ReleaseScratchPixels[pixels];
RETURN[nBands];
};
ToPixelMap: PUBLIC PROC [action: PROC[Imager.Context], rasterSpec: RasterSpec] RETURNS[PixelMap] = {
ctx: Context;
pm: PixelMap;
CedarProcess.SetPriority[background];
[ctx, pm] ← CreateContext[rasterSpec, NIL, 1];
action[ctx];
RETURN[pm];
};
CreateContext: PROC [rs: RasterSpec, pm: PixelMap ← NIL, defaultScale: REAL] RETURNS [Context, PixelMap] ~ {
context: Context ← ImagerSmoothContext.Create[
size: [s: rs.sSize, f: rs.fSize], scanMode: rs.scanMode,
initialScale: defaultScale, cacheFonts: TRUE,
surfaceUnitsPerPixel: rs.surfaceUnitsPerPixel];
samplesPerPixel: NAT;
components: LIST OF ATOM ;
maxSample: ImagerPixel.PixelProc = {RETURN[rs.maxPixel]};
SELECT rs.type FROM
gray => {samplesPerPixel ← 1; components ← LIST[$Intensity]};
rgb => {samplesPerPixel ← 3; components ← LIST[$Red, $Green, $Blue]};
cmyk => {samplesPerPixel ← 4; components ← LIST[$Cyan, $Magenta, $Yellow, $Black]};
ENDCASE => ERROR;
IF pm=NIL THEN--allows us to reuse the pixelmap
pm ← ImagerPixel.NewPixelMap[samplesPerPixel, [[0,0],[s: rs.sSize, f: rs.fSize]], maxSample];
ImagerSmoothContext.SetOutputBuffer[context, pm, components];
ImagerSmoothContextExtras.SetColorCorrection[context, rs.colorCorrection];
Imager.SetColor[context, Imager.MakeGray[0]]; --set the master to white
Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]];
Imager.SetColor[context, Imager.MakeGray[1]]; --set the current color to black
RETURN[context, pm];
};
Convenience procedures for Interpress, AIS
FromIP: PUBLIC PROC [ip: ROPE, ppiF,ppiS: REAL, page: NAT ← 1, rasterSpec: RasterSpec, proc: RasterProc, x,y,w,h: REAL ← 0] RETURNS[nBands: NAT] = {
log: Interpress.LogProc = {};
master: Interpress.Master ← Interpress.Open[ip, log];
do: PROC[context: Imager.Context] = {
Imager.Scale2T[context, [x: ppiF/metersPerInch, y: ppiS/metersPerInch]];
IF w#0 AND h#0 THEN Imager.ClipRectangle[context, [0,0,w*metersPerInch,h*metersPerInch], FALSE];
Imager.TranslateT[context, [-x*metersPerInch,-y*metersPerInch]];
Interpress.DoPage[master, page, context, log];
};
nBands ← Convert[do, rasterSpec, proc];
Interpress.Close[master];
};
metersPerInch: REAL = 0.0254;
FromIPToPixelMap: PUBLIC PROC [ip: ROPE, ppiF,ppiS: REAL, page: NAT ← 1, rasterSpec: RasterSpec, x,y,w,h: REAL ← 0] RETURNS[PixelMap] = {
log: Interpress.LogProc = {};
master: Interpress.Master ← Interpress.Open[ip, log];
do: PROC[context: Imager.Context] = {
Imager.Scale2T[context, [x: ppiF/metersPerInch, y: ppiS/metersPerInch]];
IF w#0 AND h#0 THEN Imager.ClipRectangle[context, [0,0,w*metersPerInch,h*metersPerInch], FALSE];
Imager.TranslateT[context, [-x*metersPerInch,-y*metersPerInch]];
Interpress.DoPage[master, page, context, log];
};
pm: PixelMap ← ToPixelMap[do, rasterSpec];
Interpress.Close[master];
RETURN[pm];
};
AISFromPixelMap: PUBLIC PROC[aisRoot: ROPE, pm: PixelMap] = {
SELECT pm.samplesPerPixel FROM
1 => ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, ".ais"], pm, 0];
3 => {
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-red.ais"], pm, 0];
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-grn.ais"], pm, 1];
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-blu.ais"], pm, 2];
};
4 => {
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-cyan.ais"], pm, 0];
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-magenta.ais"], pm, 1];
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-yellow.ais"], pm, 2];
ConvertRasterObject.AISFromPixelMap[Rope.Cat[aisRoot, "-black.ais"], pm, 3];
};
ENDCASE => ERROR;
};
pointsPerInch: REAL = Imager.pointsPerInch;
IPToRasterIP: PUBLIC PROC[ipIn, ipOut: ROPE, ppiF,ppiS: REAL, page: NAT ← 1, rasterSpec: RasterSpec, x,y,w,h: REAL ← 0, tx,ty: REAL ← 0] = {
Makes and Interpress master with the pixel map imaged at 0,0. Uses the appropriate color operator depending on pm.samplesPerPixel: GrayLinear, RGBLinear or CMYKLinear.
SetSampledColor: PROC [context: Context, pa: PixelArray,
m: Transformation ← NIL, colorOperator: ColorOperator];
pm: PixelMap ← FromIPToPixelMap[ipIn, ppiF,ppiS, page, rasterSpec, x,y,w,h];
pa: ImagerPixelArray.PixelArray ← ImagerPixelArray.FromPixelMap[pm, pm.box, rasterSpec.scanMode, TRUE];
ip: ImagerInterpress.Ref ← ImagerInterpress.Create[ipOut];
op: ImagerColor.ColorOperator ← SELECT rasterSpec.type FROM
rgb => ImagerColor.NewColorOperatorRGB[maxIn: rasterSpec.maxPixel+1],
gray => ImagerColor.NewColorOperatorGrayLinear[sWhite: 255, sBlack: 0, sampleTableSize: rasterSpec.maxPixel+1, sampleTableProc: NIL],
cmyk => ImagerColorFns.NewColorOperatorCMYK[maxIn: rasterSpec.maxPixel+1],
ENDCASE => ERROR;
action: PROC[context: Imager.Context] = {
Imager.TranslateT[context, [tx*pointsPerInch,ty*pointsPerInch]];
Imager.SetSampledColor[context, pa, NIL, op];
Imager.MaskRectangle[context, [x: 0, y: 0,w: rasterSpec.fSize, h: rasterSpec.sSize]];
};
ImagerInterpress.DoPage[ip, action, Imager.metersPerPoint];
ImagerInterpress.Close[ip];
};
IPWindow: PUBLIC PROC[ip: ROPE, page: NAT ← 1, tol: REAL ← 0.02] RETURNS [x,y,w,h: REAL] = {
ppi: REAL ← 1/tol;
m: Imager.Transformation ← ImagerTransformation.Scale[ppi/0.0254];
n: Imager.Transformation ← ImagerTransformation.PostScale[m, 0.0254]; -- back to inches
master: Interpress.Master ← Interpress.Open[ip, NIL];
Operator: PROC [context: Imager.Context] ~ {
Imager.SetColor[context, Imager.black];
Imager.SetStrokeEnd[context, square];
Imager.SetStrokeWidth[context, 0.0];
Imager.SetAmplifySpace[context, 1.0];
Interpress.DoPage[master, page, context, NIL];
};
b: SF.Box ← ImagerMaskCapture.CaptureBounds[Operator, m
! ImagerMaskCapture.Cant => RESUME];
r: ImagerBox.Rectangle ← ImagerTransformation.InverseTransformRectangle[
n, ImagerBox.RectangleFromBox[[b.min.s, b.min.f, b.max.s, b.max.f]]];
RETURN[x: r.x, y: r.y, w: r.w, h: r.h];
};
CreateRasterSpec: PUBLIC PROC [type: RasterType, fSize, sSize: NAT, colorCorrection: ColorCorrection, surfaceUnitsPerPixel: NAT ← 5, scanMode: Imager.ScanMode ← Imager.defaultScanMode,maxPixel: NAT ← 255] RETURNS [RasterSpec] ~ {
RETURN[[type, fSize, sSize, surfaceUnitsPerPixel, Imager.defaultScanMode,colorCorrection,maxPixel]];
};
END.