<> <> <> <> <<>> DIRECTORY Basics USING [LongDiv, LongDivMod, LongMult], ImagerColor USING [Color, ConstantColor, SampledColor], ImagerDisplayPrivate USING [Display, DisplayRep, IVEC, RectangleProc, RunProc], ImagerPixelMap USING [DeviceRectangle, Fill, Get8Bits, PixelMap], ImagerTransformation USING [PreRotate, Transformation, Translate], PrincOps USING [zBNDCK, zINC], Real USING [RoundC]; ImagerSmoothGrayDisplayImpl: CEDAR PROGRAM IMPORTS Basics, ImagerPixelMap, ImagerTransformation, Real ~ BEGIN <<>> <> Display: TYPE ~ ImagerDisplayPrivate.Display; RunProc: TYPE ~ ImagerDisplayPrivate.RunProc; RectangleProc: TYPE ~ ImagerDisplayPrivate.RectangleProc; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; Transformation: TYPE ~ ImagerTransformation.Transformation; Color: TYPE ~ ImagerColor.Color; ConstantColor: TYPE ~ ImagerColor.ConstantColor; SampledColor: TYPE ~ ImagerColor.SampledColor; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD[ frame: ImagerPixelMap.PixelMap, -- the frame buffer pixelValue: [0..255] -- for ConstantColor ]; viewUnitsPerPixel: NAT _ 5; Create: PROC[frame: ImagerPixelMap.PixelMap, ppi: REAL _ 42] RETURNS[Display] ~ { data: Data ~ NEW[DataRep _ [frame: frame, pixelValue: 0]]; vupp: NAT ~ viewUnitsPerPixel; res: REAL ~ ppi*viewUnitsPerPixel; sSize: NAT ~ frame.sSize*vupp; fSize: NAT ~ frame.fSize*vupp; surfaceToDisplay: Transformation ~ ImagerTransformation.Translate[sSize, 0]; surfaceToDisplay.PreRotate[90]; RETURN[NEW[ImagerDisplayPrivate.DisplayRep _ [type: $SmoothGray, setColor: SetColor, maskRuns: MaskRunsConst, maskRectangles: MaskRectanglesConst, surfaceToDisplay: surfaceToDisplay, clipBox: [sMin: 0, fMin: 0, sSize: sSize, fSize: fSize], sRes: res, fRes: res, viewUnitsPerPixel: vupp, data: data]]]; }; <> <> <> <> <> <> <> <> <> <<];>> < {TerminalExtras.UnlockColorFrame[vt]}];>> <> <<};>> <<>> SetColor: PROC[display: Display, color: Color, viewOrigin: ImagerDisplayPrivate.IVEC] ~ { data: Data ~ NARROW[display.data]; WITH color SELECT FROM color: ConstantColor => { data.pixelValue _ Real.RoundC[(1-color.f)*255]; display.maskRuns _ MaskRunsConst; display.maskRectangles _ MaskRectanglesConst; }; ENDCASE => ERROR; -- not implemented }; Check: PROC[x: INTEGER, max: NAT] RETURNS[NAT] ~ TRUSTED MACHINE CODE { PrincOps.zINC; PrincOps.zBNDCK }; <> MaskRectanglesConst: PROC[display: Display, rectangles: PROC[RectangleProc]] ~ { ERROR; -- not implemented }; MaskRunsConst: PROC[display: Display, runs: PROC[RunProc]] ~ { data: Data ~ NARROW[display.data]; pixelValue: [0..255] ~ data.pixelValue; lineBuff: ARRAY [0..2050] OF INTEGER _ ALL[0]; minPixel: NAT _ data.frame.fSize; maxPixel: NAT _ 0; vupp: NAT _ display.viewUnitsPerPixel; squpp: NAT _ vupp*vupp; line: NAT _ 0; s: NAT _ line*vupp; sModVupp: NAT _ 0; fImageLimit: NAT _ data.frame.fOrigin+data.frame.fMin+data.frame.fSize; fSizeSpatial: NAT ~ data.frame.fSize*vupp; DoLine: PROC ~ { sum: NAT _ 0; pixel: NAT _ minPixel; FOR j: NAT IN [minPixel..maxPixel] DO lineBuff[j] _ sum _ sum + lineBuff[j]; ENDLOOP; lineBuff[maxPixel+1] _ LAST[NAT]; WHILE pixel <= maxPixel DO bltStart: NAT; WHILE lineBuff[pixel] = 0 DO pixel _ pixel + 1 ENDLOOP; bltStart _ pixel; WHILE lineBuff[pixel] = squpp DO pixel _ pixel + 1 ENDLOOP; IF pixel > bltStart THEN { data.frame.Fill[[line, bltStart, 1, pixel-bltStart], pixelValue]; }; IF pixel <= maxPixel AND pixel < fImageLimit THEN { oldValue: CARDINAL _ data.frame.Get8Bits[line, pixel]; mix: CARDINAL _ lineBuff[pixel]; mixedValue: CARDINAL _ Basics.LongDiv[ Basics.LongMult[oldValue, squpp-mix]+Basics.LongMult[pixelValue, mix], squpp ]; data.frame.Fill[[line, pixel, 1, 1], mixedValue]; }; IF pixel <= maxPixel THEN { pixel _ pixel + 1; }; ENDLOOP; lineBuff[maxPixel+1] _ 0; FOR j: NAT IN [minPixel..maxPixel] DO lineBuff[j] _ 0; ENDLOOP; minPixel _ data.frame.fSize; maxPixel _ 0; }; run: PROC [sMin, fMin: INTEGER, fSize: NAT] ~ { q0, r0, q1, r1: CARDINAL; f0: CARDINAL _ Check[fMin, fSizeSpatial]; f1: CARDINAL _ Check[fMin+fSize, fSizeSpatial]; WHILE s < sMin DO s _ s + 1; sModVupp _ sModVupp + 1; IF sModVupp = vupp THEN { DoLine[]; sModVupp _ 0; line _ line + 1; }; ENDLOOP; IF fSize > 0 THEN { [q0, r0] _ Basics.LongDivMod[f0, vupp]; [q1, r1] _ Basics.LongDivMod[f1, vupp]; IF q0 < minPixel THEN minPixel _ q0; IF q1 > maxPixel THEN maxPixel _ q1; lineBuff[q0] _ lineBuff[q0] + vupp - r0; lineBuff[q0+1] _ lineBuff[q0+1] + r0; lineBuff[q1] _ lineBuff[q1] + r1 - vupp; lineBuff[q1+1] _ lineBuff[q1+1] - r1; }; }; runs[run]; run[s+vupp+1, 0, 0]; }; END.