tests: Add Oklab and ZCAM gamut clipping tests
diff --git a/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt
new file mode 100644
index 0000000..7543630
--- /dev/null
+++ b/src/commonTest/kotlin/dev/kdrag0n/colorkt/tests/GamutTests.kt
@@ -0,0 +1,61 @@
+package dev.kdrag0n.colorkt.tests
+
+import dev.kdrag0n.colorkt.Color.Companion.convert
+import dev.kdrag0n.colorkt.cam.Zcam
+import dev.kdrag0n.colorkt.cam.Zcam.Companion.toZcam
+import dev.kdrag0n.colorkt.data.Illuminants
+import dev.kdrag0n.colorkt.gamut.LchGamut.clipToLinearSrgb
+import dev.kdrag0n.colorkt.gamut.OklabGamut.clipToLinearSrgb
+import dev.kdrag0n.colorkt.rgb.LinearSrgb.Companion.toLinearSrgb
+import dev.kdrag0n.colorkt.rgb.Srgb
+import dev.kdrag0n.colorkt.tristimulus.CieXyz
+import dev.kdrag0n.colorkt.tristimulus.CieXyzAbs.Companion.DEFAULT_SDR_WHITE_LUMINANCE
+import dev.kdrag0n.colorkt.tristimulus.CieXyzAbs.Companion.toAbs
+import dev.kdrag0n.colorkt.ucs.lab.CieLab
+import dev.kdrag0n.colorkt.ucs.polar.Oklch
+import kotlin.test.Test
+
+class GamutTests {
+ @Test
+ fun testOklabClip() {
+ // R, G, B
+ for (channel in 2 downTo 0) {
+ val src = Srgb(0xff shl (channel * 8))
+ val srcLinear = src.toLinearSrgb()
+ val lch = src.convert<Oklch>()
+
+ // Boost the chroma
+ val clipped = lch.copy(C = lch.C * 5).toOklab().clipToLinearSrgb()
+
+ // Now check
+ assertApprox(clipped.r, srcLinear.r)
+ assertApprox(clipped.g, srcLinear.g)
+ assertApprox(clipped.b, srcLinear.b)
+ }
+ }
+
+ @Test
+ fun testZcamClip() {
+ val cond = Zcam.ViewingConditions(
+ surroundFactor = Zcam.ViewingConditions.SURROUND_AVERAGE,
+ adaptingLuminance = 0.4 * DEFAULT_SDR_WHITE_LUMINANCE,
+ backgroundLuminance = CieLab(50.0, 0.0, 0.0).toXyz().y * DEFAULT_SDR_WHITE_LUMINANCE,
+ referenceWhite = Illuminants.D65.toAbs(DEFAULT_SDR_WHITE_LUMINANCE),
+ )
+
+ // R, G, B
+ for (channel in 2 downTo 0) {
+ val src = Srgb(0xff shl (channel * 8))
+ val srcLinear = src.toLinearSrgb()
+ val zcam = src.convert<CieXyz>().toAbs(DEFAULT_SDR_WHITE_LUMINANCE).toZcam(cond, include2D = false)
+
+ // Boost the chroma
+ val clipped = zcam.copy(chroma = zcam.chroma * 5).clipToLinearSrgb()
+
+ // Now check
+ assertApprox(clipped.r, srcLinear.r)
+ assertApprox(clipped.g, srcLinear.g)
+ assertApprox(clipped.b, srcLinear.b)
+ }
+ }
+}