/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.graphics.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.graphics.ColorSpace;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Arrays;
import java.util.function.DoubleUnaryOperator;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class ColorSpaceTest {
    // Column-major RGB->XYZ transform matrix for the sRGB color space
    private static final float[] SRGB_TO_XYZ = {
            0.412391f, 0.212639f, 0.019331f,
            0.357584f, 0.715169f, 0.119195f,
            0.180481f, 0.072192f, 0.950532f
    };
    // Column-major XYZ->RGB transform matrix for the sRGB color space
    private static final float[] XYZ_TO_SRGB = {
            3.240970f, -0.969244f,  0.055630f,
           -1.537383f,  1.875968f, -0.203977f,
           -0.498611f,  0.041555f,  1.056971f
    };

    // Column-major RGB->XYZ transform matrix for the sRGB color space and a D50 white point
    private static final float[] SRGB_TO_XYZ_D50 = {
            0.4360747f, 0.2225045f, 0.0139322f,
            0.3850649f, 0.7168786f, 0.0971045f,
            0.1430804f, 0.0606169f, 0.7141733f
    };

    private static final float[] SRGB_PRIMARIES_xyY =
            { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f };
    private static final float[] SRGB_WHITE_POINT_xyY = { 0.3127f, 0.3290f };

    private static final float[] SRGB_PRIMARIES_XYZ = {
            1.939394f, 1.000000f, 0.090909f,
            0.500000f, 1.000000f, 0.166667f,
            2.500000f, 1.000000f, 13.166667f
    };
    private static final float[] SRGB_WHITE_POINT_XYZ = { 0.950456f, 1.000f, 1.089058f };

    private static final DoubleUnaryOperator sIdentity = DoubleUnaryOperator.identity();

    @Test
    public void testNamedColorSpaces() {
        for (ColorSpace.Named named : ColorSpace.Named.values()) {
            ColorSpace colorSpace = ColorSpace.get(named);
            assertNotNull(colorSpace.getName());
            assertNotNull(colorSpace);
            assertEquals(named.ordinal(), colorSpace.getId());
            assertTrue(colorSpace.getComponentCount() >= 1);
            assertTrue(colorSpace.getComponentCount() <= 4);
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testNullName() {
        new ColorSpace.Rgb(null, new float[6], new float[2], sIdentity, sIdentity, 0.0f, 1.0f);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testEmptyName() {
        new ColorSpace.Rgb("", new float[6], new float[2], sIdentity, sIdentity, 0.0f, 1.0f);
    }

    @Test
    public void testName() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2],
                sIdentity, sIdentity, 0.0f, 1.0f);
        assertEquals("Test", cs.getName());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testPrimariesLength() {
        new ColorSpace.Rgb("Test", new float[7], new float[2], sIdentity, sIdentity, 0.0f, 1.0f);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testWhitePointLength() {
        new ColorSpace.Rgb("Test", new float[6], new float[1], sIdentity, sIdentity, 0.0f, 1.0f);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testNullOETF() {
        new ColorSpace.Rgb("Test", new float[6], new float[2], null, sIdentity, 0.0f, 1.0f);
    }

    @Test
    public void testOETF() {
        DoubleUnaryOperator op = Math::sqrt;
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2],
                op, sIdentity, 0.0f, 1.0f);
        assertEquals(0.5, cs.getOetf().applyAsDouble(0.25), 1e-5);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testNullEOTF() {
        new ColorSpace.Rgb("Test", new float[6], new float[2], sIdentity, null, 0.0f, 1.0f);
    }

    @Test
    public void testEOTF() {
        DoubleUnaryOperator op = x -> x * x;
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", new float[6], new float[2],
                sIdentity, op, 0.0f, 1.0f);
        assertEquals(0.0625, cs.getEotf().applyAsDouble(0.25), 1e-5);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidRange() {
        new ColorSpace.Rgb("Test", new float[6], new float[2], sIdentity, sIdentity, 2.0f, 1.0f);
    }

    @Test
    public void testRanges() {
        ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB);

        float m1 = cs.getMinValue(0);
        float m2 = cs.getMinValue(1);
        float m3 = cs.getMinValue(2);

        assertEquals(0.0f, m1, 1e-9f);
        assertEquals(0.0f, m2, 1e-9f);
        assertEquals(0.0f, m3, 1e-9f);

        m1 = cs.getMaxValue(0);
        m2 = cs.getMaxValue(1);
        m3 = cs.getMaxValue(2);

        assertEquals(1.0f, m1, 1e-9f);
        assertEquals(1.0f, m2, 1e-9f);
        assertEquals(1.0f, m3, 1e-9f);

        cs = ColorSpace.get(ColorSpace.Named.CIE_LAB);

        m1 = cs.getMinValue(0);
        m2 = cs.getMinValue(1);
        m3 = cs.getMinValue(2);

        assertEquals(0.0f, m1, 1e-9f);
        assertEquals(-128.0f, m2, 1e-9f);
        assertEquals(-128.0f, m3, 1e-9f);

        m1 = cs.getMaxValue(0);
        m2 = cs.getMaxValue(1);
        m3 = cs.getMaxValue(2);

        assertEquals(100.0f, m1, 1e-9f);
        assertEquals(128.0f, m2, 1e-9f);
        assertEquals(128.0f, m3, 1e-9f);

        cs = ColorSpace.get(ColorSpace.Named.CIE_XYZ);

        m1 = cs.getMinValue(0);
        m2 = cs.getMinValue(1);
        m3 = cs.getMinValue(2);

        assertEquals(-2.0f, m1, 1e-9f);
        assertEquals(-2.0f, m2, 1e-9f);
        assertEquals(-2.0f, m3, 1e-9f);

        m1 = cs.getMaxValue(0);
        m2 = cs.getMaxValue(1);
        m3 = cs.getMaxValue(2);

        assertEquals(2.0f, m1, 1e-9f);
        assertEquals(2.0f, m2, 1e-9f);
        assertEquals(2.0f, m3, 1e-9f);
    }

    @Test
    public void testMat3x3() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity);

        float[] rgbToXYZ = cs.getTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f);
        }
    }

    @Test
    public void testMat3x3Inverse() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity);

        float[] xyzToRGB = cs.getInverseTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f);
        }
    }

    @Test
    public void testMat3x3Primaries() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity);

        float[] primaries = cs.getPrimaries();

        assertNotNull(primaries);
        assertEquals(6, primaries.length);

        assertEquals(SRGB_PRIMARIES_xyY[0], primaries[0], 1e-5f);
        assertEquals(SRGB_PRIMARIES_xyY[1], primaries[1], 1e-5f);
        assertEquals(SRGB_PRIMARIES_xyY[2], primaries[2], 1e-5f);
        assertEquals(SRGB_PRIMARIES_xyY[3], primaries[3], 1e-5f);
        assertEquals(SRGB_PRIMARIES_xyY[4], primaries[4], 1e-5f);
        assertEquals(SRGB_PRIMARIES_xyY[5], primaries[5], 1e-5f);
    }

    @Test
    public void testMat3x3WhitePoint() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_TO_XYZ, sIdentity, sIdentity);

        float[] whitePoint = cs.getWhitePoint();

        assertNotNull(whitePoint);
        assertEquals(2, whitePoint.length);

        assertEquals(SRGB_WHITE_POINT_xyY[0], whitePoint[0], 1e-5f);
        assertEquals(SRGB_WHITE_POINT_xyY[1], whitePoint[1], 1e-5f);
    }

    @Test
    public void testXYZFromPrimaries_xyY() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_PRIMARIES_xyY, SRGB_WHITE_POINT_xyY,
                sIdentity, sIdentity, 0.0f, 1.0f);

        float[] rgbToXYZ = cs.getTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f);
        }

        float[] xyzToRGB = cs.getInverseTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f);
        }
    }

    @Test
    public void testXYZFromPrimaries_XYZ() {
        ColorSpace.Rgb cs = new ColorSpace.Rgb("Test", SRGB_PRIMARIES_XYZ, SRGB_WHITE_POINT_XYZ,
                sIdentity, sIdentity, 0.0f, 1.0f);

        float[] primaries = cs.getPrimaries();

        assertNotNull(primaries);
        assertEquals(6, primaries.length);

        // SRGB_PRIMARIES_xyY only has 1e-3 of precision, match it
        assertEquals(SRGB_PRIMARIES_xyY[0], primaries[0], 1e-3f);
        assertEquals(SRGB_PRIMARIES_xyY[1], primaries[1], 1e-3f);
        assertEquals(SRGB_PRIMARIES_xyY[2], primaries[2], 1e-3f);
        assertEquals(SRGB_PRIMARIES_xyY[3], primaries[3], 1e-3f);
        assertEquals(SRGB_PRIMARIES_xyY[4], primaries[4], 1e-3f);
        assertEquals(SRGB_PRIMARIES_xyY[5], primaries[5], 1e-3f);

        float[] whitePoint = cs.getWhitePoint();

        assertNotNull(whitePoint);
        assertEquals(2, whitePoint.length);

        // SRGB_WHITE_POINT_xyY only has 1e-3 of precision, match it
        assertEquals(SRGB_WHITE_POINT_xyY[0], whitePoint[0], 1e-3f);
        assertEquals(SRGB_WHITE_POINT_xyY[1], whitePoint[1], 1e-3f);

        float[] rgbToXYZ = cs.getTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(SRGB_TO_XYZ[i], rgbToXYZ[i], 1e-5f);
        }

        float[] xyzToRGB = cs.getInverseTransform();
        for (int i = 0; i < 9; i++) {
            assertEquals(XYZ_TO_SRGB[i], xyzToRGB[i], 1e-5f);
        }
    }

    @Test
    public void testGetComponentCount() {
        assertEquals(3, ColorSpace.get(ColorSpace.Named.SRGB).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.LINEAR_SRGB).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.DISPLAY_P3).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.CIE_LAB).getComponentCount());
        assertEquals(3, ColorSpace.get(ColorSpace.Named.CIE_XYZ).getComponentCount());
    }

    @Test
    public void testIsSRGB() {
        assertTrue(ColorSpace.get(ColorSpace.Named.SRGB).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_SRGB).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.DISPLAY_P3).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.CIE_LAB).isSrgb());
        assertFalse(ColorSpace.get(ColorSpace.Named.CIE_XYZ).isSrgb());

        ColorSpace.Rgb cs = new ColorSpace.Rgb("My sRGB", SRGB_TO_XYZ,
                x -> Math.pow(x, 1.0f / 2.2f), x -> Math.pow(x, 2.2f));
        assertTrue(cs.isSrgb());
    }

    @Test
    public void testIsWideGamut() {
        assertFalse(ColorSpace.get(ColorSpace.Named.SRGB).isWideGamut());
        assertFalse(ColorSpace.get(ColorSpace.Named.BT709).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.DCI_P3).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.BT2020).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.ACES).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.CIE_LAB).isWideGamut());
        assertTrue(ColorSpace.get(ColorSpace.Named.CIE_XYZ).isWideGamut());
    }

    @Test
    public void testWhitePoint() {
        ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] whitePoint = cs.getWhitePoint();

        assertNotNull(whitePoint);
        assertEquals(2, whitePoint.length);

        // Make sure a copy is returned
        Arrays.fill(whitePoint, Float.NaN);
        assertArrayNotEquals(whitePoint, cs.getWhitePoint(), 1e-5f);
        assertSame(whitePoint, cs.getWhitePoint(whitePoint));
        assertArrayEquals(whitePoint, cs.getWhitePoint(), 1e-5f);
    }

    @Test
    public void testPrimaries() {
        ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] primaries = cs.getPrimaries();

        assertNotNull(primaries);
        assertEquals(6, primaries.length);

        // Make sure a copy is returned
        Arrays.fill(primaries, Float.NaN);
        assertArrayNotEquals(primaries, cs.getPrimaries(), 1e-5f);
        assertSame(primaries, cs.getPrimaries(primaries));
        assertArrayEquals(primaries, cs.getPrimaries(), 1e-5f);
    }

    @Test
    public void testRGBtoXYZMatrix() {
        ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] rgbToXYZ = cs.getTransform();

        assertNotNull(rgbToXYZ);
        assertEquals(9, rgbToXYZ.length);

        // Make sure a copy is returned
        Arrays.fill(rgbToXYZ, Float.NaN);
        assertArrayNotEquals(rgbToXYZ, cs.getTransform(), 1e-5f);
        assertSame(rgbToXYZ, cs.getTransform(rgbToXYZ));
        assertArrayEquals(rgbToXYZ, cs.getTransform(), 1e-5f);
    }

    @Test
    public void testXYZtoRGBMatrix() {
        ColorSpace.Rgb cs = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] xyzToRGB = cs.getInverseTransform();

        assertNotNull(xyzToRGB);
        assertEquals(9, xyzToRGB.length);

        // Make sure a copy is returned
        Arrays.fill(xyzToRGB, Float.NaN);
        assertArrayNotEquals(xyzToRGB, cs.getInverseTransform(), 1e-5f);
        assertSame(xyzToRGB, cs.getInverseTransform(xyzToRGB));
        assertArrayEquals(xyzToRGB, cs.getInverseTransform(), 1e-5f);
    }

    @Test
    public void testRGBtoXYZ() {
        ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB);

        float[] source = { 0.75f, 0.5f, 0.25f };
        float[] expected = { 0.3012f, 0.2679f, 0.0840f };

        float[] r1 = cs.toXyz(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayNotEquals(source, r1, 1e-5f);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r3 = { source[0], source[1], source[2] };
        assertSame(r3, cs.toXyz(r3));
        assertEquals(3, r3.length);
        assertArrayEquals(r1, r3, 1e-5f);
    }

    @Test
    public void testXYZtoRGB() {
        ColorSpace cs = ColorSpace.get(ColorSpace.Named.SRGB);

        float[] source = { 0.3012f, 0.2679f, 0.0840f };
        float[] expected = { 0.75f, 0.5f, 0.25f };

        float[] r1 = cs.fromXyz(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayNotEquals(source, r1, 1e-5f);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r3 = { source[0], source[1], source[2] };
        assertSame(r3, cs.fromXyz(r3));
        assertEquals(3, r3.length);
        assertArrayEquals(r1, r3, 1e-5f);
    }

    @Test
    public void testConnect() {
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.get(ColorSpace.Named.DCI_P3));

        assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector.getSource());
        assertSame(ColorSpace.get(ColorSpace.Named.DCI_P3), connector.getDestination());
        assertSame(ColorSpace.RenderIntent.PERCEPTUAL, connector.getRenderIntent());

        connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.get(ColorSpace.Named.SRGB));

        assertSame(connector.getDestination(), connector.getSource());
        assertSame(ColorSpace.RenderIntent.RELATIVE, connector.getRenderIntent());

        connector = ColorSpace.connect(ColorSpace.get(ColorSpace.Named.DCI_P3));
        assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector.getDestination());

        connector = ColorSpace.connect(ColorSpace.get(ColorSpace.Named.SRGB));
        assertSame(connector.getSource(), connector.getDestination());
    }

    @Test
    public void testConnector() {
        // Connect color spaces with same white points
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.get(ColorSpace.Named.ADOBE_RGB));

        float[] source = { 1.0f, 0.5f, 0.0f };
        float[] expected = { 0.8912f, 0.4962f, 0.1164f };

        float[] r1 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayNotEquals(source, r1, 1e-5f);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r3 = { source[0], source[1], source[2] };
        assertSame(r3, connector.transform(r3));
        assertEquals(3, r3.length);
        assertArrayEquals(r1, r3, 1e-5f);

        connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.ADOBE_RGB),
                ColorSpace.get(ColorSpace.Named.SRGB));

        float[] tmp = source;
        source = expected;
        expected = tmp;

        r1 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayNotEquals(source, r1, 1e-5f);
        assertArrayEquals(expected, r1, 1e-3f);

        r3 = new float[] { source[0], source[1], source[2] };
        assertSame(r3, connector.transform(r3));
        assertEquals(3, r3.length);
        assertArrayEquals(r1, r3, 1e-5f);
    }

    @Test
    public void testAdaptedConnector() {
        // Connect color spaces with different white points
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB));

        float[] source = new float[] { 1.0f, 0.0f, 0.0f };
        float[] expected = new float[] { 0.70226f, 0.2757f, 0.1036f };

        float[] r = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r);
        assertEquals(3, r.length);
        assertArrayNotEquals(source, r, 1e-5f);
        assertArrayEquals(expected, r, 1e-4f);
    }

    @Test
    public void testAdaptedConnectorWithRenderIntent() {
        // Connect a wider color space to a narrow color space
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.DCI_P3),
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.RenderIntent.RELATIVE);

        float[] source = { 0.9f, 0.9f, 0.9f };

        float[] relative = connector.transform(source[0], source[1], source[2]);
        assertNotNull(relative);
        assertEquals(3, relative.length);
        assertArrayNotEquals(source, relative, 1e-5f);
        assertArrayEquals(new float[] { 0.8862f, 0.8862f, 0.8862f }, relative, 1e-4f);

        connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.DCI_P3),
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.RenderIntent.ABSOLUTE);

        float[] absolute = connector.transform(source[0], source[1], source[2]);
        assertNotNull(absolute);
        assertEquals(3, absolute.length);
        assertArrayNotEquals(source, absolute, 1e-5f);
        assertArrayNotEquals(relative, absolute, 1e-5f);
        assertArrayEquals(new float[] { 0.8475f, 0.9217f, 0.8203f }, absolute, 1e-4f);
    }

    @Test
    public void testIdentityConnector() {
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.get(ColorSpace.Named.SRGB));

        assertSame(connector.getSource(), connector.getDestination());
        assertSame(ColorSpace.RenderIntent.RELATIVE, connector.getRenderIntent());

        float[] source = new float[] { 0.11112f, 0.22227f, 0.444448f };

        float[] r = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r);
        assertEquals(3, r.length);
        assertArrayEquals(source, r, 1e-5f);
    }

    @Test
    public void testConnectorTransformIdentity() {
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.DCI_P3),
                ColorSpace.get(ColorSpace.Named.DCI_P3));

        float[] source = { 1.0f, 0.0f, 0.0f };
        float[] expected = { 1.0f, 0.0f, 0.0f };

        float[] r1 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r3 = { source[0], source[1], source[2] };
        assertSame(r3, connector.transform(r3));
        assertEquals(3, r3.length);
        assertArrayEquals(r1, r3, 1e-5f);
    }

    @Test
    public void testAdaptation() {
        ColorSpace adapted = ColorSpace.adapt(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.ILLUMINANT_D50);

        float[] sRGBD50 = {
                0.43602175f, 0.22247513f, 0.01392813f,
                0.38510883f, 0.71690667f, 0.09710153f,
                0.14308129f, 0.06061824f, 0.71415880f
        };

        assertArrayEquals(sRGBD50, ((ColorSpace.Rgb) adapted).getTransform(), 1e-7f);

        adapted = ColorSpace.adapt(
                ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.ILLUMINANT_D50,
                ColorSpace.Adaptation.BRADFORD);
        assertArrayEquals(sRGBD50, ((ColorSpace.Rgb) adapted).getTransform(), 1e-7f);
    }

    @Test
    public void testImplicitSRGBConnector() {
        ColorSpace.Connector connector1 = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.DCI_P3));

        assertSame(ColorSpace.get(ColorSpace.Named.SRGB), connector1.getDestination());

        ColorSpace.Connector connector2 = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.DCI_P3),
                ColorSpace.get(ColorSpace.Named.SRGB));

        float[] source = { 0.6f, 0.9f, 0.7f };
        assertArrayEquals(
                connector1.transform(source[0], source[1], source[2]),
                connector2.transform(source[0], source[1], source[2]), 1e-7f);
    }

    @Test
    public void testLab() {
        ColorSpace.Connector connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.CIE_LAB));

        float[] source = { 100.0f, 0.0f, 0.0f };
        float[] expected = { 1.0f, 1.0f, 1.0f };

        float[] r1 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(expected, r1, 1e-3f);

        source = new float[] { 100.0f, 0.0f, 54.0f };
        expected = new float[] { 1.0f, 0.9925f, 0.5762f };

        float[] r2 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r2);
        assertEquals(3, r2.length);
        assertArrayEquals(expected, r2, 1e-3f);

        connector = ColorSpace.connect(
                ColorSpace.get(ColorSpace.Named.CIE_LAB), ColorSpace.RenderIntent.ABSOLUTE);

        source = new float[] { 100.0f, 0.0f, 0.0f };
        expected = new float[] { 1.0f, 0.9910f, 0.8651f };

        r1 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(expected, r1, 1e-3f);

        source = new float[] { 100.0f, 0.0f, 54.0f };
        expected = new float[] { 1.0f, 0.9853f, 0.4652f };

        r2 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r2);
        assertEquals(3, r2.length);
        assertArrayEquals(expected, r2, 1e-3f);
    }

    @Test
    public void testXYZ() {
        ColorSpace xyz = ColorSpace.get(ColorSpace.Named.CIE_XYZ);

        float[] source = { 0.32f, 0.43f, 0.54f };

        float[] r1 = xyz.toXyz(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(source, r1, 1e-7f);

        float[] r2 = xyz.fromXyz(source[0], source[1], source[2]);
        assertNotNull(r2);
        assertEquals(3, r2.length);
        assertArrayEquals(source, r2, 1e-7f);

        ColorSpace.Connector connector =
                ColorSpace.connect(ColorSpace.get(ColorSpace.Named.CIE_XYZ));

        float[] expected = { 0.2280f, 0.7541f, 0.8453f };

        float[] r3 = connector.transform(source[0], source[1], source[2]);
        assertNotNull(r3);
        assertEquals(3, r3.length);
        assertArrayEquals(expected, r3, 1e-3f);
    }

    @Test
    public void testIDs() {
        // These cannot change
        assertEquals(0, ColorSpace.get(ColorSpace.Named.SRGB).getId());
        assertEquals(-1, ColorSpace.MIN_ID);
        assertEquals(63, ColorSpace.MAX_ID);
    }

    @Test
    public void testFromLinear() {
        ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] source = { 0.0f, 0.5f, 1.0f };
        float[] expected = { 0.0f, 0.7354f, 1.0f };

        float[] r1 = colorSpace.fromLinear(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r2 = { source[0], source[1], source[2] };
        assertSame(r2, colorSpace.fromLinear(r2));
        assertEquals(3, r2.length);
        assertArrayEquals(r1, r2, 1e-5f);
    }

    @Test
    public void testToLinear() {
        ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);

        float[] source = { 0.0f, 0.5f, 1.0f };
        float[] expected = new float[] { 0.0f, 0.2140f, 1.0f };

        float[] r1 = colorSpace.toLinear(source[0], source[1], source[2]);
        assertNotNull(r1);
        assertEquals(3, r1.length);
        assertArrayEquals(expected, r1, 1e-3f);

        float[] r2 = new float[] { source[0], source[1], source[2] };
        assertSame(r2, colorSpace.toLinear(r2));
        assertEquals(3, r2.length);
        assertArrayEquals(r1, r2, 1e-5f);
    }

    @Test
    public void testTransferParameters() {
        ColorSpace.Rgb colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);
        assertNotNull(colorSpace.getTransferParameters());

        colorSpace = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
        assertNull(colorSpace.getTransferParameters());
    }

    @Test
    public void testIdempotentTransferFunctions() {
        Arrays.stream(ColorSpace.Named.values())
                .map(ColorSpace::get)
                .filter(cs -> cs.getModel() == ColorSpace.Model.RGB)
                .map(cs -> (ColorSpace.Rgb) cs)
                .forEach(cs -> {
                        float[] source = { 0.0f, 0.5f, 1.0f };
                        float[] r = cs.fromLinear(cs.toLinear(source[0], source[1], source[2]));
                        assertArrayEquals(source, r, 1e-3f);
                });
    }

    @Test
    public void testMatch() {
        for (ColorSpace.Named named : ColorSpace.Named.values()) {
            ColorSpace cs = ColorSpace.get(named);
            if (cs.getModel() == ColorSpace.Model.RGB) {
                ColorSpace.Rgb rgb = (ColorSpace.Rgb) cs;
                // match() cannot match extended sRGB
                if (rgb != ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) &&
                        rgb != ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB)) {

                    // match() uses CIE XYZ D50
                    rgb = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50);
                    assertSame(cs,
                            ColorSpace.match(rgb.getTransform(), rgb.getTransferParameters()));
                }
            }
        }

        assertSame(ColorSpace.get(ColorSpace.Named.SRGB),
                ColorSpace.match(SRGB_TO_XYZ_D50, new ColorSpace.Rgb.TransferParameters(
                        1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4)));
    }


    @SuppressWarnings("SameParameterValue")
    private static void assertArrayNotEquals(float[] a, float[] b, float eps) {
        for (int i = 0; i < a.length; i++) {
            if (Float.compare(a[i], b[i]) == 0 || Math.abs(a[i] - b[i]) < eps) {
                fail("Expected " + a[i] + ", received " + b[i]);
            }
        }
    }

    private static void assertArrayEquals(float[] a, float[] b, float eps) {
        for (int i = 0; i < a.length; i++) {
            if (Float.compare(a[i], b[i]) != 0 && Math.abs(a[i] - b[i]) > eps) {
                fail("Expected " + a[i] + ", received " + b[i]);
            }
        }
    }
}
