ColorSeparateCommand: Commander.CommandProc ~
TRUSTED {
fileStem: ROPE ~ IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc].token;
localStem: ROPE ~ LocalName[fileStem];
redAIS: AIS.FRef ~ AIS.OpenFile[fileStem.Concat["-red.AIS"]];
greenAIS: AIS.FRef ~ AIS.OpenFile[fileStem.Concat["-green.AIS"]];
blueAIS: AIS.FRef ~ AIS.OpenFile[fileStem.Concat["-blue.AIS"]];
comment: ROPE ← AIS.ReadComment[redAIS];
these three muat be the same to proceed safefly
redRaster: AIS.Raster ~ AIS.ReadRaster[redAIS];
greenRaster: AIS.Raster ~ AIS.ReadRaster[greenAIS];
blueRaster: AIS.Raster ~ AIS.ReadRaster[blueAIS];
redW: AIS.WRef ~ AIS.OpenWindow[redAIS];
greenW: AIS.WRef ~ AIS.OpenWindow[greenAIS];
blueW: AIS.WRef ~ AIS.OpenWindow[blueAIS];
redBuffer: REF BufferRep ← NEW[BufferRep ← [redRaster.scanLength]];
greenBuffer: REF BufferRep ← NEW[BufferRep ← [redRaster.scanLength]];
blueBuffer: REF BufferRep ← NEW[BufferRep ← [redRaster.scanLength]];
redBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @redBuffer.buffer];
greenBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @greenBuffer.buffer];
blueBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @blueBuffer.buffer];
blackAIS: AIS.FRef ~ AIS.CreateFile[localStem.Concat["-black.AIS"], redRaster, 1];
cyanAIS: AIS.FRef ~ AIS.CreateFile[localStem.Concat["-cyan.AIS"], redRaster, 1];
magentaAIS: AIS.FRef ~ AIS.CreateFile[localStem.Concat["-magenta.AIS"], redRaster, 1];
yellowAIS: AIS.FRef ~ AIS.CreateFile[localStem.Concat["-yellow.AIS"], redRaster, 1];
blackW: AIS.WRef ~ AIS.OpenWindow[blackAIS];
cyanW: AIS.WRef ~ AIS.OpenWindow[cyanAIS];
magentaW: AIS.WRef ~ AIS.OpenWindow[magentaAIS];
yellowW: AIS.WRef ~ AIS.OpenWindow[yellowAIS];
blackRaster: AIS.Raster ~ redRaster;
blackBuffer: REF BufferRep ← NEW[BufferRep ← [redRaster.scanLength]];
blackBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @blackBuffer.buffer];
this is where the mapping of color separations is buried
cyanBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @redBuffer.buffer];
magentaBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @greenBuffer.buffer];
yellowBufferDesc: AIS.Buffer ← [length: redRaster.scanLength, addr: @blueBuffer.buffer];
cmd.out.PutRope[comment];
If the comment is longer than 256 characters (an AIS file format limitation) then truncate it with an ellipsis.
IF comment.Length > 256 THEN comment ← Rope.Cat[comment.Substr[0, 251], "...\n"];
IF redRaster.bitsPerPixel # 8
THEN
RETURN [$Failure, "sorry, but only 8-bits-per-pixel implemented"];
IF redRaster^ # greenRaster^
OR redRaster^ # blueRaster^
THEN
RETURN [$Failure, "rasters for the three input separations did not match"];
cmd.out.PutRope["Starting color separations"];
AIS.WriteComment[blackAIS, comment];
AIS.WriteComment[cyanAIS, comment];
AIS.WriteComment[magentaAIS, comment];
AIS.WriteComment[yellowAIS, comment];
FOR i:
NAT
IN [0..redRaster.scanCount)
DO
read the three input color separations
AIS.UnsafeReadLine[redW, redBufferDesc, i];
AIS.UnsafeReadLine[greenW, greenBufferDesc, i];
AIS.UnsafeReadLine[blueW, blueBufferDesc, i];
FOR i:
NAT
IN [0..redRaster.scanCount)
DO
blackBuffer.buffer[i] ← LAST[Pixel];
ENDLOOP;
ColorSeparate[redBuffer, greenBuffer, blueBuffer, blackBuffer];
AIS.UnsafeWriteLine[blackW, blackBufferDesc, i];
AIS.UnsafeWriteLine[cyanW, cyanBufferDesc, i];
AIS.UnsafeWriteLine[magentaW, magentaBufferDesc, i];
AIS.UnsafeWriteLine[yellowW, yellowBufferDesc, i];
ENDLOOP;
AIS.CloseFile[blackAIS];
AIS.CloseFile[cyanAIS];
AIS.CloseFile[magentaAIS];
AIS.CloseFile[yellowAIS];
cmd.out.PutRope[". . . Done\n"]
};
Commander.Register[key: "FourColorSeparation", proc: ColorSeparateCommand, doc: "FourColorSeparation fileStem produces the <black, cyan, magenta, yellow> AIS files from <red, green, blue> AIS input files"];