import { internalAssertAlpha, internalAssertFinite, internalRoundColorFloat } from "../internal.ts" import type { LinearRgbColorValue, XyzColorValue } from "../types.ts" import { internalNormalizeXyzColorValue } from "./internal.ts" const internalNormalizeLinearRgbColorValueForXyzConversion = ( color: LinearRgbColorValue, ): LinearRgbColorValue => { internalAssertFinite(color.red, "Color channel red") internalAssertFinite(color.green, "Color channel green") internalAssertFinite(color.blue, "Color channel blue") internalAssertAlpha(color.alpha) return { red: color.red, green: color.green, blue: color.blue, alpha: color.alpha, } } /** * @description 将 XYZ 颜色值转换为 Linear RGB 颜色值。 * * @example * ``` * // Expect: { red: 0.2, green: 0.4, blue: 0.6, alpha: 1 } * const example1 = xyzColorValueToLinearRgbColorValue({ x: 0.333784, y: 0.3719, z: 0.621726, alpha: 1 }) * * // Expect: { red: 1, green: 0, blue: 0, alpha: 1 } * const example2 = xyzColorValueToLinearRgbColorValue({ x: 0.412456, y: 0.212673, z: 0.019334, alpha: 1 }) * ``` */ export const xyzColorValueToLinearRgbColorValue = (color: XyzColorValue): LinearRgbColorValue => { const normalizedColor = internalNormalizeXyzColorValue(color) return internalNormalizeLinearRgbColorValueForXyzConversion({ red: internalRoundColorFloat( 3.240_454_2 * normalizedColor.x - 1.537_138_5 * normalizedColor.y - 0.498_531_4 * normalizedColor.z, ), green: internalRoundColorFloat( -0.969_266 * normalizedColor.x + 1.876_010_8 * normalizedColor.y + 0.041_556 * normalizedColor.z, ), blue: internalRoundColorFloat( 0.055_643_4 * normalizedColor.x - 0.204_025_9 * normalizedColor.y + 1.057_225_2 * normalizedColor.z, ), alpha: normalizedColor.alpha, }) } /** * @description 将 Linear RGB 颜色值转换为 XYZ 颜色值。 * * @example * ``` * // Expect: { x: 0.333784, y: 0.3719, z: 0.621726, alpha: 1 } * const example1 = linearRgbColorValueToXyzColorValue({ red: 0.2, green: 0.4, blue: 0.6, alpha: 1 }) * * // Expect: { x: 0.412456, y: 0.212673, z: 0.019334, alpha: 1 } * const example2 = linearRgbColorValueToXyzColorValue({ red: 1, green: 0, blue: 0, alpha: 1 }) * ``` */ export const linearRgbColorValueToXyzColorValue = (color: LinearRgbColorValue): XyzColorValue => { const normalizedColor = internalNormalizeLinearRgbColorValueForXyzConversion(color) return internalNormalizeXyzColorValue({ x: internalRoundColorFloat( 0.412_456_4 * normalizedColor.red + 0.357_576_1 * normalizedColor.green + 0.180_437_5 * normalizedColor.blue, ), y: internalRoundColorFloat( 0.212_672_9 * normalizedColor.red + 0.715_152_2 * normalizedColor.green + 0.072_175 * normalizedColor.blue, ), z: internalRoundColorFloat( 0.019_333_9 * normalizedColor.red + 0.119_192 * normalizedColor.green + 0.950_304_1 * normalizedColor.blue, ), alpha: normalizedColor.alpha, }) }