<> <> <> <> 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> NewClass: PUBLIC PROC [type: ATOM, MaxSampleValue: MaxSampleValueProc, Get: GetProc _ NIL, GetSamples: GetSamplesProc _ NIL, Transfer: TransferProc _ NIL, Copy: CopyProc _ NIL ] RETURNS [PixelArrayClass] ~ { class: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: type, MaxSampleValue: MaxSampleValue, Get: Get, GetSamples: GetSamples, Transfer: Transfer, Copy: Copy ]]; IF Get=NIL THEN SELECT TRUE FROM GetSamples#NIL => 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 i> Join3: PUBLIC PROC [pa1, pa2, pa3: PixelArray] RETURNS [PixelArray] ~ { RETURN[Join[LIST[pa1, pa2, pa3]]]; }; pixelMapClass: PixelArrayClass ~ NewClass[ type: $PixelMap, MaxSampleValue: PixelMapMaxSampleValue, Get: PixelMapGet, GetSamples: PixelMapGetSamples, Transfer: PixelMapTransfer, Copy: PixelMapCopy ]; PixelMapData: TYPE ~ PixelMap; PixelMapMaxSampleValue: MaxSampleValueProc ~ { data: PixelMapData ~ NARROW[self.data]; map: SampleMap ~ data[i]; RETURN[Basics.BITSHIFT[1, map.bitsPerSample]-1]; }; PixelMapGet: GetProc ~ { data: PixelMapData ~ NARROW[self.data]; map: SampleMap ~ data[i]; index: Vec ~ [s: s, f: f]; RETURN[map.Get[index]]; }; PixelMapGetSamples: GetSamplesProc ~ { data: PixelMapData ~ NARROW[self.data]; map: SampleMap ~ data[i]; index: Vec ~ [s: s, f: f]; map.GetSamples[min: index, samples: samples, start: start, count: count]; }; PixelMapTransfer: TransferProc ~ { data: PixelMapData ~ NARROW[self.data]; map: SampleMap ~ data[i]; index: Vec ~ [s: s, f: f]; dst.Transfer[src: map, dstMin: dstMin, srcMin: index, size: size, function: function]; }; PixelMapCopy: CopyProc ~ { data0: PixelMapData ~ NARROW[self.data]; data1: PixelMapData ~ NEW[PixelMapRep[data0.samplesPerPixel]]; FOR i: NAT IN[0..data1.samplesPerPixel) DO data1[i] _ data0[i].CopyMap[] ENDLOOP; RETURN[New[class: pixelMapClass, data: data1, immutable: TRUE, samplesPerPixel: self.samplesPerPixel, sSize: self.sSize, fSize: self.fSize, m: self.m]]; }; FromPixelMap: PUBLIC PROC [map: PixelMap, scanMode: ScanMode, immutable: BOOL] RETURNS [PixelArray] ~ { samplesPerPixel: NAT ~ map.samplesPerPixel; sSize: NAT ~ map.size.s; fSize: NAT ~ map.size.f; RETURN[New[class: pixelMapClass, data: map, immutable: immutable, samplesPerPixel: samplesPerPixel, sSize: sSize, fSize: fSize, m: ImagerTransformation.SFToXY[scanMode: scanMode, sSize: sSize, fSize: fSize]]]; }; END.