ImagerPixelArrayImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Doug Wyatt, May 19, 1985 2:51:17 pm PDT
Michael Plass, June 3, 1985 12:40:17 pm PDT
DIRECTORY
Basics,
ImagerPixelArray,
ImagerPixelArrayDefs,
ImagerPixelArrayPrivate,
ImagerSample,
ImagerTransformation,
UnsafeStorage,
PrincOps;
ImagerPixelArrayImpl: CEDAR PROGRAM
IMPORTS Basics, ImagerSample, ImagerTransformation, UnsafeStorage
EXPORTS ImagerPixelArray, ImagerPixelArrayDefs
~ BEGIN OPEN ImagerPixelArray, ImagerPixelArrayDefs;
PixelArrayImpl: TYPE ~ ImagerPixelArrayPrivate.PixelArrayImpl;
PixelArrayImplRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayImplRep;
PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass;
PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep;
Error: PUBLIC ERROR[error: ErrorDesc] ~ CODE;
GetClass: PUBLIC PROC [pa: PixelArray] RETURNS [ATOM] ~ {
class: PixelArrayClass ~ pa.class;
RETURN[class.type];
};
MaxSampleValue: PUBLIC PROC [pa: PixelArray, i: NAT] RETURNS [Sample] ~ {
class: PixelArrayClass ~ pa.class;
RETURN class.MaxSampleValue[pa, i];
};
UnsafeGetSamples: PUBLIC UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: UnsafeSamples, count: NAT] ~ TRUSTED {
class: PixelArrayClass ~ pa.class;
class.UnsafeGetSamples[pa: pa, i: i, s: s, f: f, samples: samples, count: count];
};
bitsPerWord: NAT ~ Basics.bitsPerWord;
UnsafeGetBits: PUBLIC UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
dst: PrincOps.BitAddress, dstBpl: INTEGER, width, height: CARDINAL,
srcFunc: PrincOps.SrcFunc ← null, dstFunc: PrincOps.DstFunc ← null] ~ UNCHECKED {
class: PixelArrayClass ~ pa.class;
IF class.UnsafeGetBits # NIL THEN class.UnsafeGetBits[pa: pa, i: i, s: s, f: f,
dst: dst, dstBpl: dstBpl, width: width, height: height,
srcFunc: srcFunc, dstFunc: dstFunc]
ELSE {
tZone: UNCOUNTED ZONE ~ UnsafeStorage.GetTransientPageUZone[];
bitsPerLine: NAT ~ dstBpl;
buf: UnsafeSamples ← tZone.NEW[ImagerSample.RawSamples[width]];
base: LONG POINTER ← dst.word;
bit: NAT ← dst.bit;
FOR line: NAT IN [0..height) DO
UnsafeGetSamples[pa: pa, i: i, s: s+line, f: f, samples: buf, count: width];
ImagerSample.UnsafePutF[samples: buf, count: width, s: 0, f: bit, base: base, wordsPerLine: 0, bitsPerSample: 1, srcFunc: srcFunc, dstFunc: dstFunc];
base ← base + NAT[bit + bitsPerLine] / bitsPerWord;
bit ← NAT[bit + bitsPerLine] MOD bitsPerWord
ENDLOOP;
tZone.FREE[@buf];
};
};
GetSample: PUBLIC PROC [pa: PixelArray, i: NAT, s, f: INT] RETURNS [sample: Sample] ~ {
class: PixelArrayClass ~ pa.class;
TRUSTED { class.UnsafeGetSamples[pa: pa, i: i, s: s, f: f,
samples: LOOPHOLE[LONG[@sample]], count: 1] };
};
GetSamples: PUBLIC PROC [pa: PixelArray, i: NAT, s, f: INT,
buffer: SampleBuffer, bi, bj: NAT ← 0, count: NAT] ~ {
class: PixelArrayClass ~ pa.class;
samples: UnsafeSamples ~ buffer.GetPointer[bi, bj, count];
TRUSTED { class.UnsafeGetSamples[pa: pa, i: i, s: s, f: f, samples: samples, count: count] };
};
GetPixels: PUBLIC PROC [pa: PixelArray, s, f: INT,
buffer: SampleBuffer, bj: NAT, count: NAT] ~ {
class: PixelArrayClass ~ pa.class;
FOR i: NAT IN[0..pa.samplesPerPixel) DO
samples: UnsafeSamples ~ buffer.GetPointer[i, bj, count];
TRUSTED { class.UnsafeGetSamples[pa: pa, i: i, s: s, f: f, samples: samples, count: count] };
ENDLOOP;
};
extractedClass: PixelArrayClass ~ NEW[PixelArrayClassRep ← [
type: $Extracted,
MaxSampleValue: ExtractedMaxSampleValue,
UnsafeGetSamples: ExtractedUnsafeGetSamples
]];
ExtractedData: TYPE ~ REF ExtractedDataRep;
ExtractedDataRep: TYPE ~ RECORD [
basePA: PixelArray,
indices: SEQUENCE samplesPerPixel: NAT OF NAT
];
ExtractedMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [Sample] ~ {
ed: ExtractedData ~ NARROW[pa.data];
RETURN [MaxSampleValue[ed.basePA, ed[i]]];
};
ExtractedUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: UnsafeSamples, count: NAT] ~ UNCHECKED {
ed: ExtractedData ~ NARROW[pa.data];
UnsafeGetSamples[pa: ed.basePA, i: ed[i], s: s, f: f, samples: samples, count: count];
};
Extract: PUBLIC PROC [old: PixelArray, samplesPerPixel: NAT, select: PROC [NAT] RETURNS [NAT]]
RETURNS [new: PixelArray] ~ {
ed: ExtractedData ~ NEW[ExtractedDataRep[samplesPerPixel]];
ed.basePA ← old;
FOR i: NAT IN [0..samplesPerPixel) DO
ed[i] ← Basics.BoundsCheck[select[i], old.samplesPerPixel];
ENDLOOP;
RETURN[NEW[PixelArrayRep ← [samplesPerPixel: samplesPerPixel, sSize: old.sSize, fSize: old.fSize, m: old.m, class: extractedClass, data: ed]]];
};
joinedClass: PixelArrayClass ~ NEW[PixelArrayClassRep ← [
type: $Joined,
MaxSampleValue: JoinedMaxSampleValue,
UnsafeGetSamples: JoinedUnsafeGetSamples
]];
JoinedMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [Sample] ~ {
list: LIST OF PixelArray ~ NARROW[pa.data];
k: NAT ← Basics.BoundsCheck[i, pa.samplesPerPixel];
FOR each: LIST OF PixelArray ← list, each.rest UNTIL each=NIL DO
slice: PixelArray ~ each.first;
IF k<slice.samplesPerPixel THEN RETURN MaxSampleValue[slice, k]
ELSE k ← k-slice.samplesPerPixel;
ENDLOOP;
ERROR; -- pa.samplesPerPixel was wrong?
};
JoinedUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: UnsafeSamples, count: NAT] ~ {
list: LIST OF PixelArray ~ NARROW[pa.data];
k: NAT ← Basics.BoundsCheck[i, pa.samplesPerPixel];
FOR each: LIST OF PixelArray ← list, each.rest UNTIL each=NIL DO
slice: PixelArray ~ each.first;
IF k<slice.samplesPerPixel THEN TRUSTED {
UnsafeGetSamples[pa: slice, i: k, s: s, f: f, samples: samples, count: count];
RETURN;
}
ELSE k ← k-slice.samplesPerPixel;
ENDLOOP;
ERROR; -- pa.samplesPerPixel was wrong?
};
Join: PUBLIC PROC [list: LIST OF PixelArray] RETURNS [PixelArray] ~ {
sSize, fSize: INT ← 0;
samplesPerPixel: NAT ← 0;
m: Transformation ← NIL;
FOR each: LIST OF PixelArray ← list, each.rest UNTIL each=NIL DO
pa: PixelArray ~ each.first;
IF each=list THEN { sSize ← pa.sSize; fSize ← pa.fSize; m ← pa.m } -- first one
ELSE {
IF NOT(pa.sSize=sSize AND pa.fSize=fSize) THEN ERROR Error[[
code: $incompatibleJoin, explanation: "Sizes do not match"]];
IF NOT pa.m.Equal[m] THEN ERROR Error[[
code: $incompatibleJoin, explanation: "Transformations do not match"]];
};
samplesPerPixel ← samplesPerPixel+pa.samplesPerPixel;
ENDLOOP;
RETURN[NEW[PixelArrayRep ← [
samplesPerPixel: samplesPerPixel, sSize: sSize, fSize: fSize,
m: m, class: joinedClass, data: list]]];
};
Join3: PUBLIC PROC [pa1, pa2, pa3: PixelArray] RETURNS [PixelArray] ~ {
RETURN[Join[LIST[pa1, pa2, pa3]]];
};
pixelMapClass: PixelArrayClass ~ NEW[PixelArrayClassRep ← [
type: $PixelMap,
MaxSampleValue: PixelMapMaxSampleValue,
UnsafeGetSamples: PixelMapUnsafeGetSamples
]];
PixelMapMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [Sample] ~ {
data: REF PixelMap ~ NARROW[pa.data];
bitsPerPixel: NAT ~ Basics.BITSHIFT[1, data.refRep.lgBitsPerPixel];
[] ← Basics.BoundsCheck[i, pa.samplesPerPixel];
RETURN[Basics.BITSHIFT[WORD.LAST, INTEGER[bitsPerPixel]-Basics.bitsPerWord]];
};
PixelMapUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: UnsafeSamples, start: NAT ← 0, count: NAT] ~ {
data: REF PixelMap ~ NARROW[pa.data];
refRep: REF PixelMapRep ~ data.refRep;
i0: NAT ~ Basics.BoundsCheck[i, pa.samplesPerPixel];
s0: NAT ~ s; sRem: NAT ~ pa.sSize-s; -- bounds check: s IN[0..sSize]
f0: NAT ~ f; fRem: NAT ~ pa.fSize-f; -- bounds check: f IN[0..fSize]
[] ← Basics.BoundsCheck[0, sRem];
IF count=0 THEN RETURN ELSE [] ← Basics.BoundsCheck[count-1, fRem];
TRUSTED { ImagerSample.UnsafeGetF[samples: samples, start: start, count: count,
base: refRep.pointer, wordsPerLine: refRep.rast,
bitsPerSample: Basics.BITSHIFT[1, refRep.lgBitsPerPixel],
s: ?????, f: ?????] };
};
FromPixelMap: PUBLIC PROC [pixelMap: PixelMap, m: Transformation] RETURNS [PixelArray] ~ {
rect: ImagerPixelMap.DeviceRectangle ~ ImagerPixelMap.BoundedWindow[pixelMap];
IF rect.sMin#0 OR rect.fMin#0 THEN ERROR;
RETURN[NEW[PixelArrayRep ← [
samplesPerPixel: 1, sSize: rect.sSize, fSize: rect.fSize,
m: m, class: pixelMapClass, data: NEW[PixelMap ← pixelMap]
]]];
};
END.