// ConvertMask.bcpl -- Scan-conversion mask interpretation // errors 600 // This module deals with mask entries in the PD file. // When an "imaging command" is read from a PD file, the procedure // MaskNew is called. This procedure decodes the command and builds // a corresponding "leftover" structure for the object. Processing // proceeds as if the leftover object had been read from a leftover // list. get "PDInternals.d" get "PDConvert.d" // outgoing procedures external [ MaskInit MaskFinish MaskNew ] // incoming procedures external [ //ConvertPut PutRun PutBits // ConvertUtils LoadRead UMax UMin //WINDOW WindowRead WindowReadBlock WindowGetPosition WindowSetPosition //PDPRINT FSGetX FSPutZ PDError //PDML MulDiv MulFull DoubleAdd //OS SetBlock ] // incoming statics external [ PDWindow SMin SMax LOSizes LOProcs ] // internal statics static [ MSizes MLO ] // File-wide structure and manifest declarations. // Procedures let MaskInit() be [ MSizes=FSGetX(imagingMax+1) MLO=FSGetX(imagingMax+1) MSizes!maskSamplesRef= size MaskSamplesRef/16 MSizes!maskRunGroupRef=size MaskRunGroupRef/16 MSizes!maskRectangle=size MaskRectangle/16 MSizes!maskTrapezoid=size MaskTrapezoid/16 MSizes!maskRunGroup=size MaskRunGroup/16 MSizes!maskSamples=size MaskSamples/16 MSizes!colorSamples=size ColorSamples/16 MLO!maskSamplesRef=loSamples MLO!maskRunGroupRef=loRunGroup MLO!maskRectangle=loRectangle MLO!maskTrapezoid=loTrapezoid MLO!maskRunGroup=loRunGroup MLO!maskSamples=loSamples MLO!colorSamples=loColorSamples LOProcs!loRectangle=Rectangle LOProcs!loTrapezoid=Trapezoid LOProcs!loRunGroup=RunGroup LOProcs!loSamples=Samples LOProcs!loColorSamples=Samples LOSizes!loRectangle=size LORectangle/16 LOSizes!loTrapezoid=size LOTrapezoid/16 LOSizes!loRunGroup=size LORunGroup/16 LOSizes!loSamples=size LOSamples/16 ] and MaskFinish() be [ FSPutZ(lv MSizes) FSPutZ(lv MLO) ] // MaskNew -- called with fresh entry from PD file // command = first word of PD file entry // w = window on PD file // v = vector in which to build leftover description and MaskNew(command, w, v) = valof [ let m=v+(size Command/16) //PD structure: bypass command word let com=command<<Command.com if com ugr imagingMax then PDError(600) WindowReadBlock(w, m, MSizes!com) v!0=MLO!com //Leftover type switchon com into [ case maskRectangle: case maskTrapezoid: endcase case maskRunGroup: v>>LORunGroup.addr=-1 v>>LORunGroup.fOffset=0 endcase case maskSamples: case colorSamples: v>>LOSamples.addr=-1 if v>>LOSamples.sSize eq 0 then resultis false //Nothing to do endcase case maskSamplesRef: [ let fMin=m>>MaskSamplesRef.fMin let sMin=m>>MaskSamplesRef.sMin if command<<Command.rest ne 0 then PDError(602) let addr=m>>MaskSamplesRef.addr v>>LOSamples.fMin=fMin v>>LOSamples.sMin=sMin compileif offset SampleArray.sSize ne 0 then [ foo=nil ] compileif offset SampleArray.fSize ne 16 then [ foo=nil ] v>>LOSamples.sSize=LoadRead(addr) v>>LOSamples.fSize=LoadRead(addr+1) v>>LOSamples.addr=addr+2 if v>>LOSamples.sSize eq 0 then resultis false //Nothing to do ] endcase case maskRunGroupRef: [ let fMin=m>>MaskRunGroupRef.fMin let sMin=m>>MaskRunGroupRef.sMin if command<<Command.rest ne 0 then PDError(602) let addr=m>>MaskRunGroupRef.addr v>>LORunGroup.fOffset=fMin v>>LORunGroup.sMin=sMin compileif offset RunGroup.sSize ne 0 then [ foo=nil ] v>>LORunGroup.sSize=LoadRead(addr) v>>LORunGroup.addr=addr+1 if v>>LORunGroup.sSize eq 0 then resultis false //Nothing to do ] endcase ] let loNeeded=(LOProcs!(v!0))(v) if loNeeded then [ if com eq maskRunGroup % com eq maskSamples % com eq colorSamples then PDError(601) ] resultis loNeeded ] and Rectangle(v) = valof [ let sFirst,sLast=nil,nil let c=BandClip(v>>LORectangle.sMin, v>>LORectangle.sSize, lv sFirst, lv sLast) PutRun(sFirst, sLast, v>>LORectangle.fMin, v>>LORectangle.fSize) resultis c ] and Trapezoid(v) = valof [ let sFirst,sLast=nil,nil let c=BandClip(v>>LOTrapezoid.sMin, v>>LOTrapezoid.sSize, lv sFirst, lv sLast) let denom=v>>LOTrapezoid.sSize for s=sFirst to sLast do [ let num=s+SMin-v>>LOTrapezoid.sMin let difMin=v>>LOTrapezoid.fMinLast-v>>LOTrapezoid.fMin let fm=nil test difMin ge 0 then fm=MulDiv(difMin, num, denom) or fm=-MulDiv(-difMin, num, denom) let difTop=difMin+v>>LOTrapezoid.fSizeLast-v>>LOTrapezoid.fSize let ft=nil test difTop ge 0 then ft=MulDiv(difTop, num, denom) or ft=-MulDiv(-difTop, num, denom) let fs=ft-fm+v>>LOTrapezoid.fSize if fs ne 0 then PutRun(s, s, fm+v>>LOTrapezoid.fMin, fs) ] resultis c ] and RunGroup(v) = valof [ compileif size Run ne 32 then [ foo=nil ] //This code depends on it let sFirst,sLast=nil,nil let c=BandClip(v>>LORunGroup.sMin, v>>LORunGroup.sSize, lv sFirst, lv sLast) let pos=lv v>>LORunGroup.addr let fOffset=v>>LORunGroup.fOffset let r=vec 1 if sFirst+SMin ugr v>>LORunGroup.sMin then [ let nLines=sFirst+SMin-v>>LORunGroup.sMin for i=0 to nLines do [ r!0=PosRead(pos); r!1=PosRead(pos) ] repeatuntil r>>Run.lastRun ne 0 ] for s=sFirst to sLast do [ r!0=PosRead(pos); r!1=PosRead(pos) if r>>Run.fSize ne 0 then PutRun(s, s, r>>Run.fMin+fOffset, r>>Run.fSize) ] repeatuntil r>>Run.lastRun ne 0 if c then [ v>>LORunGroup.sSize=v>>LORunGroup.sMin+v>>LORunGroup.sSize-1-SMax v>>LORunGroup.sMin=SMax+1 //next band ] resultis c ] and Samples(v) = valof [ let sFirst,sLast=nil,nil let c=BandClip(v>>LOSamples.sMin, v>>LOSamples.sSize, lv sFirst, lv sLast) let pos=lv v>>LOSamples.addr if sFirst+SMin ugr v>>LOSamples.sMin then [ let nLines=sFirst+SMin-v>>LOSamples.sMin let wc=(v>>LOSamples.fSize+15) rshift 4 let d=vec 1 MulFull(nLines, wc, d) PosMove(pos, d) ] PutBits(sFirst, sLast, v>>LOSamples.fMin, v>>LOSamples.fSize, pos, (v!0 eq loColorSamples)) if c then [ v>>LOSamples.sSize=v>>LOSamples.sMin+v>>LOSamples.sSize-1-SMax v>>LOSamples.sMin=SMax+1 //next band ] resultis c ] and MaskError(v) = valof [ PDError(603) ] //BandClip(sMin, sSize, lv sFirst, lv sLast) // Determine whether [sMin,sSize] lies within current band. // if to left of band, error // if terminates in band, return false (no leftovers) // if overlaps into next band, return true (leftovers) // Returns in [sFirst..sLast] the scan-lines to be affected, in a // coordinate system relative to beginning of band. and BandClip(sMin, sSize, lvSFirst, lvSLast) = valof [ let sMax=sMin+sSize-1 // Check for error conditions if sMax uls sMin then PDError(604) //add overflow? if sMax uls SMin then PDError(605) if sMin ugr SMax then PDError(606) // Compute band-relative starting and finishing @lvSFirst=UMax(sMin,SMin)-SMin @lvSLast=UMin(sMax,SMax)-SMin // Decide which condition exists if sMax ule SMax then resultis false resultis true ] // Read a word from pos: // @pos=-1 means locn is in PD file // otherwise, it's a load address and PosRead(pos) = valof [ if @pos eq -1 then resultis WindowRead(PDWindow) let t=LoadRead(@pos) @pos=@pos+1 resultis t ] // Increment position by double-precision count in c and PosMove(pos, c) be [ test @pos eq -1 then [ let a=vec 2 WindowGetPosition(PDWindow, a) DoubleAdd(a, c) WindowSetPosition(PDWindow, a) ] or @pos=@pos+c!1 ]