DIRECTORY Basics, IO, PressImage, PressReader, ImagerPixelArray, ImagerColorOperator, Imager, ImagerTransformation, ImagerPixelMap, ImagerPixelArrayPrivate, SafeStorage, ImagerPixelArrayDefs, ImagerSample, PrincOps, PrincOpsUtils; PressImageImpl: CEDAR PROGRAM IMPORTS Basics, IO, ImagerPixelMap, ImagerPixelArray, ImagerColorOperator, Imager, ImagerTransformation, SafeStorage, ImagerSample, PrincOpsUtils EXPORTS PressImage, ImagerPixelArrayDefs = BEGIN Context: TYPE = Imager.Context; Transformation: TYPE = ImagerTransformation.Transformation; PixelArray: TYPE = ImagerPixelArrayDefs.PixelArray; PixelMap: TYPE = ImagerPixelMap.PixelMap; ru: NAT = 2; rd: NAT = 3; lu: NAT = 6; ld: NAT = 7; ul: NAT = 9; ur: NAT = 8; dl: NAT = 13; dr: NAT = 12; TransformationFromScanMode: PROC [scanMode: NAT, lines, pixelsPerLine: INT] RETURNS [Transformation] ~ { pixelDeltaX: REAL _ SELECT scanMode FROM ru, rd => 1, lu, ld => -1, ENDCASE => 0; pixelDeltaY: REAL _ SELECT scanMode FROM ul, ur => 1, dr, dl => -1, ENDCASE => 0; lineDeltaX: REAL _ SELECT scanMode FROM dr, ur => 1, ul, dl => -1, ENDCASE => 0; lineDeltaY: REAL _ SELECT scanMode FROM ru, lu => 1, ld, rd => -1, ENDCASE => 0; RETURN [ImagerTransformation.Create[ a: lineDeltaX, b: pixelDeltaX, c: MAX[-(pixelDeltaX*pixelsPerLine + lineDeltaX*lines), 0], d: lineDeltaY, e: pixelDeltaY, f: MAX[-(pixelDeltaY*pixelsPerLine + lineDeltaY*lines), 0] ]] }; PressImage: PUBLIC TYPE = REF PressImageData; PressImageData: PUBLIC TYPE = RECORD [ stream: IO.STREAM, streamIndex: INT, byteLength: INT, scanMode: CARDINAL, scanCount: CARDINAL, -- lines scanLength: CARDINAL, -- dots wordsPerLine: CARDINAL, -- words per scan line passDots: NAT, displayDots: NAT, passLines: NAT, displayLines: NAT, imageHeight: REAL, imageWidth: REAL, lgBitsPerPixel: [0..4], isBitmap: BOOL ]; PressImageError: PUBLIC ERROR = CODE; MakePressImage: PUBLIC PROC [sampleType, dots, lines, mode, pd, dd, pl, dl: INT, width, height: REAL, bits: PressReader.Dots] RETURNS [self: PressImage _ NIL] = { bitsperline: LONG CARDINAL _ Basics.LongMult[dots, IF sampleType IN [1..16] THEN sampleType ELSE 1]; wpl: CARDINAL _ (bitsperline + (bitsPerWord-1)) / bitsPerWord; lgBitsPerPixel: [0..4] ~ SELECT sampleType FROM 0, 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4, ENDCASE => ERROR PressImageError; IF bitsperline MOD bitsPerWord # 0 THEN ERROR PressImageError; self _ NEW[PressImageData _ [ stream: bits.file, streamIndex: LONG[bits.pageNumber]*512+bits.byteOffset, byteLength: bits.length*Basics.bytesPerWord, -- bits.length is in words! scanMode: mode, scanCount: lines, scanLength: dots, wordsPerLine: wpl, passDots: pd, displayDots: dd, passLines: pl, displayLines: dl, imageHeight: height, imageWidth: width, lgBitsPerPixel: lgBitsPerPixel, isBitmap: sampleType = 0 ]]; RETURN [self]; }; PixelArrayImpl: TYPE ~ ImagerPixelArrayPrivate.PixelArrayImpl; PixelArrayImplRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayImplRep; PixelArrayClass: TYPE ~ REF PixelArrayClassRep; PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep; pixelArrayClass: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: $PressImage, MaxSampleValue: MyMaxSampleValue, UnsafeGetSamples: MyUnsafeGetSamples, UnsafeGetBits: MyUnsafeGetBits ]]; MyMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [ImagerPixelArray.Sample] ~ { impl: PixelArrayImpl ~ pa.impl; data: REF PixelMap ~ NARROW[pa.data]; pm: PixelMap ~ data^; lgBitsPerPixel: [0..4] _ pm.refRep.lgBitsPerPixel; RETURN [Basics.BITSHIFT[1, Basics.BITSHIFT[1, lgBitsPerPixel]]-1] }; MyUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT, samples: ImagerSample.UnsafeSamples, count: NAT] ~ UNCHECKED { data: REF PixelMap ~ NARROW[pa.data]; ImagerSample.UnsafeGetF[samples: samples, count: count, base: data.refRep.pointer, wordsPerLine: data.refRep.rast, bitsPerSample: Basics.BITSHIFT[1, data.refRep.lgBitsPerPixel], s: s+data.sOrigin, f: f+data.fOrigin]; }; bitsPerWord: NAT ~ Basics.bitsPerWord; MyUnsafeGetBits: UNSAFE PROC [pa: PixelArray, i: NAT _ 0, s, f: INT, dst: PrincOps.BitAddress, dstBpl: INTEGER, width, height: CARDINAL, srcFunc: PrincOps.SrcFunc _ null, dstFunc: PrincOps.DstFunc _ null] ~ UNCHECKED { data: REF PixelMap ~ NARROW[pa.data]; source: PixelMap ~ data^; sStartSource: NAT ~ s-source.sOrigin; fMinSource: NAT ~ f-source.fOrigin; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; IF source.refRep.lgBitsPerPixel # 0 THEN ERROR; bb^ _ [ dstBpl: dstBpl, srcDesc: [srcBpl[source.refRep.rast*bitsPerWord]], height: height, width: width, flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: srcFunc, dstFunc: dstFunc], dst: dst, src: [word: (source.refRep.pointer + Basics.LongMult[sStartSource, source.refRep.rast] + (fMinSource/bitsPerWord)), bit: fMinSource MOD bitsPerWord] ]; PrincOpsUtils.BITBLT[bb]; }; identity: Transformation ~ ImagerTransformation.Scale[1]; MakePixelArray: PROC [pressImage: PressImage] RETURNS [ImagerPixelArray.PixelArray] ~ { pm: PixelMap ~ ImagerPixelMap.Create[lgBitsPerPixel: pressImage.lgBitsPerPixel, bounds: [0, 0, pressImage.scanCount, pressImage.scanLength]]; IF INT[pm.refRep.words*Basics.bytesPerWord] < pressImage.byteLength THEN ERROR PressImageError; IO.SetIndex[pressImage.stream, pressImage.streamIndex]; TRUSTED { [] _ IO.UnsafeGetBlock[pressImage.stream, [LOOPHOLE[pm.refRep.pointer], 0, pressImage.byteLength]]; }; RETURN [NEW[ImagerPixelArrayDefs.PixelArrayRep _ [ samplesPerPixel: 1, sSize: pressImage.displayLines, fSize: pressImage.displayDots, m: TransformationFromScanMode[pressImage.scanMode, pressImage.displayLines, pressImage.displayDots], impl: NIL, class: pixelArrayClass, data: NEW[PixelMap _ pm.ShiftMap[-pressImage.passLines, -pressImage.passDots].Clip[[0,0,pressImage.displayLines, pressImage.displayDots]]] ]]]; }; DrawPressImage: PUBLIC PROC [self: Context, image: PressImage] = { Proc: PROC ~ { pa: ImagerPixelArray.PixelArray ~ MakePixelArray[image]; paDimen: Imager.VEC ~ ImagerTransformation.TransformVec[pa.m, [pa.sSize, pa.fSize]]; Imager.Move[self]; Imager.Scale2T[self, [image.imageWidth/ABS[paDimen.x], image.imageHeight/ABS[paDimen.y]]]; IF image.isBitmap THEN { WhiteBackground: PROC ~ { Imager.SetColor[self, Imager.white]; Imager.MaskRectangle[self, [0, 0, ABS[paDimen.x], ABS[paDimen.y]]]; }; IF TRUE -- NOT show dots opaque -- THEN Imager.DoSave[self, WhiteBackground]; Imager.MaskPixel[context: self, pa: pa]; } ELSE { maxSampleValue: INT ~ ImagerPixelArray.MaxSampleValue[pa, 0]; SampleMap: PROC [cardinal: CARDINAL] RETURNS [REAL] ~ { RETURN [cardinal] }; colorOperator: ImagerColorOperator.ColorOperator ~ ImagerColorOperator.GrayLinearColorModel[ sWhite: maxSampleValue, sBlack: 0.0, maxSampleValue: maxSampleValue, sampleMap: SampleMap ]; Imager.SetSampledColor[ context: self, pa: pa, m: identity, colorOperator: colorOperator ]; Imager.MaskRectangle[self, [0, 0, ABS[paDimen.x], ABS[paDimen.y]]]; }; }; Imager.DoSave[self, Proc]; SafeStorage.ReclaimCollectibleObjects[]; }; END. ðPressImageImpl.mesa Last edited by Shore; December 4, 1982 12:25 am Last edited by Wyatt; December 1, 1983 5:47 pm Michael Plass, June 6, 1985 3:55:52 pm PDT Rick Beach, May 23, 1985 10:18:12 pm PDT Concrete representation of PixelArrayImplRep, exported to ImagerPixelArrayDefs. Created by Shore; September 13, 1982 6:45 pm Changed by Shore; October 14, 1982 9:24 pm converted to Cedar 3.4 (FileIO) and new PressReader (Dots) Changed by Shore; December 4, 1982 12:24 am converted to Cedar.Style Changed by Wyatt; December 1, 1983 4:14 pm converted to Cedar 5.0 (Space => VM) Changed by Plass; February 14, 1984 12:56:51 pm PST Made images work for multiple bits per pixel Michael Plass, April 4, 1985 10:42:18 am PST Imager Conversion Ê 1– "Cedar" style˜codešÏc™Kšœ/™/Kšœ.™.K™*K™(K™—šÏk œ žœÒ˜æK™—šœžœž˜Kšžœ žœ˜‘Kšžœ!˜(šœž˜K˜—Kšœ žœ˜Kšœžœ'˜;Kšœ žœ#˜3šœ žœ˜)J˜—Jšœžœ˜ Jšœžœ˜ Jšœžœ˜ Jšœžœ˜ Jšœžœ˜ Jšœžœ˜ Jšœžœ˜ šœžœ˜ J˜—š Ïnœžœ žœžœžœ˜hšœ žœžœ ž˜(Jšœ ˜ Jšœ ˜ Jšžœ˜ —šœ žœžœ ž˜(Jšœ ˜ Jšœ ˜ Jšžœ˜ —šœ žœžœ ž˜'Jšœ ˜ Jšœ ˜ Jšžœ˜ —šœ žœžœ ž˜'Jšœ ˜ Jšœ ˜ Jšžœ˜ —šžœ˜$Jšœ˜Jšœ˜Jšœžœ5˜;Jšœ˜Jšœ˜Jšœžœ4˜:Jšœ˜—Jšœ˜J˜—Kšœ žœžœžœ˜-šœžœžœžœ˜&Kšœžœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜/Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ ž˜Kšœ˜K˜—Kšœžœžœžœ˜%šŸœžœžœ1žœžœžœžœ˜¢Kš œ žœžœžœ žœ žœ žœ˜dKšœžœ1˜>šœžœ ž˜/J˜ J˜J˜J˜J˜Jšžœžœ˜!—Kšžœ žœžœžœ˜>šœžœ˜Kšœ˜Kšœ žœ&˜7Kšœ-˜HK˜Kšœ˜Kšœ˜K˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšžœ˜K˜K˜—Kšœžœ*˜>šœžœžœ-˜KšœO™OK™——Kšœžœžœ˜/šœžœžœ.˜MK˜—šœ#žœ˜=K˜Kšœ!˜!Kšœ%˜%Kšœ˜Kšœ˜K˜—šŸœžœžœžœ˜UJšœ˜Jšœžœ žœ ˜%Jšœ˜Jšœ2˜2Jšžœ žœ žœ˜AJšœ˜K˜—šŸœžœžœžœžœ/žœž œ˜ƒKšœžœ žœ ˜%Kšœ‰žœG˜ØK˜K˜—Kšœ žœ˜&šŸœžœžœžœ žœ%žœžœIž œ˜ÜKšœžœ žœ ˜%Kšœ˜Kšœžœ˜%Kšœ žœ˜#K˜$KšœA˜AKšžœ"žœžœ˜/šœ˜Kšœ˜Kšœ2˜2Kšœ˜Kšœ ˜ Kšœ&žœžœžœ&˜rKšœ ˜ Kšœ„žœ ˜”K˜—Kšœžœ˜K˜K˜—˜9K˜—šŸœžœžœ"˜WJ•StartOfExpansionD[lgBitsPerPixel: [0..4], bounds: ImagerPixelMap.DeviceRectangle]šœ˜Jšžœžœ>žœžœ˜_Jšžœ5˜7šžœ˜ Jšœžœ$žœ0˜cJšœ˜—šžœžœ'˜2Jšœ˜Jšœ˜Jšœ˜Jšœd˜dJšœžœ˜ Jšœ˜Jšœžœ˜ŠJšœ˜—Jšœ˜K˜—šŸœžœžœ'˜BšŸœžœ˜Jšœ8˜8JšœžœA˜TJšœ˜Jšœ'žœžœ˜Zšžœžœ˜šŸœžœ˜Kšœ$˜$Kšœ"žœ žœ˜CKšœ˜—Jšžœžœœžœ&˜MJšœ(˜(Jšœ˜—šžœ˜Jšœžœ*˜=š Ÿ œžœ žœžœžœ˜7Jšžœ ˜Jšœ˜—šœ\˜\Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜—šœ˜Jšœ˜Jšœ˜Jšœ ˜ J–U[sWhite: REAL, sBlack: REAL, maxSampleValue: CARDINAL _ 0B (0), sampleMap: PROC [...]šœ˜Jšœ˜—Kšœ"žœ žœ˜CJšœ˜—Jšœ˜—Kšœ˜Kšœ(˜(K˜—K˜Kšžœ˜—K™K™,K™™*K™:—K™™+K™—K™™*Kšœ!žœ™$—K™™3K™,—K™™,K™—K™—…—¨'É