DIRECTORY Basics USING [BITSHIFT, BoundsCheck, NonNegative], ImagerPixelArray USING [ErrorDesc, maxCount, maxVec, PixelArray, PixelArrayRep, zeroVec], ImagerPixelArrayPrivate USING [CopyProc, GetProc, GetSamplesProc, MaxSampleValueProc, PixelArrayClass, PixelArrayClassRep, TransferProc], ImagerSample USING [CopyMap, DoWithScratchMap, DoWithScratchSamples, Function, Get, GetSamples, maxBitsPerSample, nullFunction, PixelBuffer, PixelMap, PixelMapRep, Put, PutSamples, Sample, SampleBuffer, SampleMap, Transfer], ImagerTransformation USING [Equal, ScanMode, SFToXY, Transformation], SF USING [Min, Sub, Vec]; ImagerPixelArrayImpl: CEDAR PROGRAM IMPORTS Basics, ImagerSample, ImagerTransformation, SF EXPORTS ImagerPixelArray, ImagerPixelArrayPrivate ~ BEGIN OPEN ImagerPixelArrayPrivate, ImagerPixelArray; Vec: TYPE ~ SF.Vec; Transformation: TYPE ~ ImagerTransformation.Transformation; ScanMode: TYPE ~ ImagerTransformation.ScanMode; Sample: TYPE ~ ImagerSample.Sample; SampleBuffer: TYPE ~ ImagerSample.SampleBuffer; PixelBuffer: TYPE ~ ImagerSample.PixelBuffer; SampleMap: TYPE ~ ImagerSample.SampleMap; PixelMap: TYPE ~ ImagerSample.PixelMap; PixelMapRep: TYPE ~ ImagerSample.PixelMapRep; Function: TYPE ~ ImagerSample.Function; nullFunction: Function ~ ImagerSample.nullFunction; PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass; PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep; Error: PUBLIC ERROR [error: ErrorDesc] ~ CODE; GetClass: PUBLIC PROC [self: PixelArray] RETURNS [ATOM] ~ { class: PixelArrayClass ~ self.class; RETURN[class.type]; }; MaxSampleValue: PUBLIC PROC [self: PixelArray, i: NAT] RETURNS [Sample] ~ { class: PixelArrayClass ~ self.class; RETURN class.MaxSampleValue[self: self, i: Basics.BoundsCheck[i, self.samplesPerPixel]]; }; Get: PUBLIC PROC [self: PixelArray, i: NAT, s, f: INT] RETURNS [Sample] ~ { class: PixelArrayClass ~ self.class; iCheck: NAT ~ Basics.BoundsCheck[i, self.samplesPerPixel]; sRem: INT ~ Basics.NonNegative[self.sSize-Basics.NonNegative[s]]; fRem: INT ~ Basics.NonNegative[self.fSize-Basics.NonNegative[f]]; [] _ Basics.NonNegative[sRem-1]; [] _ Basics.NonNegative[fRem-1]; RETURN class.Get[self: self, i: i, s: s, f: f]; }; GetSamples: PUBLIC PROC [self: PixelArray, i: NAT _ 0, s, f: INT _ 0, samples: SampleBuffer, start: NAT _ 0, count: NAT _ maxCount] ~ { class: PixelArrayClass ~ self.class; iCheck: NAT ~ Basics.BoundsCheck[i, self.samplesPerPixel]; sRem: INT ~ Basics.NonNegative[self.sSize-Basics.NonNegative[s]]; fRem: INT ~ Basics.NonNegative[self.fSize-Basics.NonNegative[f]]; actualCount: NAT ~ MIN[samples.length-start, count]; [] _ Basics.NonNegative[sRem-1]; [] _ Basics.NonNegative[fRem-actualCount]; class.GetSamples[self: self, i: i, s: s, f: f, samples: samples, start: start, count: actualCount]; }; GetPixels: PUBLIC PROC [self: PixelArray, s, f: INT _ 0, pixels: PixelBuffer, start: NAT _ 0, count: NAT _ maxCount] ~ { FOR i: NAT IN[0..self.samplesPerPixel) DO GetSamples[self, i, s, f, pixels[i], start, count] ENDLOOP }; Transfer: PUBLIC PROC [self: PixelArray, i: NAT _ 0, s, f: INT _ 0, dst: SampleMap, dstMin: Vec _ zeroVec, size: Vec _ maxVec, function: Function _ nullFunction] ~ { class: PixelArrayClass ~ self.class; iCheck: NAT ~ Basics.BoundsCheck[i, self.samplesPerPixel]; sRem: INT ~ Basics.NonNegative[self.sSize-Basics.NonNegative[s]]; fRem: INT ~ Basics.NonNegative[self.fSize-Basics.NonNegative[f]]; actualSize: Vec _ dst.size.Sub[dstMin].Min[size]; IF sRem class.Get _ GetViaGetSamples; Transfer#NIL => class.Get _ GetViaTransfer; ENDCASE; IF GetSamples=NIL THEN SELECT TRUE FROM Transfer#NIL => class.GetSamples _ GetSamplesViaTransfer; Get#NIL => class.GetSamples _ GetSamplesViaGet; ENDCASE; IF Transfer=NIL THEN SELECT TRUE FROM GetSamples#NIL => class.Transfer _ TransferViaGetSamples; Get#NIL => class.Transfer _ TransferViaGet; ENDCASE; RETURN[class]; }; New: PUBLIC PROC [class: PixelArrayClass, data: REF, immutable: BOOL, samplesPerPixel: NAT, sSize, fSize: INT, m: Transformation ] RETURNS [PixelArray] ~ { RETURN[NEW[PixelArrayRep _ [immutable: immutable, samplesPerPixel: samplesPerPixel, sSize: Basics.NonNegative[sSize], fSize: Basics.NonNegative[fSize], m: m, class: class, data: data]]]; }; Layer: TYPE ~ RECORD [base: PixelArray, i: NAT]; extractedClass: PixelArrayClass ~ NewClass[ type: $Extracted, MaxSampleValue: ExtractedMaxSampleValue, Get: ExtractedGet, GetSamples: ExtractedGetSamples, Transfer: ExtractedTransfer ]; ExtractedData: TYPE ~ REF ExtractedDataRep; ExtractedDataRep: TYPE ~ RECORD [ base: PixelArray, select: SEQUENCE samplesPerPixel: NAT OF NAT ]; ExtractedLayer: PROC [data: ExtractedData, i: NAT] RETURNS [Layer] ~ { RETURN[[base: data.base, i: data.select[i]]]; }; ExtractedMaxSampleValue: MaxSampleValueProc ~ { data: ExtractedData ~ NARROW[self.data]; layer: Layer ~ ExtractedLayer[data, i]; class: PixelArrayClass ~ layer.base.class; RETURN class.MaxSampleValue[self: layer.base, i: layer.i]; }; ExtractedGet: GetProc ~ { data: ExtractedData ~ NARROW[self.data]; layer: Layer ~ ExtractedLayer[data, i]; class: PixelArrayClass ~ layer.base.class; RETURN class.Get[self: layer.base, i: layer.i, s: s, f: f]; }; ExtractedGetSamples: GetSamplesProc ~ { data: ExtractedData ~ NARROW[self.data]; layer: Layer ~ ExtractedLayer[data, i]; class: PixelArrayClass ~ layer.base.class; class.GetSamples[self: layer.base, i: layer.i, s: s, f: f, samples: samples, start: start, count: count]; }; ExtractedTransfer: TransferProc ~ { data: ExtractedData ~ NARROW[self.data]; layer: Layer ~ ExtractedLayer[data, i]; class: PixelArrayClass ~ layer.base.class; class.Transfer[self: layer.base, i: layer.i, s: s, f: f, dst: dst, dstMin: dstMin, size: size, function: function]; }; Extract: PUBLIC PROC [old: PixelArray, samplesPerPixel: NAT, select: PROC [NAT] RETURNS [NAT]] RETURNS [new: PixelArray] ~ { data: ExtractedData ~ NEW[ExtractedDataRep[samplesPerPixel] _ [base: old, select: ]]; FOR i: NAT IN [0..data.samplesPerPixel) DO data.select[i] _ Basics.BoundsCheck[select[i], old.samplesPerPixel]; ENDLOOP; RETURN[New[class: extractedClass, data: data, immutable: old.immutable, samplesPerPixel: samplesPerPixel, sSize: old.sSize, fSize: old.fSize, m: old.m]]; }; joinedClass: PixelArrayClass ~ NewClass[ type: $Joined, MaxSampleValue: JoinedMaxSampleValue, Get: JoinedGet, GetSamples: JoinedGetSamples, Transfer: JoinedTransfer ]; JoinedData: TYPE ~ LIST OF PixelArray; JoinedLayer: PROC [data: JoinedData, i: NAT] RETURNS [Layer] ~ { FOR each: LIST OF PixelArray _ data, each.rest UNTIL each=NIL DO base: PixelArray ~ each.first; IF iKšœS˜SKšžœ˜—Kšžœ˜—K˜K˜—š œžœžœžœB˜‚K˜$šœžœ˜(šžœžœžœ ž˜Kšœ\˜\Kšœm˜mKšžœ˜—K˜—Kšœ2˜2K˜K˜—K™š œžœžœžœ7žœ žœžœžœžœ˜Τšœžœ˜3Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—š žœžœžœžœžœž˜ Kšœ žœ!˜/Kšœ žœ˜+Kšžœ˜—š žœ žœžœžœžœž˜'Kšœ žœ-˜9Kšœžœ(˜/Kšžœ˜—š žœ žœžœžœžœž˜%Kšœ žœ+˜9Kšœžœ$˜+Kšžœ˜—Kšžœ˜K˜K˜—š œžœžœ žœ žœžœžœžœ˜›Kšžœžœ²˜ΌK˜K˜—K˜Kšœžœžœžœ˜0K˜šœ+˜+Kšœ˜Kšœ)˜)Kšœ˜Kšœ ˜ Kšœ˜K˜K˜—Kšœžœžœ˜+šœžœžœ˜!Kšœ˜Kšœžœžœžœž˜,Kšœ˜K˜—š œžœžœžœ ˜FKšžœ'˜-Kšœ˜K˜—š œ˜/Kšœžœ ˜(J˜'K˜*Kšžœ4˜:K˜K˜—š  œ ˜Kšœžœ ˜(J˜'K˜*Kšžœ5˜;K˜K˜—š œ˜'Kšœžœ ˜(J˜'K˜*Kšœj˜jK˜K˜—š œ˜#Kšœžœ ˜(J˜'K˜*Kšœt˜tK˜K˜—š œžœžœ$žœ žœžœžœžœžœ˜}Kšœžœ<˜Ušžœžœžœž˜*KšœD˜DKšžœ˜—šžœA˜GKšœQ˜Q—Kšœ˜K˜—K˜šœ(˜(Kšœ˜Kšœ&˜&Kšœ˜Kšœ˜Kšœ˜K˜K˜—šœ žœžœžœ ˜&K˜—š  œžœžœžœ ˜@š žœžœžœžœžœž˜@K˜Kšžœžœžœ˜9Kšžœ˜ Kšžœ˜—KšžœΟc ˜'Kšœ˜K˜—š œ˜,Kšœžœ ˜%J˜$K˜*Kšžœ4˜:K˜K˜—š  œ ˜Kšœžœ ˜%J˜$K˜*Kšžœ5˜;K˜K˜—š œ˜$Kšœžœ ˜%J˜$K˜*Kšœj˜jK˜K˜—š œ˜ Kšœžœ ˜%J˜$K˜*Kšœt˜tK˜K˜—š  œžœžœžœžœ žœ˜EKšœ žœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜š žœžœžœžœžœž˜@K˜Kšœžœ˜'K˜5Kšžœ žœ2‘ ˜Ošžœ˜Kš žœžœžœžœžœF˜zKšžœžœžœžœP˜oK˜—Kšžœ˜—šžœ:˜@KšœE˜E—K˜K™—š œžœžœžœ˜GKšžœžœ˜"K˜K˜—K˜šœ*˜*Kšœ˜Kšœ(˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜K˜—šœžœ ˜K˜—š œ˜.Kšœžœ ˜'Kšœ˜Kšžœžœ˜0K˜K˜—š  œ ˜Kšœžœ ˜'Kšœ˜K˜Kšžœ˜K˜K˜—š œ˜&Kšœžœ ˜'Kšœ˜K˜K˜IK˜K˜—š œ˜"Kšœžœ ˜'Kšœ˜K˜KšœV˜VK˜K˜—š  œ˜Kšœžœ ˜(Kšœžœ%˜>Kš žœžœžœžœžœ˜Qšžœ3žœ˜>KšœY˜Y—K˜K˜—š   œžœžœ0žœžœ˜hKšœžœ˜+Kšœžœ˜Kšœžœ˜šžœ;˜AKšœ>˜>KšœQ˜Q—Kšœ˜K˜—K˜Kšžœ˜—…—5ΒCn