1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.graphics.cts; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertSame; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 26 import android.graphics.ColorSpace; 27 import android.hardware.DataSpace; 28 import android.platform.test.annotations.RequiresFlagsEnabled; 29 import android.platform.test.flag.junit.CheckFlagsRule; 30 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 31 import android.util.Log; 32 33 import androidx.test.filters.SmallTest; 34 35 import com.android.graphics.flags.Flags; 36 37 import junitparams.JUnitParamsRunner; 38 import junitparams.Parameters; 39 40 import org.junit.Rule; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 44 import java.util.Arrays; 45 import java.util.function.DoubleUnaryOperator; 46 47 @SmallTest 48 @RunWith(JUnitParamsRunner.class) 49 public class ColorSpaceTest { 50 51 @Rule 52 public final CheckFlagsRule mCheckFlagsRule = 53 DeviceFlagsValueProvider.createCheckFlagsRule(); 54 55 // Column-major RGB->XYZ transform matrix for the sRGB color space 56 private static final float[] SRGB_TO_XYZ = { 57 0.412391f, 0.212639f, 0.019331f, 58 0.357584f, 0.715169f, 0.119195f, 59 0.180481f, 0.072192f, 0.950532f 60 }; 61 // Column-major XYZ->RGB transform matrix for the sRGB color space 62 private static final float[] XYZ_TO_SRGB = { 63 3.240970f, -0.969244f, 0.055630f, 64 -1.537383f, 1.875968f, -0.203977f, 65 -0.498611f, 0.041555f, 1.056971f 66 }; 67 68 // Column-major RGB->XYZ transform matrix for the sRGB color space and a D50 white point 69 private static final float[] SRGB_TO_XYZ_D50 = { 70 0.4360747f, 0.2225045f, 0.0139322f, 71 0.3850649f, 0.7168786f, 0.0971045f, 72 0.1430804f, 0.0606169f, 0.7141733f 73 }; 74 75 private static final float[] SRGB_PRIMARIES_xyY = 76 { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f }; 77 private static final float[] SRGB_WHITE_POINT_xyY = { 0.3127f, 0.3290f }; 78 79 private static final float[] SRGB_PRIMARIES_XYZ = { 80 1.939394f, 1.000000f, 0.090909f, 81 0.500000f, 1.000000f, 0.166667f, 82 2.500000f, 1.000000f, 13.166667f 83 }; 84 private static final float[] SRGB_WHITE_POINT_XYZ = { 0.950456f, 1.000f, 1.089058f }; 85 86 private static final DoubleUnaryOperator sIdentity = DoubleUnaryOperator.identity(); 87 88 @Test testNamedColorSpaces()89 public void testNamedColorSpaces() { 90 ColorSpace.Named[] values = ColorSpace.Named.values(); 91 int numColorSpaces; 92 if (Flags.okLabColorspace()) { 93 numColorSpaces = values.length; 94 } else { 95 numColorSpaces = values.length - 1; 96 } 97 for (int i = 0; i < numColorSpaces; i++) { 98 ColorSpace.Named named = values[i]; 99 ColorSpace colorSpace = ColorSpace.get(named); 100 Log.v("ResolvedColorSpace", "ColorSpace: " + colorSpace); 101 assertNotNull(colorSpace.getName()); 102 assertNotNull(colorSpace); 103 assertEquals(named.ordinal(), colorSpace.getId()); 104 assertTrue(colorSpace.getComponentCount() >= 1); 105 assertTrue(colorSpace.getComponentCount() <= 4); 106 } 107 } 108 109 @Test(expected = IllegalArgumentException.class) testNullName()110 public void testNullName() { 111 new ColorSpace.Rgb(null, new float[6], new float[2], sIdentity, sIdentity, 0.0f, 1.0f); 112 } 113 114 @Test(expected = IllegalArgumentException.class) testEmptyName()115 public void testEmptyName() { 116 new ColorSpace.Rgb("", new float[6], new float[2], sIdentity, sIdentity, 0.0f, 1.0f); 117 } 118 119 @Test testName()120 public void testName() { 121 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2], 122 sIdentity, sIdentity, 0.0f, 1.0f); 123 assertEquals("Test", cs.getName()); 124 } 125 126 @Test(expected = IllegalArgumentException.class) testPrimariesLength()127 public void testPrimariesLength() { 128 new ColorSpace.Rgb("Test", new float[7], new float[2], sIdentity, sIdentity, 0.0f, 1.0f); 129 } 130 131 @Test(expected = IllegalArgumentException.class) testWhitePointLength()132 public void testWhitePointLength() { 133 new ColorSpace.Rgb("Test", new float[6], new float[1], sIdentity, sIdentity, 0.0f, 1.0f); 134 } 135 136 @Test(expected = IllegalArgumentException.class) testNullOETF()137 public void testNullOETF() { 138 new ColorSpace.Rgb("Test", new float[6], new float[2], null, sIdentity, 0.0f, 1.0f); 139 } 140 141 @Test testOETF()142 public void testOETF() { 143 DoubleUnaryOperator op = Math::sqrt; 144 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2], 145 op, sIdentity, 0.0f, 1.0f); 146 assertEquals(0.5, cs.getOetf().applyAsDouble(0.25), 1e-5); 147 } 148 149 @Test(expected = IllegalArgumentException.class) testNullEOTF()150 public void testNullEOTF() { 151 new ColorSpace.Rgb("Test", new float[6], new float[2], sIdentity, null, 0.0f, 1.0f); 152 } 153 154 @Test testEOTF()155 public void testEOTF() { 156 DoubleUnaryOperator op = x -> x * x; 157 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2], 158 sIdentity, op, 0.0f, 1.0f); 159 assertEquals(0.0625, cs.getEotf().applyAsDouble(0.25), 1e-5); 160 } 161 162 @Test(expected = IllegalArgumentException.class) testInvalidRange()163 public void testInvalidRange() { 164 new ColorSpace.Rgb("Test", new float[6], new float[2], sIdentity, sIdentity, 2.0f, 1.0f); 165 } 166 167 @Test testRanges()168 public void testRanges() { 169 ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB); 170 171 float m1 = cs.getMinValue(0); 172 float m2 = cs.getMinValue(1); 173 float m3 = cs.getMinValue(2); 174 175 assertEquals(0.0f, m1, 1e-9f); 176 assertEquals(0.0f, m2, 1e-9f); 177 assertEquals(0.0f, m3, 1e-9f); 178 179 m1 = cs.getMaxValue(0); 180 m2 = cs.getMaxValue(1); 181 m3 = cs.getMaxValue(2); 182 183 assertEquals(1.0f, m1, 1e-9f); 184 assertEquals(1.0f, m2, 1e-9f); 185 assertEquals(1.0f, m3, 1e-9f); 186 187 cs = ColorSpace.get(ColorSpace.Named.CIE_LAB); 188 189 m1 = cs.getMinValue(0); 190 m2 = cs.getMinValue(1); 191 m3 = cs.getMinValue(2); 192 193 assertEquals(0.0f, m1, 1e-9f); 194 assertEquals(-128.0f, m2, 1e-9f); 195 assertEquals(-128.0f, m3, 1e-9f); 196 197 m1 = cs.getMaxValue(0); 198 m2 = cs.getMaxValue(1); 199 m3 = cs.getMaxValue(2); 200 201 assertEquals(100.0f, m1, 1e-9f); 202 assertEquals(128.0f, m2, 1e-9f); 203 assertEquals(128.0f, m3, 1e-9f); 204 205 cs = ColorSpace.get(ColorSpace.Named.CIE_XYZ); 206 207 m1 = cs.getMinValue(0); 208 m2 = cs.getMinValue(1); 209 m3 = cs.getMinValue(2); 210 211 assertEquals(-2.0f, m1, 1e-9f); 212 assertEquals(-2.0f, m2, 1e-9f); 213 assertEquals(-2.0f, m3, 1e-9f); 214 215 m1 = cs.getMaxValue(0); 216 m2 = cs.getMaxValue(1); 217 m3 = cs.getMaxValue(2); 218 219 assertEquals(2.0f, m1, 1e-9f); 220 assertEquals(2.0f, m2, 1e-9f); 221 assertEquals(2.0f, m3, 1e-9f); 222 223 if (Flags.okLabColorspace()) { 224 cs = ColorSpace.get(ColorSpace.Named.OK_LAB); 225 226 m1 = cs.getMinValue(0); 227 m2 = cs.getMinValue(1); 228 m3 = cs.getMinValue(2); 229 230 assertEquals(0f, m1, 1e-9f); 231 assertEquals(-0.5f, m2, 1e-9f); 232 assertEquals(-0.5f, m3, 1e-9f); 233 234 m1 = cs.getMaxValue(0); 235 m2 = cs.getMaxValue(1); 236 m3 = cs.getMaxValue(2); 237 238 assertEquals(1f, m1, 1e-9f); 239 assertEquals(0.5f, m2, 1e-9f); 240 assertEquals(0.5f, m3, 1e-9f); 241 } 242 } 243 244 @Test testMat3x3()245 public void testMat3x3() { 246 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity); 247 248 float[] rgbToXYZ = cs.getTransform(); 249 for (int i = 0; i < 9; i++) { 250 assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f); 251 } 252 } 253 254 @Test testMat3x3Inverse()255 public void testMat3x3Inverse() { 256 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity); 257 258 float[] xyzToRGB = cs.getInverseTransform(); 259 for (int i = 0; i < 9; i++) { 260 assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f); 261 } 262 } 263 264 @Test testMat3x3Primaries()265 public void testMat3x3Primaries() { 266 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity); 267 268 float[] primaries = cs.getPrimaries(); 269 270 assertNotNull(primaries); 271 assertEquals(6, primaries.length); 272 273 assertEquals(SRGB_PRIMARIES_xyY[0], primaries[0], 1e-5f); 274 assertEquals(SRGB_PRIMARIES_xyY[1], primaries[1], 1e-5f); 275 assertEquals(SRGB_PRIMARIES_xyY[2], primaries[2], 1e-5f); 276 assertEquals(SRGB_PRIMARIES_xyY[3], primaries[3], 1e-5f); 277 assertEquals(SRGB_PRIMARIES_xyY[4], primaries[4], 1e-5f); 278 assertEquals(SRGB_PRIMARIES_xyY[5], primaries[5], 1e-5f); 279 } 280 281 @Test testMat3x3WhitePoint()282 public void testMat3x3WhitePoint() { 283 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity); 284 285 float[] whitePoint = cs.getWhitePoint(); 286 287 assertNotNull(whitePoint); 288 assertEquals(2, whitePoint.length); 289 290 assertEquals(SRGB_WHITE_POINT_xyY[0], whitePoint[0], 1e-5f); 291 assertEquals(SRGB_WHITE_POINT_xyY[1], whitePoint[1], 1e-5f); 292 } 293 294 @Test testXYZFromPrimaries_xyY()295 public void testXYZFromPrimaries_xyY() { 296 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_PRIMARIES_xyY, SRGB_WHITE_POINT_xyY, 297 sIdentity, sIdentity, 0.0f, 1.0f); 298 299 float[] rgbToXYZ = cs.getTransform(); 300 for (int i = 0; i < 9; i++) { 301 assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f); 302 } 303 304 float[] xyzToRGB = cs.getInverseTransform(); 305 for (int i = 0; i < 9; i++) { 306 assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f); 307 } 308 } 309 310 @Test testXYZFromPrimaries_XYZ()311 public void testXYZFromPrimaries_XYZ() { 312 ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_PRIMARIES_XYZ, SRGB_WHITE_POINT_XYZ, 313 sIdentity, sIdentity, 0.0f, 1.0f); 314 315 float[] primaries = cs.getPrimaries(); 316 317 assertNotNull(primaries); 318 assertEquals(6, primaries.length); 319 320 // SRGB_PRIMARIES_xyY only has 1e-3 of precision, match it 321 assertEquals(SRGB_PRIMARIES_xyY[0], primaries[0], 1e-3f); 322 assertEquals(SRGB_PRIMARIES_xyY[1], primaries[1], 1e-3f); 323 assertEquals(SRGB_PRIMARIES_xyY[2], primaries[2], 1e-3f); 324 assertEquals(SRGB_PRIMARIES_xyY[3], primaries[3], 1e-3f); 325 assertEquals(SRGB_PRIMARIES_xyY[4], primaries[4], 1e-3f); 326 assertEquals(SRGB_PRIMARIES_xyY[5], primaries[5], 1e-3f); 327 328 float[] whitePoint = cs.getWhitePoint(); 329 330 assertNotNull(whitePoint); 331 assertEquals(2, whitePoint.length); 332 333 // SRGB_WHITE_POINT_xyY only has 1e-3 of precision, match it 334 assertEquals(SRGB_WHITE_POINT_xyY[0], whitePoint[0], 1e-3f); 335 assertEquals(SRGB_WHITE_POINT_xyY[1], whitePoint[1], 1e-3f); 336 337 float[] rgbToXYZ = cs.getTransform(); 338 for (int i = 0; i < 9; i++) { 339 assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f); 340 } 341 342 float[] xyzToRGB = cs.getInverseTransform(); 343 for (int i = 0; i < 9; i++) { 344 assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f); 345 } 346 } 347 348 @Test testGetComponentCount()349 public void testGetComponentCount() { 350 assertEquals(3, ColorSpace.get(ColorSpace.Named.SRGB).getComponentCount()); 351 assertEquals(3, ColorSpace.get(ColorSpace.Named.LINEAR_SRGB).getComponentCount()); 352 assertEquals(3, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).getComponentCount()); 353 assertEquals(3, ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB).getComponentCount()); 354 assertEquals(3, ColorSpace.get(ColorSpace.Named.DISPLAY_P3).getComponentCount()); 355 assertEquals(3, ColorSpace.get(ColorSpace.Named.CIE_LAB).getComponentCount()); 356 assertEquals(3, ColorSpace.get(ColorSpace.Named.CIE_XYZ).getComponentCount()); 357 if (Flags.okLabColorspace()) { 358 assertEquals(3, ColorSpace.get(ColorSpace.Named.OK_LAB).getComponentCount()); 359 } 360 } 361 362 @Test testIsSRGB()363 public void testIsSRGB() { 364 for (ColorSpace.Named e : ColorSpace.Named.values()) { 365 ColorSpace colorSpace = ColorSpace.get(e); 366 // ColorSpace.get is guaranteed to return non-null. So if this is queried with 367 // a ColorSpace that is flagged, this falls back ot return SRGB as a default. 368 // The values method of an enum will always return the full set of enum values 369 // regardless if they are flagged out or not 370 boolean isSrgbFallback = (colorSpace.getId() == 0 && !Flags.okLabColorspace()); 371 if (e == ColorSpace.Named.SRGB || isSrgbFallback) { 372 assertTrue(colorSpace.isSrgb()); 373 } else { 374 assertFalse("Incorrectly treating " + e + " as SRGB!", 375 colorSpace.isSrgb()); 376 } 377 } 378 379 ColorSpace.Rgb cs = new ColorSpace.Rgb("Almost sRGB", SRGB_TO_XYZ, 380 x -> Math.pow(x, 1.0f / 2.2f), x -> Math.pow(x, 2.2f)); 381 assertFalse(cs.isSrgb()); 382 } 383 384 @Test testIsWideGamut()385 public void testIsWideGamut() { 386 assertFalse(ColorSpace.get(ColorSpace.Named.SRGB).isWideGamut()); 387 assertFalse(ColorSpace.get(ColorSpace.Named.BT709).isWideGamut()); 388 assertTrue(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).isWideGamut()); 389 assertTrue(ColorSpace.get(ColorSpace.Named.DCI_P3).isWideGamut()); 390 assertTrue(ColorSpace.get(ColorSpace.Named.BT2020).isWideGamut()); 391 assertTrue(ColorSpace.get(ColorSpace.Named.ACES).isWideGamut()); 392 assertTrue(ColorSpace.get(ColorSpace.Named.CIE_LAB).isWideGamut()); 393 assertTrue(ColorSpace.get(ColorSpace.Named.CIE_XYZ).isWideGamut()); 394 if (Flags.okLabColorspace()) { 395 assertTrue(ColorSpace.get(ColorSpace.Named.OK_LAB).isWideGamut()); 396 } 397 } 398 399 @Test testWhitePoint()400 public void testWhitePoint() { 401 ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 402 403 float[] whitePoint = cs.getWhitePoint(); 404 405 assertNotNull(whitePoint); 406 assertEquals(2, whitePoint.length); 407 408 // Make sure a copy is returned 409 Arrays.fill(whitePoint, Float.NaN); 410 assertArrayNotEquals(whitePoint, cs.getWhitePoint(), 1e-5f); 411 assertSame(whitePoint, cs.getWhitePoint(whitePoint)); 412 assertArrayEquals(whitePoint, cs.getWhitePoint(), 1e-5f); 413 } 414 415 @Test testPrimaries()416 public void testPrimaries() { 417 ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 418 419 float[] primaries = cs.getPrimaries(); 420 421 assertNotNull(primaries); 422 assertEquals(6, primaries.length); 423 424 // Make sure a copy is returned 425 Arrays.fill(primaries, Float.NaN); 426 assertArrayNotEquals(primaries, cs.getPrimaries(), 1e-5f); 427 assertSame(primaries, cs.getPrimaries(primaries)); 428 assertArrayEquals(primaries, cs.getPrimaries(), 1e-5f); 429 } 430 431 @Test testRGBtoXYZMatrix()432 public void testRGBtoXYZMatrix() { 433 ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 434 435 float[] rgbToXYZ = cs.getTransform(); 436 437 assertNotNull(rgbToXYZ); 438 assertEquals(9, rgbToXYZ.length); 439 440 // Make sure a copy is returned 441 Arrays.fill(rgbToXYZ, Float.NaN); 442 assertArrayNotEquals(rgbToXYZ, cs.getTransform(), 1e-5f); 443 assertSame(rgbToXYZ, cs.getTransform(rgbToXYZ)); 444 assertArrayEquals(rgbToXYZ, cs.getTransform(), 1e-5f); 445 } 446 447 @Test testXYZtoRGBMatrix()448 public void testXYZtoRGBMatrix() { 449 ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 450 451 float[] xyzToRGB = cs.getInverseTransform(); 452 453 assertNotNull(xyzToRGB); 454 assertEquals(9, xyzToRGB.length); 455 456 // Make sure a copy is returned 457 Arrays.fill(xyzToRGB, Float.NaN); 458 assertArrayNotEquals(xyzToRGB, cs.getInverseTransform(), 1e-5f); 459 assertSame(xyzToRGB, cs.getInverseTransform(xyzToRGB)); 460 assertArrayEquals(xyzToRGB, cs.getInverseTransform(), 1e-5f); 461 } 462 463 @Test testRGBtoXYZ()464 public void testRGBtoXYZ() { 465 ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB); 466 467 float[] source = { 0.75f, 0.5f, 0.25f }; 468 float[] expected = { 0.3012f, 0.2679f, 0.0840f }; 469 470 float[] r1 = cs.toXyz(source[0], source[1], source[2]); 471 assertNotNull(r1); 472 assertEquals(3, r1.length); 473 assertArrayNotEquals(source, r1, 1e-5f); 474 assertArrayEquals(expected, r1, 1e-3f); 475 476 float[] r3 = { source[0], source[1], source[2] }; 477 assertSame(r3, cs.toXyz(r3)); 478 assertEquals(3, r3.length); 479 assertArrayEquals(r1, r3, 1e-5f); 480 } 481 482 @Test testXYZtoRGB()483 public void testXYZtoRGB() { 484 ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB); 485 486 float[] source = { 0.3012f, 0.2679f, 0.0840f }; 487 float[] expected = { 0.75f, 0.5f, 0.25f }; 488 489 float[] r1 = cs.fromXyz(source[0], source[1], source[2]); 490 assertNotNull(r1); 491 assertEquals(3, r1.length); 492 assertArrayNotEquals(source, r1, 1e-5f); 493 assertArrayEquals(expected, r1, 1e-3f); 494 495 float[] r3 = { source[0], source[1], source[2] }; 496 assertSame(r3, cs.fromXyz(r3)); 497 assertEquals(3, r3.length); 498 assertArrayEquals(r1, r3, 1e-5f); 499 } 500 501 @Test testConnect()502 public void testConnect() { 503 ColorSpace.Connector connector = ColorSpace.connect( 504 ColorSpace.get(ColorSpace.Named.SRGB), 505 ColorSpace.get(ColorSpace.Named.DCI_P3)); 506 507 assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector.getSource()); 508 assertSame(ColorSpace.get(ColorSpace.Named.DCI_P3), connector.getDestination()); 509 assertSame(ColorSpace.RenderIntent.PERCEPTUAL, connector.getRenderIntent()); 510 511 connector = ColorSpace.connect( 512 ColorSpace.get(ColorSpace.Named.SRGB), 513 ColorSpace.get(ColorSpace.Named.SRGB)); 514 515 assertSame(connector.getDestination(), connector.getSource()); 516 assertSame(ColorSpace.RenderIntent.RELATIVE, connector.getRenderIntent()); 517 518 connector = ColorSpace.connect(ColorSpace.get(ColorSpace.Named.DCI_P3)); 519 assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector.getDestination()); 520 521 connector = ColorSpace.connect(ColorSpace.get(ColorSpace.Named.SRGB)); 522 assertSame(connector.getSource(), connector.getDestination()); 523 } 524 525 @Test testConnector()526 public void testConnector() { 527 // Connect color spaces with same white points 528 ColorSpace.Connector connector = ColorSpace.connect( 529 ColorSpace.get(ColorSpace.Named.SRGB), 530 ColorSpace.get(ColorSpace.Named.ADOBE_RGB)); 531 532 float[] source = { 1.0f, 0.5f, 0.0f }; 533 float[] expected = { 0.8912f, 0.4962f, 0.1164f }; 534 535 float[] r1 = connector.transform(source[0], source[1], source[2]); 536 assertNotNull(r1); 537 assertEquals(3, r1.length); 538 assertArrayNotEquals(source, r1, 1e-5f); 539 assertArrayEquals(expected, r1, 1e-3f); 540 541 float[] r3 = { source[0], source[1], source[2] }; 542 assertSame(r3, connector.transform(r3)); 543 assertEquals(3, r3.length); 544 assertArrayEquals(r1, r3, 1e-5f); 545 546 connector = ColorSpace.connect( 547 ColorSpace.get(ColorSpace.Named.ADOBE_RGB), 548 ColorSpace.get(ColorSpace.Named.SRGB)); 549 550 float[] tmp = source; 551 source = expected; 552 expected = tmp; 553 554 r1 = connector.transform(source[0], source[1], source[2]); 555 assertNotNull(r1); 556 assertEquals(3, r1.length); 557 assertArrayNotEquals(source, r1, 1e-5f); 558 assertArrayEquals(expected, r1, 1e-3f); 559 560 r3 = new float[] { source[0], source[1], source[2] }; 561 assertSame(r3, connector.transform(r3)); 562 assertEquals(3, r3.length); 563 assertArrayEquals(r1, r3, 1e-5f); 564 } 565 566 @Test testAdaptedConnector()567 public void testAdaptedConnector() { 568 // Connect color spaces with different white points 569 ColorSpace.Connector connector = ColorSpace.connect( 570 ColorSpace.get(ColorSpace.Named.SRGB), 571 ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB)); 572 573 float[] source = new float[] { 1.0f, 0.0f, 0.0f }; 574 float[] expected = new float[] { 0.70226f, 0.2757f, 0.1036f }; 575 576 float[] r = connector.transform(source[0], source[1], source[2]); 577 assertNotNull(r); 578 assertEquals(3, r.length); 579 assertArrayNotEquals(source, r, 1e-5f); 580 assertArrayEquals(expected, r, 1e-4f); 581 } 582 583 @Test testAdaptedConnectorWithRenderIntent()584 public void testAdaptedConnectorWithRenderIntent() { 585 // Connect a wider color space to a narrow color space 586 ColorSpace.Connector connector = ColorSpace.connect( 587 ColorSpace.get(ColorSpace.Named.DCI_P3), 588 ColorSpace.get(ColorSpace.Named.SRGB), 589 ColorSpace.RenderIntent.RELATIVE); 590 591 float[] source = { 0.9f, 0.9f, 0.9f }; 592 593 float[] relative = connector.transform(source[0], source[1], source[2]); 594 assertNotNull(relative); 595 assertEquals(3, relative.length); 596 assertArrayNotEquals(source, relative, 1e-5f); 597 assertArrayEquals(new float[] { 0.8862f, 0.8862f, 0.8862f }, relative, 1e-4f); 598 599 connector = ColorSpace.connect( 600 ColorSpace.get(ColorSpace.Named.DCI_P3), 601 ColorSpace.get(ColorSpace.Named.SRGB), 602 ColorSpace.RenderIntent.ABSOLUTE); 603 604 float[] absolute = connector.transform(source[0], source[1], source[2]); 605 assertNotNull(absolute); 606 assertEquals(3, absolute.length); 607 assertArrayNotEquals(source, absolute, 1e-5f); 608 assertArrayNotEquals(relative, absolute, 1e-5f); 609 assertArrayEquals(new float[] { 0.8475f, 0.9217f, 0.8203f }, absolute, 1e-4f); 610 } 611 612 @Test testIdentityConnector()613 public void testIdentityConnector() { 614 ColorSpace.Connector connector = ColorSpace.connect( 615 ColorSpace.get(ColorSpace.Named.SRGB), 616 ColorSpace.get(ColorSpace.Named.SRGB)); 617 618 assertSame(connector.getSource(), connector.getDestination()); 619 assertSame(ColorSpace.RenderIntent.RELATIVE, connector.getRenderIntent()); 620 621 float[] source = new float[] { 0.11112f, 0.22227f, 0.444448f }; 622 623 float[] r = connector.transform(source[0], source[1], source[2]); 624 assertNotNull(r); 625 assertEquals(3, r.length); 626 assertArrayEquals(source, r, 1e-5f); 627 } 628 629 @Test testConnectorTransformIdentity()630 public void testConnectorTransformIdentity() { 631 ColorSpace.Connector connector = ColorSpace.connect( 632 ColorSpace.get(ColorSpace.Named.DCI_P3), 633 ColorSpace.get(ColorSpace.Named.DCI_P3)); 634 635 float[] source = { 1.0f, 0.0f, 0.0f }; 636 float[] expected = { 1.0f, 0.0f, 0.0f }; 637 638 float[] r1 = connector.transform(source[0], source[1], source[2]); 639 assertNotNull(r1); 640 assertEquals(3, r1.length); 641 assertArrayEquals(expected, r1, 1e-3f); 642 643 float[] r3 = { source[0], source[1], source[2] }; 644 assertSame(r3, connector.transform(r3)); 645 assertEquals(3, r3.length); 646 assertArrayEquals(r1, r3, 1e-5f); 647 } 648 649 @Test testAdaptation()650 public void testAdaptation() { 651 ColorSpace adapted = ColorSpace.adapt( 652 ColorSpace.get(ColorSpace.Named.SRGB), 653 ColorSpace.ILLUMINANT_D50); 654 655 float[] sRGBD50 = { 656 0.43602175f, 0.22247513f, 0.01392813f, 657 0.38510883f, 0.71690667f, 0.09710153f, 658 0.14308129f, 0.06061824f, 0.71415880f 659 }; 660 661 assertArrayEquals(sRGBD50, ((ColorSpace.Rgb) adapted).getTransform(), 1e-7f); 662 663 adapted = ColorSpace.adapt( 664 ColorSpace.get(ColorSpace.Named.SRGB), 665 ColorSpace.ILLUMINANT_D50, 666 ColorSpace.Adaptation.BRADFORD); 667 assertArrayEquals(sRGBD50, ((ColorSpace.Rgb) adapted).getTransform(), 1e-7f); 668 } 669 670 @Test testImplicitSRGBConnector()671 public void testImplicitSRGBConnector() { 672 ColorSpace.Connector connector1 = ColorSpace.connect( 673 ColorSpace.get(ColorSpace.Named.DCI_P3)); 674 675 assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector1.getDestination()); 676 677 ColorSpace.Connector connector2 = ColorSpace.connect( 678 ColorSpace.get(ColorSpace.Named.DCI_P3), 679 ColorSpace.get(ColorSpace.Named.SRGB)); 680 681 float[] source = { 0.6f, 0.9f, 0.7f }; 682 assertArrayEquals( 683 connector1.transform(source[0], source[1], source[2]), 684 connector2.transform(source[0], source[1], source[2]), 1e-7f); 685 } 686 687 @Test testLab()688 public void testLab() { 689 ColorSpace.Connector connector = ColorSpace.connect( 690 ColorSpace.get(ColorSpace.Named.CIE_LAB)); 691 692 float[] source = { 100.0f, 0.0f, 0.0f }; 693 float[] expected = { 1.0f, 1.0f, 1.0f }; 694 695 float[] r1 = connector.transform(source[0], source[1], source[2]); 696 assertNotNull(r1); 697 assertEquals(3, r1.length); 698 assertArrayEquals(expected, r1, 1e-3f); 699 700 source = new float[] { 100.0f, 0.0f, 54.0f }; 701 expected = new float[] { 1.0f, 0.9925f, 0.5762f }; 702 703 float[] r2 = connector.transform(source[0], source[1], source[2]); 704 assertNotNull(r2); 705 assertEquals(3, r2.length); 706 assertArrayEquals(expected, r2, 1e-3f); 707 708 connector = ColorSpace.connect( 709 ColorSpace.get(ColorSpace.Named.CIE_LAB), ColorSpace.RenderIntent.ABSOLUTE); 710 711 source = new float[] { 100.0f, 0.0f, 0.0f }; 712 expected = new float[] { 1.0f, 0.9910f, 0.8651f }; 713 714 r1 = connector.transform(source[0], source[1], source[2]); 715 assertNotNull(r1); 716 assertEquals(3, r1.length); 717 assertArrayEquals(expected, r1, 1e-3f); 718 719 source = new float[] { 100.0f, 0.0f, 54.0f }; 720 expected = new float[] { 1.0f, 0.9853f, 0.4652f }; 721 722 r2 = connector.transform(source[0], source[1], source[2]); 723 assertNotNull(r2); 724 assertEquals(3, r2.length); 725 assertArrayEquals(expected, r2, 1e-3f); 726 } 727 728 @RequiresFlagsEnabled(Flags.FLAG_OK_LAB_COLORSPACE) 729 @Test testOkLab()730 public void testOkLab() { 731 ColorSpace.Connector connector = ColorSpace.connect( 732 ColorSpace.get(ColorSpace.Named.OK_LAB)); 733 734 float[] source = { 100.0f, 0.0f, 0.0f }; 735 float[] expected = { 1.0f, 1.0f, 1.0f }; 736 737 float[] r1 = connector.transform(source[0], source[1], source[2]); 738 assertNotNull(r1); 739 assertEquals(3, r1.length); 740 assertArrayEquals(expected, r1, 1e-3f); 741 742 source = new float[] { 100.0f, 0.0f, 54.0f }; 743 expected = new float[] { 1.0f, 0.8137f, 0f }; 744 745 float[] r2 = connector.transform(source[0], source[1], source[2]); 746 assertNotNull(r2); 747 assertEquals(3, r2.length); 748 assertArrayEquals(expected, r2, 1e-3f); 749 750 connector = ColorSpace.connect( 751 ColorSpace.get(ColorSpace.Named.OK_LAB), ColorSpace.RenderIntent.ABSOLUTE); 752 753 source = new float[] { 100.0f, 0.0f, 0.0f }; 754 expected = new float[] { 1.0f, 0.9910f, 0.8651f }; 755 756 r1 = connector.transform(source[0], source[1], source[2]); 757 assertNotNull(r1); 758 assertEquals(3, r1.length); 759 assertArrayEquals(expected, r1, 1e-3f); 760 761 source = new float[] { 100.0f, 0.0f, 54.0f }; 762 expected = new float[] { 1.0f, 0.80465f, 0.0f }; 763 764 r2 = connector.transform(source[0], source[1], source[2]); 765 assertNotNull(r2); 766 assertEquals(3, r2.length); 767 assertArrayEquals(expected, r2, 1e-3f); 768 } 769 770 @Test testXYZ()771 public void testXYZ() { 772 ColorSpace xyz = ColorSpace.get(ColorSpace.Named.CIE_XYZ); 773 774 float[] source = { 0.32f, 0.43f, 0.54f }; 775 776 float[] r1 = xyz.toXyz(source[0], source[1], source[2]); 777 assertNotNull(r1); 778 assertEquals(3, r1.length); 779 assertArrayEquals(source, r1, 1e-7f); 780 781 float[] r2 = xyz.fromXyz(source[0], source[1], source[2]); 782 assertNotNull(r2); 783 assertEquals(3, r2.length); 784 assertArrayEquals(source, r2, 1e-7f); 785 786 ColorSpace.Connector connector = 787 ColorSpace.connect(ColorSpace.get(ColorSpace.Named.CIE_XYZ)); 788 789 float[] expected = { 0.2280f, 0.7541f, 0.8453f }; 790 791 float[] r3 = connector.transform(source[0], source[1], source[2]); 792 assertNotNull(r3); 793 assertEquals(3, r3.length); 794 assertArrayEquals(expected, r3, 1e-3f); 795 } 796 797 @Test testIDs()798 public void testIDs() { 799 // These cannot change 800 assertEquals(0, ColorSpace.get(ColorSpace.Named.SRGB).getId()); 801 assertEquals(-1, ColorSpace.MIN_ID); 802 assertEquals(63, ColorSpace.MAX_ID); 803 } 804 805 @Test testFromLinear()806 public void testFromLinear() { 807 ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 808 809 float[] source = { 0.0f, 0.5f, 1.0f }; 810 float[] expected = { 0.0f, 0.7354f, 1.0f }; 811 812 float[] r1 = colorSpace.fromLinear(source[0], source[1], source[2]); 813 assertNotNull(r1); 814 assertEquals(3, r1.length); 815 assertArrayEquals(expected, r1, 1e-3f); 816 817 float[] r2 = { source[0], source[1], source[2] }; 818 assertSame(r2, colorSpace.fromLinear(r2)); 819 assertEquals(3, r2.length); 820 assertArrayEquals(r1, r2, 1e-5f); 821 } 822 823 @Test testToLinear()824 public void testToLinear() { 825 ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 826 827 float[] source = { 0.0f, 0.5f, 1.0f }; 828 float[] expected = new float[] { 0.0f, 0.2140f, 1.0f }; 829 830 float[] r1 = colorSpace.toLinear(source[0], source[1], source[2]); 831 assertNotNull(r1); 832 assertEquals(3, r1.length); 833 assertArrayEquals(expected, r1, 1e-3f); 834 835 float[] r2 = new float[] { source[0], source[1], source[2] }; 836 assertSame(r2, colorSpace.toLinear(r2)); 837 assertEquals(3, r2.length); 838 assertArrayEquals(r1, r2, 1e-5f); 839 } 840 841 @Test testTransferParameters()842 public void testTransferParameters() { 843 ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB); 844 assertNotNull(colorSpace.getTransferParameters()); 845 846 colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB); 847 assertNotNull(colorSpace.getTransferParameters()); 848 849 colorSpace = new ColorSpace.Rgb("Almost sRGB", SRGB_TO_XYZ, 850 x -> Math.pow(x, 1.0f / 2.2f), x -> Math.pow(x, 2.2f)); 851 assertNull(colorSpace.getTransferParameters()); 852 } 853 854 @Test testIdempotentTransferFunctions()855 public void testIdempotentTransferFunctions() { 856 Arrays.stream(ColorSpace.Named.values()) 857 .map(ColorSpace::get) 858 .filter(cs -> cs.getModel() == ColorSpace.Model.RGB) 859 .map(cs -> (ColorSpace.Rgb) cs) 860 .forEach(cs -> { 861 float[] source = { 0.0f, 0.5f, 1.0f }; 862 float[] r = cs.fromLinear(cs.toLinear(source[0], source[1], source[2])); 863 assertArrayEquals(source, r, 1e-3f); 864 }); 865 } 866 867 @Test testMatch()868 public void testMatch() { 869 for (ColorSpace.Named named : ColorSpace.Named.values()) { 870 ColorSpace cs = ColorSpace.get(named); 871 if (cs.getModel() == ColorSpace.Model.RGB) { 872 ColorSpace.Rgb rgb = (ColorSpace.Rgb) cs; 873 // match() cannot match extended sRGB, BT2020_HLG, BT2020_PQ 874 if (rgb != ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) 875 && rgb != ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB) 876 && rgb != ColorSpace.get(ColorSpace.Named.BT2020_HLG) 877 && rgb != ColorSpace.get(ColorSpace.Named.BT2020_PQ)) { 878 879 // match() uses CIE XYZ D50 880 rgb = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50); 881 assertSame(cs, 882 ColorSpace.match(rgb.getTransform(), rgb.getTransferParameters())); 883 } 884 } 885 } 886 887 assertSame(ColorSpace.get(ColorSpace.Named.SRGB), 888 ColorSpace.match(SRGB_TO_XYZ_D50, new ColorSpace.Rgb.TransferParameters( 889 1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4))); 890 } 891 892 @Test(expected = IllegalArgumentException.class) 893 @Parameters({"0", "-1", "-50"}) testInvalidCct(int cct)894 public void testInvalidCct(int cct) { 895 ColorSpace.cctToXyz(cct); 896 } 897 898 @Test testCctToXyz()899 public void testCctToXyz() { 900 // Verify that range listed as meaningful by the API return float arrays as expected. 901 for (int i = 1667; i <= 25000; i++) { 902 float[] result = ColorSpace.cctToXyz(i); 903 assertNotNull(result); 904 assertEquals(3, result.length); 905 } 906 } 907 cctToXyzExpected()908 private static Object[] cctToXyzExpected() { 909 return new Object[] { 910 // ILLUMINANT_A 911 new Object[] { 2856, new float[] { 1.0970824f, 1.0f, 0.3568525f }}, 912 // ILLUMINANT_B 913 new Object[] { 4874, new float[] { 0.98355806f, 1.0f, 0.8376475f }}, 914 // ILLUMINANT_C 915 new Object[] { 6774, new float[] { 0.9680535f, 1.0f, 1.1603559f }}, 916 // ILLUMINANT_D50 917 new Object[] { 5003, new float[] { 0.9811904f, 1.0f, 0.86360276f }}, 918 // ILLUMINANT_D55 919 new Object[] { 5503, new float[] { 0.97444946f, 1.0f, 0.9582717f }}, 920 // ILLUMINANT_D60 921 new Object[] { 6004, new float[] { 0.9705604f, 1.0f, 1.0441511f }}, 922 // ILLUMINANT_D65 923 new Object[] { 6504, new float[] { 0.968573f, 1.0f, 1.1216444f }}, 924 // ILLUMINANT_D75 925 new Object[] { 7504, new float[] { 0.9679457f, 1.0f, 1.2551404f }}, 926 // ILLUMINANT_E 927 new Object[] { 5454, new float[] { 0.9749648f, 1.0f, 0.9494016f }}, 928 // Test a sample of values in the meaningful range according to the API. 929 new Object[] { 1667, new float[] { 1.4014802f, 1.0f, 0.08060435f }}, 930 new Object[] { 1668, new float[] { 1.4010513f, 1.0f, 0.08076303f }}, 931 new Object[] { 1700, new float[] { 1.3874257f, 1.0f, 0.08596305f }}, 932 new Object[] { 1701, new float[] { 1.3870035f, 1.0f, 0.08612958f }}, 933 new Object[] { 2020, new float[] { 1.2686056f, 1.0f, 0.14921218f }}, 934 new Object[] { 2102, new float[] { 1.2439337f, 1.0f, 0.1678791f }}, 935 new Object[] { 2360, new float[] { 1.1796018f, 1.0f, 0.2302558f }}, 936 new Object[] { 4688, new float[] { 0.9875373f, 1.0f, 0.79908675f }}, 937 new Object[] { 5797, new float[] { 0.97189087f, 1.0f, 1.0097121f }}, 938 new Object[] { 7625, new float[] { 0.96806175f, 1.0f, 1.2695707f }}, 939 new Object[] { 8222, new float[] { 0.9690009f, 1.0f, 1.3359972f }}, 940 new Object[] { 8330, new float[] { 0.9692224f, 1.0f, 1.3472213f }}, 941 new Object[] { 9374, new float[] { 0.9718307f, 1.0f, 1.4447508f }}, 942 new Object[] { 9604, new float[] { 0.97247595f, 1.0f, 1.4638413f }}, 943 new Object[] { 9894, new float[] { 0.9733059f, 1.0f, 1.4868189f }}, 944 new Object[] { 10764, new float[] { 0.97584003f, 1.0f, 1.5491791f }}, 945 new Object[] { 11735, new float[] { 0.97862047f, 1.0f, 1.6088297f }}, 946 new Object[] { 12819, new float[] { 0.98155034f, 1.0f, 1.6653923f }}, 947 new Object[] { 13607, new float[] { 0.98353446f, 1.0f, 1.7010691f }}, 948 new Object[] { 15185, new float[] { 0.98712224f, 1.0f, 1.7615601f }}, 949 new Object[] { 17474, new float[] { 0.9914801f, 1.0f, 1.8297766f }}, 950 new Object[] { 18788, new float[] { 0.9935937f, 1.0f, 1.8612393f }}, 951 new Object[] { 19119, new float[] { 0.99408686f, 1.0f, 1.8684553f }}, 952 new Object[] { 19174, new float[] { 0.99416786f, 1.0f, 1.8696303f }}, 953 new Object[] { 19437, new float[] { 0.9945476f, 1.0f, 1.8751476f }}, 954 new Object[] { 19533, new float[] { 0.99468416f, 1.0f, 1.8771234f }}, 955 new Object[] { 19548, new float[] { 0.99470526f, 1.0f, 1.8774294f }}, 956 new Object[] { 19762, new float[] { 0.995005f, 1.0f, 1.8817542f }}, 957 new Object[] { 19774, new float[] { 0.9950216f, 1.0f, 1.8819935f }}, 958 new Object[] { 20291, new float[] { 0.99572146f, 1.0f, 1.8920314f }}, 959 new Object[] { 23018, new float[] { 0.99893945f, 1.0f, 1.9371331f }}, 960 new Object[] { 23509, new float[] { 0.999445f, 1.0f, 1.9440757f }}, 961 new Object[] { 24761, new float[] { 1.0006485f, 1.0f, 1.9604537f }}, 962 963 }; 964 } 965 966 @Test 967 @Parameters(method = "cctToXyzExpected") testCctToXyzValues(int cct, float[] xyz)968 public void testCctToXyzValues(int cct, float[] xyz) { 969 float[] result = ColorSpace.cctToXyz(cct); 970 assertArrayEquals(xyz, result, 1e-3f); 971 } 972 chromaticAdaptationNullParameters()973 private static Object[] chromaticAdaptationNullParameters() { 974 return new Object[] { 975 new Object[] { null, ColorSpace.ILLUMINANT_D50, ColorSpace.ILLUMINANT_D60 }, 976 new Object[] { ColorSpace.Adaptation.BRADFORD, null, ColorSpace.ILLUMINANT_D60 }, 977 new Object[] { ColorSpace.Adaptation.BRADFORD, ColorSpace.ILLUMINANT_D60, null }, 978 }; 979 } 980 981 @Test(expected = NullPointerException.class) 982 @Parameters(method = "chromaticAdaptationNullParameters") testChromaticAdaptationNullParameters(ColorSpace.Adaptation adaptation, float[] srcWhitePoint, float[] dstWhitePoint)983 public void testChromaticAdaptationNullParameters(ColorSpace.Adaptation adaptation, 984 float[] srcWhitePoint, float[] dstWhitePoint) { 985 ColorSpace.chromaticAdaptation(adaptation, srcWhitePoint, dstWhitePoint); 986 } 987 chromaticAdaptationWrongSizedArrays()988 private static Object[] chromaticAdaptationWrongSizedArrays() { 989 return new Object[] { 990 new Object[] { ColorSpace.Adaptation.BRADFORD, new float[] { 1.0f }, 991 ColorSpace.ILLUMINANT_D60 }, 992 new Object[] { ColorSpace.Adaptation.BRADFORD, ColorSpace.ILLUMINANT_D60, 993 new float[] { 1.0f, 1.0f, 1.0f, 1.0f }}, 994 }; 995 } 996 997 @Test(expected = IllegalArgumentException.class) 998 @Parameters(method = "chromaticAdaptationWrongSizedArrays") testChromaticAdaptationWrongSizedArrays(ColorSpace.Adaptation adaptation, float[] srcWhitePoint, float[] dstWhitePoint)999 public void testChromaticAdaptationWrongSizedArrays(ColorSpace.Adaptation adaptation, 1000 float[] srcWhitePoint, float[] dstWhitePoint) { 1001 ColorSpace.chromaticAdaptation(adaptation, srcWhitePoint, dstWhitePoint); 1002 } 1003 1004 private static float[] sIdentityMatrix = new float[] { 1005 1.0f, 0.0f, 0.0f, 1006 0.0f, 1.0f, 0.0f, 1007 0.0f, 0.0f, 1.0f 1008 }; 1009 1010 @Test testChromaticAdaptation()1011 public void testChromaticAdaptation() { 1012 for (ColorSpace.Adaptation adaptation : ColorSpace.Adaptation.values()) { 1013 float[][] whitePoints = { 1014 ColorSpace.ILLUMINANT_A, 1015 ColorSpace.ILLUMINANT_B, 1016 ColorSpace.ILLUMINANT_C, 1017 ColorSpace.ILLUMINANT_D50, 1018 ColorSpace.ILLUMINANT_D55, 1019 ColorSpace.ILLUMINANT_D60, 1020 ColorSpace.ILLUMINANT_D65, 1021 ColorSpace.ILLUMINANT_D75, 1022 ColorSpace.ILLUMINANT_E, 1023 }; 1024 for (float[] srcWhitePoint : whitePoints) { 1025 for (float[] dstWhitePoint : whitePoints) { 1026 float[] result = ColorSpace.chromaticAdaptation(adaptation, srcWhitePoint, 1027 dstWhitePoint); 1028 assertNotNull(result); 1029 assertEquals(9, result.length); 1030 if (Arrays.equals(srcWhitePoint, dstWhitePoint)) { 1031 assertArrayEquals(sIdentityMatrix, result, 0f); 1032 } 1033 } 1034 } 1035 } 1036 } 1037 1038 @Test getDataSpaceFromColorSpace()1039 public void getDataSpaceFromColorSpace() { 1040 ColorSpace cs = ColorSpace.get(ColorSpace.Named.BT709); 1041 assertNotNull(cs); 1042 assertEquals(DataSpace.DATASPACE_BT709, cs.getDataSpace()); 1043 1044 cs = ColorSpace.get(ColorSpace.Named.ACES); 1045 assertEquals(DataSpace.DATASPACE_UNKNOWN, cs.getDataSpace()); 1046 } 1047 1048 @Test getColorSpaceFromDataSpace()1049 public void getColorSpaceFromDataSpace() { 1050 ColorSpace cs = ColorSpace.getFromDataSpace(DataSpace.DATASPACE_SRGB); 1051 assertNotNull(cs); 1052 assertEquals(DataSpace.DATASPACE_SRGB, cs.getDataSpace()); 1053 1054 assertNull(ColorSpace.getFromDataSpace(DataSpace.DATASPACE_JFIF)); 1055 } 1056 1057 @SuppressWarnings("SameParameterValue") assertArrayNotEquals(float[] a, float[] b, float eps)1058 private void assertArrayNotEquals(float[] a, float[] b, float eps) { 1059 for (int i = 0; i < a.length; i++) { 1060 if (Float.compare(a[i], b[i]) == 0 || Math.abs(a[i] - b[i]) < eps) { 1061 fail("Expected " + a[i] + ", received " + b[i]); 1062 } 1063 } 1064 } 1065 assertArrayEquals(float[] a, float[] b, float eps)1066 private void assertArrayEquals(float[] a, float[] b, float eps) { 1067 for (int i = 0; i < a.length; i++) { 1068 if (Float.compare(a[i], b[i]) != 0 && Math.abs(a[i] - b[i]) > eps) { 1069 fail("Expected " + a[i] + ", received " + b[i]); 1070 } 1071 } 1072 } 1073 } 1074