DIRECTORY Basics, DynamicBits, ImagerPixelMap, ImagerSample, PixelMapOps, PrincOps, PrincOpsUtils, Random; DynamicBitsImpl: CEDAR PROGRAM IMPORTS ImagerPixelMap, ImagerSample, PixelMapOps, PrincOpsUtils, Basics, Random EXPORTS DynamicBits ~ BEGIN OPEN DynamicBits; SampleBuffer: TYPE ~ ImagerSample.SampleBuffer; ModelParameterFault: PUBLIC ERROR [data: REF] ~ CODE; MakePixelMapFromBits: PUBLIC PROC [ bitPointer: LONG POINTER, bitsPerLine: NAT, window: DeviceRectangle, scratch: REF ImagerPixelMap.PixelMapRep ] RETURNS [pixelMap: PixelMap] = TRUSTED { bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; pixelMap _ scratch.Reshape[0, window]; bb^ _ [ dst: [word: pixelMap.refRep.pointer, bit: 0], dstBpl: pixelMap.refRep.rast*Basics.bitsPerWord, src: [word: bitPointer, bit: 0], srcDesc: [srcBpl[bitsPerLine]], height: window.sSize, width: window.fSize, flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: null, dstFunc: null] ]; PrincOpsUtils.BITBLT[bb]; }; CreatePrinterModel: PUBLIC PROC [neighborhood: DeviceRectangle, printerModel: PrinterModel, kernel: PixelMap] RETURNS [model: Model] ~ { model _ FindClass[neighborhood, kernel.Window].CreatePrinterModel[neighborhood, printerModel, kernel]; }; RotatePixelMap: PROC [pm: PixelMap, scratch: REF ImagerPixelMap.PixelMapRep _ NIL] RETURNS [PixelMap] ~ { RETURN [ImagerPixelMap.ShiftMap[ImagerPixelMap.Rotate[pm, scratch], 0, 1]]; }; RotateModel: PUBLIC PROC [model: Model] RETURNS [new: Model] ~ { kernel: PixelMap ~ RotatePixelMap[model.kernel]; t: PixelMap ~ ImagerPixelMap.Create[0, model.neighborhood]; neighborhood: DeviceRectangle ~ ImagerPixelMap.Window[RotatePixelMap[t]]; action: PROC [oldPrinterModel: PrinterModel] ~ { printerModel: PROC [bitmap: PixelMap, encoding: CARDINAL] RETURNS [i: Intensity, n: NoisePenalty] ~ { b: PixelMap ~ RotatePixelMap[bitmap, t.refRep]; w: DeviceRectangle ~ ImagerPixelMap.Window[b]; e: CARDINAL _ 0; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO FOR f: INTEGER IN [w.fMin..w.fMin+w.fSize) DO e _ 2*e + ImagerPixelMap.GetPixel[b, s, f]; ENDLOOP; ENDLOOP; [i,n] _ oldPrinterModel[b, e]; }; new _ CreatePrinterModel[neighborhood, printerModel, kernel]; }; FindClass[model.neighborhood, model.kernel.Window].DoWithPrinterModel[model, action]; }; Convolve: PUBLIC PROC [pixelMap: PixelMap, kernel: Kernel, unitIntensity: CARDINAL] ~ { FindClass[[0,0,1,1], kernel.Window].Convolve[pixelMap, kernel, unitIntensity]; }; Run: TYPE ~ RECORD [s: INTEGER, f: INTEGER, count: NAT]; GetRow: PROC [row: SampleBuffer, pixelMap: PixelMap, run: Run] ~ INLINE { PixelMapOps.GetF[pixelMap: pixelMap, s: run.s, f: run.f, buffer: row, bi: 0, bj: 0, count: run.count]; }; PutRow: PROC [row: SampleBuffer, pixelMap: PixelMap, run: Run] ~ INLINE { PixelMapOps.PutF[pixelMap: pixelMap, s: run.s, f: run.f, buffer: row, bi: 0, bj: 0, count: run.count]; }; KernelWeight: PUBLIC PROC [kernel: Kernel] RETURNS [weight: INT _ 0] ~ { w: DeviceRectangle _ kernel.BoundedWindow; row: SampleBuffer _ ImagerSample.NewBuffer[iSize: 1, jSize: w.fSize]; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO GetRow[row, kernel, [s, w.fMin, w.fSize]]; FOR j: NAT IN [0..w.fSize) DO weight _ weight + LOOPHOLE[row[j], INTEGER]; ENDLOOP; ENDLOOP; }; AddBorder: PUBLIC PROC [pixelMap: PixelMap, borderSize: NAT, borderValue: CARDINAL] RETURNS [bordered: PixelMap] ~ { w: DeviceRectangle _ pixelMap.Window; w.sMin _ w.sMin - borderSize; w.fMin _ w.fMin - borderSize; w.sSize _ w.sSize + 2*borderSize; w.fSize _ w.fSize + 2*borderSize; bordered _ ImagerPixelMap.Create[pixelMap.refRep.lgBitsPerPixel, w]; bordered.Fill[w, borderValue]; bordered.Transfer[pixelMap]; }; ErrorOf: PUBLIC PROC [gray: PixelMap, bitmap: PixelMap, model: Model] RETURNS [INT] ~ { t: PixelMap _ ApplyModel[bitmap, model]; Convolve[t, model.kernel, 255]; RETURN [AbsDiff[gray, t]]; }; debug: BOOLEAN _ TRUE; ApplyModel: PUBLIC PROC [bitmap: PixelMap, model: Model] RETURNS [PixelMap] ~ { RETURN [FindClass[model.neighborhood, model.kernel.Window].ApplyModel[bitmap, model]]; }; AbsDiff: PUBLIC PROC [a, b: PixelMap] RETURNS [error: INT _ 0] ~ { w: DeviceRectangle _ ImagerPixelMap.Intersect[a.BoundedWindow, b.BoundedWindow]; ar: SampleBuffer _ ImagerSample.NewBuffer[iSize: 1, jSize: w.fSize]; br: SampleBuffer _ ImagerSample.NewBuffer[iSize: 1, jSize: w.fSize]; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO GetRow[ar, a, [s, w.fMin, w.fSize]]; GetRow[br, b, [s, w.fMin, w.fSize]]; FOR j: NAT IN [0..w.fSize) DO error _ error + ABS[LOOPHOLE[ar[j], INTEGER]-LOOPHOLE[br[j], INTEGER]]; ENDLOOP; ENDLOOP; }; RandomDither: PUBLIC PROC [gray: PixelMap] RETURNS [bitmap: PixelMap] ~ { w: DeviceRectangle _ gray.Window; row: SampleBuffer _ ImagerSample.NewBuffer[iSize: 1, jSize: w.fSize]; maxPixel: CARDINAL _ Basics.BITSHIFT[1, Basics.BITSHIFT[1, gray.refRep.lgBitsPerPixel]]-1; random: Random.RandomStream _ Random.Create[seed: 283745734]; bitmap _ ImagerPixelMap.Create[0, w]; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO GetRow[row, gray, [s, w.fMin, w.fSize]]; FOR j: NAT IN [0..w.fSize) DO row[j] _ IF Random.ChooseInt[random, 1, maxPixel] > row[j] THEN 0 ELSE 1; ENDLOOP; PutRow[row, bitmap, [s, w.fMin, w.fSize]]; ENDLOOP; }; FindFixedBits: PUBLIC PROC [gray: PixelMap, radius: NAT] RETURNS [fixedBits: PixelMap] ~ { w: DeviceRectangle _ gray.Window; row: SampleBuffer _ ImagerSample.NewBuffer[iSize: 1, jSize: w.fSize]; maxPixel: CARDINAL _ Basics.BITSHIFT[1, Basics.BITSHIFT[1, gray.refRep.lgBitsPerPixel]]-1; zeros: PixelMap _ ImagerPixelMap.Create[0, w]; ones: PixelMap _ ImagerPixelMap.Create[0, w]; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO GetRow[row, gray, [s, w.fMin, w.fSize]]; FOR j: NAT IN [0..w.fSize) DO pix: CARDINAL _ row[j]; row[j] _ IF pix = 255 THEN 1 ELSE 0; ENDLOOP; PutRow[row, ones, [s, w.fMin, w.fSize]]; ENDLOOP; FOR s: INTEGER IN [w.sMin..w.sMin+w.sSize) DO GetRow[row, gray, [s, w.fMin, w.fSize]]; FOR j: NAT IN [0..w.fSize) DO pix: CARDINAL _ row[j]; row[j] _ IF pix = 0 THEN 1 ELSE 0; ENDLOOP; PutRow[row, zeros, [s, w.fMin, w.fSize]]; ENDLOOP; FOR i: NAT IN [0..radius) DO ones.Transfer[ones.ShiftMap[-1, 0], [and, null]]; ones.Transfer[ones.ShiftMap[1, 0], [and, null]]; ones.Transfer[ones.ShiftMap[0, 1], [and, null]]; ones.Transfer[ones.ShiftMap[0, -1], [and, null]]; ENDLOOP; FOR i: NAT IN [0..radius) DO zeros.Transfer[zeros.ShiftMap[-1, 0], [and, null]]; zeros.Transfer[zeros.ShiftMap[1, 0], [and, null]]; zeros.Transfer[zeros.ShiftMap[0, 1], [and, null]]; zeros.Transfer[zeros.ShiftMap[0, -1], [and, null]]; ENDLOOP; fixedBits _ zeros; fixedBits.Transfer[ones, [or, null]]; }; TuneSwath: PUBLIC PROC [gray: PixelMap, bitmap: PixelMap, fixedBits: PixelMap, swath: DeviceRectangle, model: Model, scratch: REF] RETURNS [newScratch: REF] ~ { newScratch _ FindClass[model.neighborhood, model.kernel.Window, swath.fSize].TuneSwath[gray, bitmap, fixedBits, swath, model, scratch]; }; registeredClasses: LIST OF Class _ NIL; FindClass: PROC [neighborhood, kernelBounds: DeviceRectangle, swathSize: NAT _ 1] RETURNS [Class] ~ { sModelRadius: NAT _ -neighborhood.sMin; fModelRadius: NAT _ -neighborhood.fMin; sKernelRadius: NAT _ -kernelBounds.sMin; fKernelRadius: NAT _ -kernelBounds.fMin; FOR p: LIST OF Class _ registeredClasses, p.rest UNTIL p=NIL DO IF p.first.sKernelRadius = sKernelRadius AND p.first.fKernelRadius = fKernelRadius AND p.first.sModelRadius = sModelRadius AND p.first.fModelRadius = fModelRadius AND p.first.swathSize = swathSize THEN RETURN [p.first] ENDLOOP; ModelParameterFault[$UnsupportedParameterCombination]; }; RegisterImpl: PUBLIC PROC [class: Class] ~ { registeredClasses _ CONS[class, registeredClasses]; }; END. ΖDynamicBitsImpl.mesa Copyright (C) 1984, 1985, Xerox Corporation. All rights reserved. Michael Plass, November 6, 1985 11:25:49 am PST Rotates counterclockwise about the point s=1/2, f=1/2; Κ ˜šœ™JšœB™BJšœ/™/—J˜JšΟk œa˜jJ˜JšΠlnœœ˜JšœI˜PJšœ ˜šœœœ ˜J˜šœœ˜/J˜—Jš œœœœœ˜5J˜šΟnœœœ˜#Jšœ œœ˜Jšœ œ˜J˜Jšœ œ˜'Jšœœœ˜*J˜$J˜AJ˜&˜J˜-J˜0J˜ J˜J˜J˜Jšœ&œœœ˜kJ˜—Jšœœ˜J˜J˜—šŸœœœOœ˜ˆJšœf˜fJ˜J˜—codeš Ÿœœœœœ˜iK™6KšœE˜KKšœ˜K˜—šŸ œœœœ˜@Kšœ0˜0Kšœ;˜;KšœI˜Išœœ$˜0šœœœœ$˜eKšœ/˜/Kšœ.˜.Kšœœ˜šœœœ˜-šœœœ˜-Kšœ+˜+Kšœ˜—Kšœ˜—Kšœ˜Kšœ˜—Kšœ=˜=Kšœ˜—KšœU˜UKšœ˜J˜—šŸœœœ5œ˜WJšœN˜NJ˜J˜—š œœœœœ œ˜8K˜—šŸœœ5œ˜IKšœf˜fKšœ˜J˜—šŸœœ5œ˜IKšœf˜fKšœ˜J˜—š Ÿ œœœœ œ ˜HJ˜*JšœE˜Ešœœœ˜-Jšœ*˜*šœœœ˜Jšœœ œ˜,Jšœ˜—Jšœ˜—J˜J˜—š Ÿ œœœ"œœœ˜tJ˜%J˜J˜J˜!J˜!JšœD˜DJ˜J˜J˜J˜—š Ÿœœœ2œœ˜WJ˜(Jšœ˜Jšœ˜J˜J˜—Jšœœœ˜šŸ œœœ"œ˜OJšœP˜VJ˜J˜—š Ÿœœœœ œ ˜BJšœP˜PJšœD˜DJšœD˜Dšœœœ˜-Jšœ$˜$Jšœ$˜$šœœœ˜Jš œœœœœœ˜GJšœ˜—Jšœ˜—J˜J˜—šŸ œœœœ˜IJšœ!˜!JšœE˜EJšœ œ œ œ#˜ZJšœ=˜=Jšœ%˜%šœœœ˜-Jšœ(˜(šœœœ˜Jšœ œ0œœ˜IJšœ˜—Jšœ*˜*Jšœ˜—Jšœ˜J˜—š Ÿ œœœœœ˜ZJšœ!˜!JšœE˜EJšœ œ œ œ#˜ZJšœ.˜.Jšœ-˜-šœœœ˜-Jšœ(˜(šœœœ˜Jšœœ ˜Jšœ œ œœ˜$Jšœ˜—Jšœ(˜(Jšœ˜—šœœœ˜-Jšœ(˜(šœœœ˜Jšœœ ˜Jšœ œ œœ˜"Jšœ˜—Jšœ)˜)Jšœ˜—šœœœ ˜Jšœ1˜1Jšœ0˜0Jšœ0˜0Jšœ1˜1Jšœ˜—šœœœ ˜Jšœ3˜3Jšœ2˜2Jšœ2˜2Jšœ3˜3Jšœ˜—Jšœ˜Jšœ%˜%Jšœ˜J˜—š Ÿ œœœhœœœ˜ Jšœ‡˜‡J˜J˜—šœœœ œ˜'J˜—šŸ œœ:œœ ˜eJšœœ˜'Jšœœ˜'Jšœœ˜(Jšœœ˜(š œœœ#œœ˜?Jšœ&˜(Jšœ&˜)Jšœ$˜'Jšœ$˜'Jšœ˜!Jšœœ ˜Jšœ˜—Jšœ6˜6Jšœ˜J˜—šŸ œœœ˜,Jšœœ˜3Jšœ˜J˜—Jšœ˜——…—$&τ