~
BEGIN
Buffer: TYPE ~ REF BufferRep;
BufferRep: TYPE ~ RECORD [SEQUENCE length: NAT OF INTEGER];
Transform:
TYPE ~
ARRAY [0..4)
OF
ARRAY [0..3)
OF
REAL ←
ALL[
ALL[0.0]];
A Transform t takes some color in a 3-space (x0, x1, x2) and returns a color in 3-space (y0, y1, y2) according to the formulas:
y0 ← t[0][0]*x0 + t[1][0]*x1 + t[2][0]*x2 + t[3][0]
y1 ← t[0][1]*x0 + t[1][1]*x1 + t[2][1]*x2 + t[3][1]
y2 ← t[0][2]*x0 + t[1][2]*x1 + t[2][2]*x2 + t[3][2]
CCT: TYPE ~ ARRAY [0..3) OF ARRAY [0..3) OF Buffer; --Color correction transform
UCR:
TYPE ~
RECORD [
black, remove: Buffer,
invert: WORD
];
TRC: TYPE ~ REF TRCRep;
TRCRep: TYPE ~ RECORD [SEQUENCE length: NAT OF REAL];
RawBytes: TYPE ~ RECORD [PACKED SEQUENCE COMPUTED CARDINAL OF [0..256)];
BuildCCT: PROC [t: Transform, trc: ARRAY [0..3) OF TRC] RETURNS [cct: CCT];
BuildCCTForMaskedApply:
PROC [old:
CCT]
RETURNS [cct:
CCT];
Create a new CCT where the underlying buffers are twice as long as the old CCT, and where the last half of each buffer contains the old CCT values, and the first half contains an identity CCT (cct[x][y][index] is IF x=y THEN index ELSE 0).
This is useful is the client places a mask bit in lowest order unused bit of each word in a Basics.RawWords, and then uses the new CCT to perform the apply. The CCT is applied only to the masked bits.
ApplyCCT:
UNSAFE
PROC [cct:
CCT, x0, x1, x2, y0, y1, y2:
LONG
POINTER
TO Basics.RawWords, count:
LONG
CARDINAL];
Note that ApplyCCT reads x0, x1, x2 and writes to y0, y1, y2. However, writing in place presents no problem to the code.
ApplyCCTToBytes:
UNSAFE
PROC [cct:
CCT, x0, x1, x2, y0, y1, y2:
LONG
POINTER
TO RawBytes, count:
LONG
CARDINAL];
Note that ApplyCCT reads x0, x1, x2 and writes to y0, y1, y2. However, writing in place presents no problem to the code.
ApplyCCTToSample: PROC [cct: CCT, x0, x1, x2: CARDINAL] RETURNS [y0, y1, y2: INTEGER];
BuildUCR: PROC [threshold, gamma, fractionRemoved: REAL, invertResult: BOOLEAN ← TRUE, bufferSize: NAT ← 256] RETURNS [ucr: UCR];
ApplyUCR:
UNSAFE
PROC [ucr:
UCR, x0, x1, x2, y0, y1, y2, y3:
LONG
POINTER
TO Basics.RawWords, count:
LONG
CARDINAL];
Note that ApplyUCR reads x0, x1, x2 and writes to y0, y1, y2. However, writing in place presents no problem to the code.
ApplyUCRToBytes:
UNSAFE
PROC [ucr:
UCR, x0, x1, x2, y0, y1, y2, y3:
LONG
POINTER
TO RawBytes, count:
LONG
CARDINAL];
Note that ApplyUCR reads x0, x1, x2 and writes to y0, y1, y2. However, writing in place presents no problem to the code.
ApplyUCRToSample: PROC [ucr: UCR, x0, x1, x2: CARDINAL] RETURNS [y0, y1, y2, y3: CARDINAL];