<> <> <> <> DIRECTORY Basics USING [BITSHIFT, BoundsCheck, NonNegative], IIPixel USING [PixelBuffer, PixelMap, PixelMapRep], IIPixelArray USING [ErrorDesc, maxCount, maxVec, PixelArray, PixelArrayRep, zeroVec], IIPixelArrayPrivate USING [CopyProc, GetProc, GetSamplesProc, MaxSampleValueProc, PixelArrayClass, PixelArrayClassRep, TransferProc], IISample USING [BasicTransfer, Copy, DoWithScratchMap, DoWithScratchSamples, Function, Get, GetBitsPerSample, GetBox, GetSamples, maxBitsPerSample, maxCount, nullFunction, Put, PutSamples, ReIndex, Sample, SampleBuffer, SampleMap], IITransformation USING [Equal, ScanMode, SFToXY, Transformation], RuntimeError USING [BoundsFault], SF; IIPixelArrayImpl: CEDAR PROGRAM IMPORTS Basics, IISample, IITransformation, RuntimeError, SF EXPORTS IIPixelArray, IIPixelArrayPrivate ~ BEGIN OPEN IIPixelArrayPrivate, IIPixelArray; Vec: TYPE ~ SF.Vec; Transformation: TYPE ~ IITransformation.Transformation; ScanMode: TYPE ~ IITransformation.ScanMode; Sample: TYPE ~ IISample.Sample; SampleBuffer: TYPE ~ IISample.SampleBuffer; PixelBuffer: TYPE ~ IIPixel.PixelBuffer; SampleMap: TYPE ~ IISample.SampleMap; PixelMap: TYPE ~ IIPixel.PixelMap; PixelMapRep: TYPE ~ IIPixel.PixelMapRep; Function: TYPE ~ IISample.Function; nullFunction: Function ~ IISample.nullFunction; PixelArrayClass: TYPE ~ IIPixelArrayPrivate.PixelArrayClass; PixelArrayClassRep: PUBLIC TYPE ~ IIPixelArrayPrivate.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, buffer: 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[buffer.length-start, count]; [] _ Basics.NonNegative[sRem-1]; [] _ Basics.NonNegative[fRem-actualCount]; class.GetSamples[self: self, i: i, s: s, f: f, buffer: buffer, 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]]; dstBox: SF.Box ~ IISample.GetBox[dst]; actualSize: Vec _ dstBox.max.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, buffer: buffer, 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, IISample.GetBitsPerSample[map]]-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]; IISample.GetSamples[map: map, initIndex: index, buffer: buffer, start: start, count: count]; }; PixelMapTransfer: TransferProc ~ { data: PixelMapData ~ NARROW[self.data]; map: SampleMap ~ data[i]; index: Vec ~ [s: s, f: f]; IISample.BasicTransfer[dst: dst, src: map, dstMin: dstMin, srcMin: index, size: size, function: function]; }; PixelMapCopy: CopyProc ~ { data0: PixelMapData ~ NARROW[self.data]; data1: PixelMapData ~ NEW[PixelMapRep[data0.samplesPerPixel]]; data1.box _ data0.box; FOR i: NAT IN[0..data1.samplesPerPixel) DO data1[i] _ IISample.Copy[data0[i]] ENDLOOP; RETURN[New[class: pixelMapClass, data: data1, immutable: TRUE, samplesPerPixel: self.samplesPerPixel, sSize: self.sSize, fSize: self.fSize, m: self.m]]; }; FromPixelMap: PUBLIC PROC [pixelMap: PixelMap, box: SF.Box, scanMode: ScanMode, immutable: BOOL] RETURNS [PixelArray] ~ { samplesPerPixel: NAT ~ pixelMap.samplesPerPixel; IF SF.Inside[box, pixelMap.box] THEN { delta: Vec ~ SF.Neg[box.min]; size: Vec ~ SF.Size[box]; m: Transformation ~ IITransformation.SFToXY[scanMode: scanMode, sSize: size.s, fSize: size.f]; new: PixelMap _ NEW[PixelMapRep[samplesPerPixel]]; new.box _ [max: size]; FOR j: NAT IN [0..samplesPerPixel) DO new[j] _ IISample.ReIndex[map: pixelMap[j], delta: delta, box: [max: size]]; ENDLOOP; RETURN[New[class: pixelMapClass, data: new, immutable: immutable, samplesPerPixel: samplesPerPixel, sSize: size.s, fSize: size.f, m: m]]; }; ERROR RuntimeError.BoundsFault; }; END.