/*
 * 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;

import android.annotation.AnyThread;
import android.annotation.ColorInt;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.SuppressAutoDoc;
import android.util.Pair;

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

/**
 * {@usesMathJax}
 *
 * <p>A {@link ColorSpace} is used to identify a specific organization of colors.
 * Each color space is characterized by a {@link Model color model} that defines
 * how a color value is represented (for instance the {@link Model#RGB RGB} color
 * model defines a color value as a triplet of numbers).</p>
 *
 * <p>Each component of a color must fall within a valid range, specific to each
 * color space, defined by {@link #getMinValue(int)} and {@link #getMaxValue(int)}
 * This range is commonly \([0..1]\). While it is recommended to use values in the
 * valid range, a color space always clamps input and output values when performing
 * operations such as converting to a different color space.</p>
 *
 * <h3>Using color spaces</h3>
 *
 * <p>This implementation provides a pre-defined set of common color spaces
 * described in the {@link Named} enum. To obtain an instance of one of the
 * pre-defined color spaces, simply invoke {@link #get(Named)}:</p>
 *
 * <pre class="prettyprint">
 * ColorSpace sRgb = ColorSpace.get(ColorSpace.Named.SRGB);
 * </pre>
 *
 * <p>The {@link #get(Named)} method always returns the same instance for a given
 * name. Color spaces with an {@link Model#RGB RGB} color model can be safely
 * cast to {@link Rgb}. Doing so gives you access to more APIs to query various
 * properties of RGB color models: color gamut primaries, transfer functions,
 * conversions to and from linear space, etc. Please refer to {@link Rgb} for
 * more information.</p>
 *
 * <p>The documentation of {@link Named} provides a detailed description of the
 * various characteristics of each available color space.</p>
 *
 * <h3>Color space conversions</h3>

 * <p>To allow conversion between color spaces, this implementation uses the CIE
 * XYZ profile connection space (PCS). Color values can be converted to and from
 * this PCS using {@link #toXyz(float[])} and {@link #fromXyz(float[])}.</p>
 *
 * <p>For color space with a non-RGB color model, the white point of the PCS
 * <em>must be</em> the CIE standard illuminant D50. RGB color spaces use their
 * native white point (D65 for {@link Named#SRGB sRGB} for instance and must
 * undergo {@link Adaptation chromatic adaptation} as necessary.</p>
 *
 * <p>Since the white point of the PCS is not defined for RGB color space, it is
 * highly recommended to use the variants of the {@link #connect(ColorSpace, ColorSpace)}
 * method to perform conversions between color spaces. A color space can be
 * manually adapted to a specific white point using {@link #adapt(ColorSpace, float[])}.
 * Please refer to the documentation of {@link Rgb RGB color spaces} for more
 * information. Several common CIE standard illuminants are provided in this
 * class as reference (see {@link #ILLUMINANT_D65} or {@link #ILLUMINANT_D50}
 * for instance).</p>
 *
 * <p>Here is an example of how to convert from a color space to another:</p>
 *
 * <pre class="prettyprint">
 * // Convert from DCI-P3 to Rec.2020
 * ColorSpace.Connector connector = ColorSpace.connect(
 *         ColorSpace.get(ColorSpace.Named.DCI_P3),
 *         ColorSpace.get(ColorSpace.Named.BT2020));
 *
 * float[] bt2020 = connector.transform(p3r, p3g, p3b);
 * </pre>
 *
 * <p>You can easily convert to {@link Named#SRGB sRGB} by omitting the second
 * parameter:</p>
 *
 * <pre class="prettyprint">
 * // Convert from DCI-P3 to sRGB
 * ColorSpace.Connector connector = ColorSpace.connect(ColorSpace.get(ColorSpace.Named.DCI_P3));
 *
 * float[] sRGB = connector.transform(p3r, p3g, p3b);
 * </pre>
 *
 * <p>Conversions also work between color spaces with different color models:</p>
 *
 * <pre class="prettyprint">
 * // Convert from CIE L*a*b* (color model Lab) to Rec.709 (color model RGB)
 * ColorSpace.Connector connector = ColorSpace.connect(
 *         ColorSpace.get(ColorSpace.Named.CIE_LAB),
 *         ColorSpace.get(ColorSpace.Named.BT709));
 * </pre>
 *
 * <h3>Color spaces and multi-threading</h3>
 *
 * <p>Color spaces and other related classes ({@link Connector} for instance)
 * are immutable and stateless. They can be safely used from multiple concurrent
 * threads.</p>
 *
 * <p>Public static methods provided by this class, such as {@link #get(Named)}
 * and {@link #connect(ColorSpace, ColorSpace)}, are also guaranteed to be
 * thread-safe.</p>
 *
 * @see #get(Named)
 * @see Named
 * @see Model
 * @see Connector
 * @see Adaptation
 */
@AnyThread
@SuppressWarnings("StaticInitializerReferencesSubClass")
@SuppressAutoDoc
public abstract class ColorSpace {
    /**
     * Standard CIE 1931 2° illuminant A, encoded in xyY.
     * This illuminant has a color temperature of 2856K.
     */
    public static final float[] ILLUMINANT_A   = { 0.44757f, 0.40745f };
    /**
     * Standard CIE 1931 2° illuminant B, encoded in xyY.
     * This illuminant has a color temperature of 4874K.
     */
    public static final float[] ILLUMINANT_B   = { 0.34842f, 0.35161f };
    /**
     * Standard CIE 1931 2° illuminant C, encoded in xyY.
     * This illuminant has a color temperature of 6774K.
     */
    public static final float[] ILLUMINANT_C   = { 0.31006f, 0.31616f };
    /**
     * Standard CIE 1931 2° illuminant D50, encoded in xyY.
     * This illuminant has a color temperature of 5003K. This illuminant
     * is used by the profile connection space in ICC profiles.
     */
    public static final float[] ILLUMINANT_D50 = { 0.34567f, 0.35850f };
    /**
     * Standard CIE 1931 2° illuminant D55, encoded in xyY.
     * This illuminant has a color temperature of 5503K.
     */
    public static final float[] ILLUMINANT_D55 = { 0.33242f, 0.34743f };
    /**
     * Standard CIE 1931 2° illuminant D60, encoded in xyY.
     * This illuminant has a color temperature of 6004K.
     */
    public static final float[] ILLUMINANT_D60 = { 0.32168f, 0.33767f };
    /**
     * Standard CIE 1931 2° illuminant D65, encoded in xyY.
     * This illuminant has a color temperature of 6504K. This illuminant
     * is commonly used in RGB color spaces such as sRGB, BT.209, etc.
     */
    public static final float[] ILLUMINANT_D65 = { 0.31271f, 0.32902f };
    /**
     * Standard CIE 1931 2° illuminant D75, encoded in xyY.
     * This illuminant has a color temperature of 7504K.
     */
    public static final float[] ILLUMINANT_D75 = { 0.29902f, 0.31485f };
    /**
     * Standard CIE 1931 2° illuminant E, encoded in xyY.
     * This illuminant has a color temperature of 5454K.
     */
    public static final float[] ILLUMINANT_E   = { 0.33333f, 0.33333f };

    /**
     * The minimum ID value a color space can have.
     *
     * @see #getId()
     */
    public static final int MIN_ID = -1; // Do not change
    /**
     * The maximum ID value a color space can have.
     *
     * @see #getId()
     */
    public static final int MAX_ID = 63; // Do not change, used to encode in longs

    private static final float[] SRGB_PRIMARIES = { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f };
    private static final float[] NTSC_1953_PRIMARIES = { 0.67f, 0.33f, 0.21f, 0.71f, 0.14f, 0.08f };
    private static final float[] ILLUMINANT_D50_XYZ = { 0.964212f, 1.0f, 0.825188f };

    // See static initialization block next to #get(Named)
    private static final ColorSpace[] sNamedColorSpaces = new ColorSpace[Named.values().length];

    @NonNull private final String mName;
    @NonNull private final Model mModel;
    @IntRange(from = MIN_ID, to = MAX_ID) private final int mId;

