diff --git a/api/current.txt b/api/current.txt index 83e0f942c69eb..635c79ad7354f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -14487,6 +14487,8 @@ package android.graphics { @AnyThread public abstract class ColorSpace { method @NonNull public static android.graphics.ColorSpace adapt(@NonNull android.graphics.ColorSpace, @NonNull @Size(min=2, max=3) float[]); method @NonNull public static android.graphics.ColorSpace adapt(@NonNull android.graphics.ColorSpace, @NonNull @Size(min=2, max=3) float[], @NonNull android.graphics.ColorSpace.Adaptation); + method @NonNull @Size(3) public static float[] cctToXyz(@IntRange(from=1) int); + method @NonNull @Size(9) public static float[] chromaticAdaptation(@NonNull android.graphics.ColorSpace.Adaptation, @NonNull @Size(min=2, max=3) float[], @NonNull @Size(min=2, max=3) float[]); method @NonNull public static android.graphics.ColorSpace.Connector connect(@NonNull android.graphics.ColorSpace, @NonNull android.graphics.ColorSpace); method @NonNull public static android.graphics.ColorSpace.Connector connect(@NonNull android.graphics.ColorSpace, @NonNull android.graphics.ColorSpace, @NonNull android.graphics.ColorSpace.RenderIntent); method @NonNull public static android.graphics.ColorSpace.Connector connect(@NonNull android.graphics.ColorSpace); diff --git a/core/tests/coretests/src/android/graphics/ColorSpaceRendererTest.java b/core/tests/coretests/src/android/graphics/ColorSpaceRendererTest.java deleted file mode 100644 index 8e9b38cc5a1f1..0000000000000 --- a/core/tests/coretests/src/android/graphics/ColorSpaceRendererTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2017 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class ColorSpaceRendererTest { - - @Test - public void testRendererSize() { - Bitmap b = ColorSpace.createRenderer() - .size(0) - .render(); - assertEquals(128, b.getWidth()); - assertEquals(128, b.getHeight()); - - b = ColorSpace.createRenderer() - .size(768) - .render(); - assertEquals(768, b.getWidth()); - assertEquals(768, b.getHeight()); - } - - @Test - public void testRenderer() { - Bitmap b = ColorSpace.createRenderer() - .size(1024) - .clip(true) - .showWhitePoint(false) - .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffffff) - .add(ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), 0.1f, 0.5f, 0.1f, 0xff000000) - .add(ColorSpace.get(ColorSpace.Named.ADOBE_RGB), 0.1f, 0.5f, 0.1f, 0xff000000) - .render(); - assertNotNull(b); - } - - @Test - public void testUcsRenderer() { - Bitmap b = ColorSpace.createRenderer() - .size(1024) - .clip(true) - .showWhitePoint(false) - .uniformChromaticityScale(true) - .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffffff) - .add(ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), 0.1f, 0.5f, 0.1f, 0xff000000) - .add(ColorSpace.get(ColorSpace.Named.ADOBE_RGB), 0.1f, 0.5f, 0.1f, 0xff000000) - .render(); - assertNotNull(b); - } -} diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java index 1aeafa391b41a..2f978fc1fc2d0 100644 --- a/graphics/java/android/graphics/ColorSpace.java +++ b/graphics/java/android/graphics/ColorSpace.java @@ -17,19 +17,15 @@ 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 libcore.util.NativeAllocationRegistry; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.function.DoubleUnaryOperator; /** @@ -872,8 +868,7 @@ public abstract class ColorSpace { } } - /** @hide */ - ColorSpace( + /*package*/ ColorSpace( @NonNull String name, @NonNull Model model, @IntRange(from = MIN_ID, to = MAX_ID) int id) { @@ -1441,22 +1436,6 @@ public abstract class ColorSpace { return null; } - /** - *
Creates a new {@link Renderer} that can be used to visualize and - * debug color spaces. See the documentation of {@link Renderer} for - * more information.
- * - * @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", @@ -1701,12 +1680,10 @@ public abstract class ColorSpace { * @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 - * - * @hide */ @NonNull @Size(9) - public static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) { + 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]; @@ -1774,28 +1751,6 @@ public abstract class ColorSpace { 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; - } - } - /** *Computes the chromatic adaptation transform from the specified * source white point to the specified destination white point.
@@ -1834,8 +1789,6 @@ public abstract class ColorSpace { * @param cct The correlated color temperature, in Kelvin * @return Corresponding XYZ values * @throws IllegalArgumentException If cct is invalid - * - * @hide */ @NonNull @Size(3) @@ -1860,38 +1813,6 @@ public abstract class ColorSpace { return xyYToXyz(new float[] {x, y}); } - /** - *Computes the chromaticity coordinates of a CIE series D illuminant - * from the specified correlated color temperature (CCT). The specified CCT - * must be greater than 0. A meaningful CCT range is [4000, 25000].
- * - *The transform is computed using the methods referred to in Kang et - * al., Design of Advanced Color - Temperature Control System for HDTV - * Applications, Journal of Korean Physical Society 41, 865-871 - * (2002).
- * - * @param cct The correlated color temperature, in Kelvin - * @return Corresponding XYZ values - * @throws IllegalArgumentException If cct is invalid - * - * @hide - */ - @NonNull - @Size(3) - public static float[] cctToIlluminantdXyz(@IntRange(from = 1) int cct) { - if (cct < 1) { - throw new IllegalArgumentException("Temperature must be greater than 0"); - } - - final float icct = 1.0f / cct; - final float icct2 = icct * icct; - final float x = cct <= 7000.0f ? - 0.244063f + 0.09911e3f * icct + 2.9678e6f * icct2 - 4.6070e9f * icct2 * icct : - 0.237040f + 0.24748e3f * icct + 1.9018e6f * icct2 - 2.0064e9f * icct2 * icct; - final float y = -3.0f * x * x + 2.87f * x - 0.275f; - return xyYToXyz(new float[] {x, y}); - } - /** *Computes the chromatic adaptation transform from the specified * source white point to the specified destination white point.
@@ -1905,14 +1826,16 @@ public abstract class ColorSpace { * @param srcWhitePoint The white point to adapt from * @param dstWhitePoint The white point to adapt to * @return A 3x3 matrix as a non-null array of 9 floats - * - * @hide */ @NonNull @Size(9) public static float[] chromaticAdaptation(@NonNull Adaptation adaptation, @NonNull @Size(min = 2, max = 3) float[] srcWhitePoint, @NonNull @Size(min = 2, max = 3) float[] dstWhitePoint) { + if ((srcWhitePoint.length != 2 && srcWhitePoint.length != 3) + || (dstWhitePoint.length != 2 && dstWhitePoint.length != 3)) { + throw new IllegalArgumentException("A white point array must have 2 or 3 floats"); + } float[] srcXyz = srcWhitePoint.length == 3 ? Arrays.copyOf(srcWhitePoint, 3) : xyYToXyz(srcWhitePoint); float[] dstXyz = dstWhitePoint.length == 3 ? @@ -3925,771 +3848,4 @@ public abstract class ColorSpace { }; } } - - /** - *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.
- * - *The following code snippet shows how to compare the {@link Named#SRGB} - * and {@link Named#DCI_P3} color spaces in a CIE 1931 diagram:
- * - *- * Bitmap bitmap = ColorSpace.createRenderer() - * .size(768) - * .clip(true) - * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845) - * .render(); - *- *
- *
- *
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.
- * - * @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 ListDefines whether the chromaticity diagram should be clipped by the first - * registered color space. The default value is false.
- * - *The following code snippet and image show the default behavior:
- *- * Bitmap bitmap = ColorSpace.createRenderer() - * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845) - * .render(); - *- *
- *
- *
Here is the same example with clipping enabled:
- *- * Bitmap bitmap = ColorSpace.createRenderer() - * .clip(true) - * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845) - * .render(); - *- *
- *
- *
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.
- * - *The following code snippet shows how to enable the uniform chromaticity - * scale. The image below shows the result:
- *- * Bitmap bitmap = ColorSpace.createRenderer() - * .uniformChromaticityScale(true) - * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845) - * .render(); - *- *
- *
- *
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.
- * - *Color spaces with a color model that is not RGB are - * accepted but ignored.
- * - *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}:
- *- * Bitmap bitmap = ColorSpace.createRenderer() - * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff) - * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845) - * .render(); - *- *
- *
- *
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:
- *- * 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(); - *- *
- *
- *
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.
- * - *The following code snippet and image show an example of calling this - * method to render the location of several sRGB colors as white circles:
- *- * 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(); - *- *
- *
- *
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).
- * - * @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