1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jni.h"
18 #include "GraphicsJNI.h"
19 #include "core_jni_helpers.h"
20
21 #include "SkColor.h"
22 #include "SkColorSpace.h"
23
24 using namespace android;
25
getNativeXYZMatrix(JNIEnv * env,jfloatArray xyzD50)26 static skcms_Matrix3x3 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50) {
27 skcms_Matrix3x3 xyzMatrix;
28 jfloat* array = env->GetFloatArrayElements(xyzD50, NULL);
29 xyzMatrix.vals[0][0] = array[0];
30 xyzMatrix.vals[1][0] = array[1];
31 xyzMatrix.vals[2][0] = array[2];
32 xyzMatrix.vals[0][1] = array[3];
33 xyzMatrix.vals[1][1] = array[4];
34 xyzMatrix.vals[2][1] = array[5];
35 xyzMatrix.vals[0][2] = array[6];
36 xyzMatrix.vals[1][2] = array[7];
37 xyzMatrix.vals[2][2] = array[8];
38 env->ReleaseFloatArrayElements(xyzD50, array, 0);
39 return xyzMatrix;
40 }
41
42 ///////////////////////////////////////////////////////////////////////////////
43
halfToFloat(uint16_t bits)44 static float halfToFloat(uint16_t bits) {
45 __fp16 h;
46 memcpy(&h, &bits, 2);
47 return (float)h;
48 }
49
convertColorLong(jlong color)50 SkColor4f GraphicsJNI::convertColorLong(jlong color) {
51 if ((color & 0x3f) == 0) {
52 // This corresponds to sRGB, which is treated differently than the rest.
53 uint8_t a = color >> 56 & 0xff;
54 uint8_t r = color >> 48 & 0xff;
55 uint8_t g = color >> 40 & 0xff;
56 uint8_t b = color >> 32 & 0xff;
57 SkColor c = SkColorSetARGB(a, r, g, b);
58 return SkColor4f::FromColor(c);
59 }
60
61 // These match the implementation of android.graphics.Color#red(long) etc.
62 float r = halfToFloat((uint16_t)(color >> 48 & 0xffff));
63 float g = halfToFloat((uint16_t)(color >> 32 & 0xffff));
64 float b = halfToFloat((uint16_t)(color >> 16 & 0xffff));
65 float a = (color >> 6 & 0x3ff) / 1023.0f;
66
67 return SkColor4f{r, g, b, a};
68 }
69
getNativeColorSpace(jlong colorSpaceHandle)70 sk_sp<SkColorSpace> GraphicsJNI::getNativeColorSpace(jlong colorSpaceHandle) {
71 if (colorSpaceHandle == 0) return nullptr;
72 return sk_ref_sp(reinterpret_cast<SkColorSpace*>(colorSpaceHandle));
73 }
74
unref_colorSpace(SkColorSpace * cs)75 static void unref_colorSpace(SkColorSpace* cs) {
76 SkSafeUnref(cs);
77 }
78
ColorSpace_getNativeFinalizer(JNIEnv *,jobject)79 static jlong ColorSpace_getNativeFinalizer(JNIEnv*, jobject) {
80 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&unref_colorSpace));
81 }
82
ColorSpace_creator(JNIEnv * env,jobject,jfloat a,jfloat b,jfloat c,jfloat d,jfloat e,jfloat f,jfloat g,jfloatArray xyzD50)83 static jlong ColorSpace_creator(JNIEnv* env, jobject, jfloat a, jfloat b, jfloat c,
84 jfloat d, jfloat e, jfloat f, jfloat g, jfloatArray xyzD50) {
85 skcms_TransferFunction p;
86 p.a = a;
87 p.b = b;
88 p.c = c;
89 p.d = d;
90 p.e = e;
91 p.f = f;
92 p.g = g;
93 skcms_Matrix3x3 xyzMatrix = getNativeXYZMatrix(env, xyzD50);
94
95 return reinterpret_cast<jlong>(SkColorSpace::MakeRGB(p, xyzMatrix).release());
96 }
97
98 static const JNINativeMethod gColorSpaceRgbMethods[] = {
99 { "nativeGetNativeFinalizer", "()J", (void*)ColorSpace_getNativeFinalizer },
100 { "nativeCreate", "(FFFFFFF[F)J", (void*)ColorSpace_creator }
101 };
102
103 namespace android {
104
register_android_graphics_ColorSpace(JNIEnv * env)105 int register_android_graphics_ColorSpace(JNIEnv* env) {
106 return android::RegisterMethodsOrDie(env, "android/graphics/ColorSpace$Rgb",
107 gColorSpaceRgbMethods, NELEM(gColorSpaceRgbMethods));
108 }
109
110 }; // namespace android
111