OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkColorSpace_Base.h" | 9 #include "SkColorSpace_Base.h" |
10 #include "SkColorSpaceXform.h" | 10 #include "SkColorSpaceXform.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 if (as_CSB(srcSpace)->colorLUT() || as_CSB(dstSpace)->colorLUT()) { | 30 if (as_CSB(srcSpace)->colorLUT() || as_CSB(dstSpace)->colorLUT()) { |
31 // Unimplemented | 31 // Unimplemented |
32 return nullptr; | 32 return nullptr; |
33 } | 33 } |
34 | 34 |
35 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); | 35 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); |
36 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) { | 36 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) { |
37 return nullptr; | 37 return nullptr; |
38 } | 38 } |
39 | 39 |
40 if (SkColorSpace::k2Dot2Curve_GammaNamed == srcSpace->gammaNamed() && | 40 if (SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gammaNamed() && |
41 SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gammaNamed()) | 41 0.0f == srcToDst.getFloat(3, 0) && |
| 42 0.0f == srcToDst.getFloat(3, 1) && |
| 43 0.0f == srcToDst.getFloat(3, 2)) |
42 { | 44 { |
43 return std::unique_ptr<SkColorSpaceXform>(new Sk2Dot2Xform(srcToDst)); | 45 if (SkColorSpace::kSRGB_GammaNamed == srcSpace->gammaNamed()) { |
| 46 return std::unique_ptr<SkColorSpaceXform>(new SkSRGBTo2Dot2Xform(src
ToDst)); |
| 47 } else if (SkColorSpace::k2Dot2Curve_GammaNamed == srcSpace->gammaNamed(
)) { |
| 48 return std::unique_ptr<SkColorSpaceXform>(new Sk2Dot2To2Dot2Xform(sr
cToDst)); |
| 49 } |
44 } | 50 } |
45 | 51 |
46 return std::unique_ptr<SkColorSpaceXform>( | 52 return std::unique_ptr<SkColorSpaceXform>( |
47 new SkDefaultXform(as_CSB(srcSpace)->gammas(), srcToDst, as_CSB(dstS
pace)->gammas())); | 53 new SkDefaultXform(as_CSB(srcSpace)->gammas(), srcToDst, as_CSB(dstS
pace)->gammas())); |
48 } | 54 } |
49 | 55 |
50 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 56 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
51 | 57 |
52 Sk2Dot2Xform::Sk2Dot2Xform(const SkMatrix44& srcToDst) | 58 static void build_src_to_dst(float srcToDstArray[12], const SkMatrix44& srcToDst
Matrix) { |
53 { | 59 // Build the following row major matrix: |
54 // Build row major 4x4 matrix: | |
55 // rX gX bX 0 | 60 // rX gX bX 0 |
56 // rY gY bY 0 | 61 // rY gY bY 0 |
57 // rZ gZ bZ 0 | 62 // rZ gZ bZ 0 |
58 // rQ gQ bQ 0 | 63 // Swap R and B if necessary to make sure that we output SkPMColor order. |
59 fSrcToDst[0] = srcToDst.getFloat(0, 0); | 64 #ifdef SK_PMCOLOR_IS_BGRA |
60 fSrcToDst[1] = srcToDst.getFloat(0, 1); | 65 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 2); |
61 fSrcToDst[2] = srcToDst.getFloat(0, 2); | 66 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1); |
62 fSrcToDst[3] = 0.0f; | 67 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 0); |
63 fSrcToDst[4] = srcToDst.getFloat(1, 0); | 68 srcToDstArray[3] = 0.0f; |
64 fSrcToDst[5] = srcToDst.getFloat(1, 1); | 69 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 2); |
65 fSrcToDst[6] = srcToDst.getFloat(1, 2); | 70 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1); |
66 fSrcToDst[7] = 0.0f; | 71 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 0); |
67 fSrcToDst[8] = srcToDst.getFloat(2, 0); | 72 srcToDstArray[7] = 0.0f; |
68 fSrcToDst[9] = srcToDst.getFloat(2, 1); | 73 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 2); |
69 fSrcToDst[10] = srcToDst.getFloat(2, 2); | 74 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1); |
70 fSrcToDst[11] = 0.0f; | 75 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 0); |
71 fSrcToDst[12] = srcToDst.getFloat(3, 0); | 76 srcToDstArray[11] = 0.0f; |
72 fSrcToDst[13] = srcToDst.getFloat(3, 1); | 77 #else |
73 fSrcToDst[14] = srcToDst.getFloat(3, 2); | 78 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 0); |
74 fSrcToDst[15] = 0.0f; | 79 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1); |
| 80 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 2); |
| 81 srcToDstArray[3] = 0.0f; |
| 82 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 0); |
| 83 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1); |
| 84 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 2); |
| 85 srcToDstArray[7] = 0.0f; |
| 86 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 0); |
| 87 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1); |
| 88 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 2); |
| 89 srcToDstArray[11] = 0.0f; |
| 90 #endif |
75 } | 91 } |
76 | 92 |
77 void Sk2Dot2Xform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t
len) const { | 93 SkSRGBTo2Dot2Xform::SkSRGBTo2Dot2Xform(const SkMatrix44& srcToDst) |
78 SkOpts::color_xform_2Dot2_RGBA_to_8888(dst, src, len, fSrcToDst); | 94 { |
| 95 build_src_to_dst(fSrcToDst, srcToDst); |
| 96 } |
| 97 |
| 98 void SkSRGBTo2Dot2Xform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uin
t32_t len) const { |
| 99 SkOpts::color_xform_RGB1_srgb_to_2dot2(dst, src, len, fSrcToDst); |
79 } | 100 } |
80 | 101 |
81 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 102 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 103 |
| 104 Sk2Dot2To2Dot2Xform::Sk2Dot2To2Dot2Xform(const SkMatrix44& srcToDst) |
| 105 { |
| 106 build_src_to_dst(fSrcToDst, srcToDst); |
| 107 } |
| 108 |
| 109 void Sk2Dot2To2Dot2Xform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, ui
nt32_t len) const { |
| 110 SkOpts::color_xform_RGB1_2dot2_to_2dot2(dst, src, len, fSrcToDst); |
| 111 } |
| 112 |
| 113 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
82 | 114 |
83 static inline float byte_to_float(uint8_t v) { | 115 static inline float byte_to_float(uint8_t v) { |
84 return ((float) v) * (1.0f / 255.0f); | 116 return ((float) v) * (1.0f / 255.0f); |
85 } | 117 } |
86 | 118 |
87 // Expand range from 0-1 to 0-255, then convert. | 119 // Expand range from 0-1 to 0-255, then convert. |
88 static inline uint8_t clamp_normalized_float_to_byte(float v) { | 120 static inline uint8_t clamp_normalized_float_to_byte(float v) { |
| 121 // The ordering of the logic is a little strange here in order |
| 122 // to make sure we convert NaNs to 0. |
89 v = v * 255.0f; | 123 v = v * 255.0f; |
90 if (v >= 254.5f) { | 124 if (v >= 254.5f) { |
91 return 255; | 125 return 255; |
92 } else if (v < 0.5f) { | 126 } else if (v >= 0.5f) { |
| 127 return (uint8_t) (v + 0.5f); |
| 128 } else { |
93 return 0; | 129 return 0; |
94 } else { | |
95 return (uint8_t) (v + 0.5f); | |
96 } | 130 } |
97 } | 131 } |
98 | 132 |
99 // Interpolating lookup in a variably sized table. | 133 // Interpolating lookup in a variably sized table. |
100 static inline float interp_lut(uint8_t byte, float* table, size_t tableSize) { | 134 static inline float interp_lut(uint8_t byte, float* table, size_t tableSize) { |
101 float index = byte_to_float(byte) * (tableSize - 1); | 135 float index = byte_to_float(byte) * (tableSize - 1); |
102 float diff = index - sk_float_floor2int(index); | 136 float diff = index - sk_float_floor2int(index); |
103 return table[(int) sk_float_floor2int(index)] * (1.0f - diff) + | 137 return table[(int) sk_float_floor2int(index)] * (1.0f - diff) + |
104 table[(int) sk_float_ceil2int(index)] * diff; | 138 table[(int) sk_float_ceil2int(index)] * diff; |
105 } | 139 } |
(...skipping 29 matching lines...) Expand all Loading... |
135 return 0.0f; | 169 return 0.0f; |
136 } | 170 } |
137 | 171 |
138 SkDefaultXform::SkDefaultXform(const sk_sp<SkGammas>& srcGammas, const SkMatrix4
4& srcToDst, | 172 SkDefaultXform::SkDefaultXform(const sk_sp<SkGammas>& srcGammas, const SkMatrix4
4& srcToDst, |
139 const sk_sp<SkGammas>& dstGammas) | 173 const sk_sp<SkGammas>& dstGammas) |
140 : fSrcGammas(srcGammas) | 174 : fSrcGammas(srcGammas) |
141 , fSrcToDst(srcToDst) | 175 , fSrcToDst(srcToDst) |
142 , fDstGammas(dstGammas) | 176 , fDstGammas(dstGammas) |
143 {} | 177 {} |
144 | 178 |
145 void SkDefaultXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_
t len) const { | 179 void SkDefaultXform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_
t len) const { |
146 while (len-- > 0) { | 180 while (len-- > 0) { |
147 // Convert to linear. | 181 // Convert to linear. |
148 // FIXME (msarett): | 182 // FIXME (msarett): |
149 // Rather than support three different strategies of transforming gamma,
QCMS | 183 // Rather than support three different strategies of transforming gamma,
QCMS |
150 // builds a 256 entry float lookup table from the gamma info. This hand
les | 184 // builds a 256 entry float lookup table from the gamma info. This hand
les |
151 // the gamma transform and the conversion from bytes to floats. This ma
y | 185 // the gamma transform and the conversion from bytes to floats. This ma
y |
152 // be simpler and faster than our current approach. | 186 // be simpler and faster than our current approach. |
153 float srcFloats[3]; | 187 float srcFloats[3]; |
154 for (int i = 0; i < 3; i++) { | 188 for (int i = 0; i < 3; i++) { |
155 const SkGammaCurve& gamma = (*fSrcGammas)[i]; | 189 const SkGammaCurve& gamma = (*fSrcGammas)[i]; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 | 270 |
237 *dst = SkPackARGB32NoCheck(((*src >> 24) & 0xFF), | 271 *dst = SkPackARGB32NoCheck(((*src >> 24) & 0xFF), |
238 clamp_normalized_float_to_byte(dstFloats[0]), | 272 clamp_normalized_float_to_byte(dstFloats[0]), |
239 clamp_normalized_float_to_byte(dstFloats[1]), | 273 clamp_normalized_float_to_byte(dstFloats[1]), |
240 clamp_normalized_float_to_byte(dstFloats[2]))
; | 274 clamp_normalized_float_to_byte(dstFloats[2]))
; |
241 | 275 |
242 dst++; | 276 dst++; |
243 src++; | 277 src++; |
244 } | 278 } |
245 } | 279 } |
OLD | NEW |