--VideoColor.mesa
--last edited by Maureen Stone September 13, 1982 2:02 pm
DIRECTORY
GraphicsColor,
Graphics,
LinearSystem,
JaMFnsDefs,
RealFns;
VideoColor: PROGRAM
IMPORTS RealFns, LinearSystem, JaMFnsDefs = {
--this procedure clips the current r,g,b to be within the NTSC bandwidth for chroma
--algorithm from Siggraph tutorial on animation (C. R. Odgers)
matrix: LinearSystem.Matrix3 ← [[.299, .587, .11], [.599, -.2773, -.3217], [.213, -.525, .3121]];
ClipColor: PROC [r,g,b: REAL] RETURNS [nr,ng,nb: REAL] = {
i,y,q,cr,cg,cb: REAL;
gamma: REAL ← 2.2;
igamma: REAL ← 1.0/2.2;
videoAmplitude: REAL;
--gamma correct r,g,b and convert to i, y, q
cr ← RealFns.Power[r,igamma];
cg ← RealFns.Power[g,igamma];
cb ← RealFns.Power[b,igamma];
y ← matrix[1][1]*cr+matrix[1][2]*cg+matrix[1][3]*cb;
i ← matrix[2][1]*cr+matrix[2][2]*cg+matrix[2][3]*cb;
q ← matrix[3][1]*cr+matrix[3][2]*cg+matrix[3][3]*cb;
videoAmplitude ← y+RealFns.SqRt[(i*i)+(q*q)];
IF videoAmplitude>1 THEN {
f: REAL ← 1.0/videoAmplitude;
rgb,yiq: LinearSystem.Column3;
yiq[1] ← y/videoAmplitude;
yiq[2] ← i/videoAmplitude;
yiq[3] ← q/videoAmplitude;
rgb ← LinearSystem.Solve3[matrix,yiq];
nr ← RealFns.Power[MAX[0,rgb[1]],gamma];
ng ← RealFns.Power[MAX[0,rgb[2]],gamma];
nb ← RealFns.Power[MAX[0,rgb[3]],gamma];
RETURN[nr,ng,nb];
}
ELSE RETURN[nr: r, ng: g, nb: b];
};
SetColor: PROC = {
r,g,b: REAL;
b ← JaMFnsDefs.PopReal[];
g ← JaMFnsDefs.PopReal[];
r ← JaMFnsDefs.PopReal[];
[r,g,b] ← ClipColor[r,g,b];
JaMFnsDefs.PushReal[r];
JaMFnsDefs.PushReal[g];
JaMFnsDefs.PushReal[b];
};
JaMFnsDefs.Register[".ntsccolor", SetColor];
}.