blob: 7648fd021d1879841f9254841a335fd18962d401 [file] [log] [blame]
/*
* Copyright (C) 2019 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.
*/
#include "jni.h"
#include "GraphicsJNI.h"
#include "core_jni_helpers.h"
#include "SkColor.h"
#include "SkColorSpace.h"
using namespace android;
static skcms_Matrix3x3 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50) {
skcms_Matrix3x3 xyzMatrix;
jfloat* array = env->GetFloatArrayElements(xyzD50, NULL);
xyzMatrix.vals[0][0] = array[0];
xyzMatrix.vals[1][0] = array[1];
xyzMatrix.vals[2][0] = array[2];
xyzMatrix.vals[0][1] = array[3];
xyzMatrix.vals[1][1] = array[4];
xyzMatrix.vals[2][1] = array[5];
xyzMatrix.vals[0][2] = array[6];
xyzMatrix.vals[1][2] = array[7];
xyzMatrix.vals[2][2] = array[8];
env->ReleaseFloatArrayElements(xyzD50, array, 0);
return xyzMatrix;
}
///////////////////////////////////////////////////////////////////////////////
static float halfToFloat(uint16_t bits) {
__fp16 h;
memcpy(&h, &bits, 2);
return (float)h;
}
SkColor4f GraphicsJNI::convertColorLong(jlong color) {
if ((color & 0x3f) == 0) {
// This corresponds to sRGB, which is treated differently than the rest.
uint8_t a = color >> 56 & 0xff;
uint8_t r = color >> 48 & 0xff;
uint8_t g = color >> 40 & 0xff;
uint8_t b = color >> 32 & 0xff;
SkColor c = SkColorSetARGB(a, r, g, b);
return SkColor4f::FromColor(c);
}
// These match the implementation of android.graphics.Color#red(long) etc.
float r = halfToFloat((uint16_t)(color >> 48 & 0xffff));
float g = halfToFloat((uint16_t)(color >> 32 & 0xffff));
float b = halfToFloat((uint16_t)(color >> 16 & 0xffff));
float a = (color >> 6 & 0x3ff) / 1023.0f;
return SkColor4f{r, g, b, a};
}
sk_sp<SkColorSpace> GraphicsJNI::getNativeColorSpace(jlong colorSpaceHandle) {
if (colorSpaceHandle == 0) return nullptr;
return sk_ref_sp(reinterpret_cast<SkColorSpace*>(colorSpaceHandle));
}
static void unref_colorSpace(SkColorSpace* cs) {
SkSafeUnref(cs);
}
static jlong ColorSpace_getNativeFinalizer(JNIEnv*, jobject) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&unref_colorSpace));
}
static jlong ColorSpace_creator(JNIEnv* env, jobject, jfloat a, jfloat b, jfloat c,
jfloat d, jfloat e, jfloat f, jfloat g, jfloatArray xyzD50) {
skcms_TransferFunction p;
p.a = a;
p.b = b;
p.c = c;
p.d = d;
p.e = e;
p.f = f;
p.g = g;
skcms_Matrix3x3 xyzMatrix = getNativeXYZMatrix(env, xyzD50);
return reinterpret_cast<jlong>(SkColorSpace::MakeRGB(p, xyzMatrix).release());
}
static const JNINativeMethod gColorSpaceRgbMethods[] = {
{ "nativeGetNativeFinalizer", "()J", (void*)ColorSpace_getNativeFinalizer },
{ "nativeCreate", "(FFFFFFF[F)J", (void*)ColorSpace_creator }
};
namespace android {
int register_android_graphics_ColorSpace(JNIEnv* env) {
return android::RegisterMethodsOrDie(env, "android/graphics/ColorSpace$Rgb",
gColorSpaceRgbMethods, NELEM(gColorSpaceRgbMethods));
}
}; // namespace android