Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cam16 and hct type errors #622

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions src/spaces/cam16.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {WHITES} from "../adapt.js";
/** @typedef {import("../types.js").Coords} Coords */
/** @typedef {import("../types.js").Matrix3x3} Matrix3x3 */
/** @typedef {import("../types.js").Vector3} Vector3 */
/** @typedef {import("../types.js").Cam16Object} Cam16Object */
/** @typedef {import("../types.js").Cam16Input} Cam16Input */
/** @typedef {import("../types.js").Cam16Environment} Cam16Environment */

const white = WHITES.D65;
const adaptedCoef = 0.42;
Expand Down Expand Up @@ -117,6 +120,7 @@ export function invHueQuadrature (H) {
* @param {number} backgroundLuminance
* @param {keyof typeof surroundMap} surround
* @param {boolean} discounting
* @returns {Cam16Environment}
*/
export function environment (
refWhite,
Expand Down Expand Up @@ -146,11 +150,10 @@ export function environment (
const rgbW = multiply_v3_m3x3(xyzW, cat16);

// Surround: dark, dim, and average
// @ts-expect-error surround is never used again
surround = surroundMap[env.surround];
const f = surround[0];
env.c = surround[1];
env.nc = surround[2];
let values = surroundMap[env.surround];
const f = values[0];
env.c = values[1];
env.nc = values[2];

const k = 1 / (5 * env.la + 1);
const k4 = k ** 4;
Expand Down Expand Up @@ -199,27 +202,28 @@ const viewingConditions = environment(
false,
);

/** @typedef {{J: number, C: number, h: number, s: number, Q: number, M: number, H: number}} Cam16Object */

/**
* @param {Cam16Object} cam16
* @param {Record<string, unknown>} env
* @param {Cam16Input} cam16
* @param {Cam16Environment} env
* @returns {[number, number, number]}
* @todo Add types for `env`
*/
export function fromCam16 (cam16, env) {

// These check ensure one, and only one attribute for a
// given category is provided.
// @ts-expect-error The '^` operator is not allowed for boolean types
if (!((cam16.J !== undefined) ^ (cam16.Q !== undefined))) {
throw new Error("Conversion requires one and only one: 'J' or 'Q'");
}

// @ts-expect-error - The '^` operator is not allowed for boolean types
if (!((cam16.C !== undefined) ^ (cam16.M !== undefined) ^ (cam16.s !== undefined))) {
throw new Error("Conversion requires one and only one: 'C', 'M' or 's'");
}

// Hue is absolutely required
// @ts-expect-error - The '^` operator is not allowed for boolean types
if (!((cam16.h !== undefined) ^ (cam16.H !== undefined))) {
throw new Error("Conversion requires one and only one: 'h' or 'H'");
}
Expand Down Expand Up @@ -302,9 +306,8 @@ export function fromCam16 (cam16, env) {

/**
* @param {[number, number, number]} xyzd65
* @param {Record<string, unknown>} env
* @param {Cam16Environment} env
* @returns {Cam16Object}
* @todo Add types for `env`
*/
export function toCam16 (xyzd65, env) {
// Cone response
Expand Down
35 changes: 35 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,38 @@ export interface DeltasReturn {
coords: [number, number, number];
alpha: number;
}

// cam16.js
export type LightnessOrBrightness = { J: number; Q?: never; } | { J?: never; Q: number; };
export type ChromaOrColorfulnessOrSaturation = { C: number; M?: never; s?: never; } | { C?: never; M: number; s?: never; } | { C?: never; M?: never; s: number; };
export type HueOrHueQuadrature = { h: number; H?: never; } | { h?: never; H: number; };
export type Cam16Input = LightnessOrBrightness & ChromaOrColorfulnessOrSaturation & HueOrHueQuadrature;

export interface Cam16Object {
J: number,
C: number,
h: number,
s: number,
Q: number,
M: number,
H: number
}

export interface Cam16Environment {
discounting: boolean;
refWhite: [number, number, number];
surround: "dark" | "dim" | "average";
la: number;
yb: number;
c: number;
nc: number;
fl: number;
flRoot: number;
n: number;
z: number;
nbb: number;
ncb: number;
dRgb: number[];
dRgbInv: number[];
aW: number;
}
46 changes: 46 additions & 0 deletions types/test/cam16.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { environment, fromCam16 } from "colorjs.io/src/spaces/cam16";

const viewingConditions = environment(
[1, 2, 3],
64 / Math.PI * 0.2, 20,
"average",
false,
);
// @ts-expect-error
fromCam16({}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0}, viewingConditions);

// @ts-expect-error
fromCam16({C: 0}, viewingConditions);

// @ts-expect-error
fromCam16({h: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, C: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, H: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, C: 0, H: 0, Q: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, C: 0, H: 0, M: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, C: 0, H: 0, s: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, M: 0, H: 0, s: 0}, viewingConditions);

// @ts-expect-error
fromCam16({J: 0, C: 0, H: 0, h: 0}, viewingConditions);

fromCam16({J: 0, C: 0, H: 0}, viewingConditions); // $ExpectType [number, number, number]
fromCam16({Q: 0, M: 0, h: 0}, viewingConditions); // $ExpectType [number, number, number]
fromCam16({Q: 0, s: 0, h: 0}, viewingConditions); // $ExpectType [number, number, number]


Loading