• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/ports/SkNDKConversions.h"
9 
10 namespace {
11 static const struct {
12     SkColorType         colorType;
13     AndroidBitmapFormat format;
14 } gColorTypeTable[] = {
15     { kRGBA_8888_SkColorType, ANDROID_BITMAP_FORMAT_RGBA_8888 },
16     { kRGBA_F16_SkColorType,  ANDROID_BITMAP_FORMAT_RGBA_F16 },
17     { kRGB_565_SkColorType,   ANDROID_BITMAP_FORMAT_RGB_565 },
18     // Android allows using its alpha 8 format to get 8 bit gray pixels.
19     { kGray_8_SkColorType,    ANDROID_BITMAP_FORMAT_A_8 },
20 };
21 
22 } // anonymous namespace
23 
24 namespace SkNDKConversions {
toAndroidBitmapFormat(SkColorType colorType)25     AndroidBitmapFormat toAndroidBitmapFormat(SkColorType colorType) {
26         for (const auto& entry : gColorTypeTable) {
27             if (entry.colorType == colorType) {
28                 return entry.format;
29             }
30         }
31         return ANDROID_BITMAP_FORMAT_NONE;
32     }
33 
toColorType(AndroidBitmapFormat format)34     SkColorType toColorType(AndroidBitmapFormat format) {
35         for (const auto& entry : gColorTypeTable) {
36             if (entry.format == format) {
37                 return entry.colorType;
38             }
39         }
40         return kUnknown_SkColorType;
41     }
42 
43 } // SkNDKConversions
44 
45 static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
46 
47 static constexpr skcms_Matrix3x3 kDCIP3 = {{
48         {0.486143, 0.323835, 0.154234},
49         {0.226676, 0.710327, 0.0629966},
50         {0.000800549, 0.0432385, 0.78275},
51 }};
52 
53 namespace {
54 static const struct {
55     ADataSpace             dataSpace;
56     skcms_TransferFunction transferFunction;
57     skcms_Matrix3x3        gamut;
58 } gColorSpaceTable[] = {
59     { ADATASPACE_SRGB,         SkNamedTransferFn::kSRGB,    SkNamedGamut::kSRGB },
60     { ADATASPACE_SCRGB,        SkNamedTransferFn::kSRGB,    SkNamedGamut::kSRGB },
61     { ADATASPACE_SCRGB_LINEAR, SkNamedTransferFn::kLinear,  SkNamedGamut::kSRGB },
62     { ADATASPACE_SRGB_LINEAR,  SkNamedTransferFn::kLinear,  SkNamedGamut::kSRGB },
63     { ADATASPACE_ADOBE_RGB,    SkNamedTransferFn::k2Dot2,   SkNamedGamut::kAdobeRGB },
64     { ADATASPACE_DISPLAY_P3,   SkNamedTransferFn::kSRGB,    SkNamedGamut::kDisplayP3 },
65     { ADATASPACE_BT2020,       SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020 },
66     { ADATASPACE_BT709,        SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB },
67     { ADATASPACE_DCI_P3,       k2Dot6,                      kDCIP3 },
68 };
69 
70 } // anonymous namespace
71 
nearly_equal(float a,float b)72 static bool nearly_equal(float a, float b) {
73     return fabs(a - b) < .002f;
74 }
75 
nearly_equal(const skcms_TransferFunction & x,const skcms_TransferFunction & y)76 static bool nearly_equal(const skcms_TransferFunction& x, const skcms_TransferFunction& y) {
77     return nearly_equal(x.g, y.g)
78         && nearly_equal(x.a, y.a)
79         && nearly_equal(x.b, y.b)
80         && nearly_equal(x.c, y.c)
81         && nearly_equal(x.d, y.d)
82         && nearly_equal(x.e, y.e)
83         && nearly_equal(x.f, y.f);
84 }
85 
nearly_equal(const skcms_Matrix3x3 & a,const skcms_Matrix3x3 & b)86 static bool nearly_equal(const skcms_Matrix3x3& a, const skcms_Matrix3x3& b) {
87     for (int i = 0; i < 3; i++)
88     for (int j = 0; j < 3; j++) {
89         if (!nearly_equal(a.vals[i][j], b.vals[i][j])) return false;
90     }
91     return true;
92 }
93 
94 namespace SkNDKConversions {
toDataSpace(SkColorSpace * cs)95     ADataSpace toDataSpace(SkColorSpace* cs) {
96         if (!cs) return ADATASPACE_SRGB;
97 
98         skcms_TransferFunction fn;
99         skcms_Matrix3x3 gamut;
100         if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&gamut)) {
101             for (const auto& entry : gColorSpaceTable) {
102                 if (nearly_equal(gamut, entry.gamut) && nearly_equal(fn, entry.transferFunction)) {
103                     return entry.dataSpace;
104                 }
105             }
106         }
107         return ADATASPACE_UNKNOWN;
108     }
109 
toColorSpace(ADataSpace dataSpace)110     sk_sp<SkColorSpace> toColorSpace(ADataSpace dataSpace) {
111         for (const auto& entry : gColorSpaceTable) {
112             if (entry.dataSpace == dataSpace) {
113                 return SkColorSpace::MakeRGB(entry.transferFunction, entry.gamut);
114             }
115         }
116         return nullptr;
117     }
118 }
119 
120