Leon Scroggins III | 0e443d1 | 2018-12-19 11:38:35 -0500 | [diff] [blame] | 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 | |
Leon Scroggins III | 94ba100 | 2019-01-17 13:34:51 -0500 | [diff] [blame] | 21 | #include "SkColor.h" |
Leon Scroggins III | 0e443d1 | 2018-12-19 11:38:35 -0500 | [diff] [blame] | 22 | #include "SkColorSpace.h" |
| 23 | |
| 24 | using namespace android; |
| 25 | |
| 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 | |
Leon Scroggins III | c4892a7 | 2019-01-22 16:33:42 -0500 | [diff] [blame] | 44 | static float halfToFloat(uint16_t bits) { |
| 45 | __fp16 h; |
| 46 | memcpy(&h, &bits, 2); |
| 47 | return (float)h; |
| 48 | } |
| 49 | |
Leon Scroggins III | 94ba100 | 2019-01-17 13:34:51 -0500 | [diff] [blame] | 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. |
Leon Scroggins III | c4892a7 | 2019-01-22 16:33:42 -0500 | [diff] [blame] | 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)); |
Leon Scroggins III | 94ba100 | 2019-01-17 13:34:51 -0500 | [diff] [blame] | 65 | float a = (color >> 6 & 0x3ff) / 1023.0f; |
| 66 | |
| 67 | return SkColor4f{r, g, b, a}; |
| 68 | } |
| 69 | |
Leon Scroggins III | 0e443d1 | 2018-12-19 11:38:35 -0500 | [diff] [blame] | 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 | |
| 75 | static void unref_colorSpace(SkColorSpace* cs) { |
| 76 | SkSafeUnref(cs); |
| 77 | } |
| 78 | |
| 79 | static jlong ColorSpace_getNativeFinalizer(JNIEnv*, jobject) { |
| 80 | return static_cast<jlong>(reinterpret_cast<uintptr_t>(&unref_colorSpace)); |
| 81 | } |
| 82 | |
| 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 | |
| 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 |