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.