blob: a977815db24829602fc0cf551a9f2c0f4b6716e2 [file] [log] [blame]
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/ports/SkNDKConversions.h"
namespace {
static const struct {
SkColorType colorType;
AndroidBitmapFormat format;
} gColorTypeTable[] = {
{ kRGBA_8888_SkColorType, ANDROID_BITMAP_FORMAT_RGBA_8888 },
{ kRGBA_F16_SkColorType, ANDROID_BITMAP_FORMAT_RGBA_F16 },
{ kRGB_565_SkColorType, ANDROID_BITMAP_FORMAT_RGB_565 },
// Android allows using its alpha 8 format to get 8 bit gray pixels.
{ kGray_8_SkColorType, ANDROID_BITMAP_FORMAT_A_8 },
};
} // anonymous namespace
namespace SkNDKConversions {
AndroidBitmapFormat toAndroidBitmapFormat(SkColorType colorType) {
for (const auto& entry : gColorTypeTable) {
if (entry.colorType == colorType) {
return entry.format;
}
}
return ANDROID_BITMAP_FORMAT_NONE;
}
SkColorType toColorType(AndroidBitmapFormat format) {
for (const auto& entry : gColorTypeTable) {
if (entry.format == format) {
return entry.colorType;
}
}
return kUnknown_SkColorType;
}
} // SkNDKConversions
static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
static constexpr skcms_Matrix3x3 kDCIP3 = {{
{0.486143, 0.323835, 0.154234},
{0.226676, 0.710327, 0.0629966},
{0.000800549, 0.0432385, 0.78275},
}};
namespace {
static const struct {
ADataSpace dataSpace;
skcms_TransferFunction transferFunction;
skcms_Matrix3x3 gamut;
} gColorSpaceTable[] = {
{ ADATASPACE_SRGB, SkNamedTransferFn::kSRGB, SkNamedGamut::kSRGB },
{ ADATASPACE_SCRGB, SkNamedTransferFn::kSRGB, SkNamedGamut::kSRGB },
{ ADATASPACE_SCRGB_LINEAR, SkNamedTransferFn::kLinear, SkNamedGamut::kSRGB },
{ ADATASPACE_SRGB_LINEAR, SkNamedTransferFn::kLinear, SkNamedGamut::kSRGB },
{ ADATASPACE_ADOBE_RGB, SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB },
{ ADATASPACE_DISPLAY_P3, SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3 },
{ ADATASPACE_BT2020, SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020 },
{ ADATASPACE_BT709, SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB },
{ ADATASPACE_DCI_P3, k2Dot6, kDCIP3 },
};
} // anonymous namespace
static bool nearly_equal(float a, float b) {
return fabs(a - b) < .002f;
}
static bool nearly_equal(const skcms_TransferFunction& x, const skcms_TransferFunction& y) {
return nearly_equal(x.g, y.g)
&& nearly_equal(x.a, y.a)
&& nearly_equal(x.b, y.b)
&& nearly_equal(x.c, y.c)
&& nearly_equal(x.d, y.d)
&& nearly_equal(x.e, y.e)
&& nearly_equal(x.f, y.f);
}
static bool nearly_equal(const skcms_Matrix3x3& a, const skcms_Matrix3x3& b) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (!nearly_equal(a.vals[i][j], b.vals[i][j])) return false;
}
return true;
}
namespace SkNDKConversions {
ADataSpace toDataSpace(SkColorSpace* cs) {
if (!cs) return ADATASPACE_SRGB;
skcms_TransferFunction fn;
skcms_Matrix3x3 gamut;
if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&gamut)) {
for (const auto& entry : gColorSpaceTable) {
if (nearly_equal(gamut, entry.gamut) && nearly_equal(fn, entry.transferFunction)) {
return entry.dataSpace;
}
}
}
return ADATASPACE_UNKNOWN;
}
sk_sp<SkColorSpace> toColorSpace(ADataSpace dataSpace) {
for (const auto& entry : gColorSpaceTable) {
if (entry.dataSpace == dataSpace) {
return SkColorSpace::MakeRGB(entry.transferFunction, entry.gamut);
}
}
return nullptr;
}
}