<> <> <> <> <> <<>> DIRECTORY Basics, ImagerPixelMaps, PDFileFormat, PDInterpBitmap, PDInterpOutput, PDQueue, IO, FS, Rope, PupDefs, Convert; PDInterpOutputExpandImpl: PROGRAM IMPORTS Basics, ImagerPixelMaps, PDQueue, IO, FS, Rope, PupDefs, Convert EXPORTS PDInterpOutput = BEGIN ROPE: TYPE ~ Rope.ROPE; bandMap: ImagerPixelMaps.PixelMap _ [0, 0, 0, 0, 0, 0, NIL]; scratchMap: ImagerPixelMaps.PixelMap _ [0, 0, 0, 0, 0, 0, NIL]; currentStartImage: PDFileFormat.StartImage; currentHerald: PDFileFormat.Herald; bandNumber: NAT _ 0; pdFileStream: IO.STREAM _ NIL; requestTime: ROPE _ NIL; pdFileName: ROPE _ NIL; workingDirectory: ROPE _ NIL; pageNumber: INT _ 0; msgStart: ROPE; RopeFromString: PROC [name: LONG STRING] RETURNS [ROPE] ~ { i: INTEGER _ -1; action: SAFE PROC RETURNS [CHAR] ~ TRUSTED {RETURN [name[i_i+1]]}; RETURN [Rope.FromProc[name.length, action]] }; GetWorkingDirectory: PROC [] RETURNS [ROPE] ~ { cp: FS.ComponentPositions; fullFName: Rope.ROPE; [fullFName, cp] _ FS.ExpandName["*"]; RETURN [Rope.Substr[fullFName, 0, cp.base.start]] }; GetFileNameRoot: PROC [name: ROPE] RETURNS [ROPE] ~ { cp: FS.ComponentPositions; fullFName: Rope.ROPE; [fullFName, cp] _ FS.ExpandName[name]; RETURN [Rope.Substr[fullFName, cp.base.start, cp.base.length]] }; GetCurrentRequestNumber: PROC RETURNS [number: INT _ -1] ~ { action: PROC [requestNumber: CARDINAL, request: PDQueue.Request, status: PDQueue.RequestStatus] RETURNS [continue: BOOLEAN _ TRUE] ~ { IF status = printing THEN {number _ requestNumber; continue _ FALSE}; }; PDQueue.EnumerateRequests[action]; }; WriteBlock: PROC [stream: IO.STREAM, addr: LONG POINTER, wordCount: INT] ~ { IO.UnsafePutBlock[stream, [base: addr, startIndex: 0, count: wordCount*Basics.bytesPerWord]]; }; WriteHerald: PROC [pdFileStream: IO.STREAM, herald: PDFileFormat.Herald] ~ { herald.maxLoadWord _ 0; WriteBlock[pdFileStream, @herald, SIZE[PDFileFormat.Herald]]; }; WriteStartImage: PROC [pdFileStream: IO.STREAM, startImage: PDFileFormat.StartImage] ~ { startImageCommand: PDFileFormat.Command _ [control[startImage]]; WriteBlock[pdFileStream, @startImageCommand, SIZE[PDFileFormat.Command]]; WriteBlock[pdFileStream, @startImage, SIZE[PDFileFormat.StartImage]]; }; StartImage: PUBLIC PROC [herald: PDFileFormat.Herald, startImage: PDFileFormat.StartImage, request: PDQueue.Request] RETURNS [PDInterpBitmap.BitmapDesc] = { inputName: ROPE _ RopeFromString[request.fileName]; time: ROPE _ RopeFromString[request.requestTime]; bytesPerImage: INT ~ INT[herald.imageFSize]*herald.bandSSize*startImage.nBands/8; IF NOT time.Equal[requestTime] THEN {pageNumber _ 0; requestTime _ time}; IF startImage.feed THEN { pageNumber _ pageNumber + 1; pdFileName _ Rope.Cat[ workingDirectory, GetFileNameRoot[inputName], "-", Convert.RopeFromInt[pageNumber], ".pd" ]; pdFileStream _ FS.StreamOpen[pdFileName, $create]; WriteHerald[pdFileStream, herald]; }; WriteStartImage[pdFileStream, startImage]; IO.SetLength[pdFileStream, IO.GetIndex[pdFileStream]+bytesPerImage]; bandMap _ ImagerPixelMaps.Create[0, [startImage.passBands*herald.bandSSize, startImage.fMinPage, herald.bandSSize, startImage.fSizePage]]; currentStartImage _ startImage; currentHerald _ herald; bandNumber _ 0; bandMap.Clear; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; Trim: PROC [pixelMap: ImagerPixelMaps.PixelMap, scratch: REF ImagerPixelMaps.PixelMapRep] RETURNS [ImagerPixelMaps.PixelMap] ~ { temp: ImagerPixelMaps.PixelMap _ pixelMap; IsAllZero: PROC [pixelMap: ImagerPixelMaps.PixelMap] RETURNS [BOOLEAN] = { w: ImagerPixelMaps.DeviceRectangle _ pixelMap.Window; t: ImagerPixelMaps.PixelMap _ scratch.Reshape[0, w]; t.Clear; t.Transfer[pixelMap]; TRUSTED { p: LONG POINTER TO WORD _ t.refRep.pointer; FOR i: LONG CARDINAL IN [0..Basics.LongMult[pixelMap.refRep.lines, pixelMap.refRep.rast]) DO IF (p+i)^ # 0 THEN RETURN [FALSE]; ENDLOOP; }; RETURN [TRUE] }; WHILE pixelMap.sSize > 0 DO temp.sSize _ 1; temp.sMin _ pixelMap.sMin+pixelMap.sSize-1; IF IsAllZero[temp] THEN {pixelMap.sSize _ pixelMap.sSize - 1} ELSE EXIT; ENDLOOP; WHILE pixelMap.sSize > 0 DO temp.sSize _ 1; temp.sMin _ pixelMap.sMin; IF IsAllZero[temp] THEN {pixelMap.sSize _ pixelMap.sSize - 1; pixelMap.sMin _ pixelMap.sMin + 1} ELSE EXIT; ENDLOOP; IF pixelMap.sSize = 0 THEN pixelMap.fSize _ 0; temp _ pixelMap; WHILE pixelMap.fSize > 0 DO temp.fSize _ 1; temp.fMin _ pixelMap.fMin+pixelMap.fSize-1; IF IsAllZero[temp] THEN {pixelMap.fSize _ pixelMap.fSize - 1} ELSE EXIT; ENDLOOP; WHILE pixelMap.fSize > 0 DO temp.fSize _ 1; temp.fMin _ pixelMap.fMin; IF IsAllZero[temp] THEN {pixelMap.fSize _ pixelMap.fSize - 1; pixelMap.fMin _ pixelMap.fMin + 1} ELSE EXIT; ENDLOOP; IF pixelMap.fSize = 0 THEN pixelMap.sSize _ 0; RETURN [pixelMap] }; EndBand: PUBLIC PROC RETURNS [PDInterpBitmap.BitmapDesc] = { trimmedBand: ImagerPixelMaps.PixelMap _ Trim[bandMap, scratchMap.refRep]; endBandCommand: PDFileFormat.Command _ [control[endBand]]; IF trimmedBand.sSize > 0 THEN { w: ImagerPixelMaps.DeviceRectangle _ trimmedBand.Window; colorCommand: PDFileFormat.Command _ [imaging[colorSamples]]; args: PDFileFormat.ColorSamples _ [ sMin: w.sMin, fMin: w.fMin ]; sampleArray: PDFileFormat.SampleArray _ [ sSize: w.sSize, fSize: w.fSize ]; scratchMap _ scratchMap.refRep.Reshape[0, w]; scratchMap.Clear; scratchMap.Transfer[trimmedBand]; WriteBlock[pdFileStream, @colorCommand, SIZE[PDFileFormat.Command]]; WriteBlock[pdFileStream, @args, SIZE[PDFileFormat.ColorSamples]]; WriteBlock[pdFileStream, @sampleArray, SIZE[PDFileFormat.SampleArray]]; WriteBlock[pdFileStream, scratchMap.refRep.pointer, Basics.LongMult[scratchMap.refRep.rast, w.sSize]]; }; WriteBlock[pdFileStream, @endBandCommand, SIZE[PDFileFormat.Command]]; bandNumber _ bandNumber + 1; bandMap _ bandMap.ShiftMap[currentHerald.bandSSize, 0]; bandMap.Clear; IF bandNumber > currentStartImage.nBands THEN ERROR; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; EndImage: PUBLIC PROC [request: PDQueue.Request] = { IF currentStartImage.strip THEN { endDocumentCommand: PDFileFormat.Command _ [control[endDocument]]; rope: ROPE ~ msgStart.Concat[pdFileName.Substr[4]]; message: LONG STRING = [200]; FOR i: INT IN [0..rope.Length) DO message[i] _ rope.Fetch[i]; ENDLOOP; message.length _ rope.Length; WriteBlock[pdFileStream, @endDocumentCommand, SIZE[PDFileFormat.Command]]; IO.SetLength[pdFileStream, IO.GetIndex[pdFileStream]]; pdFileStream.Close; pdFileStream _ NIL; bandMap.refRep _ scratchMap.refRep _ NIL; PDQueue.LogMessage[message, GetCurrentRequestNumber[], request.requestor]; }; }; ReprintLastPage: PUBLIC PROC [copies: CARDINAL] = { }; ReadQueue: PROC [address: LONG POINTER, nwords: CARDINAL] = TRUSTED { stream: IO.STREAM; stream _ FS.StreamOpen["[]<>PeachExpand.queue", $read, ALL[FALSE] ! FS.Error => CONTINUE]; IF stream#NIL THEN { [] _ stream.UnsafeGetBlock[[base: address, startIndex: 0, count: nwords*2]]; stream.Close; }; }; WriteQueue: PROC [address: LONG POINTER, nwords: CARDINAL] = TRUSTED { stream: IO.STREAM _ FS.StreamOpen["[]<>PeachExpand.queue", $create]; [] _ stream.UnsafePutBlock[[base: address, startIndex: 0, count: nwords*2]]; stream.Close; }; RegisterDisk: PROC = {PDQueue.RegisterDisk[ReadQueue, WriteQueue, 16*1024]}; Init: PROC ~ { RegisterDisk[]; workingDirectory _ GetWorkingDirectory[]; msgStart _ IO.PutFR["Output page: [%g]", IO.rope[PupDefs.GetMyName[]]]; }; Init[]; END.