    /**
     * {@usesMathJax}
     *
     * <p>List of common, named color spaces. A corresponding instance of
     * {@link ColorSpace} can be obtained by calling {@link ColorSpace#get(Named)}:</p>
     *
     * <pre class="prettyprint">
     * ColorSpace cs = ColorSpace.get(ColorSpace.Named.DCI_P3);
     * </pre>
     *
     * <p>The properties of each color space are described below (see {@link #SRGB sRGB}
     * for instance). When applicable, the color gamut of each color space is compared
     * to the color gamut of sRGB using a CIE 1931 xy chromaticity diagram. This diagram
     * shows the location of the color space's primaries and white point.</p>
     *
     * @see ColorSpace#get(Named)
     */
    public enum Named {
        // NOTE: Do NOT change the order of the enum
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space sRGB standardized as IEC 61966-2.1:1999.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.640</td><td>0.300</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.330</td><td>0.600</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">sRGB IEC61966-2.1</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{sRGB} = \begin{cases} 12.92 \times C_{linear} & C_{linear} \lt 0.0031308 \\
         *             1.055 \times C_{linear}^{\frac{1}{2.4}} - 0.055 & C_{linear} \ge 0.0031308 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{sRGB}}{12.92} & C_{sRGB} \lt 0.04045 \\
         *             \left( \frac{C_{sRGB} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.04045 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
         *     <figcaption style="text-align: center;">sRGB</figcaption>
         * </p>
         */
        SRGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space sRGB standardized as IEC 61966-2.1:1999.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.640</td><td>0.300</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.330</td><td>0.600</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">sRGB IEC61966-2.1 (Linear)</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{sRGB} = C_{linear}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{sRGB}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
         *     <figcaption style="text-align: center;">sRGB</figcaption>
         * </p>
         */
        LINEAR_SRGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space scRGB-nl standardized as IEC 61966-2-2:2003.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.640</td><td>0.300</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.330</td><td>0.600</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">scRGB-nl IEC 61966-2-2:2003</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{scRGB} = \begin{cases} sign(C_{linear}) 12.92 \times \left| C_{linear} \right| &
         *                      \left| C_{linear} \right| \lt 0.0031308 \\
         *             sign(C_{linear}) 1.055 \times \left| C_{linear} \right| ^{\frac{1}{2.4}} - 0.055 &
         *                      \left| C_{linear} \right| \ge 0.0031308 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}sign(C_{scRGB}) \frac{\left| C_{scRGB} \right|}{12.92} &
         *                  \left| C_{scRGB} \right| \lt 0.04045 \\
         *             sign(C_{scRGB}) \left( \frac{\left| C_{scRGB} \right| + 0.055}{1.055} \right) ^{2.4} &
         *                  \left| C_{scRGB} \right| \ge 0.04045 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([-0.799..2.399[\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
         *     <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        EXTENDED_SRGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space scRGB standardized as IEC 61966-2-2:2003.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.640</td><td>0.300</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.330</td><td>0.600</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">scRGB IEC 61966-2-2:2003</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{scRGB} = C_{linear}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{scRGB}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([-0.5..7.499[\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
         *     <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        LINEAR_EXTENDED_SRGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space BT.709 standardized as Rec. ITU-R BT.709-5.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.640</td><td>0.300</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.330</td><td>0.600</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Rec. ITU-R BT.709-5</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{BT709} = \begin{cases} 4.5 \times C_{linear} & C_{linear} \lt 0.018 \\
         *             1.099 \times C_{linear}^{\frac{1}{2.2}} - 0.099 & C_{linear} \ge 0.018 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{BT709}}{4.5} & C_{BT709} \lt 0.081 \\
         *             \left( \frac{C_{BT709} + 0.099}{1.099} \right) ^{2.2} & C_{BT709} \ge 0.081 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt709.png" />
         *     <figcaption style="text-align: center;">BT.709</figcaption>
         * </p>
         */
        BT709,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space BT.2020 standardized as Rec. ITU-R BT.2020-1.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.708</td><td>0.170</td><td>0.131</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.292</td><td>0.797</td><td>0.046</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Rec. ITU-R BT.2020-1</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{BT2020} = \begin{cases} 4.5 \times C_{linear} & C_{linear} \lt 0.0181 \\
         *             1.0993 \times C_{linear}^{\frac{1}{2.2}} - 0.0993 & C_{linear} \ge 0.0181 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{BT2020}}{4.5} & C_{BT2020} \lt 0.08145 \\
         *             \left( \frac{C_{BT2020} + 0.0993}{1.0993} \right) ^{2.2} & C_{BT2020} \ge 0.08145 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt2020.png" />
         *     <figcaption style="text-align: center;">BT.2020 (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        BT2020,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space DCI-P3 standardized as SMPTE RP 431-2-2007.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.680</td><td>0.265</td><td>0.150</td><td>0.314</td></tr>
         *     <tr><td>y</td><td>0.320</td><td>0.690</td><td>0.060</td><td>0.351</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">SMPTE RP 431-2-2007 DCI (P3)</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">N/A</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{P3} = C_{linear}^{\frac{1}{2.6}}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{P3}^{2.6}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_dci_p3.png" />
         *     <figcaption style="text-align: center;">DCI-P3 (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        DCI_P3,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space Display P3 based on SMPTE RP 431-2-2007 and IEC 61966-2.1:1999.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.680</td><td>0.265</td><td>0.150</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.320</td><td>0.690</td><td>0.060</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Display P3</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{DisplayP3} = \begin{cases} 12.92 \times C_{linear} & C_{linear} \lt 0.0030186 \\
         *             1.055 \times C_{linear}^{\frac{1}{2.4}} - 0.055 & C_{linear} \ge 0.0030186 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{DisplayP3}}{12.92} & C_{sRGB} \lt 0.039 \\
         *             \left( \frac{C_{DisplayP3} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.039 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_display_p3.png" />
         *     <figcaption style="text-align: center;">Display P3 (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        DISPLAY_P3,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space NTSC, 1953 standard.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.67</td><td>0.21</td><td>0.14</td><td>0.310</td></tr>
         *     <tr><td>y</td><td>0.33</td><td>0.71</td><td>0.08</td><td>0.316</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">NTSC (1953)</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">C</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{BT709} = \begin{cases} 4.5 \times C_{linear} & C_{linear} \lt 0.018 \\
         *             1.099 \times C_{linear}^{\frac{1}{2.2}} - 0.099 & C_{linear} \ge 0.018 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{BT709}}{4.5} & C_{BT709} \lt 0.081 \\
         *             \left( \frac{C_{BT709} + 0.099}{1.099} \right) ^{2.2} & C_{BT709} \ge 0.081 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ntsc_1953.png" />
         *     <figcaption style="text-align: center;">NTSC 1953 (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        NTSC_1953,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space SMPTE C.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.630</td><td>0.310</td><td>0.155</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.340</td><td>0.595</td><td>0.070</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">SMPTE-C RGB</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{BT709} = \begin{cases} 4.5 \times C_{linear} & C_{linear} \lt 0.018 \\
         *             1.099 \times C_{linear}^{\frac{1}{2.2}} - 0.099 & C_{linear} \ge 0.018 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{BT709}}{4.5} & C_{BT709} \lt 0.081 \\
         *             \left( \frac{C_{BT709} + 0.099}{1.099} \right) ^{2.2} & C_{BT709} \ge 0.081 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_smpte_c.png" />
         *     <figcaption style="text-align: center;">SMPTE-C (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        SMPTE_C,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space Adobe RGB (1998).</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.64</td><td>0.21</td><td>0.15</td><td>0.3127</td></tr>
         *     <tr><td>y</td><td>0.33</td><td>0.71</td><td>0.06</td><td>0.3290</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Adobe RGB (1998)</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D65</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{RGB} = C_{linear}^{\frac{1}{2.2}}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{RGB}^{2.2}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_adobe_rgb.png" />
         *     <figcaption style="text-align: center;">Adobe RGB (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        ADOBE_RGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space ProPhoto RGB standardized as ROMM RGB ISO 22028-2:2013.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.7347</td><td>0.1596</td><td>0.0366</td><td>0.3457</td></tr>
         *     <tr><td>y</td><td>0.2653</td><td>0.8404</td><td>0.0001</td><td>0.3585</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">ROMM RGB ISO 22028-2:2013</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D50</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{ROMM} = \begin{cases} 16 \times C_{linear} & C_{linear} \lt 0.001953 \\
         *             C_{linear}^{\frac{1}{1.8}} & C_{linear} \ge 0.001953 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(\begin{equation}
         *             C_{linear} = \begin{cases}\frac{C_{ROMM}}{16} & C_{ROMM} \lt 0.031248 \\
         *             C_{ROMM}^{1.8} & C_{ROMM} \ge 0.031248 \end{cases}
         *             \end{equation}\)
         *         </td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_pro_photo_rgb.png" />
         *     <figcaption style="text-align: center;">ProPhoto RGB (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        PRO_PHOTO_RGB,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space ACES standardized as SMPTE ST 2065-1:2012.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.73470</td><td>0.00000</td><td>0.00010</td><td>0.32168</td></tr>
         *     <tr><td>y</td><td>0.26530</td><td>1.00000</td><td>-0.07700</td><td>0.33767</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">SMPTE ST 2065-1:2012 ACES</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D60</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{ACES} = C_{linear}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{ACES}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_aces.png" />
         *     <figcaption style="text-align: center;">ACES (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        ACES,
        /**
         * <p>{@link ColorSpace.Rgb RGB} color space ACEScg standardized as Academy S-2014-004.</p>
         * <table summary="Color space definition">
         *     <tr>
         *         <th>Chromaticity</th><th>Red</th><th>Green</th><th>Blue</th><th>White point</th>
         *     </tr>
         *     <tr><td>x</td><td>0.713</td><td>0.165</td><td>0.128</td><td>0.32168</td></tr>
         *     <tr><td>y</td><td>0.293</td><td>0.830</td><td>0.044</td><td>0.33767</td></tr>
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Academy S-2014-004 ACEScg</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D60</td></tr>
         *     <tr>
         *         <td>Opto-electronic transfer function (OETF)</td>
         *         <td colspan="4">\(C_{ACEScg} = C_{linear}\)</td>
         *     </tr>
         *     <tr>
         *         <td>Electro-optical transfer function (EOTF)</td>
         *         <td colspan="4">\(C_{linear} = C_{ACEScg}\)</td>
         *     </tr>
         *     <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
         * </table>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_acescg.png" />
         *     <figcaption style="text-align: center;">ACEScg (orange) vs sRGB (white)</figcaption>
         * </p>
         */
        ACESCG,
        /**
         * <p>{@link Model#XYZ XYZ} color space CIE XYZ. This color space assumes standard
         * illuminant D50 as its white point.</p>
         * <table summary="Color space definition">
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Generic XYZ</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D50</td></tr>
         *     <tr><td>Range</td><td colspan="4">\([-2.0, 2.0]\)</td></tr>
         * </table>
         */
        CIE_XYZ,
        /**
         * <p>{@link Model#LAB Lab} color space CIE L*a*b*. This color space uses CIE XYZ D50
         * as a profile conversion space.</p>
         * <table summary="Color space definition">
         *     <tr><th>Property</th><th colspan="4">Value</th></tr>
         *     <tr><td>Name</td><td colspan="4">Generic L*a*b*</td></tr>
         *     <tr><td>CIE standard illuminant</td><td colspan="4">D50</td></tr>
         *     <tr><td>Range</td><td colspan="4">\(L: [0.0, 100.0], a: [-128, 128], b: [-128, 128]\)</td></tr>
         * </table>
         */
        CIE_LAB
        // Update the initialization block next to #get(Named) when adding new values
    }

    /**
     * <p>A render intent determines how a {@link ColorSpace.Connector connector}
     * maps colors from one color space to another. The choice of mapping is
     * important when the source color space has a larger color gamut than the
     * destination color space.</p>
     *
     * @see ColorSpace#connect(ColorSpace, ColorSpace, RenderIntent)
     */
    public enum RenderIntent {
        /**
         * <p>Compresses the source gamut into the destination gamut.
         * This render intent affects all colors, inside and outside
         * of destination gamut. The goal of this render intent is
         * to preserve the visual relationship between colors.</p>
         *
         * <p class="note">This render intent is currently not
         * implemented and behaves like {@link #RELATIVE}.</p>
         */
        PERCEPTUAL,
        /**
         * Similar to the {@link #ABSOLUTE} render intent, this render
         * intent matches the closest color in the destination gamut
         * but makes adjustments for the destination white point.
         */
        RELATIVE,
        /**
         * <p>Attempts to maintain the relative saturation of colors
         * from the source gamut to the destination gamut, to keep
         * highly saturated colors as saturated as possible.</p>
         *
         * <p class="note">This render intent is currently not
         * implemented and behaves like {@link #RELATIVE}.</p>
         */
        SATURATION,
        /**
         * Colors that are in the destination gamut are left unchanged.
         * Colors that fall outside of the destination gamut are mapped
         * to the closest possible color within the gamut of the destination
         * color space (they are clipped).
         */
        ABSOLUTE
    }

    /**
     * {@usesMathJax}
     *
     * <p>List of adaptation matrices that can be used for chromatic adaptation
     * using the von Kries transform. These matrices are used to convert values
     * in the CIE XYZ space to values in the LMS space (Long Medium Short).</p>
     *
     * <p>Given an adaptation matrix \(A\), the conversion from XYZ to
     * LMS is straightforward:</p>
     *
     * $$\left[ \begin{array}{c} L\\ M\\ S \end{array} \right] =
     * A \left[ \begin{array}{c} X\\ Y\\ Z \end{array} \right]$$
     *
     * <p>The complete von Kries transform \(T\) uses a diagonal matrix
     * noted \(D\) to perform the adaptation in LMS space. In addition
     * to \(A\) and \(D\), the source white point \(W1\) and the destination
     * white point \(W2\) must be specified:</p>
     *
     * $$\begin{align*}
     * \left[ \begin{array}{c} L_1\\ M_1\\ S_1 \end{array} \right] &=
     *      A \left[ \begin{array}{c} W1_X\\ W1_Y\\ W1_Z \end{array} \right] \\
     * \left[ \begin{array}{c} L_2\\ M_2\\ S_2 \end{array} \right] &=
     *      A \left[ \begin{array}{c} W2_X\\ W2_Y\\ W2_Z \end{array} \right] \\
     * D &= \left[ \begin{matrix} \frac{L_2}{L_1} & 0 & 0 \\
     *      0 & \frac{M_2}{M_1} & 0 \\
     *      0 & 0 & \frac{S_2}{S_1} \end{matrix} \right] \\
     * T &= A^{-1}.D.A
     * \end{align*}$$
     *
     * <p>As an example, the resulting matrix \(T\) can then be used to
     * perform the chromatic adaptation of sRGB XYZ transform from D65
     * to D50:</p>
     *
     * $$sRGB_{D50} = T.sRGB_{D65}$$
     *
     * @see ColorSpace.Connector
     * @see ColorSpace#connect(ColorSpace, ColorSpace)
     */
    public enum Adaptation {
        /**
         * Bradford chromatic adaptation transform, as defined in the
         * CIECAM97s color appearance model.
         */
        BRADFORD(new float[] {
                 0.8951f, -0.7502f,  0.0389f,
                 0.2664f,  1.7135f, -0.0685f,
                -0.1614f,  0.0367f,  1.0296f
        }),
        /**
         * von Kries chromatic adaptation transform.
         */
        VON_KRIES(new float[] {
                 0.40024f, -0.22630f, 0.00000f,
                 0.70760f,  1.16532f, 0.00000f,
                -0.08081f,  0.04570f, 0.91822f
        }),
        /**
         * CIECAT02 chromatic adaption transform, as defined in the
         * CIECAM02 color appearance model.
         */
        CIECAT02(new float[] {
                 0.7328f, -0.7036f,  0.0030f,
                 0.4296f,  1.6975f,  0.0136f,
                -0.1624f,  0.0061f,  0.9834f
        });

        final float[] mTransform;

        Adaptation(@NonNull @Size(9) float[] transform) {
            mTransform = transform;
        }
    }

    /**
     * A color model is required by a {@link ColorSpace} to describe the
     * way colors can be represented as tuples of numbers. A common color
     * model is the {@link #RGB RGB} color model which defines a color
     * as represented by a tuple of 3 numbers (red, green and blue).
     */
    public enum Model {
        /**
         * The RGB model is a color model with 3 components that
         * refer to the three additive primiaries: red, green
         * andd blue.
         */
        RGB(3),
        /**
         * The XYZ model is a color model with 3 components that
         * are used to model human color vision on a basic sensory
         * level.
         */
        XYZ(3),
        /**
         * The Lab model is a color model with 3 components used
         * to describe a color space that is more perceptually
         * uniform than XYZ.
         */
        LAB(3),
        /**
         * The CMYK model is a color model with 4 components that
         * refer to four inks used in color printing: cyan, magenta,
         * yellow and black (or key). CMYK is a subtractive color
         * model.
         */
        CMYK(4);

        private final int mComponentCount;

        Model(@IntRange(from = 1, to = 4) int componentCount) {
            mComponentCount = componentCount;
        }

        /**
         * Returns the number of components for this color model.
         *
         * @return An integer between 1 and 4
         */
        @IntRange(from = 1, to = 4)
        public int getComponentCount() {
            return mComponentCount;
        }
    }

    private ColorSpace(
            @NonNull String name,
            @NonNull Model model,
            @IntRange(from = MIN_ID, to = MAX_ID) int id) {

        if (name == null || name.length() < 1) {
            throw new IllegalArgumentException("The name of a color space cannot be null and " +
                    "must contain at least 1 character");
        }

        if (model == null) {
            throw new IllegalArgumentException("A color space must have a model");
        }

        if (id < MIN_ID || id > MAX_ID) {
            throw new IllegalArgumentException("The id must be between " +
                    MIN_ID + " and " + MAX_ID);
        }

        mName = name;
        mModel = model;
        mId = id;
    }

    /**
     * <p>Returns the name of this color space. The name is never null
     * and contains always at least 1 character.</p>
     *
     * <p>Color space names are recommended to be unique but are not
     * guaranteed to be. There is no defined format but the name usually
     * falls in one of the following categories:</p>
     * <ul>
     *     <li>Generic names used to identify color spaces in non-RGB
     *     color models. For instance: {@link Named#CIE_LAB Generic L*a*b*}.</li>
     *     <li>Names tied to a particular specification. For instance:
     *     {@link Named#SRGB sRGB IEC61966-2.1} or
     *     {@link Named#ACES SMPTE ST 2065-1:2012 ACES}.</li>
     *     <li>Ad-hoc names, often generated procedurally or by the user
     *     during a calibration workflow. These names often contain the
     *     make and model of the display.</li>
     * </ul>
     *
     * <p>Because the format of color space names is not defined, it is
     * not recommended to programmatically identify a color space by its
     * name alone. Names can be used as a first approximation.</p>
     *
     * <p>It is however perfectly acceptable to display color space names to
     * users in a UI, or in debuggers and logs. When displaying a color space
     * name to the user, it is recommended to add extra information to avoid
     * ambiguities: color model, a representation of the color space's gamut,
     * white point, etc.</p>
     *
     * @return A non-null String of length >= 1
     */
    @NonNull
    public String getName() {
        return mName;
    }

    /**
     * Returns the ID of this color space. Positive IDs match the color
     * spaces enumerated in {@link Named}. A negative ID indicates a
     * color space created by calling one of the public constructors.
     *
     * @return An integer between {@link #MIN_ID} and {@link #MAX_ID}
     */
    @IntRange(from = MIN_ID, to = MAX_ID)
    public int getId() {
        return mId;
    }

    /**
     * Return the color model of this color space.
     *
     * @return A non-null {@link Model}
     *
     * @see Model
     * @see #getComponentCount()
     */
    @NonNull
    public Model getModel() {
        return mModel;
    }

    /**
     * Returns the number of components that form a color value according
     * to this color space's color model.
     *
     * @return An integer between 1 and 4
     *
     * @see Model
     * @see #getModel()
     */
    @IntRange(from = 1, to = 4)
    public int getComponentCount() {
        return mModel.getComponentCount();
    }

    /**
     * Returns whether this color space is a wide-gamut color space.
     * An RGB color space is wide-gamut if its gamut entirely contains
     * the {@link Named#SRGB sRGB} gamut and if the area of its gamut is
     * 90% of greater than the area of the {@link Named#NTSC_1953 NTSC}
     * gamut.
     *
     * @return True if this color space is a wide-gamut color space,
     *         false otherwise
     */
    public abstract boolean isWideGamut();

    /**
     * <p>Indicates whether this color space is the sRGB color space or
     * equivalent to the sRGB color space.</p>
     * <p>A color space is considered sRGB if it meets all the following
     * conditions:</p>
     * <ul>
     *     <li>Its color model is {@link Model#RGB}.</li>
     *     <li>
     *         Its primaries are within 1e-3 of the true
     *         {@link Named#SRGB sRGB} primaries.
     *     </li>
     *     <li>
     *         Its white point is withing 1e-3 of the CIE standard
     *         illuminant {@link #ILLUMINANT_D65 D65}.
     *     </li>
     *     <li>Its opto-electronic transfer function is not linear.</li>
     *     <li>Its electro-optical transfer function is not linear.</li>
     *     <li>Its range is \([0..1]\).</li>
     * </ul>
     * <p>This method always returns true for {@link Named#SRGB}.</p>
     *
     * @return True if this color space is the sRGB color space (or a
     *         close approximation), false otherwise
     */
    public boolean isSrgb() {
        return false;
    }

    /**
     * Returns the minimum valid value for the specified component of this
     * color space's color model.
     *
     * @param component The index of the component
     * @return A floating point value less than {@link #getMaxValue(int)}
     *
     * @see #getMaxValue(int)
     * @see Model#getComponentCount()
     */
    public abstract float getMinValue(@IntRange(from = 0, to = 3) int component);

    /**
     * Returns the maximum valid value for the specified component of this
     * color space's color model.
     *
     * @param component The index of the component
     * @return A floating point value greater than {@link #getMinValue(int)}
     *
     * @see #getMinValue(int)
     * @see Model#getComponentCount()
     */
    public abstract float getMaxValue(@IntRange(from = 0, to = 3) int component);

    /**
     * <p>Converts a color value from this color space's model to
     * tristimulus CIE XYZ values. If the color model of this color
     * space is not {@link Model#RGB RGB}, it is assumed that the
     * target CIE XYZ space uses a {@link #ILLUMINANT_D50 D50}
     * standard illuminant.</p>
     *
     * <p>This method is a convenience for color spaces with a model
     * of 3 components ({@link Model#RGB RGB} or {@link Model#LAB}
     * for instance). With color spaces using fewer or more components,
     * use {@link #toXyz(float[])} instead</p>.
     *
     * @param r The first component of the value to convert from (typically R in RGB)
     * @param g The second component of the value to convert from (typically G in RGB)
     * @param b The third component of the value to convert from (typically B in RGB)
     * @return A new array of 3 floats, containing tristimulus XYZ values
     *
     * @see #toXyz(float[])
     * @see #fromXyz(float, float, float)
     */
    @NonNull
    @Size(3)
    public float[] toXyz(float r, float g, float b) {
        return toXyz(new float[] { r, g, b });
    }

    /**
     * <p>Converts a color value from this color space's model to
     * tristimulus CIE XYZ values. If the color model of this color
     * space is not {@link Model#RGB RGB}, it is assumed that the
     * target CIE XYZ space uses a {@link #ILLUMINANT_D50 D50}
     * standard illuminant.</p>
     *
     * <p class="note">The specified array's length  must be at least
     * equal to to the number of color components as returned by
     * {@link Model#getComponentCount()}.</p>
     *
     * @param v An array of color components containing the color space's
     *          color value to convert to XYZ, and large enough to hold
     *          the resulting tristimulus XYZ values
     * @return The array passed in parameter
     *
     * @see #toXyz(float, float, float)
     * @see #fromXyz(float[])
     */
    @NonNull
    @Size(min = 3)
    public abstract float[] toXyz(@NonNull @Size(min = 3) float[] v);

    /**
     * <p>Converts tristimulus values from the CIE XYZ space to this
     * color space's color model.</p>
     *
     * @param x The X component of the color value
     * @param y The Y component of the color value
     * @param z The Z component of the color value
     * @return A new array whose size is equal to the number of color
     *         components as returned by {@link Model#getComponentCount()}
     *
     * @see #fromXyz(float[])
     * @see #toXyz(float, float, float)
     */
    @NonNull
    @Size(min = 3)
    public float[] fromXyz(float x, float y, float z) {
        float[] xyz = new float[mModel.getComponentCount()];
        xyz[0] = x;
        xyz[1] = y;
        xyz[2] = z;
        return fromXyz(xyz);
    }

    /**
     * <p>Converts tristimulus values from the CIE XYZ space to this color
     * space's color model. The resulting value is passed back in the specified
     * array.</p>
     *
     * <p class="note">The specified array's length  must be at least equal to
     * to the number of color components as returned by
     * {@link Model#getComponentCount()}, and its first 3 values must
     * be the XYZ components to convert from.</p>
     *
     * @param v An array of color components containing the XYZ values
     *          to convert from, and large enough to hold the number
     *          of components of this color space's model
     * @return The array passed in parameter
     *
     * @see #fromXyz(float, float, float)
     * @see #toXyz(float[])
     */
    @NonNull
    @Size(min = 3)
    public abstract float[] fromXyz(@NonNull @Size(min = 3) float[] v);

    /**
     * <p>Returns a string representation of the object. This method returns
     * a string equal to the value of:</p>
     *
     * <pre class="prettyprint">
     * getName() + "(id=" + getId() + ", model=" + getModel() + ")"
     * </pre>
     *
     * <p>For instance, the string representation of the {@link Named#SRGB sRGB}
     * color space is equal to the following value:</p>
     *
     * <pre>
     * sRGB IEC61966-2.1 (id=0, model=RGB)
     * </pre>
     *
     * @return A string representation of the object
     */
    @Override
    @NonNull
    public String toString() {
        return mName + " (id=" + mId + ", model=" + mModel + ")";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ColorSpace that = (ColorSpace) o;

        if (mId != that.mId) return false;
        //noinspection SimplifiableIfStatement
        if (!mName.equals(that.mName)) return false;
        return mModel == that.mModel;

    }

    @Override
    public int hashCode() {
        int result = mName.hashCode();
        result = 31 * result + mModel.hashCode();
        result = 31 * result + mId;
        return result;
    }

    /**
     * <p>Connects two color spaces to allow conversion from the source color
     * space to the destination color space. If the source and destination
     * color spaces do not have the same profile connection space (CIE XYZ
     * with the same white point), they are chromatically adapted to use the
     * CIE standard illuminant {@link #ILLUMINANT_D50 D50} as needed.</p>
     *
     * <p>If the source and destination are the same, an optimized connector
     * is returned to avoid unnecessary computations and loss of precision.</p>
     *
     * <p>Colors are mapped from the source color space to the destination color
     * space using the {@link RenderIntent#PERCEPTUAL perceptual} render intent.</p>
     *
     * @param source The color space to convert colors from
     * @param destination The color space to convert colors to
     * @return A non-null connector between the two specified color spaces
     *
     * @see #connect(ColorSpace)
     * @see #connect(ColorSpace, RenderIntent)
     * @see #connect(ColorSpace, ColorSpace, RenderIntent)
     */
    @NonNull
    public static Connector connect(@NonNull ColorSpace source, @NonNull ColorSpace destination) {
        return connect(source, destination, RenderIntent.PERCEPTUAL);
    }

    /**
     * <p>Connects two color spaces to allow conversion from the source color
     * space to the destination color space. If the source and destination
     * color spaces do not have the same profile connection space (CIE XYZ
     * with the same white point), they are chromatically adapted to use the
     * CIE standard illuminant {@link #ILLUMINANT_D50 D50} as needed.</p>
     *
     * <p>If the source and destination are the same, an optimized connector
     * is returned to avoid unnecessary computations and loss of precision.</p>
     *
     * @param source The color space to convert colors from
     * @param destination The color space to convert colors to
     * @param intent The render intent to map colors from the source to the destination
     * @return A non-null connector between the two specified color spaces
     *
     * @see #connect(ColorSpace)
     * @see #connect(ColorSpace, RenderIntent)
     * @see #connect(ColorSpace, ColorSpace)
     */
    @NonNull
    @SuppressWarnings("ConstantConditions")
    public static Connector connect(@NonNull ColorSpace source, @NonNull ColorSpace destination,
            @NonNull RenderIntent intent) {
        if (source.equals(destination)) return Connector.identity(source);

        if (source.getModel() == Model.RGB && destination.getModel() == Model.RGB) {
            return new Connector.Rgb((Rgb) source, (Rgb) destination, intent);
        }

        return new Connector(source, destination, intent);
    }

    /**
     * <p>Connects the specified color spaces to sRGB.
     * If the source color space does not use CIE XYZ D65 as its profile
     * connection space, the two spaces are chromatically adapted to use the
     * CIE standard illuminant {@link #ILLUMINANT_D50 D50} as needed.</p>
     *
     * <p>If the source is the sRGB color space, an optimized connector
     * is returned to avoid unnecessary computations and loss of precision.</p>
     *
     * <p>Colors are mapped from the source color space to the destination color
     * space using the {@link RenderIntent#PERCEPTUAL perceptual} render intent.</p>
     *
     * @param source The color space to convert colors from
     * @return A non-null connector between the specified color space and sRGB
     *
     * @see #connect(ColorSpace, RenderIntent)
     * @see #connect(ColorSpace, ColorSpace)
     * @see #connect(ColorSpace, ColorSpace, RenderIntent)
     */
    @NonNull
    public static Connector connect(@NonNull ColorSpace source) {
        return connect(source, RenderIntent.PERCEPTUAL);
    }

    /**
     * <p>Connects the specified color spaces to sRGB.
     * If the source color space does not use CIE XYZ D65 as its profile
     * connection space, the two spaces are chromatically adapted to use the
     * CIE standard illuminant {@link #ILLUMINANT_D50 D50} as needed.</p>
     *
     * <p>If the source is the sRGB color space, an optimized connector
     * is returned to avoid unnecessary computations and loss of precision.</p>
     *
     * @param source The color space to convert colors from
     * @param intent The render intent to map colors from the source to the destination
     * @return A non-null connector between the specified color space and sRGB
     *
     * @see #connect(ColorSpace)
     * @see #connect(ColorSpace, ColorSpace)
     * @see #connect(ColorSpace, ColorSpace, RenderIntent)
     */
    @NonNull
    public static Connector connect(@NonNull ColorSpace source, @NonNull RenderIntent intent) {
        if (source.isSrgb()) return Connector.identity(source);

        if (source.getModel() == Model.RGB) {
            return new Connector.Rgb((Rgb) source, (Rgb) get(Named.SRGB), intent);
        }

        return new Connector(source, get(Named.SRGB), intent);
    }

    /**
     * <p>Performs the chromatic adaptation of a color space from its native
     * white point to the specified white point.</p>
     *
     * <p>The chromatic adaptation is performed using the
     * {@link Adaptation#BRADFORD} matrix.</p>
     *
     * <p class="note">The color space returned by this method always has
     * an ID of {@link #MIN_ID}.</p>
     *
     * @param colorSpace The color space to chromatically adapt
     * @param whitePoint The new white point
     * @return A {@link ColorSpace} instance with the same name, primaries,
     *         transfer functions and range as the specified color space
     *
     * @see Adaptation
     * @see #adapt(ColorSpace, float[], Adaptation)
     */
    @NonNull
    public static ColorSpace adapt(@NonNull ColorSpace colorSpace,
            @NonNull @Size(min = 2, max = 3) float[] whitePoint) {
        return adapt(colorSpace, whitePoint, Adaptation.BRADFORD);
    }

    /**
     * <p>Performs the chromatic adaptation of a color space from its native
     * white point to the specified white point. If the specified color space
     * does not have an {@link Model#RGB RGB} color model, or if the color
     * space already has the target white point, the color space is returned
     * unmodified.</p>
     *
     * <p>The chromatic adaptation is performed using the von Kries method
     * described in the documentation of {@link Adaptation}.</p>
     *
     * <p class="note">The color space returned by this method always has
     * an ID of {@link #MIN_ID}.</p>
     *
     * @param colorSpace The color space to chromatically adapt
     * @param whitePoint The new white point
     * @param adaptation The adaptation matrix
     * @return A new color space if the specified color space has an RGB
     *         model and a white point different from the specified white
     *         point; the specified color space otherwise
     *
     * @see Adaptation
     * @see #adapt(ColorSpace, float[])
     */
    @NonNull
    public static ColorSpace adapt(@NonNull ColorSpace colorSpace,
            @NonNull @Size(min = 2, max = 3) float[] whitePoint,
            @NonNull Adaptation adaptation) {
        if (colorSpace.getModel() == Model.RGB) {
            ColorSpace.Rgb rgb = (ColorSpace.Rgb) colorSpace;
            if (compare(rgb.mWhitePoint, whitePoint)) return colorSpace;

            float[] xyz = whitePoint.length == 3 ?
                    Arrays.copyOf(whitePoint, 3) : xyYToXyz(whitePoint);
            float[] adaptationTransform = chromaticAdaptation(adaptation.mTransform,
                    xyYToXyz(rgb.getWhitePoint()), xyz);
            float[] transform = mul3x3(adaptationTransform, rgb.mTransform);

            return new ColorSpace.Rgb(rgb, transform, whitePoint);
        }
        return colorSpace;
    }

    /**
     * <p>Returns an instance of {@link ColorSpace} whose ID matches the
     * specified ID.</p>
     *
     * <p>This method always returns the same instance for a given ID.</p>
     *
     * <p>This method is thread-safe.</p>
     *
     * @param index An integer ID between {@link #MIN_ID} and {@link #MAX_ID}
     * @return A non-null {@link ColorSpace} instance
     * @throws IllegalArgumentException If the ID does not match the ID of one of the
     *         {@link Named named color spaces}
     */
    @NonNull
    static ColorSpace get(@IntRange(from = MIN_ID, to = MAX_ID) int index) {
        if (index < 0 || index > Named.values().length) {
            throw new IllegalArgumentException("Invalid ID, must be in the range [0.." +
                    Named.values().length + "]");
        }
        return sNamedColorSpaces[index];
    }

    /**
     * <p>Returns an instance of {@link ColorSpace} identified by the specified
     * name. The list of names provided in the {@link Named} enum gives access
     * to a variety of common RGB color spaces.</p>
     *
     * <p>This method always returns the same instance for a given name.</p>
     *
     * <p>This method is thread-safe.</p>
     *
     * @param name The name of the color space to get an instance of
     * @return A non-null {@link ColorSpace} instance
     */
    @NonNull
    public static ColorSpace get(@NonNull Named name) {
        return sNamedColorSpaces[name.ordinal()];
    }

    /**
     * <p>Returns a {@link Named} instance of {@link ColorSpace} that matches
     * the specified RGB to CIE XYZ transform and transfer functions. If no
     * instance can be found, this method returns null.</p>
     *
     * <p>The color transform matrix is assumed to target the CIE XYZ space
     * a {@link #ILLUMINANT_D50 D50} standard illuminant.</p>
     *
     * @param toXYZD50 3x3 column-major transform matrix from RGB to the profile
     *                 connection space CIE XYZ as an array of 9 floats, cannot be null
     * @param function Parameters for the transfer functions
     * @return A non-null {@link ColorSpace} if a match is found, null otherwise
     */
    @Nullable
    public static ColorSpace match(
            @NonNull @Size(9) float[] toXYZD50,
            @NonNull Rgb.TransferParameters function) {

        for (ColorSpace colorSpace : sNamedColorSpaces) {
            if (colorSpace.getModel() == Model.RGB) {
                ColorSpace.Rgb rgb = (ColorSpace.Rgb) adapt(colorSpace, ILLUMINANT_D50_XYZ);
                if (compare(toXYZD50, rgb.mTransform) &&
                        compare(function, rgb.mTransferParameters)) {
                    return colorSpace;
                }
            }
        }

        return null;
    }

    /**
     * <p>Creates a new {@link Renderer} that can be used to visualize and
     * debug color spaces. See the documentation of {@link Renderer} for
     * more information.</p>
     *
     * @return A new non-null {@link Renderer} instance
     *
     * @see Renderer
     *
     * @hide
     */
    @NonNull
    public static Renderer createRenderer() {
        return new Renderer();
    }

    static {
        sNamedColorSpaces[Named.SRGB.ordinal()] = new ColorSpace.Rgb(
                "sRGB IEC61966-2.1",
                SRGB_PRIMARIES,
                ILLUMINANT_D65,
                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4),
                Named.SRGB.ordinal()
        );
        sNamedColorSpaces[Named.LINEAR_SRGB.ordinal()] = new ColorSpace.Rgb(
                "sRGB IEC61966-2.1 (Linear)",
                SRGB_PRIMARIES,
                ILLUMINANT_D65,
                1.0,
                0.0f, 1.0f,
                Named.LINEAR_SRGB.ordinal()
        );
        sNamedColorSpaces[Named.EXTENDED_SRGB.ordinal()] = new ColorSpace.Rgb(
                "scRGB-nl IEC 61966-2-2:2003",
                SRGB_PRIMARIES,
                ILLUMINANT_D65,
                x -> absRcpResponse(x, 1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4),
                x -> absResponse(x, 1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4),
                -0.799f, 2.399f,
                Named.EXTENDED_SRGB.ordinal()
        );
        sNamedColorSpaces[Named.LINEAR_EXTENDED_SRGB.ordinal()] = new ColorSpace.Rgb(
                "scRGB IEC 61966-2-2:2003",
                SRGB_PRIMARIES,
                ILLUMINANT_D65,
                1.0,
                -0.5f, 7.499f,
                Named.LINEAR_EXTENDED_SRGB.ordinal()
        );
        sNamedColorSpaces[Named.BT709.ordinal()] = new ColorSpace.Rgb(
                "Rec. ITU-R BT.709-5",
                new float[] { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f },
                ILLUMINANT_D65,
                new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45),
                Named.BT709.ordinal()
        );
        sNamedColorSpaces[Named.BT2020.ordinal()] = new ColorSpace.Rgb(
                "Rec. ITU-R BT.2020-1",
                new float[] { 0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f },
                ILLUMINANT_D65,
                new Rgb.TransferParameters(1 / 1.0993, 0.0993 / 1.0993, 1 / 4.5, 0.08145, 1 / 0.45),
                Named.BT2020.ordinal()
        );
        sNamedColorSpaces[Named.DCI_P3.ordinal()] = new ColorSpace.Rgb(
                "SMPTE RP 431-2-2007 DCI (P3)",
                new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f },
                new float[] { 0.314f, 0.351f },
                2.6,
                0.0f, 1.0f,
                Named.DCI_P3.ordinal()
        );
        sNamedColorSpaces[Named.DISPLAY_P3.ordinal()] = new ColorSpace.Rgb(
                "Display P3",
                new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f },
                ILLUMINANT_D65,
                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.039, 2.4),
                Named.DISPLAY_P3.ordinal()
        );
        sNamedColorSpaces[Named.NTSC_1953.ordinal()] = new ColorSpace.Rgb(
                "NTSC (1953)",
                NTSC_1953_PRIMARIES,
                ILLUMINANT_C,
                new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45),
                Named.NTSC_1953.ordinal()
        );
        sNamedColorSpaces[Named.SMPTE_C.ordinal()] = new ColorSpace.Rgb(
                "SMPTE-C RGB",
                new float[] { 0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f },
                ILLUMINANT_D65,
                new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45),
                Named.SMPTE_C.ordinal()
        );
        sNamedColorSpaces[Named.ADOBE_RGB.ordinal()] = new ColorSpace.Rgb(
                "Adobe RGB (1998)",
                new float[] { 0.64f, 0.33f, 0.21f, 0.71f, 0.15f, 0.06f },
                ILLUMINANT_D65,
                2.2,
                0.0f, 1.0f,
                Named.ADOBE_RGB.ordinal()
        );
        sNamedColorSpaces[Named.PRO_PHOTO_RGB.ordinal()] = new ColorSpace.Rgb(
                "ROMM RGB ISO 22028-2:2013",
                new float[] { 0.7347f, 0.2653f, 0.1596f, 0.8404f, 0.0366f, 0.0001f },
                ILLUMINANT_D50,
                new Rgb.TransferParameters(1.0, 0.0, 1 / 16.0, 0.031248, 1.8),
                Named.PRO_PHOTO_RGB.ordinal()
        );
        sNamedColorSpaces[Named.ACES.ordinal()] = new ColorSpace.Rgb(
                "SMPTE ST 2065-1:2012 ACES",
                new float[] { 0.73470f, 0.26530f, 0.0f, 1.0f, 0.00010f, -0.0770f },
                ILLUMINANT_D60,
                1.0,
                -65504.0f, 65504.0f,
                Named.ACES.ordinal()
        );
        sNamedColorSpaces[Named.ACESCG.ordinal()] = new ColorSpace.Rgb(
                "Academy S-2014-004 ACEScg",
                new float[] { 0.713f, 0.293f, 0.165f, 0.830f, 0.128f, 0.044f },
                ILLUMINANT_D60,
                1.0,
                -65504.0f, 65504.0f,
                Named.ACESCG.ordinal()
        );
        sNamedColorSpaces[Named.CIE_XYZ.ordinal()] = new Xyz(
                "Generic XYZ",
                Named.CIE_XYZ.ordinal()
        );
        sNamedColorSpaces[Named.CIE_LAB.ordinal()] = new ColorSpace.Lab(
                "Generic L*a*b*",
                Named.CIE_LAB.ordinal()
        );
    }

    // Reciprocal piecewise gamma response
    private static double rcpResponse(double x, double a, double b, double c, double d, double g) {
        return x >= d * c ? (Math.pow(x, 1.0 / g) - b) / a : x / c;
    }

    // Piecewise gamma response
    private static double response(double x, double a, double b, double c, double d, double g) {
        return x >= d ? Math.pow(a * x + b, g) : c * x;
    }

    // Reciprocal piecewise gamma response
    private static double rcpResponse(double x, double a, double b, double c, double d,
            double e, double f, double g) {
        return x >= d * c ? (Math.pow(x - e, 1.0 / g) - b) / a : (x - f) / c;
    }

    // Piecewise gamma response
    private static double response(double x, double a, double b, double c, double d,
            double e, double f, double g) {
        return x >= d ? Math.pow(a * x + b, g) + e : c * x + f;
    }

    // Reciprocal piecewise gamma response, encoded as sign(x).f(abs(x)) for color
    // spaces that allow negative values
    @SuppressWarnings("SameParameterValue")
    private static double absRcpResponse(double x, double a, double b, double c, double d, double g) {
        return Math.copySign(rcpResponse(x < 0.0 ? -x : x, a, b, c, d, g), x);
    }

    // Piecewise gamma response, encoded as sign(x).f(abs(x)) for color spaces that
    // allow negative values
    @SuppressWarnings("SameParameterValue")
    private static double absResponse(double x, double a, double b, double c, double d, double g) {
        return Math.copySign(response(x < 0.0 ? -x : x, a, b, c, d, g), x);
    }

    /**
     * Compares two sets of parametric transfer functions parameters with a precision of 1e-3.
     *
     * @param a The first set of parameters to compare
     * @param b The second set of parameters to compare
     * @return True if the two sets are equal, false otherwise
     */
    private static boolean compare(
            @Nullable Rgb.TransferParameters a,
            @Nullable Rgb.TransferParameters b) {
        //noinspection SimplifiableIfStatement
        if (a == null && b == null) return true;
        return a != null && b != null &&
                Math.abs(a.a - b.a) < 1e-3 &&
                Math.abs(a.b - b.b) < 1e-3 &&
                Math.abs(a.c - b.c) < 1e-3 &&
                Math.abs(a.d - b.d) < 2e-3 && // Special case for variations in sRGB OETF/EOTF
                Math.abs(a.e - b.e) < 1e-3 &&
                Math.abs(a.f - b.f) < 1e-3 &&
                Math.abs(a.g - b.g) < 1e-3;
    }

    /**
     * Compares two arrays of float with a precision of 1e-3.
     *
     * @param a The first array to compare
     * @param b The second array to compare
     * @return True if the two arrays are equal, false otherwise
     */
    private static boolean compare(@NonNull float[] a, @NonNull float[] b) {
        if (a == b) return true;
        for (int i = 0; i < a.length; i++) {
            if (Float.compare(a[i], b[i]) != 0 && Math.abs(a[i] - b[i]) > 1e-3f) return false;
        }
        return true;
    }

    /**
     * Inverts a 3x3 matrix. This method assumes the matrix is invertible.
     *
     * @param m A 3x3 matrix as a non-null array of 9 floats
     * @return A new array of 9 floats containing the inverse of the input matrix
     */
    @NonNull
    @Size(9)
    private static float[] inverse3x3(@NonNull @Size(9) float[] m) {
        float a = m[0];
        float b = m[3];
        float c = m[6];
        float d = m[1];
        float e = m[4];
        float f = m[7];
        float g = m[2];
        float h = m[5];
        float i = m[8];

        float A = e * i - f * h;
        float B = f * g - d * i;
        float C = d * h - e * g;

        float det = a * A + b * B + c * C;

        float inverted[] = new float[m.length];
        inverted[0] = A / det;
        inverted[1] = B / det;
        inverted[2] = C / det;
        inverted[3] = (c * h - b * i) / det;
        inverted[4] = (a * i - c * g) / det;
        inverted[5] = (b * g - a * h) / det;
        inverted[6] = (b * f - c * e) / det;
        inverted[7] = (c * d - a * f) / det;
        inverted[8] = (a * e - b * d) / det;
        return inverted;
    }

    /**
     * Multiplies two 3x3 matrices, represented as non-null arrays of 9 floats.
     *
     * @param lhs 3x3 matrix, as a non-null array of 9 floats
     * @param rhs 3x3 matrix, as a non-null array of 9 floats
     * @return A new array of 9 floats containing the result of the multiplication
     *         of rhs by lhs
     */
    @NonNull
    @Size(9)
    private static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) {
        float[] r = new float[9];
        r[0] = lhs[0] * rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2];
        r[1] = lhs[1] * rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2];
        r[2] = lhs[2] * rhs[0] + lhs[5] * rhs[1] + lhs[8] * rhs[2];
        r[3] = lhs[0] * rhs[3] + lhs[3] * rhs[4] + lhs[6] * rhs[5];
        r[4] = lhs[1] * rhs[3] + lhs[4] * rhs[4] + lhs[7] * rhs[5];
        r[5] = lhs[2] * rhs[3] + lhs[5] * rhs[4] + lhs[8] * rhs[5];
        r[6] = lhs[0] * rhs[6] + lhs[3] * rhs[7] + lhs[6] * rhs[8];
        r[7] = lhs[1] * rhs[6] + lhs[4] * rhs[7] + lhs[7] * rhs[8];
        r[8] = lhs[2] * rhs[6] + lhs[5] * rhs[7] + lhs[8] * rhs[8];
        return r;
    }

    /**
     * Multiplies a vector of 3 components by a 3x3 matrix and stores the
     * result in the input vector.
     *
     * @param lhs 3x3 matrix, as a non-null array of 9 floats
     * @param rhs Vector of 3 components, as a non-null array of 3 floats
     * @return The array of 3 passed as the rhs parameter
     */
    @NonNull
    @Size(min = 3)
    private static float[] mul3x3Float3(
            @NonNull @Size(9) float[] lhs, @NonNull @Size(min = 3) float[] rhs) {
        float r0 = rhs[0];
        float r1 = rhs[1];
        float r2 = rhs[2];
        rhs[0] = lhs[0] * r0 + lhs[3] * r1 + lhs[6] * r2;
        rhs[1] = lhs[1] * r0 + lhs[4] * r1 + lhs[7] * r2;
        rhs[2] = lhs[2] * r0 + lhs[5] * r1 + lhs[8] * r2;
        return rhs;
    }

    /**
     * Multiplies a diagonal 3x3 matrix lhs, represented as an array of 3 floats,
     * by a 3x3 matrix represented as an array of 9 floats.
     *
     * @param lhs Diagonal 3x3 matrix, as a non-null array of 3 floats
     * @param rhs 3x3 matrix, as a non-null array of 9 floats
     * @return A new array of 9 floats containing the result of the multiplication
     *         of rhs by lhs
     */
    @NonNull
    @Size(9)
    private static float[] mul3x3Diag(
            @NonNull @Size(3) float[] lhs, @NonNull @Size(9) float[] rhs) {
        return new float[] {
                lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2],
                lhs[0] * rhs[3], lhs[1] * rhs[4], lhs[2] * rhs[5],
                lhs[0] * rhs[6], lhs[1] * rhs[7], lhs[2] * rhs[8]
        };
    }

    /**
     * Converts a value from CIE xyY to CIE XYZ. Y is assumed to be 1 so the
     * input xyY array only contains the x and y components.
     *
     * @param xyY The xyY value to convert to XYZ, cannot be null, length must be 2
     * @return A new float array of length 3 containing XYZ values
     */
    @NonNull
    @Size(3)
    private static float[] xyYToXyz(@NonNull @Size(2) float[] xyY) {
        return new float[] { xyY[0] / xyY[1], 1.0f, (1 - xyY[0] - xyY[1]) / xyY[1] };
    }

    /**
     * Converts values from CIE xyY to CIE L*u*v*. Y is assumed to be 1 so the
     * input xyY array only contains the x and y components. After this method
     * returns, the xyY array contains the converted u and v components.
     *
     * @param xyY The xyY value to convert to XYZ, cannot be null,
     *            length must be a multiple of 2
     */
    private static void xyYToUv(@NonNull @Size(multiple = 2) float[] xyY) {
        for (int i = 0; i < xyY.length; i += 2) {
            float x = xyY[i];
            float y = xyY[i + 1];

            float d = -2.0f * x + 12.0f * y + 3;
            float u = (4.0f * x) / d;
            float v = (9.0f * y) / d;

            xyY[i] = u;
            xyY[i + 1] = v;
        }
    }

    /**
     * <p>Computes the chromatic adaptation transform from the specified
     * source white point to the specified destination white point.</p>
     *
     * <p>The transform is computed using the von Kries method, described
     * in more details in the documentation of {@link Adaptation}. The
     * {@link Adaptation} enum provides different matrices that can be
     * used to perform the adaptation.</p>
     *
     * @param matrix The adaptation matrix
     * @param srcWhitePoint The white point to adapt from, *will be modified*
     * @param dstWhitePoint The white point to adapt to, *will be modified*
     * @return A 3x3 matrix as a non-null array of 9 floats
     */
    @NonNull
    @Size(9)
    private static float[] chromaticAdaptation(@NonNull @Size(9) float[] matrix,
            @NonNull @Size(3) float[] srcWhitePoint, @NonNull @Size(3) float[] dstWhitePoint) {
        float[] srcLMS = mul3x3Float3(matrix, srcWhitePoint);
        float[] dstLMS = mul3x3Float3(matrix, dstWhitePoint);
        // LMS is a diagonal matrix stored as a float[3]
        float[] LMS = { dstLMS[0] / srcLMS[0], dstLMS[1] / srcLMS[1], dstLMS[2] / srcLMS[2] };
        return mul3x3(inverse3x3(matrix), mul3x3Diag(LMS, matrix));
    }

    /**
     * Implementation of the CIE XYZ color space. Assumes the white point is D50.
     */
    @AnyThread
    private static final class Xyz extends ColorSpace {
        private Xyz(@NonNull String name, @IntRange(from = MIN_ID, to = MAX_ID) int id) {
            super(name, Model.XYZ, id);
        }

        @Override
        public boolean isWideGamut() {
            return true;
        }

        @Override
        public float getMinValue(@IntRange(from = 0, to = 3) int component) {
            return -2.0f;
        }

        @Override
        public float getMaxValue(@IntRange(from = 0, to = 3) int component) {
            return 2.0f;
        }

        @Override
        public float[] toXyz(@NonNull @Size(min = 3) float[] v) {
            v[0] = clamp(v[0]);
            v[1] = clamp(v[1]);
            v[2] = clamp(v[2]);
            return v;
        }

        @Override
        public float[] fromXyz(@NonNull @Size(min = 3) float[] v) {
            v[0] = clamp(v[0]);
            v[1] = clamp(v[1]);
            v[2] = clamp(v[2]);
            return v;
        }

        private static float clamp(float x) {
            return x < -2.0f ? -2.0f : x > 2.0f ? 2.0f : x;
        }
    }

    /**
     * Implementation of the CIE L*a*b* color space. Its PCS is CIE XYZ
     * with a white point of D50.
     */
    @AnyThread
    private static final class Lab extends ColorSpace {
        private static final float A = 216.0f / 24389.0f;
        private static final float B = 841.0f / 108.0f;
        private static final float C = 4.0f / 29.0f;
        private static final float D = 6.0f / 29.0f;

        private Lab(@NonNull String name, @IntRange(from = MIN_ID, to = MAX_ID) int id) {
            super(name, Model.LAB, id);
        }

        @Override
        public boolean isWideGamut() {
            return true;
        }

        @Override
        public float getMinValue(@IntRange(from = 0, to = 3) int component) {
            return component == 0 ? 0.0f : -128.0f;
        }

        @Override
        public float getMaxValue(@IntRange(from = 0, to = 3) int component) {
            return component == 0 ? 100.0f : 128.0f;
        }

        @Override
        public float[] toXyz(@NonNull @Size(min = 3) float[] v) {
            v[0] = clamp(v[0], 0.0f, 100.0f);
            v[1] = clamp(v[1], -128.0f, 128.0f);
            v[2] = clamp(v[2], -128.0f, 128.0f);

            float fy = (v[0] + 16.0f) / 116.0f;
            float fx = fy + (v[1] * 0.002f);
            float fz = fy - (v[2] * 0.005f);
            float X = fx > D ? fx * fx * fx : (1.0f / B) * (fx - C);
            float Y = fy > D ? fy * fy * fy : (1.0f / B) * (fy - C);
            float Z = fz > D ? fz * fz * fz : (1.0f / B) * (fz - C);

            v[0] = X * ILLUMINANT_D50_XYZ[0];
            v[1] = Y * ILLUMINANT_D50_XYZ[1];
            v[2] = Z * ILLUMINANT_D50_XYZ[2];

            return v;
        }

        @Override
        public float[] fromXyz(@NonNull @Size(min = 3) float[] v) {
            float X = v[0] / ILLUMINANT_D50_XYZ[0];
            float Y = v[1] / ILLUMINANT_D50_XYZ[1];
            float Z = v[2] / ILLUMINANT_D50_XYZ[2];

            float fx = X > A ? (float) Math.pow(X, 1.0 / 3.0) : B * X + C;
            float fy = Y > A ? (float) Math.pow(Y, 1.0 / 3.0) : B * Y + C;
            float fz = Z > A ? (float) Math.pow(Z, 1.0 / 3.0) : B * Z + C;

            float L = 116.0f * fy - 16.0f;
            float a = 500.0f * (fx - fy);
            float b = 200.0f * (fy - fz);

            v[0] = clamp(L, 0.0f, 100.0f);
            v[1] = clamp(a, -128.0f, 128.0f);
            v[2] = clamp(b, -128.0f, 128.0f);

            return v;
        }

        private static float clamp(float x, float min, float max) {
            return x < min ? min : x > max ? max : x;
        }
    }

    /**
     * {@usesMathJax}
     *
     * <p>An RGB color space is an additive color space using the
     * {@link Model#RGB RGB} color model (a color is therefore represented
     * by a tuple of 3 numbers).</p>
     *
     * <p>A specific RGB color space is defined by the following properties:</p>
     * <ul>
     *     <li>Three chromaticities of the red, green and blue primaries, which
     *     define the gamut of the color space.</li>
     *     <li>A white point chromaticity that defines the stimulus to which
     *     color space values are normalized (also just called "white").</li>
     *     <li>An opto-electronic transfer function, also called opto-electronic
     *     conversion function or often, and approximately, gamma function.</li>
     *     <li>An electro-optical transfer function, also called electo-optical
     *     conversion function or often, and approximately, gamma function.</li>
     *     <li>A range of valid RGB values (most commonly \([0..1]\)).</li>
     * </ul>
     *
     * <p>The most commonly used RGB color space is {@link Named#SRGB sRGB}.</p>
     *
     * <h3>Primaries and white point chromaticities</h3>
     * <p>In this implementation, the chromaticity of the primaries and the white
     * point of an RGB color space is defined in the CIE xyY color space. This
     * color space separates the chromaticity of a color, the x and y components,
     * and its luminance, the Y component. Since the primaries and the white
     * point have full brightness, the Y component is assumed to be 1 and only
     * the x and y components are needed to encode them.</p>
     * <p>For convenience, this implementation also allows to define the
     * primaries and white point in the CIE XYZ space. The tristimulus XYZ values
     * are internally converted to xyY.</p>
     *
     * <p>
     *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
     *     <figcaption style="text-align: center;">sRGB primaries and white point</figcaption>
     * </p>
     *
     * <h3>Transfer functions</h3>
     * <p>A transfer function is a color component conversion function, defined as
     * a single variable, monotonic mathematical function. It is applied to each
     * individual component of a color. They are used to perform the mapping
     * between linear tristimulus values and non-linear electronic signal value.</p>
     * <p>The <em>opto-electronic transfer function</em> (OETF or OECF) encodes
     * tristimulus values in a scene to a non-linear electronic signal value.
     * An OETF is often expressed as a power function with an exponent between
     * 0.38 and 0.55 (the reciprocal of 1.8 to 2.6).</p>
     * <p>The <em>electro-optical transfer function</em> (EOTF or EOCF) decodes
     * a non-linear electronic signal value to a tristimulus value at the display.
     * An EOTF is often expressed as a power function with an exponent between
     * 1.8 and 2.6.</p>
     * <p>Transfer functions are used as a compression scheme. For instance,
     * linear sRGB values would normally require 11 to 12 bits of precision to
     * store all values that can be perceived by the human eye. When encoding
     * sRGB values using the appropriate OETF (see {@link Named#SRGB sRGB} for
     * an exact mathematical description of that OETF), the values can be
     * compressed to only 8 bits precision.</p>
     * <p>When manipulating RGB values, particularly sRGB values, it is safe
     * to assume that these values have been encoded with the appropriate
     * OETF (unless noted otherwise). Encoded values are often said to be in
     * "gamma space". They are therefore defined in a non-linear space. This
     * in turns means that any linear operation applied to these values is
     * going to yield mathematically incorrect results (any linear interpolation
     * such as gradient generation for instance, most image processing functions
     * such as blurs, etc.).</p>
     * <p>To properly process encoded RGB values you must first apply the
     * EOTF to decode the value into linear space. After processing, the RGB
     * value must be encoded back to non-linear ("gamma") space. Here is a
     * formal description of the process, where \(f\) is the processing
     * function to apply:</p>
     *
     * $$RGB_{out} = OETF(f(EOTF(RGB_{in})))$$
     *
     * <p>If the transfer functions of the color space can be expressed as an
     * ICC parametric curve as defined in ICC.1:2004-10, the numeric parameters
     * can be retrieved by calling {@link #getTransferParameters()}. This can
     * be useful to match color spaces for instance.</p>
     *
     * <p class="note">Some RGB color spaces, such as {@link Named#ACES} and
     * {@link Named#LINEAR_EXTENDED_SRGB scRGB}, are said to be linear because
     * their transfer functions are the identity function: \(f(x) = x\).
     * If the source and/or destination are known to be linear, it is not
     * necessary to invoke the transfer functions.</p>
     *
     * <h3>Range</h3>
     * <p>Most RGB color spaces allow RGB values in the range \([0..1]\). There
     * are however a few RGB color spaces that allow much larger ranges. For
     * instance, {@link Named#EXTENDED_SRGB scRGB} is used to manipulate the
     * range \([-0.5..7.5]\) while {@link Named#ACES ACES} can be used throughout
     * the range \([-65504, 65504]\).</p>
     *
     * <p>
     *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
     *     <figcaption style="text-align: center;">Extended sRGB and its large range</figcaption>
     * </p>
     *
     * <h3>Converting between RGB color spaces</h3>
     * <p>Conversion between two color spaces is achieved by using an intermediate
     * color space called the profile connection space (PCS). The PCS used by
     * this implementation is CIE XYZ. The conversion operation is defined
     * as such:</p>
     *
     * $$RGB_{out} = OETF(T_{dst}^{-1} \cdot T_{src} \cdot EOTF(RGB_{in}))$$
     *
     * <p>Where \(T_{src}\) is the {@link #getTransform() RGB to XYZ transform}
     * of the source color space and \(T_{dst}^{-1}\) the {@link #getInverseTransform()
     * XYZ to RGB transform} of the destination color space.</p>
     * <p>Many RGB color spaces commonly used with electronic devices use the
     * standard illuminant {@link #ILLUMINANT_D65 D65}. Care must be take however
     * when converting between two RGB color spaces if their white points do not
     * match. This can be achieved by either calling
     * {@link #adapt(ColorSpace, float[])} to adapt one or both color spaces to
     * a single common white point. This can be achieved automatically by calling
     * {@link ColorSpace#connect(ColorSpace, ColorSpace)}, which also handles
     * non-RGB color spaces.</p>
     * <p>To learn more about the white point adaptation process, refer to the
     * documentation of {@link Adaptation}.</p>
     */
    @AnyThread
    public static class Rgb extends ColorSpace {
        /**
         * {@usesMathJax}
         *
         * <p>Defines the parameters for the ICC parametric curve type 4, as
         * defined in ICC.1:2004-10, section 10.15.</p>
         *
         * <p>The EOTF is of the form:</p>
         *
         * \(\begin{equation}
         * Y = \begin{cases}c X + f & X \lt d \\
         * \left( a X + b \right) ^{g} + e & X \ge d \end{cases}
         * \end{equation}\)
         *
         * <p>The corresponding OETF is simply the inverse function.</p>
         *
         * <p>The parameters defined by this class form a valid transfer
         * function only if all the following conditions are met:</p>
         * <ul>
         *     <li>No parameter is a {@link Double#isNaN(double) Not-a-Number}</li>
         *     <li>\(d\) is in the range \([0..1]\)</li>
         *     <li>The function is not constant</li>
         *     <li>The function is positive and increasing</li>
         * </ul>
         */
        public static class TransferParameters {
            /** Variable \(a\) in the equation of the EOTF described above. */
            public final double a;
            /** Variable \(b\) in the equation of the EOTF described above. */
            public final double b;
            /** Variable \(c\) in the equation of the EOTF described above. */
            public final double c;
            /** Variable \(d\) in the equation of the EOTF described above. */
            public final double d;
            /** Variable \(e\) in the equation of the EOTF described above. */
            public final double e;
            /** Variable \(f\) in the equation of the EOTF described above. */
            public final double f;
            /** Variable \(g\) in the equation of the EOTF described above. */
            public final double g;

            /**
             * <p>Defines the parameters for the ICC parametric curve type 3, as
             * defined in ICC.1:2004-10, section 10.15.</p>
             *
             * <p>The EOTF is of the form:</p>
             *
             * \(\begin{equation}
             * Y = \begin{cases}c X & X \lt d \\
             * \left( a X + b \right) ^{g} & X \ge d \end{cases}
             * \end{equation}\)
             *
             * <p>This constructor is equivalent to setting  \(e\) and \(f\) to 0.</p>
             *
             * @param a The value of \(a\) in the equation of the EOTF described above
             * @param b The value of \(b\) in the equation of the EOTF described above
             * @param c The value of \(c\) in the equation of the EOTF described above
             * @param d The value of \(d\) in the equation of the EOTF described above
             * @param g The value of \(g\) in the equation of the EOTF described above
             *
             * @throws IllegalArgumentException If the parameters form an invalid transfer function
             */
            public TransferParameters(double a, double b, double c, double d, double g) {
                this(a, b, c, d, 0.0, 0.0, g);
            }

            /**
             * <p>Defines the parameters for the ICC parametric curve type 4, as
             * defined in ICC.1:2004-10, section 10.15.</p>
             *
             * @param a The value of \(a\) in the equation of the EOTF described above
             * @param b The value of \(b\) in the equation of the EOTF described above
             * @param c The value of \(c\) in the equation of the EOTF described above
             * @param d The value of \(d\) in the equation of the EOTF described above
             * @param e The value of \(e\) in the equation of the EOTF described above
             * @param f The value of \(f\) in the equation of the EOTF described above
             * @param g The value of \(g\) in the equation of the EOTF described above
             *
             * @throws IllegalArgumentException If the parameters form an invalid transfer function
             */
            public TransferParameters(double a, double b, double c, double d, double e,
                    double f, double g) {

                if (Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(c) ||
                        Double.isNaN(d) || Double.isNaN(e) || Double.isNaN(f) ||
                        Double.isNaN(g)) {
                    throw new IllegalArgumentException("Parameters cannot be NaN");
                }

                // Next representable float after 1.0
                // We use doubles here but the representation inside our native code is often floats
                if (!(d >= 0.0 && d <= 1.0f + Math.ulp(1.0f))) {
                    throw new IllegalArgumentException("Parameter d must be in the range [0..1], " +
                            "was " + d);
                }

                if (d == 0.0 && (a == 0.0 || g == 0.0)) {
                    throw new IllegalArgumentException(
                            "Parameter a or g is zero, the transfer function is constant");
                }

                if (d >= 1.0 && c == 0.0) {
                    throw new IllegalArgumentException(
                            "Parameter c is zero, the transfer function is constant");
                }

                if ((a == 0.0 || g == 0.0) && c == 0.0) {
                    throw new IllegalArgumentException("Parameter a or g is zero," +
                            " and c is zero, the transfer function is constant");
                }

                if (c < 0.0) {
                    throw new IllegalArgumentException("The transfer function must be increasing");
                }

                if (a < 0.0 || g < 0.0) {
                    throw new IllegalArgumentException("The transfer function must be " +
                            "positive or increasing");
                }

                this.a = a;
                this.b = b;
                this.c = c;
                this.d = d;
                this.e = e;
                this.f = f;
                this.g = g;
            }

            @SuppressWarnings("SimplifiableIfStatement")
            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;

                TransferParameters that = (TransferParameters) o;

                if (Double.compare(that.a, a) != 0) return false;
                if (Double.compare(that.b, b) != 0) return false;
                if (Double.compare(that.c, c) != 0) return false;
                if (Double.compare(that.d, d) != 0) return false;
                if (Double.compare(that.e, e) != 0) return false;
                if (Double.compare(that.f, f) != 0) return false;
                return Double.compare(that.g, g) == 0;
            }

            @Override
            public int hashCode() {
                int result;
                long temp;
                temp = Double.doubleToLongBits(a);
                result = (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(b);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(c);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(d);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(e);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(f);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                temp = Double.doubleToLongBits(g);
                result = 31 * result + (int) (temp ^ (temp >>> 32));
                return result;
            }
        }

        @NonNull private final float[] mWhitePoint;
        @NonNull private final float[] mPrimaries;
        @NonNull private final float[] mTransform;
        @NonNull private final float[] mInverseTransform;

        @NonNull private final DoubleUnaryOperator mOetf;
        @NonNull private final DoubleUnaryOperator mEotf;
        @NonNull private final DoubleUnaryOperator mClampedOetf;
        @NonNull private final DoubleUnaryOperator mClampedEotf;

        private final float mMin;
        private final float mMax;

        private final boolean mIsWideGamut;
        private final boolean mIsSrgb;

        @Nullable private TransferParameters mTransferParameters;

        /**
         * <p>Creates a new RGB color space using a 3x3 column-major transform matrix.
         * The transform matrix must convert from the RGB space to the profile connection
         * space CIE XYZ.</p>
         *
         * <p class="note">The range of the color space is imposed to be \([0..1]\).</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param toXYZ 3x3 column-major transform matrix from RGB to the profile
         *              connection space CIE XYZ as an array of 9 floats, cannot be null
         * @param oetf Opto-electronic transfer function, cannot be null
         * @param eotf Electro-optical transfer function, cannot be null
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The OETF is null or the EOTF is null.</li>
         *     <li>The minimum valid value is >= the maximum valid value.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(9) float[] toXYZ,
                @NonNull DoubleUnaryOperator oetf,
                @NonNull DoubleUnaryOperator eotf) {
            this(name, computePrimaries(toXYZ), computeWhitePoint(toXYZ),
                    oetf, eotf, 0.0f, 1.0f, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * <p class="note">The ID, areturned by {@link #getId()}, of an object created by
         * this constructor is always {@link #MIN_ID}.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param oetf Opto-electronic transfer function, cannot be null
         * @param eotf Electro-optical transfer function, cannot be null
         * @param min The minimum valid value in this color space's RGB range
         * @param max The maximum valid value in this color space's RGB range
         *
         * @throws IllegalArgumentException <p>If any of the following conditions is met:</p>
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>The OETF is null or the EOTF is null.</li>
         *     <li>The minimum valid value is >= the maximum valid value.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                @NonNull DoubleUnaryOperator oetf,
                @NonNull DoubleUnaryOperator eotf,
                float min,
                float max) {
            this(name, primaries, whitePoint, oetf, eotf, min, max, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a 3x3 column-major transform matrix.
         * The transform matrix must convert from the RGB space to the profile connection
         * space CIE XYZ.</p>
         *
         * <p class="note">The range of the color space is imposed to be \([0..1]\).</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param toXYZ 3x3 column-major transform matrix from RGB to the profile
         *              connection space CIE XYZ as an array of 9 floats, cannot be null
         * @param function Parameters for the transfer functions
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>Gamma is negative.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(9) float[] toXYZ,
                @NonNull TransferParameters function) {
            this(name, computePrimaries(toXYZ), computeWhitePoint(toXYZ), function, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param function Parameters for the transfer functions
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>The transfer parameters are invalid.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                @NonNull TransferParameters function) {
            this(name, primaries, whitePoint, function, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param function Parameters for the transfer functions
         * @param id ID of this color space as an integer between {@link #MIN_ID} and {@link #MAX_ID}
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>The ID is not between {@link #MIN_ID} and {@link #MAX_ID}.</li>
         *     <li>The transfer parameters are invalid.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        private Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                @NonNull TransferParameters function,
                @IntRange(from = MIN_ID, to = MAX_ID) int id) {
            this(name, primaries, whitePoint,
                    function.e == 0.0 && function.f == 0.0 ?
                            x -> rcpResponse(x, function.a, function.b,
                                    function.c, function.d, function.g) :
                            x -> rcpResponse(x, function.a, function.b, function.c,
                                    function.d, function.e, function.f, function.g),
                    function.e == 0.0 && function.f == 0.0 ?
                            x -> response(x, function.a, function.b,
                                    function.c, function.d, function.g) :
                            x -> response(x, function.a, function.b, function.c,
                                    function.d, function.e, function.f, function.g),
                    0.0f, 1.0f, id);
            mTransferParameters = function;
        }

        /**
         * <p>Creates a new RGB color space using a 3x3 column-major transform matrix.
         * The transform matrix must convert from the RGB space to the profile connection
         * space CIE XYZ.</p>
         *
         * <p class="note">The range of the color space is imposed to be \([0..1]\).</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param toXYZ 3x3 column-major transform matrix from RGB to the profile
         *              connection space CIE XYZ as an array of 9 floats, cannot be null
         * @param gamma Gamma to use as the transfer function
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>Gamma is negative.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(9) float[] toXYZ,
                double gamma) {
            this(name, computePrimaries(toXYZ), computeWhitePoint(toXYZ), gamma, 0.0f, 1.0f, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param gamma Gamma to use as the transfer function
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>Gamma is negative.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        public Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                double gamma) {
            this(name, primaries, whitePoint, gamma, 0.0f, 1.0f, MIN_ID);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param gamma Gamma to use as the transfer function
         * @param min The minimum valid value in this color space's RGB range
         * @param max The maximum valid value in this color space's RGB range
         * @param id ID of this color space as an integer between {@link #MIN_ID} and {@link #MAX_ID}
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>The minimum valid value is >= the maximum valid value.</li>
         *     <li>The ID is not between {@link #MIN_ID} and {@link #MAX_ID}.</li>
         *     <li>Gamma is negative.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        private Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                double gamma,
                float min,
                float max,
                @IntRange(from = MIN_ID, to = MAX_ID) int id) {
            this(name, primaries, whitePoint,
                    gamma == 1.0 ? DoubleUnaryOperator.identity() :
                            x -> Math.pow(x < 0.0 ? 0.0 : x, 1 / gamma),
                    gamma == 1.0 ? DoubleUnaryOperator.identity() :
                            x -> Math.pow(x < 0.0 ? 0.0 : x, gamma),
                    min, max, id);
            mTransferParameters = gamma == 1.0 ?
                    new TransferParameters(0.0, 0.0, 1.0, 1.0 + Math.ulp(1.0f), gamma) :
                    new TransferParameters(1.0, 0.0, 0.0, 0.0, gamma);
        }

        /**
         * <p>Creates a new RGB color space using a specified set of primaries
         * and a specified white point.</p>
         *
         * <p>The primaries and white point can be specified in the CIE xyY space
         * or in CIE XYZ. The length of the arrays depends on the chosen space:</p>
         *
         * <table summary="Parameters length">
         *     <tr><th>Space</th><th>Primaries length</th><th>White point length</th></tr>
         *     <tr><td>xyY</td><td>6</td><td>2</td></tr>
         *     <tr><td>XYZ</td><td>9</td><td>3</td></tr>
         * </table>
         *
         * <p>When the primaries and/or white point are specified in xyY, the Y component
         * does not need to be specified and is assumed to be 1.0. Only the xy components
         * are required.</p>
         *
         * @param name Name of the color space, cannot be null, its length must be >= 1
         * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats
         * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats
         * @param oetf Opto-electronic transfer function, cannot be null
         * @param eotf Electro-optical transfer function, cannot be null
         * @param min The minimum valid value in this color space's RGB range
         * @param max The maximum valid value in this color space's RGB range
         * @param id ID of this color space as an integer between {@link #MIN_ID} and {@link #MAX_ID}
         *
         * @throws IllegalArgumentException If any of the following conditions is met:
         * <ul>
         *     <li>The name is null or has a length of 0.</li>
         *     <li>The primaries array is null or has a length that is neither 6 or 9.</li>
         *     <li>The white point array is null or has a length that is neither 2 or 3.</li>
         *     <li>The OETF is null or the EOTF is null.</li>
         *     <li>The minimum valid value is >= the maximum valid value.</li>
         *     <li>The ID is not between {@link #MIN_ID} and {@link #MAX_ID}.</li>
         * </ul>
         *
         * @see #get(Named)
         */
        private Rgb(
                @NonNull @Size(min = 1) String name,
                @NonNull @Size(min = 6, max = 9) float[] primaries,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint,
                @NonNull DoubleUnaryOperator oetf,
                @NonNull DoubleUnaryOperator eotf,
                float min,
                float max,
                @IntRange(from = MIN_ID, to = MAX_ID) int id) {

            super(name, Model.RGB, id);

            if (primaries == null || (primaries.length != 6 && primaries.length != 9)) {
                throw new IllegalArgumentException("The color space's primaries must be " +
                        "defined as an array of 6 floats in xyY or 9 floats in XYZ");
            }

            if (whitePoint == null || (whitePoint.length != 2 && whitePoint.length != 3)) {
                throw new IllegalArgumentException("The color space's white point must be " +
                        "defined as an array of 2 floats in xyY or 3 float in XYZ");
            }

            if (oetf == null || eotf == null) {
                throw new IllegalArgumentException("The transfer functions of a color space " +
                        "cannot be null");
            }

            if (min >= max) {
                throw new IllegalArgumentException("Invalid range: min=" + min + ", max=" + max +
                        "; min must be strictly < max");
            }

            mWhitePoint = xyWhitePoint(whitePoint);
            mPrimaries =  xyPrimaries(primaries);

            mTransform = computeXYZMatrix(mPrimaries, mWhitePoint);
            mInverseTransform = inverse3x3(mTransform);

            mOetf = oetf;
            mEotf = eotf;

            mMin = min;
            mMax = max;

            DoubleUnaryOperator clamp = this::clamp;
            mClampedOetf = oetf.andThen(clamp);
            mClampedEotf = clamp.andThen(eotf);

            // A color space is wide-gamut if its area is >90% of NTSC 1953 and
            // if it entirely contains the Color space definition in xyY
            mIsWideGamut = isWideGamut(mPrimaries, min, max);
            mIsSrgb = isSrgb(mPrimaries, mWhitePoint, oetf, eotf, min, max, id);
        }

        /**
         * Creates a copy of the specified color space with a new transform.
         *
         * @param colorSpace The color space to create a copy of
         */
        private Rgb(Rgb colorSpace,
                @NonNull @Size(9) float[] transform,
                @NonNull @Size(min = 2, max = 3) float[] whitePoint) {
            super(colorSpace.getName(), Model.RGB, -1);

            mWhitePoint = xyWhitePoint(whitePoint);
            mPrimaries = colorSpace.mPrimaries;

            mTransform = transform;
            mInverseTransform = inverse3x3(transform);

            mMin = colorSpace.mMin;
            mMax = colorSpace.mMax;

            mOetf = colorSpace.mOetf;
            mEotf = colorSpace.mEotf;

            mClampedOetf = colorSpace.mClampedOetf;
            mClampedEotf = colorSpace.mClampedEotf;

            mIsWideGamut = colorSpace.mIsWideGamut;
            mIsSrgb = colorSpace.mIsSrgb;

            mTransferParameters = colorSpace.mTransferParameters;
        }

        /**
         * Copies the non-adapted CIE xyY white point of this color space in
         * specified array. The Y component is assumed to be 1 and is therefore
         * not copied into the destination. The x and y components are written
         * in the array at positions 0 and 1 respectively.
         *
         * @param whitePoint The destination array, cannot be null, its length
         *                   must be >= 2
         *
         * @return The destination array passed as a parameter
         *
         * @see #getWhitePoint(float[])
         */
        @NonNull
        @Size(min = 2)
        public float[] getWhitePoint(@NonNull @Size(min = 2) float[] whitePoint) {
            whitePoint[0] = mWhitePoint[0];
            whitePoint[1] = mWhitePoint[1];
            return whitePoint;
        }

        /**
         * Returns the non-adapted CIE xyY white point of this color space as
         * a new array of 2 floats. The Y component is assumed to be 1 and is
         * therefore not copied into the destination. The x and y components
         * are written in the array at positions 0 and 1 respectively.
         *
         * @return A new non-null array of 2 floats
         *
         * @see #getWhitePoint()
         */
        @NonNull
        @Size(2)
        public float[] getWhitePoint() {
            return Arrays.copyOf(mWhitePoint, mWhitePoint.length);
        }

        /**
         * Copies the primaries of this color space in specified array. The Y
         * component is assumed to be 1 and is therefore not copied into the
         * destination. The x and y components of the first primary are written
         * in the array at positions 0 and 1 respectively.
         *
         * @param primaries The destination array, cannot be null, its length
         *                  must be >= 6
         *
         * @return The destination array passed as a parameter
         *
         * @see #getPrimaries(float[])
         */
        @NonNull
        @Size(min = 6)
        public float[] getPrimaries(@NonNull @Size(min = 6) float[] primaries) {
            System.arraycopy(mPrimaries, 0, primaries, 0, mPrimaries.length);
            return primaries;
        }

        /**
         * Returns the primaries of this color space as a new array of 6 floats.
         * The Y component is assumed to be 1 and is therefore not copied into
         * the destination. The x and y components of the first primary are
         * written in the array at positions 0 and 1 respectively.
         *
         * @return A new non-null array of 2 floats
         *
         * @see #getWhitePoint()
         */
        @NonNull
        @Size(6)
        public float[] getPrimaries() {
            return Arrays.copyOf(mPrimaries, mPrimaries.length);
        }

        /**
         * <p>Copies the transform of this color space in specified array. The
         * transform is used to convert from RGB to XYZ (with the same white
         * point as this color space). To connect color spaces, you must first
         * {@link ColorSpace#adapt(ColorSpace, float[]) adapt} them to the
         * same white point.</p>
         * <p>It is recommended to use {@link ColorSpace#connect(ColorSpace, ColorSpace)}
         * to convert between color spaces.</p>
         *
         * @param transform The destination array, cannot be null, its length
         *                  must be >= 9
         *
         * @return The destination array passed as a parameter
         *
         * @see #getInverseTransform()
         */
        @NonNull
        @Size(min = 9)
        public float[] getTransform(@NonNull @Size(min = 9) float[] transform) {
            System.arraycopy(mTransform, 0, transform, 0, mTransform.length);
            return transform;
        }

        /**
         * <p>Returns the transform of this color space as a new array. The
         * transform is used to convert from RGB to XYZ (with the same white
         * point as this color space). To connect color spaces, you must first
         * {@link ColorSpace#adapt(ColorSpace, float[]) adapt} them to the
         * same white point.</p>
         * <p>It is recommended to use {@link ColorSpace#connect(ColorSpace, ColorSpace)}
         * to convert between color spaces.</p>
         *
         * @return A new array of 9 floats
         *
         * @see #getInverseTransform(float[])
         */
        @NonNull
        @Size(9)
        public float[] getTransform() {
            return Arrays.copyOf(mTransform, mTransform.length);
        }

        /**
         * <p>Copies the inverse transform of this color space in specified array.
         * The inverse transform is used to convert from XYZ to RGB (with the
         * same white point as this color space). To connect color spaces, you
         * must first {@link ColorSpace#adapt(ColorSpace, float[]) adapt} them
         * to the same white point.</p>
         * <p>It is recommended to use {@link ColorSpace#connect(ColorSpace, ColorSpace)}
         * to convert between color spaces.</p>
         *
         * @param inverseTransform The destination array, cannot be null, its length
         *                  must be >= 9
         *
         * @return The destination array passed as a parameter
         *
         * @see #getTransform()
         */
        @NonNull
        @Size(min = 9)
        public float[] getInverseTransform(@NonNull @Size(min = 9) float[] inverseTransform) {
            System.arraycopy(mInverseTransform, 0, inverseTransform, 0, mInverseTransform.length);
            return inverseTransform;
        }

        /**
         * <p>Returns the inverse transform of this color space as a new array.
         * The inverse transform is used to convert from XYZ to RGB (with the
         * same white point as this color space). To connect color spaces, you
         * must first {@link ColorSpace#adapt(ColorSpace, float[]) adapt} them
         * to the same white point.</p>
         * <p>It is recommended to use {@link ColorSpace#connect(ColorSpace, ColorSpace)}
         * to convert between color spaces.</p>
         *
         * @return A new array of 9 floats
         *
         * @see #getTransform(float[])
         */
        @NonNull
        @Size(9)
        public float[] getInverseTransform() {
            return Arrays.copyOf(mInverseTransform, mInverseTransform.length);
        }

        /**
         * <p>Returns the opto-electronic transfer function (OETF) of this color space.
         * The inverse function is the electro-optical transfer function (EOTF) returned
         * by {@link #getEotf()}. These functions are defined to satisfy the following
         * equality for \(x \in [0..1]\):</p>
         *
         * $$OETF(EOTF(x)) = EOTF(OETF(x)) = x$$
         *
         * <p>For RGB colors, this function can be used to convert from linear space
         * to "gamma space" (gamma encoded). The terms gamma space and gamma encoded
         * are frequently used because many OETFs can be closely approximated using
         * a simple power function of the form \(x^{\frac{1}{\gamma}}\) (the
         * approximation of the {@link Named#SRGB sRGB} OETF uses \(\gamma=2.2\)
         * for instance).</p>
         *
         * @return A transfer function that converts from linear space to "gamma space"
         *
         * @see #getEotf()
         * @see #getTransferParameters()
         */
        @NonNull
        public DoubleUnaryOperator getOetf() {
            return mClampedOetf;
        }

        /**
         * <p>Returns the electro-optical transfer function (EOTF) of this color space.
         * The inverse function is the opto-electronic transfer function (OETF)
         * returned by {@link #getOetf()}. These functions are defined to satisfy the
         * following equality for \(x \in [0..1]\):</p>
         *
         * $$OETF(EOTF(x)) = EOTF(OETF(x)) = x$$
         *
         * <p>For RGB colors, this function can be used to convert from "gamma space"
         * (gamma encoded) to linear space. The terms gamma space and gamma encoded
         * are frequently used because many EOTFs can be closely approximated using
         * a simple power function of the form \(x^\gamma\) (the approximation of the
         * {@link Named#SRGB sRGB} EOTF uses \(\gamma=2.2\) for instance).</p>
         *
         * @return A transfer function that converts from "gamma space" to linear space
         *
         * @see #getOetf()
         * @see #getTransferParameters()
         */
        @NonNull
        public DoubleUnaryOperator getEotf() {
            return mClampedEotf;
        }

        /**
         * <p>Returns the parameters used by the {@link #getEotf() electro-optical}
         * and {@link #getOetf() opto-electronic} transfer functions. If the transfer
         * functions do not match the ICC parametric curves defined in ICC.1:2004-10
         * (section 10.15), this method returns null.</p>
         *
         * <p>See {@link TransferParameters} for a full description of the transfer
         * functions.</p>
         *
         * @return An instance of {@link TransferParameters} or null if this color
         *         space's transfer functions do not match the equation defined in
         *         {@link TransferParameters}
         */
        @Nullable
        public TransferParameters getTransferParameters() {
            return mTransferParameters;
        }

        @Override
        public boolean isSrgb() {
            return mIsSrgb;
        }

        @Override
        public boolean isWideGamut() {
            return mIsWideGamut;
        }

        @Override
        public float getMinValue(int component) {
            return mMin;
        }

        @Override
        public float getMaxValue(int component) {
            return mMax;
        }

        /**
         * <p>Decodes an RGB value to linear space. This is achieved by
         * applying this color space's electro-optical transfer function
         * to the supplied values.</p>
         *
         * <p>Refer to the documentation of {@link ColorSpace.Rgb} for
         * more information about transfer functions and their use for
         * encoding and decoding RGB values.</p>
         *
         * @param r The red component to decode to linear space
         * @param g The green component to decode to linear space
         * @param b The blue component to decode to linear space
         * @return A new array of 3 floats containing linear RGB values
         *
         * @see #toLinear(float[])
         * @see #fromLinear(float, float, float)
         */
        @NonNull
        @Size(3)
        public float[] toLinear(float r, float g, float b) {
            return toLinear(new float[] { r, g, b });
        }

        /**
         * <p>Decodes an RGB value to linear space. This is achieved by
         * applying this color space's electro-optical transfer function
         * to the first 3 values of the supplied array. The result is
         * stored back in the input array.</p>
         *
         * <p>Refer to the documentation of {@link ColorSpace.Rgb} for
         * more information about transfer functions and their use for
         * encoding and decoding RGB values.</p>
         *
         * @param v A non-null array of non-linear RGB values, its length
         *          must be at least 3
         * @return The specified array
         *
         * @see #toLinear(float, float, float)
         * @see #fromLinear(float[])
         */
        @NonNull
        @Size(min = 3)
        public float[] toLinear(@NonNull @Size(min = 3) float[] v) {
            v[0] = (float) mClampedEotf.applyAsDouble(v[0]);
            v[1] = (float) mClampedEotf.applyAsDouble(v[1]);
            v[2] = (float) mClampedEotf.applyAsDouble(v[2]);
            return v;
        }

        /**
         * <p>Encodes an RGB value from linear space to this color space's
         * "gamma space". This is achieved by applying this color space's
         * opto-electronic transfer function to the supplied values.</p>
         *
         * <p>Refer to the documentation of {@link ColorSpace.Rgb} for
         * more information about transfer functions and their use for
         * encoding and decoding RGB values.</p>
         *
         * @param r The red component to encode from linear space
         * @param g The green component to encode from linear space
         * @param b The blue component to encode from linear space
         * @return A new array of 3 floats containing non-linear RGB values
         *
         * @see #fromLinear(float[])
         * @see #toLinear(float, float, float)
         */
        @NonNull
        @Size(3)
        public float[] fromLinear(float r, float g, float b) {
            return fromLinear(new float[] { r, g, b });
        }

        /**
         * <p>Encodes an RGB value from linear space to this color space's
         * "gamma space". This is achieved by applying this color space's
         * opto-electronic transfer function to the first 3 values of the
         * supplied array. The result is stored back in the input array.</p>
         *
         * <p>Refer to the documentation of {@link ColorSpace.Rgb} for
         * more information about transfer functions and their use for
         * encoding and decoding RGB values.</p>
         *
         * @param v A non-null array of linear RGB values, its length
         *          must be at least 3
         * @return A new array of 3 floats containing non-linear RGB values
         *
         * @see #fromLinear(float[])
         * @see #toLinear(float, float, float)
         */
        @NonNull
        @Size(min = 3)
        public float[] fromLinear(@NonNull @Size(min = 3) float[] v) {
            v[0] = (float) mClampedOetf.applyAsDouble(v[0]);
            v[1] = (float) mClampedOetf.applyAsDouble(v[1]);
            v[2] = (float) mClampedOetf.applyAsDouble(v[2]);
            return v;
        }

        @Override
        @NonNull
        @Size(min = 3)
        public float[] toXyz(@NonNull @Size(min = 3) float[] v) {
            v[0] = (float) mClampedEotf.applyAsDouble(v[0]);
            v[1] = (float) mClampedEotf.applyAsDouble(v[1]);
            v[2] = (float) mClampedEotf.applyAsDouble(v[2]);
            return mul3x3Float3(mTransform, v);
        }

        @Override
        @NonNull
        @Size(min = 3)
        public float[] fromXyz(@NonNull @Size(min = 3) float[] v) {
            mul3x3Float3(mInverseTransform, v);
            v[0] = (float) mClampedOetf.applyAsDouble(v[0]);
            v[1] = (float) mClampedOetf.applyAsDouble(v[1]);
            v[2] = (float) mClampedOetf.applyAsDouble(v[2]);
            return v;
        }

        private double clamp(double x) {
            return x < mMin ? mMin : x > mMax ? mMax : x;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            if (!super.equals(o)) return false;

            Rgb rgb = (Rgb) o;

            if (Float.compare(rgb.mMin, mMin) != 0) return false;
            if (Float.compare(rgb.mMax, mMax) != 0) return false;
            if (!Arrays.equals(mWhitePoint, rgb.mWhitePoint)) return false;
            if (!Arrays.equals(mPrimaries, rgb.mPrimaries)) return false;
            if (mTransferParameters != null) {
                return mTransferParameters.equals(rgb.mTransferParameters);
            } else if (rgb.mTransferParameters == null) {
                return true;
            }
            //noinspection SimplifiableIfStatement
            if (!mOetf.equals(rgb.mOetf)) return false;
            return mEotf.equals(rgb.mEotf);
        }

        @Override
        public int hashCode() {
            int result = super.hashCode();
            result = 31 * result + Arrays.hashCode(mWhitePoint);
            result = 31 * result + Arrays.hashCode(mPrimaries);
            result = 31 * result + (mMin != +0.0f ? Float.floatToIntBits(mMin) : 0);
            result = 31 * result + (mMax != +0.0f ? Float.floatToIntBits(mMax) : 0);
            result = 31 * result +
                    (mTransferParameters != null ? mTransferParameters.hashCode() : 0);
            if (mTransferParameters == null) {
                result = 31 * result + mOetf.hashCode();
                result = 31 * result + mEotf.hashCode();
            }
            return result;
        }

        /**
         * Computes whether a color space is the sRGB color space or at least
         * a close approximation.
         *
         * @param primaries The set of RGB primaries in xyY as an array of 6 floats
         * @param whitePoint The white point in xyY as an array of 2 floats
         * @param OETF The opto-electronic transfer function
         * @param EOTF The electro-optical transfer function
         * @param min The minimum value of the color space's range
         * @param max The minimum value of the color space's range
         * @param id The ID of the color space
         * @return True if the color space can be considered as the sRGB color space
         *
         * @see #isSrgb()
         */
        @SuppressWarnings("RedundantIfStatement")
        private static boolean isSrgb(
                @NonNull @Size(6) float[] primaries,
                @NonNull @Size(2) float[] whitePoint,
                @NonNull DoubleUnaryOperator OETF,
                @NonNull DoubleUnaryOperator EOTF,
                float min,
                float max,
                @IntRange(from = MIN_ID, to = MAX_ID) int id) {
            if (id == 0) return true;
            if (!compare(primaries, SRGB_PRIMARIES)) {
                return false;
            }
            if (!compare(whitePoint, ILLUMINANT_D65)) {
                return false;
            }
            if (OETF.applyAsDouble(0.5) < 0.5001) return false;
            if (EOTF.applyAsDouble(0.5) > 0.5001) return false;
            if (min != 0.0f) return false;
            if (max != 1.0f) return false;
            return true;
        }

        /**
         * Computes whether the specified CIE xyY or XYZ primaries (with Y set to 1) form
         * a wide color gamut. A color gamut is considered wide if its area is &gt; 90%
         * of the area of NTSC 1953 and if it contains the sRGB color gamut entirely.
         * If the conditions above are not met, the color space is considered as having
         * a wide color gamut if its range is larger than [0..1].
         *
         * @param primaries RGB primaries in CIE xyY as an array of 6 floats
         * @param min The minimum value of the color space's range
         * @param max The minimum value of the color space's range
         * @return True if the color space has a wide gamut, false otherwise
         *
         * @see #isWideGamut()
         * @see #area(float[])
         */
        private static boolean isWideGamut(@NonNull @Size(6) float[] primaries,
                float min, float max) {
            return (area(primaries) / area(NTSC_1953_PRIMARIES) > 0.9f &&
                            contains(primaries, SRGB_PRIMARIES)) || (min < 0.0f && max > 1.0f);
        }

        /**
         * Computes the area of the triangle represented by a set of RGB primaries
         * in the CIE xyY space.
         *
         * @param primaries The triangle's vertices, as RGB primaries in an array of 6 floats
         * @return The area of the triangle
         *
         * @see #isWideGamut(float[], float, float)
         */
        private static float area(@NonNull @Size(6) float[] primaries) {
            float Rx = primaries[0];
            float Ry = primaries[1];
            float Gx = primaries[2];
            float Gy = primaries[3];
            float Bx = primaries[4];
            float By = primaries[5];
            float det = Rx * Gy + Ry * Bx + Gx * By - Gy * Bx - Ry * Gx - Rx * By;
            float r = 0.5f * det;
            return r < 0.0f ? -r : r;
        }

        /**
         * Computes the cross product of two 2D vectors.
         *
         * @param ax The x coordinate of the first vector
         * @param ay The y coordinate of the first vector
         * @param bx The x coordinate of the second vector
         * @param by The y coordinate of the second vector
         * @return The result of a x b
         */
        private static float cross(float ax, float ay, float bx, float by) {
            return ax * by - ay * bx;
        }

        /**
         * Decides whether a 2D triangle, identified by the 6 coordinates of its
         * 3 vertices, is contained within another 2D triangle, also identified
         * by the 6 coordinates of its 3 vertices.
         *
         * In the illustration below, we want to test whether the RGB triangle
         * is contained within the triangle XYZ formed by the 3 vertices at
         * the "+" locations.
         *
         *                                     Y     .
         *                                 .   +    .
         *                                  .     ..
         *                                   .   .
         *                                    . .
         *                                     .  G
         *                                     *
         *                                    * *
         *                                  **   *
         *                                 *      **
         *                                *         *
         *                              **           *
         *                             *              *
         *                            *                *
         *                          **                  *
         *                         *                     *
         *                        *                       **
         *                      **                          *   R    ...
         *                     *                             *  .....
         *                    *                         ***** ..
         *                  **              ************       .   +
         *              B  *    ************                    .   X
         *           ......*****                                 .
         *     ......    .                                        .
         *             ..
         *        +   .
         *      Z    .
         *
         * RGB is contained within XYZ if all the following conditions are true
         * (with "x" the cross product operator):
         *
         *   -->  -->
         *   GR x RX >= 0
         *   -->  -->
         *   RX x BR >= 0
         *   -->  -->
         *   RG x GY >= 0
         *   -->  -->
         *   GY x RG >= 0
         *   -->  -->
         *   RB x BZ >= 0
         *   -->  -->
         *   BZ x GB >= 0
         *
         * @param p1 The enclosing triangle
         * @param p2 The enclosed triangle
         * @return True if the triangle p1 contains the triangle p2
         *
         * @see #isWideGamut(float[], float, float)
         */
        @SuppressWarnings("RedundantIfStatement")
        private static boolean contains(@NonNull @Size(6) float[] p1, @NonNull @Size(6) float[] p2) {
            // Translate the vertices p1 in the coordinates system
            // with the vertices p2 as the origin
            float[] p0 = new float[] {
                    p1[0] - p2[0], p1[1] - p2[1],
                    p1[2] - p2[2], p1[3] - p2[3],
                    p1[4] - p2[4], p1[5] - p2[5],
            };
            // Check the first vertex of p1
            if (cross(p0[0], p0[1], p2[0] - p2[4], p2[1] - p2[5]) < 0 ||
                    cross(p2[0] - p2[2], p2[1] - p2[3], p0[0], p0[1]) < 0) {
                return false;
            }
            // Check the second vertex of p1
            if (cross(p0[2], p0[3], p2[2] - p2[0], p2[3] - p2[1]) < 0 ||
                    cross(p2[2] - p2[4], p2[3] - p2[5], p0[2], p0[3]) < 0) {
                return false;
            }
            // Check the third vertex of p1
            if (cross(p0[4], p0[5], p2[4] - p2[2], p2[5] - p2[3]) < 0 ||
                    cross(p2[4] - p2[0], p2[5] - p2[1], p0[4], p0[5]) < 0) {
                return false;
            }
            return true;
        }

        /**
         * Computes the primaries  of a color space identified only by
         * its RGB->XYZ transform matrix. This method assumes that the
         * range of the color space is [0..1].
         *
         * @param toXYZ The color space's 3x3 transform matrix to XYZ
         * @return A new array of 6 floats containing the color space's
         *         primaries in CIE xyY
         */
        @NonNull
        @Size(6)
        private static float[] computePrimaries(@NonNull @Size(9) float[] toXYZ) {
            float[] r = mul3x3Float3(toXYZ, new float[] { 1.0f, 0.0f, 0.0f });
            float[] g = mul3x3Float3(toXYZ, new float[] { 0.0f, 1.0f, 0.0f });
            float[] b = mul3x3Float3(toXYZ, new float[] { 0.0f, 0.0f, 1.0f });

            float rSum = r[0] + r[1] + r[2];
            float gSum = g[0] + g[1] + g[2];
            float bSum = b[0] + b[1] + b[2];

            return new float[] {
                    r[0] / rSum, r[1] / rSum,
                    g[0] / gSum, g[1] / gSum,
                    b[0] / bSum, b[1] / bSum,
            };
        }

        /**
         * Computes the white point of a color space identified only by
         * its RGB->XYZ transform matrix. This method assumes that the
         * range of the color space is [0..1].
         *
         * @param toXYZ The color space's 3x3 transform matrix to XYZ
         * @return A new array of 2 floats containing the color space's
         *         white point in CIE xyY
         */
        @NonNull
        @Size(2)
        private static float[] computeWhitePoint(@NonNull @Size(9) float[] toXYZ) {
            float[] w = mul3x3Float3(toXYZ, new float[] { 1.0f, 1.0f, 1.0f });
            float sum = w[0] + w[1] + w[2];
            return new float[] { w[0] / sum, w[1] / sum };
        }

        /**
         * Converts the specified RGB primaries point to xyY if needed. The primaries
         * can be specified as an array of 6 floats (in CIE xyY) or 9 floats
         * (in CIE XYZ). If no conversion is needed, the input array is copied.
         *
         * @param primaries The primaries in xyY or XYZ
         * @return A new array of 6 floats containing the primaries in xyY
         */
        @NonNull
        @Size(6)
        private static float[] xyPrimaries(@NonNull @Size(min = 6, max = 9) float[] primaries) {
            float[] xyPrimaries = new float[6];

            // XYZ to xyY
            if (primaries.length == 9) {
                float sum;

                sum = primaries[0] + primaries[1] + primaries[2];
                xyPrimaries[0] = primaries[0] / sum;
                xyPrimaries[1] = primaries[1] / sum;

                sum = primaries[3] + primaries[4] + primaries[5];
                xyPrimaries[2] = primaries[3] / sum;
                xyPrimaries[3] = primaries[4] / sum;

                sum = primaries[6] + primaries[7] + primaries[8];
                xyPrimaries[4] = primaries[6] / sum;
                xyPrimaries[5] = primaries[7] / sum;
            } else {
                System.arraycopy(primaries, 0, xyPrimaries, 0, 6);
            }

            return xyPrimaries;
        }

        /**
         * Converts the specified white point to xyY if needed. The white point
         * can be specified as an array of 2 floats (in CIE xyY) or 3 floats
         * (in CIE XYZ). If no conversion is needed, the input array is copied.
         *
         * @param whitePoint The white point in xyY or XYZ
         * @return A new array of 2 floats containing the white point in xyY
         */
        @NonNull
        @Size(2)
        private static float[] xyWhitePoint(@Size(min = 2, max = 3) float[] whitePoint) {
            float[] xyWhitePoint = new float[2];

            // XYZ to xyY
            if (whitePoint.length == 3) {
                float sum = whitePoint[0] + whitePoint[1] + whitePoint[2];
                xyWhitePoint[0] = whitePoint[0] / sum;
                xyWhitePoint[1] = whitePoint[1] / sum;
            } else {
                System.arraycopy(whitePoint, 0, xyWhitePoint, 0, 2);
            }

            return xyWhitePoint;
        }

        /**
         * Computes the matrix that converts from RGB to XYZ based on RGB
         * primaries and a white point, both specified in the CIE xyY space.
         * The Y component of the primaries and white point is implied to be 1.
         *
         * @param primaries The RGB primaries in xyY, as an array of 6 floats
         * @param whitePoint The white point in xyY, as an array of 2 floats
         * @return A 3x3 matrix as a new array of 9 floats
         */
        @NonNull
        @Size(9)
        private static float[] computeXYZMatrix(
                @NonNull @Size(6) float[] primaries,
                @NonNull @Size(2) float[] whitePoint) {
            float Rx = primaries[0];
            float Ry = primaries[1];
            float Gx = primaries[2];
            float Gy = primaries[3];
            float Bx = primaries[4];
            float By = primaries[5];
            float Wx = whitePoint[0];
            float Wy = whitePoint[1];

            float oneRxRy = (1 - Rx) / Ry;
            float oneGxGy = (1 - Gx) / Gy;
            float oneBxBy = (1 - Bx) / By;
            float oneWxWy = (1 - Wx) / Wy;

            float RxRy = Rx / Ry;
            float GxGy = Gx / Gy;
            float BxBy = Bx / By;
            float WxWy = Wx / Wy;

            float BY =
                    ((oneWxWy - oneRxRy) * (GxGy - RxRy) - (WxWy - RxRy) * (oneGxGy - oneRxRy)) /
                    ((oneBxBy - oneRxRy) * (GxGy - RxRy) - (BxBy - RxRy) * (oneGxGy - oneRxRy));
            float GY = (WxWy - RxRy - BY * (BxBy - RxRy)) / (GxGy - RxRy);
            float RY = 1 - GY - BY;

            float RYRy = RY / Ry;
            float GYGy = GY / Gy;
            float BYBy = BY / By;

            return new float[] {
                    RYRy * Rx, RY, RYRy * (1 - Rx - Ry),
                    GYGy * Gx, GY, GYGy * (1 - Gx - Gy),
                    BYBy * Bx, BY, BYBy * (1 - Bx - By)
            };
        }
    }

    /**
     * {@usesMathJax}
     *
     * <p>A connector transforms colors from a source color space to a destination
     * color space.</p>
     *
     * <p>A source color space is connected to a destination color space using the
     * color transform \(C\) computed from their respective transforms noted
     * \(T_{src}\) and \(T_{dst}\) in the following equation:</p>
     *
     * $$C = T^{-1}_{dst} . T_{src}$$
     *
     * <p>The transform \(C\) shown above is only valid when the source and
     * destination color spaces have the same profile connection space (PCS).
     * We know that instances of {@link ColorSpace} always use CIE XYZ as their
     * PCS but their white points might differ. When they do, we must perform
     * a chromatic adaptation of the color spaces' transforms. To do so, we
     * use the von Kries method described in the documentation of {@link Adaptation},
     * using the CIE standard illuminant {@link ColorSpace#ILLUMINANT_D50 D50}
     * as the target white point.</p>
     *
     * <p>Example of conversion from {@link Named#SRGB sRGB} to
     * {@link Named#DCI_P3 DCI-P3}:</p>
     *
     * <pre class="prettyprint">
     * ColorSpace.Connector connector = ColorSpace.connect(
     *         ColorSpace.get(ColorSpace.Named.SRGB),
     *         ColorSpace.get(ColorSpace.Named.DCI_P3));
     * float[] p3 = connector.transform(1.0f, 0.0f, 0.0f);
     * // p3 contains { 0.9473, 0.2740, 0.2076 }
     * </pre>
     *
     * @see Adaptation
     * @see ColorSpace#adapt(ColorSpace, float[], Adaptation)
     * @see ColorSpace#adapt(ColorSpace, float[])
     * @see ColorSpace#connect(ColorSpace, ColorSpace, RenderIntent)
     * @see ColorSpace#connect(ColorSpace, ColorSpace)
     * @see ColorSpace#connect(ColorSpace, RenderIntent)
     * @see ColorSpace#connect(ColorSpace)
     */
    @AnyThread
    public static class Connector {
        @NonNull private final ColorSpace mSource;
        @NonNull private final ColorSpace mDestination;
        @NonNull private final ColorSpace mTransformSource;
        @NonNull private final ColorSpace mTransformDestination;
        @NonNull private final RenderIntent mIntent;
        @NonNull @Size(3) private final float[] mTransform;

        /**
         * Creates a new connector between a source and a destination color space.
         *
         * @param source The source color space, cannot be null
         * @param destination The destination color space, cannot be null
         * @param intent The render intent to use when compressing gamuts
         */
        Connector(@NonNull ColorSpace source, @NonNull ColorSpace destination,
                @NonNull RenderIntent intent) {
            this(source, destination,
                    source.getModel() == Model.RGB ? adapt(source, ILLUMINANT_D50_XYZ) : source,
                    destination.getModel() == Model.RGB ?
                            adapt(destination, ILLUMINANT_D50_XYZ) : destination,
                    intent, computeTransform(source, destination, intent));
        }

        /**
         * To connect between color spaces, we might need to use adapted transforms.
         * This should be transparent to the user so this constructor takes the
         * original source and destinations (returned by the getters), as well as
         * possibly adapted color spaces used by transform().
         */
        private Connector(
                @NonNull ColorSpace source, @NonNull ColorSpace destination,
                @NonNull ColorSpace transformSource, @NonNull ColorSpace transformDestination,
                @NonNull RenderIntent intent, @Nullable @Size(3) float[] transform) {
            mSource = source;
            mDestination = destination;
            mTransformSource = transformSource;
            mTransformDestination = transformDestination;
            mIntent = intent;
            mTransform = transform;
        }

        /**
         * Computes an extra transform to apply in XYZ space depending on the
         * selected rendering intent.
         */
        @Nullable
        private static float[] computeTransform(@NonNull ColorSpace source,
                @NonNull ColorSpace destination, @NonNull RenderIntent intent) {
            if (intent != RenderIntent.ABSOLUTE) return null;

            boolean srcRGB = source.getModel() == Model.RGB;
            boolean dstRGB = destination.getModel() == Model.RGB;

            if (srcRGB && dstRGB) return null;

            if (srcRGB || dstRGB) {
                ColorSpace.Rgb rgb = (ColorSpace.Rgb) (srcRGB ? source : destination);
                float[] srcXYZ = srcRGB ? xyYToXyz(rgb.mWhitePoint) : ILLUMINANT_D50_XYZ;
                float[] dstXYZ = dstRGB ? xyYToXyz(rgb.mWhitePoint) : ILLUMINANT_D50_XYZ;
                return new float[] {
                        srcXYZ[0] / dstXYZ[0],
                        srcXYZ[1] / dstXYZ[1],
                        srcXYZ[2] / dstXYZ[2],
                };
            }

            return null;
        }

        /**
         * Returns the source color space this connector will convert from.
         *
         * @return A non-null instance of {@link ColorSpace}
         *
         * @see #getDestination()
         */
        @NonNull
        public ColorSpace getSource() {
            return mSource;
        }

        /**
         * Returns the destination color space this connector will convert to.
         *
         * @return A non-null instance of {@link ColorSpace}
         *
         * @see #getSource()
         */
        @NonNull
        public ColorSpace getDestination() {
            return mDestination;
        }

        /**
         * Returns the render intent this connector will use when mapping the
         * source color space to the destination color space.
         *
         * @return A non-null {@link RenderIntent}
         *
         * @see RenderIntent
         */
        public RenderIntent getRenderIntent() {
            return mIntent;
        }

        /**
         * <p>Transforms the specified color from the source color space
         * to a color in the destination color space. This convenience
         * method assumes a source color model with 3 components
         * (typically RGB). To transform from color models with more than
         * 3 components, such as {@link Model#CMYK CMYK}, use
         * {@link #transform(float[])} instead.</p>
         *
         * @param r The red component of the color to transform
         * @param g The green component of the color to transform
         * @param b The blue component of the color to transform
         * @return A new array of 3 floats containing the specified color
         *         transformed from the source space to the destination space
         *
         * @see #transform(float[])
         */
        @NonNull
        @Size(3)
        public float[] transform(float r, float g, float b) {
            return transform(new float[] { r, g, b });
        }

        /**
         * <p>Transforms the specified color from the source color space
         * to a color in the destination color space.</p>
         *
         * @param v A non-null array of 3 floats containing the value to transform
         *            and that will hold the result of the transform
         * @return The v array passed as a parameter, containing the specified color
         *         transformed from the source space to the destination space
         *
         * @see #transform(float, float, float)
         */
        @NonNull
        @Size(min = 3)
        public float[] transform(@NonNull @Size(min = 3) float[] v) {
            float[] xyz = mTransformSource.toXyz(v);
            if (mTransform != null) {
                xyz[0] *= mTransform[0];
                xyz[1] *= mTransform[1];
                xyz[2] *= mTransform[2];
            }
            return mTransformDestination.fromXyz(xyz);
        }

        /**
         * Optimized connector for RGB->RGB conversions.
         */
        private static class Rgb extends Connector {
            @NonNull private final ColorSpace.Rgb mSource;
            @NonNull private final ColorSpace.Rgb mDestination;
            @NonNull private final float[] mTransform;

            Rgb(@NonNull ColorSpace.Rgb source, @NonNull ColorSpace.Rgb destination,
                    @NonNull RenderIntent intent) {
                super(source, destination, source, destination, intent, null);
                mSource = source;
                mDestination = destination;
                mTransform = computeTransform(source, destination, intent);
            }

            @Override
            public float[] transform(@NonNull @Size(min = 3) float[] rgb) {
                rgb[0] = (float) mSource.mClampedEotf.applyAsDouble(rgb[0]);
                rgb[1] = (float) mSource.mClampedEotf.applyAsDouble(rgb[1]);
                rgb[2] = (float) mSource.mClampedEotf.applyAsDouble(rgb[2]);
                mul3x3Float3(mTransform, rgb);
                rgb[0] = (float) mDestination.mClampedOetf.applyAsDouble(rgb[0]);
                rgb[1] = (float) mDestination.mClampedOetf.applyAsDouble(rgb[1]);
                rgb[2] = (float) mDestination.mClampedOetf.applyAsDouble(rgb[2]);
                return rgb;
            }

            /**
             * <p>Computes the color transform that connects two RGB color spaces.</p>
             *
             * <p>We can only connect color spaces if they use the same profile
             * connection space. We assume the connection space is always
             * CIE XYZ but we maye need to perform a chromatic adaptation to
             * match the white points. If an adaptation is needed, we use the
             * CIE standard illuminant D50. The unmatched color space is adapted
             * using the von Kries transform and the {@link Adaptation#BRADFORD}
             * matrix.</p>
             *
             * @param source The source color space, cannot be null
             * @param destination The destination color space, cannot be null
             * @param intent The render intent to use when compressing gamuts
             * @return An array of 9 floats containing the 3x3 matrix transform
             */
            @NonNull
            @Size(9)
            private static float[] computeTransform(
                    @NonNull ColorSpace.Rgb source,
                    @NonNull ColorSpace.Rgb destination,
                    @NonNull RenderIntent intent) {
                if (compare(source.mWhitePoint, destination.mWhitePoint)) {
                    // RGB->RGB using the PCS of both color spaces since they have the same
                    return mul3x3(destination.mInverseTransform, source.mTransform);
                } else {
                    // RGB->RGB using CIE XYZ D50 as the PCS
                    float[] transform = source.mTransform;
                    float[] inverseTransform = destination.mInverseTransform;

                    float[] srcXYZ = xyYToXyz(source.mWhitePoint);
                    float[] dstXYZ = xyYToXyz(destination.mWhitePoint);

                    if (!compare(source.mWhitePoint, ILLUMINANT_D50)) {
                        float[] srcAdaptation = chromaticAdaptation(
                                Adaptation.BRADFORD.mTransform, srcXYZ,
                                Arrays.copyOf(ILLUMINANT_D50_XYZ, 3));
                        transform = mul3x3(srcAdaptation, source.mTransform);
                    }

                    if (!compare(destination.mWhitePoint, ILLUMINANT_D50)) {
                        float[] dstAdaptation = chromaticAdaptation(
                                Adaptation.BRADFORD.mTransform, dstXYZ,
                                Arrays.copyOf(ILLUMINANT_D50_XYZ, 3));
                        inverseTransform = inverse3x3(mul3x3(dstAdaptation, destination.mTransform));
                    }

                    if (intent == RenderIntent.ABSOLUTE) {
                        transform = mul3x3Diag(
                                new float[] {
                                        srcXYZ[0] / dstXYZ[0],
                                        srcXYZ[1] / dstXYZ[1],
                                        srcXYZ[2] / dstXYZ[2],
                                }, transform);
                    }

                    return mul3x3(inverseTransform, transform);
                }
            }
        }

        /**
         * Returns the identity connector for a given color space.
         *
         * @param source The source and destination color space
         * @return A non-null connector that does not perform any transform
         *
         * @see ColorSpace#connect(ColorSpace, ColorSpace)
         */
        static Connector identity(ColorSpace source) {
            return new Connector(source, source, RenderIntent.RELATIVE) {
                @Override
                public float[] transform(@NonNull @Size(min = 3) float[] v) {
                    return v;
                }
            };
        }
    }

    /**
     * <p>A color space renderer can be used to visualize and compare the gamut and
     * white point of one or more color spaces. The output is an sRGB {@link Bitmap}
     * showing a CIE 1931 xyY or a CIE 1976 UCS chromaticity diagram.</p>
     *
     * <p>The following code snippet shows how to compare the {@link Named#SRGB}
     * and {@link Named#DCI_P3} color spaces in a CIE 1931 diagram:</p>
     *
     * <pre class="prettyprint">
     * Bitmap bitmap = ColorSpace.createRenderer()
     *     .size(768)
     *     .clip(true)
     *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
     *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
     *     .render();
     * </pre>
     * <p>
     *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
     *     <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
     * </p>
     *
     * <p>A renderer can also be used to show the location of specific colors,
     * associated with a color space, in the CIE 1931 xyY chromaticity diagram.
     * See {@link #add(ColorSpace, float, float, float, int)} for more information.</p>
     *
     * @see ColorSpace#createRenderer()
     *
     * @hide
     */
    public static class Renderer {
        private static final int NATIVE_SIZE = 1440;
        private static final float UCS_SCALE = 9.0f / 6.0f;

        // Number of subdivision of the inside of the spectral locus
        private static final int CHROMATICITY_RESOLUTION = 32;
        private static final double ONE_THIRD = 1.0 / 3.0;

        @IntRange(from = 128, to = Integer.MAX_VALUE)
        private int mSize = 1024;

        private boolean mShowWhitePoint = true;
        private boolean mClip = false;
        private boolean mUcs = false;

        private final List<Pair<ColorSpace, Integer>> mColorSpaces = new ArrayList<>(2);
        private final List<Point> mPoints = new ArrayList<>(0);

        private Renderer() {
        }

        /**
         * <p>Defines whether the chromaticity diagram should be clipped by the first
         * registered color space. The default value is false.</p>
         *
         * <p>The following code snippet and image show the default behavior:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
         *     <figcaption style="text-align: center;">Clipping disabled</figcaption>
         * </p>
         *
         * <p>Here is the same example with clipping enabled:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .clip(true)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
         *     <figcaption style="text-align: center;">Clipping enabled</figcaption>
         * </p>
         *
         * @param clip True to clip the chromaticity diagram to the first registered color space,
         *             false otherwise
         * @return This instance of {@link Renderer}
         */
        @NonNull
        public Renderer clip(boolean clip) {
            mClip = clip;
            return this;
        }

        /**
         * <p>Defines whether the chromaticity diagram should use the uniform
         * chromaticity scale (CIE 1976 UCS). When the uniform chromaticity scale
         * is used, the distance between two points on the diagram is approximately
         * proportional to the perceived color difference.</p>
         *
         * <p>The following code snippet shows how to enable the uniform chromaticity
         * scale. The image below shows the result:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .uniformChromaticityScale(true)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
         *     <figcaption style="text-align: center;">CIE 1976 UCS diagram</figcaption>
         * </p>
         *
         * @param ucs True to render the chromaticity diagram as the CIE 1976 UCS diagram
         * @return This instance of {@link Renderer}
         */
        @NonNull
        public Renderer uniformChromaticityScale(boolean ucs) {
            mUcs = ucs;
            return this;
        }

        /**
         * Sets the dimensions (width and height) in pixels of the output bitmap.
         * The size must be at least 128px and defaults to 1024px.
         *
         * @param size The size in pixels of the output bitmap
         * @return This instance of {@link Renderer}
         */
        @NonNull
        public Renderer size(@IntRange(from = 128, to = Integer.MAX_VALUE) int size) {
            mSize = Math.max(128, size);
            return this;
        }

        /**
         * Shows or hides the white point of each color space in the output bitmap.
         * The default is true.
         *
         * @param show True to show the white point of each color space, false
         *             otherwise
         * @return This instance of {@link Renderer}
         */
        @NonNull
        public Renderer showWhitePoint(boolean show) {
            mShowWhitePoint = show;
            return this;
        }

        /**
         * <p>Adds a color space to represent on the output CIE 1931 chromaticity
         * diagram. The color space is represented as a triangle showing the
         * footprint of its color gamut and, optionally, the location of its
         * white point.</p>
         *
         * <p class="note">Color spaces with a color model that is not RGB are
         * accepted but ignored.</p>
         *
         * <p>The following code snippet and image show an example of calling this
         * method to compare {@link Named#SRGB sRGB} and {@link Named#DCI_P3 DCI-P3}:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
         *     <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
         * </p>
         *
         * <p>Adding a color space extending beyond the boundaries of the
         * spectral locus will alter the size of the diagram within the output
         * bitmap as shown in this example:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
         *     .add(ColorSpace.get(ColorSpace.Named.ACES), 0xff097ae9)
         *     .add(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), 0xff000000)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
         *     <figcaption style="text-align: center;">sRGB, DCI-P3, ACES and scRGB</figcaption>
         * </p>
         *
         * @param colorSpace The color space whose gamut to render on the diagram
         * @param color The sRGB color to use to render the color space's gamut and white point
         * @return This instance of {@link Renderer}
         *
         * @see #clip(boolean)
         * @see #showWhitePoint(boolean)
         */
        @NonNull
        public Renderer add(@NonNull ColorSpace colorSpace, @ColorInt int color) {
            mColorSpaces.add(new Pair<>(colorSpace, color));
            return this;
        }

        /**
         * <p>Adds a color to represent as a point on the chromaticity diagram.
         * The color is associated with a color space which will be used to
         * perform the conversion to CIE XYZ and compute the location of the point
         * on the diagram. The point is rendered as a colored circle.</p>
         *
         * <p>The following code snippet and image show an example of calling this
         * method to render the location of several sRGB colors as white circles:</p>
         * <pre class="prettyprint">
         * Bitmap bitmap = ColorSpace.createRenderer()
         *     .clip(true)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.0f, 0.1f, 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.1f, 0.1f, 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.2f, 0.1f, 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.3f, 0.1f, 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.4f, 0.1f, 0xffffffff)
         *     .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.5f, 0.1f, 0xffffffff)
         *     .render();
         * </pre>
         * <p>
         *     <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
         *     <figcaption style="text-align: center;">
         *         Locating colors on the chromaticity diagram
         *     </figcaption>
         * </p>
         *
         * @param colorSpace The color space of the color to locate on the diagram
         * @param r The first component of the color to locate on the diagram
         * @param g The second component of the color to locate on the diagram
         * @param b The third component of the color to locate on the diagram
         * @param pointColor The sRGB color to use to render the point on the diagram
         * @return This instance of {@link Renderer}
         */
        @NonNull
        public Renderer add(@NonNull ColorSpace colorSpace, float r, float g, float b,
                @ColorInt int pointColor) {
            mPoints.add(new Point(colorSpace, new float[] { r, g, b }, pointColor));
            return this;
        }

        /**
         * <p>Renders the {@link #add(ColorSpace, int) color spaces} and
         * {@link #add(ColorSpace, float, float, float, int) points} registered
         * with this renderer. The output bitmap is an sRGB image with the
         * dimensions specified by calling {@link #size(int)} (1204x1024px by
         * default).</p>
         *
         * @return A new non-null {@link Bitmap} with the dimensions specified
         *        by {@link #size(int)} (1024x1024 by default)
         */
        @NonNull
        public Bitmap render() {
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            Bitmap bitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);

            float[] primaries = new float[6];
            float[] whitePoint = new float[2];

            int width = NATIVE_SIZE;
            int height = NATIVE_SIZE;

            Path path = new Path();

            setTransform(canvas, width, height, primaries);
            drawBox(canvas, width, height, paint, path);
            setUcsTransform(canvas, height);
            drawLocus(canvas, width, height, paint, path, primaries);
            drawGamuts(canvas, width, height, paint, path, primaries, whitePoint);
            drawPoints(canvas, width, height, paint);

            return bitmap;
        }

        /**
         * Draws registered points at their correct position in the xyY coordinates.
         * Each point is positioned according to its associated color space.
         *
         * @param canvas The canvas to transform
         * @param width Width in pixel of the final image
         * @param height Height in pixel of the final image
         * @param paint A pre-allocated paint used to avoid temporary allocations
         */
        private void drawPoints(@NonNull Canvas canvas, int width, int height,
                @NonNull Paint paint) {

            paint.setStyle(Paint.Style.FILL);

            float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);

            float[] v = new float[3];
            float[] xy = new float[2];

            for (final Point point : mPoints) {
                v[0] = point.mRgb[0];
                v[1] = point.mRgb[1];
                v[2] = point.mRgb[2];
                point.mColorSpace.toXyz(v);

                paint.setColor(point.mColor);

                // XYZ to xyY, assuming Y=1.0, then to L*u*v* if needed
                float sum = v[0] + v[1] + v[2];
                xy[0] = v[0] / sum;
                xy[1] = v[1] / sum;
                if (mUcs) xyYToUv(xy);

                canvas.drawCircle(width * xy[0], height - height * xy[1], radius, paint);
            }
        }

        /**
         * Draws the color gamuts and white points of all the registered color
         * spaces. Only color spaces with an RGB color model are rendered, the
         * others are ignored.
         *
         * @param canvas The canvas to transform
         * @param width Width in pixel of the final image
         * @param height Height in pixel of the final image
         * @param paint A pre-allocated paint used to avoid temporary allocations
         * @param path A pre-allocated path used to avoid temporary allocations
         * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
         * @param whitePoint A pre-allocated array of 2 floats to avoid temporary allocations
         */
        private void drawGamuts(
                @NonNull Canvas canvas, int width, int height,
                @NonNull Paint paint, @NonNull Path path,
                @NonNull @Size(6) float[] primaries, @NonNull @Size(2) float[] whitePoint) {

            float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);

            for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
                ColorSpace colorSpace = item.first;
                int color = item.second;

                if (colorSpace.getModel() != Model.RGB) continue;

                Rgb rgb = (Rgb) colorSpace;
                getPrimaries(rgb, primaries, mUcs);

                path.rewind();
                path.moveTo(width * primaries[0], height - height * primaries[1]);
                path.lineTo(width * primaries[2], height - height * primaries[3]);
                path.lineTo(width * primaries[4], height - height * primaries[5]);
                path.close();

                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(color);
                canvas.drawPath(path, paint);

                // Draw the white point
                if (mShowWhitePoint) {
                    rgb.getWhitePoint(whitePoint);
                    if (mUcs) xyYToUv(whitePoint);

                    paint.setStyle(Paint.Style.FILL);
                    paint.setColor(color);
                    canvas.drawCircle(
                            width * whitePoint[0], height - height * whitePoint[1], radius, paint);
                }
            }
        }

        /**
         * Returns the primaries of the specified RGB color space. This method handles
         * the special case of the {@link Named#EXTENDED_SRGB} family of color spaces.
         *
         * @param rgb The color space whose primaries to extract
         * @param primaries A pre-allocated array of 6 floats that will hold the result
         * @param asUcs True if the primaries should be returned in Luv, false for xyY
         */
        @NonNull
        @Size(6)
        private static void getPrimaries(@NonNull Rgb rgb,
                @NonNull @Size(6) float[] primaries, boolean asUcs) {
            // TODO: We should find a better way to handle these cases
            if (rgb.equals(ColorSpace.get(Named.EXTENDED_SRGB)) ||
                    rgb.equals(ColorSpace.get(Named.LINEAR_EXTENDED_SRGB))) {
                primaries[0] = 1.41f;
                primaries[1] = 0.33f;
                primaries[2] = 0.27f;
                primaries[3] = 1.24f;
                primaries[4] = -0.23f;
                primaries[5] = -0.57f;
            } else {
                rgb.getPrimaries(primaries);
            }
            if (asUcs) xyYToUv(primaries);
        }

        /**
         * Draws the CIE 1931 chromaticity diagram: the spectral locus and its inside.
         * This method respect the clip parameter.
         *
         * @param canvas The canvas to transform
         * @param width Width in pixel of the final image
         * @param height Height in pixel of the final image
         * @param paint A pre-allocated paint used to avoid temporary allocations
         * @param path A pre-allocated path used to avoid temporary allocations
         * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
         */
        private void drawLocus(
                @NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
                @NonNull Path path, @NonNull @Size(6) float[] primaries) {

            int vertexCount = SPECTRUM_LOCUS_X.length * CHROMATICITY_RESOLUTION * 6;
            float[] vertices = new float[vertexCount * 2];
            int[] colors = new int[vertices.length];
            computeChromaticityMesh(vertices, colors);

            if (mUcs) xyYToUv(vertices);
            for (int i = 0; i < vertices.length; i += 2) {
                vertices[i] *= width;
                vertices[i + 1] = height - vertices[i + 1] * height;
            }

            // Draw the spectral locus
            if (mClip && mColorSpaces.size() > 0) {
                for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
                    ColorSpace colorSpace = item.first;
                    if (colorSpace.getModel() != Model.RGB) continue;

                    Rgb rgb = (Rgb) colorSpace;
                    getPrimaries(rgb, primaries, mUcs);

                    break;
                }

                path.rewind();
                path.moveTo(width * primaries[0], height - height * primaries[1]);
                path.lineTo(width * primaries[2], height - height * primaries[3]);
                path.lineTo(width * primaries[4], height - height * primaries[5]);
                path.close();

                int[] solid = new int[colors.length];
                Arrays.fill(solid, 0xff6c6c6c);
                canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
                        null, 0, solid, 0, null, 0, 0, paint);

                canvas.save();
                canvas.clipPath(path);

                canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
                        null, 0, colors, 0, null, 0, 0, paint);

                canvas.restore();
            } else {
                canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
                        null, 0, colors, 0, null, 0, 0, paint);
            }

            // Draw the non-spectral locus
            int index = (CHROMATICITY_RESOLUTION - 1) * 12;
            path.reset();
            path.moveTo(vertices[index], vertices[index + 1]);
            for (int x = 2; x < SPECTRUM_LOCUS_X.length; x++) {
                index += CHROMATICITY_RESOLUTION * 12;
                path.lineTo(vertices[index], vertices[index + 1]);
            }
            path.close();

            paint.setStrokeWidth(4.0f / (mUcs ? UCS_SCALE : 1.0f));
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(0xff000000);
            canvas.drawPath(path, paint);
        }

        /**
         * Draws the diagram box, including borders, tick marks, grid lines
         * and axis labels.
         *
         * @param canvas The canvas to transform
         * @param width Width in pixel of the final image
         * @param height Height in pixel of the final image
         * @param paint A pre-allocated paint used to avoid temporary allocations
         * @param path A pre-allocated path used to avoid temporary allocations
         */
        private void drawBox(@NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
                @NonNull Path path) {

            int lineCount = 10;
            float scale = 1.0f;
            if (mUcs) {
                lineCount = 7;
                scale = UCS_SCALE;
            }

            // Draw the unit grid
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(2.0f);
            paint.setColor(0xffc0c0c0);

            for (int i = 1; i < lineCount - 1; i++) {
                float v = i / 10.0f;
                float x = (width * v) * scale;
                float y = height - (height * v) * scale;

                canvas.drawLine(0.0f, y, 0.9f * width, y, paint);
                canvas.drawLine(x, height, x, 0.1f * height, paint);
            }

            // Draw tick marks
            paint.setStrokeWidth(4.0f);
            paint.setColor(0xff000000);
            for (int i = 1; i < lineCount - 1; i++) {
                float v = i / 10.0f;
                float x = (width * v) * scale;
                float y = height - (height * v) * scale;

                canvas.drawLine(0.0f, y, width / 100.0f, y, paint);
                canvas.drawLine(x, height, x, height - (height / 100.0f), paint);
            }

            // Draw the axis labels
            paint.setStyle(Paint.Style.FILL);
            paint.setTextSize(36.0f);
            paint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));

            Rect bounds = new Rect();
            for (int i = 1; i < lineCount - 1; i++) {
                String text = "0." + i;
                paint.getTextBounds(text, 0, text.length(), bounds);

                float v = i / 10.0f;
                float x = (width * v) * scale;
                float y = height - (height * v) * scale;

                canvas.drawText(text, -0.05f * width + 10, y + bounds.height() / 2.0f, paint);
                canvas.drawText(text, x - bounds.width() / 2.0f,
                        height + bounds.height() + 16, paint);
            }
            paint.setStyle(Paint.Style.STROKE);

            // Draw the diagram box
            path.moveTo(0.0f, height);
            path.lineTo(0.9f * width, height);
            path.lineTo(0.9f * width, 0.1f * height);
            path.lineTo(0.0f, 0.1f * height);
            path.close();
            canvas.drawPath(path, paint);
        }

        /**
         * Computes and applies the Canvas transforms required to make the color
         * gamut of each color space visible in the final image.
         *
         * @param canvas The canvas to transform
         * @param width Width in pixel of the final image
         * @param height Height in pixel of the final image
         * @param primaries Array of 6 floats used to avoid temporary allocations
         */
        private void setTransform(@NonNull Canvas canvas, int width, int height,
                @NonNull @Size(6) float[] primaries) {

            RectF primariesBounds = new RectF();
            for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
                ColorSpace colorSpace = item.first;
                if (colorSpace.getModel() != Model.RGB) continue;

                Rgb rgb = (Rgb) colorSpace;
                getPrimaries(rgb, primaries, mUcs);

                primariesBounds.left = Math.min(primariesBounds.left, primaries[4]);
                primariesBounds.top = Math.min(primariesBounds.top, primaries[5]);
                primariesBounds.right = Math.max(primariesBounds.right, primaries[0]);
                primariesBounds.bottom = Math.max(primariesBounds.bottom, primaries[3]);
            }

            float max = mUcs ? 0.6f : 0.9f;

            primariesBounds.left = Math.min(0.0f, primariesBounds.left);
            primariesBounds.top = Math.min(0.0f, primariesBounds.top);
            primariesBounds.right = Math.max(max, primariesBounds.right);
            primariesBounds.bottom = Math.max(max, primariesBounds.bottom);

            float scaleX = max / primariesBounds.width();
            float scaleY = max / primariesBounds.height();
            float scale = Math.min(scaleX, scaleY);

            canvas.scale(mSize / (float) NATIVE_SIZE, mSize / (float) NATIVE_SIZE);
            canvas.scale(scale, scale);
            canvas.translate(
                    (primariesBounds.width() - max) * width / 2.0f,
                    (primariesBounds.height() - max) * height / 2.0f);

            // The spectrum extends ~0.85 vertically and ~0.65 horizontally
            // We shift the canvas a little bit to get nicer margins
            canvas.translate(0.05f * width, -0.05f * height);
        }

        /**
         * Computes and applies the Canvas transforms required to render the CIE
         * 197 UCS chromaticity diagram.
         *
         * @param canvas The canvas to transform
         * @param height Height in pixel of the final image
         */
        private void setUcsTransform(@NonNull Canvas canvas, int height) {
            if (mUcs) {
                canvas.translate(0.0f, (height - height * UCS_SCALE));
                canvas.scale(UCS_SCALE, UCS_SCALE);
            }
        }

        // X coordinates of the spectral locus in CIE 1931
        private static final float[] SPECTRUM_LOCUS_X = {
                0.175596f, 0.172787f, 0.170806f, 0.170085f, 0.160343f,
                0.146958f, 0.139149f, 0.133536f, 0.126688f, 0.115830f,
                0.109616f, 0.099146f, 0.091310f, 0.078130f, 0.068717f,
                0.054675f, 0.040763f, 0.027497f, 0.016270f, 0.008169f,
                0.004876f, 0.003983f, 0.003859f, 0.004646f, 0.007988f,
                0.013870f, 0.022244f, 0.027273f, 0.032820f, 0.038851f,
                0.045327f, 0.052175f, 0.059323f, 0.066713f, 0.074299f,
                0.089937f, 0.114155f, 0.138695f, 0.154714f, 0.192865f,
                0.229607f, 0.265760f, 0.301588f, 0.337346f, 0.373083f,
                0.408717f, 0.444043f, 0.478755f, 0.512467f, 0.544767f,
                0.575132f, 0.602914f, 0.627018f, 0.648215f, 0.665746f,
                0.680061f, 0.691487f, 0.700589f, 0.707901f, 0.714015f,
                0.719017f, 0.723016f, 0.734674f, 0.717203f, 0.699732f,
                0.682260f, 0.664789f, 0.647318f, 0.629847f, 0.612376f,
                0.594905f, 0.577433f, 0.559962f, 0.542491f, 0.525020f,
                0.507549f, 0.490077f, 0.472606f, 0.455135f, 0.437664f,
                0.420193f, 0.402721f, 0.385250f, 0.367779f, 0.350308f,
                0.332837f, 0.315366f, 0.297894f, 0.280423f, 0.262952f,
                0.245481f, 0.228010f, 0.210538f, 0.193067f, 0.175596f
        };
        // Y coordinates of the spectral locus in CIE 1931
        private static final float[] SPECTRUM_LOCUS_Y = {
                0.005295f, 0.004800f, 0.005472f, 0.005976f, 0.014496f,
                0.026643f, 0.035211f, 0.042704f, 0.053441f, 0.073601f,
                0.086866f, 0.112037f, 0.132737f, 0.170464f, 0.200773f,
                0.254155f, 0.317049f, 0.387997f, 0.463035f, 0.538504f,
                0.587196f, 0.610526f, 0.654897f, 0.675970f, 0.715407f,
                0.750246f, 0.779682f, 0.792153f, 0.802971f, 0.812059f,
                0.819430f, 0.825200f, 0.829460f, 0.832306f, 0.833833f,
                0.833316f, 0.826231f, 0.814796f, 0.805884f, 0.781648f,
                0.754347f, 0.724342f, 0.692326f, 0.658867f, 0.624470f,
                0.589626f, 0.554734f, 0.520222f, 0.486611f, 0.454454f,
                0.424252f, 0.396516f, 0.372510f, 0.351413f, 0.334028f,
                0.319765f, 0.308359f, 0.299317f, 0.292044f, 0.285945f,
                0.280951f, 0.276964f, 0.265326f, 0.257200f, 0.249074f,
                0.240948f, 0.232822f, 0.224696f, 0.216570f, 0.208444f,
                0.200318f, 0.192192f, 0.184066f, 0.175940f, 0.167814f,
                0.159688f, 0.151562f, 0.143436f, 0.135311f, 0.127185f,
                0.119059f, 0.110933f, 0.102807f, 0.094681f, 0.086555f,
                0.078429f, 0.070303f, 0.062177f, 0.054051f, 0.045925f,
                0.037799f, 0.029673f, 0.021547f, 0.013421f, 0.005295f
        };

        /**
         * Computes a 2D mesh representation of the CIE 1931 chromaticity
         * diagram.
         *
         * @param vertices Array of floats that will hold the mesh vertices
         * @param colors Array of floats that will hold the mesh colors
         */
        private static void computeChromaticityMesh(@NonNull float[] vertices,
                @NonNull int[] colors) {

            ColorSpace colorSpace = get(Named.SRGB);

            float[] color = new float[3];

            int vertexIndex = 0;
            int colorIndex = 0;

            for (int x = 0; x < SPECTRUM_LOCUS_X.length; x++) {
                int nextX = (x % (SPECTRUM_LOCUS_X.length - 1)) + 1;

                float a1 = (float) Math.atan2(
                        SPECTRUM_LOCUS_Y[x] - ONE_THIRD,
                        SPECTRUM_LOCUS_X[x] - ONE_THIRD);
                float a2 = (float) Math.atan2(
                        SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD,
                        SPECTRUM_LOCUS_X[nextX] - ONE_THIRD);

                float radius1 = (float) Math.pow(
                        sqr(SPECTRUM_LOCUS_X[x] - ONE_THIRD) +
                                sqr(SPECTRUM_LOCUS_Y[x] - ONE_THIRD),
                        0.5);
                float radius2 = (float) Math.pow(
                        sqr(SPECTRUM_LOCUS_X[nextX] - ONE_THIRD) +
                                sqr(SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD),
                        0.5);

                // Compute patches; each patch is a quad with a different
                // color associated with each vertex
                for (int c = 1; c <= CHROMATICITY_RESOLUTION; c++) {
                    float f1 = c / (float) CHROMATICITY_RESOLUTION;
                    float f2 = (c - 1) / (float) CHROMATICITY_RESOLUTION;

                    double cr1 = radius1 * Math.cos(a1);
                    double sr1 = radius1 * Math.sin(a1);
                    double cr2 = radius2 * Math.cos(a2);
                    double sr2 = radius2 * Math.sin(a2);

                    // Compute the XYZ coordinates of the 4 vertices of the patch
                    float v1x = (float) (ONE_THIRD + cr1 * f1);
                    float v1y = (float) (ONE_THIRD + sr1 * f1);
                    float v1z = 1 - v1x - v1y;

                    float v2x = (float) (ONE_THIRD + cr1 * f2);
                    float v2y = (float) (ONE_THIRD + sr1 * f2);
                    float v2z = 1 - v2x - v2y;

                    float v3x = (float) (ONE_THIRD + cr2 * f2);
                    float v3y = (float) (ONE_THIRD + sr2 * f2);
                    float v3z = 1 - v3x - v3y;

                    float v4x = (float) (ONE_THIRD + cr2 * f1);
                    float v4y = (float) (ONE_THIRD + sr2 * f1);
                    float v4z = 1 - v4x - v4y;

                    // Compute the sRGB representation of each XYZ coordinate of the patch
                    colors[colorIndex    ] = computeColor(color, v1x, v1y, v1z, colorSpace);
                    colors[colorIndex + 1] = computeColor(color, v2x, v2y, v2z, colorSpace);
                    colors[colorIndex + 2] = computeColor(color, v3x, v3y, v3z, colorSpace);
                    colors[colorIndex + 3] = colors[colorIndex];
                    colors[colorIndex + 4] = colors[colorIndex + 2];
                    colors[colorIndex + 5] = computeColor(color, v4x, v4y, v4z, colorSpace);
                    colorIndex += 6;

                    // Flip the mesh upside down to match Canvas' coordinates system
                    vertices[vertexIndex++] = v1x;
                    vertices[vertexIndex++] = v1y;
                    vertices[vertexIndex++] = v2x;
                    vertices[vertexIndex++] = v2y;
                    vertices[vertexIndex++] = v3x;
                    vertices[vertexIndex++] = v3y;
                    vertices[vertexIndex++] = v1x;
                    vertices[vertexIndex++] = v1y;
                    vertices[vertexIndex++] = v3x;
                    vertices[vertexIndex++] = v3y;
                    vertices[vertexIndex++] = v4x;
                    vertices[vertexIndex++] = v4y;
                }
            }
        }

        @ColorInt
        private static int computeColor(@NonNull @Size(3) float[] color,
                float x, float y, float z, @NonNull ColorSpace cs) {
            color[0] = x;
            color[1] = y;
            color[2] = z;
            cs.fromXyz(color);
            return 0xff000000 |
                    (((int) (color[0] * 255.0f) & 0xff) << 16) |
                    (((int) (color[1] * 255.0f) & 0xff) <<  8) |
                    (((int) (color[2] * 255.0f) & 0xff)      );
        }

        private static double sqr(double v) {
            return v * v;
        }

        private static class Point {
            @NonNull final ColorSpace mColorSpace;
            @NonNull final float[] mRgb;
            final int mColor;

            Point(@NonNull ColorSpace colorSpace,
                    @NonNull @Size(3) float[] rgb, @ColorInt int color) {
                mColorSpace = colorSpace;
                mRgb = rgb;
                mColor = color;
            }
        }
    }
}
