Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/core/SkColorSpaceXform.cpp

Issue 2130013002: Make all color xforms 'fast' (step 1) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Need to round to pass tests Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | src/core/SkOpts.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkOpts.h" 11 #include "SkOpts.h"
12 #include "SkSRGB.h" 12 #include "SkSRGB.h"
13 13
14 static inline bool compute_gamut_xform(SkMatrix44* srcToDst, const SkMatrix44& s rcToXYZ, 14 static constexpr float sk_linear_from_2dot2[256] = {
15 const SkMatrix44& dstToXYZ) {
16 if (!dstToXYZ.invert(srcToDst)) {
17 return false;
18 }
19
20 srcToDst->postConcat(srcToXYZ);
21 return true;
22 }
23
24 std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa ce>& srcSpace,
25 const sk_sp<SkColorSpa ce>& dstSpace) {
26 if (!srcSpace || !dstSpace) {
27 // Invalid input
28 return nullptr;
29 }
30
31 if (as_CSB(dstSpace)->colorLUT()) {
32 // It would be really weird for a dst profile to have a color LUT. I do n't think
33 // we need to support this.
34 return nullptr;
35 }
36
37 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor);
38 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) {
39 return nullptr;
40 }
41
42 if (0.0f == srcToDst.getFloat(3, 0) &&
43 0.0f == srcToDst.getFloat(3, 1) &&
44 0.0f == srcToDst.getFloat(3, 2) &&
45 !as_CSB(srcSpace)->colorLUT())
46 {
47 switch (srcSpace->gammaNamed()) {
48 case SkColorSpace::kSRGB_GammaNamed:
49 if (SkColorSpace::kSRGB_GammaNamed == dstSpace->gammaNamed()) {
50 return std::unique_ptr<SkColorSpaceXform>(
51 new SkFastXform<SkColorSpace::kSRGB_GammaNamed,
52 SkColorSpace::kSRGB_GammaNamed>(srcT oDst));
53 } else if (SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gam maNamed()) {
54 return std::unique_ptr<SkColorSpaceXform>(
55 new SkFastXform<SkColorSpace::kSRGB_GammaNamed,
56 SkColorSpace::k2Dot2Curve_GammaNamed >(srcToDst));
57 }
58 break;
59 case SkColorSpace::k2Dot2Curve_GammaNamed:
60 if (SkColorSpace::kSRGB_GammaNamed == dstSpace->gammaNamed()) {
61 return std::unique_ptr<SkColorSpaceXform>(
62 new SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed ,
63 SkColorSpace::kSRGB_GammaNamed>(srcT oDst));
64 } else if (SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gam maNamed()) {
65 return std::unique_ptr<SkColorSpaceXform>(
66 new SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed ,
67 SkColorSpace::k2Dot2Curve_GammaNamed >(srcToDst));
68 }
69 break;
70 default:
71 break;
72 }
73 }
74
75 return std::unique_ptr<SkColorSpaceXform>(new SkDefaultXform(srcSpace, srcTo Dst, dstSpace));
76 }
77
78 //////////////////////////////////////////////////////////////////////////////// ///////////////////
79
80 static void build_src_to_dst(float srcToDstArray[12], const SkMatrix44& srcToDst Matrix) {
81 // Build the following row major matrix:
82 // rX gX bX 0
83 // rY gY bY 0
84 // rZ gZ bZ 0
85 // Swap R and B if necessary to make sure that we output SkPMColor order.
86 #ifdef SK_PMCOLOR_IS_BGRA
87 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 2);
88 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1);
89 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 0);
90 srcToDstArray[3] = 0.0f;
91 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 2);
92 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1);
93 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 0);
94 srcToDstArray[7] = 0.0f;
95 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 2);
96 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1);
97 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 0);
98 srcToDstArray[11] = 0.0f;
99 #else
100 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 0);
101 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1);
102 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 2);
103 srcToDstArray[3] = 0.0f;
104 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 0);
105 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1);
106 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 2);
107 srcToDstArray[7] = 0.0f;
108 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 0);
109 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1);
110 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 2);
111 srcToDstArray[11] = 0.0f;
112 #endif
113 }
114
115 template <SkColorSpace::GammaNamed Src, SkColorSpace::GammaNamed Dst>
116 SkFastXform<Src, Dst>::SkFastXform(const SkMatrix44& srcToDst)
117 {
118 build_src_to_dst(fSrcToDst, srcToDst);
119 }
120
121 template <>
122 void SkFastXform<SkColorSpace::kSRGB_GammaNamed, SkColorSpace::kSRGB_GammaNamed>
123 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
124 {
125 SkOpts::color_xform_RGB1_srgb_to_srgb(dst, src, len, fSrcToDst);
126 }
127
128 template <>
129 void SkFastXform<SkColorSpace::kSRGB_GammaNamed, SkColorSpace::k2Dot2Curve_Gamma Named>
130 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
131 {
132 SkOpts::color_xform_RGB1_srgb_to_2dot2(dst, src, len, fSrcToDst);
133 }
134
135 template <>
136 void SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed, SkColorSpace::kSRGB_Gamma Named>
137 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
138 {
139 SkOpts::color_xform_RGB1_2dot2_to_srgb(dst, src, len, fSrcToDst);
140 }
141
142 template <>
143 void SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed, SkColorSpace::k2Dot2Curve _GammaNamed>
144 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
145 {
146 SkOpts::color_xform_RGB1_2dot2_to_2dot2(dst, src, len, fSrcToDst);
147 }
148
149 //////////////////////////////////////////////////////////////////////////////// ///////////////////
150
151 extern const float sk_linear_from_2dot2[256] = {
152 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.0 00056921765712193f, 15 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.0 00056921765712193f,
153 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.0 00367136269815943f, 16 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.0 00367136269815943f,
154 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.0 00992374304074325f, 17 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.0 00992374304074325f,
155 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.0 01963416213396470f, 18 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.0 01963416213396470f,
156 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.0 03302703032003640f, 19 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.0 03302703032003640f,
157 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.0 05028203456855540f, 20 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.0 05028203456855540f,
158 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.0 07155037004573030f, 21 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.0 07155037004573030f,
159 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.0 09696328701658230f, 22 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.0 09696328701658230f,
160 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.0 12663720031582100f, 23 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.0 12663720031582100f,
161 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.0 16067700890886900f, 24 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.0 16067700890886900f,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Y = eX + f otherwise 111 // Y = eX + f otherwise
249 for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 112 for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) {
250 if (x >= d) { 113 if (x >= d) {
251 *outTable++ = powf(a * x + b, g) + c; 114 *outTable++ = powf(a * x + b, g) + c;
252 } else { 115 } else {
253 *outTable++ = e * x + f; 116 *outTable++ = e * x + f;
254 } 117 }
255 } 118 }
256 } 119 }
257 120
121 static inline bool compute_gamut_xform(SkMatrix44* srcToDst, const SkMatrix44& s rcToXYZ,
122 const SkMatrix44& dstToXYZ) {
123 if (!dstToXYZ.invert(srcToDst)) {
124 return false;
125 }
126
127 srcToDst->postConcat(srcToXYZ);
128 return true;
129 }
130
131 //////////////////////////////////////////////////////////////////////////////// ///////////////////
132
258 static constexpr uint8_t linear_to_srgb[1024] = { 133 static constexpr uint8_t linear_to_srgb[1024] = {
259 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 3 1, 32, 34, 35, 134 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 3 1, 32, 34, 35,
260 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4 9, 50, 51, 52, 135 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4 9, 50, 51, 52,
261 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61, 61, 62, 6 2, 63, 64, 64, 136 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61, 61, 62, 6 2, 63, 64, 64,
262 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, 71, 71, 72, 72, 7 3, 73, 74, 74, 137 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, 71, 71, 72, 72, 7 3, 73, 74, 74,
263 75, 76, 76, 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 8 2, 82, 83, 83, 138 75, 76, 76, 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 8 2, 82, 83, 83,
264 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 9 0, 90, 91, 91, 139 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 9 0, 90, 91, 91,
265 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 9 7, 97, 98, 98, 140 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 9 7, 97, 98, 98,
266 98, 99, 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 10 3, 104, 104, 104, 141 98, 99, 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 10 3, 104, 104, 104,
267 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 11 0, 110, 110, 110, 142 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 11 0, 110, 110, 110,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 341
467 static void build_table_linear_to_gamma(uint8_t* outTable, int outTableSize, flo at g, float a, 342 static void build_table_linear_to_gamma(uint8_t* outTable, int outTableSize, flo at g, float a,
468 float b, float c, float d, float e, floa t f) { 343 float b, float c, float d, float e, floa t f) {
469 for (int i = 0; i < outTableSize; i++) { 344 for (int i = 0; i < outTableSize; i++) {
470 float x = ((float) i) * (1.0f / ((float) (outTableSize - 1))); 345 float x = ((float) i) * (1.0f / ((float) (outTableSize - 1)));
471 float y = inverse_parametric(x, g, a, b, c, d, e, f); 346 float y = inverse_parametric(x, g, a, b, c, d, e, f);
472 outTable[i] = clamp_normalized_float_to_byte(y); 347 outTable[i] = clamp_normalized_float_to_byte(y);
473 } 348 }
474 } 349 }
475 350
351 //////////////////////////////////////////////////////////////////////////////// ///////////////////
352
353 std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa ce>& srcSpace,
354 const sk_sp<SkColorSpa ce>& dstSpace) {
355 if (!srcSpace || !dstSpace) {
356 // Invalid input
357 return nullptr;
358 }
359
360 if (as_CSB(dstSpace)->colorLUT()) {
361 // It would be really weird for a dst profile to have a color LUT. I do n't think
362 // we need to support this.
363 return nullptr;
364 }
365
366 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor);
367 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) {
368 return nullptr;
369 }
370
371 if (0.0f == srcToDst.getFloat(3, 0) &&
372 0.0f == srcToDst.getFloat(3, 1) &&
373 0.0f == srcToDst.getFloat(3, 2) &&
374 !as_CSB(srcSpace)->colorLUT())
375 {
376 switch (dstSpace->gammaNamed()) {
377 case SkColorSpace::kSRGB_GammaNamed:
378 return std::unique_ptr<SkColorSpaceXform>(
379 new SkFastXform<SkColorSpace::kSRGB_GammaNamed>(srcSpace , srcToDst,
380 dstSpace ));
381 case SkColorSpace::k2Dot2Curve_GammaNamed:
382 return std::unique_ptr<SkColorSpaceXform>(
383 new SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed>(sr cSpace, srcToDst,
384 ds tSpace));
385 default:
386 return std::unique_ptr<SkColorSpaceXform>(
387 new SkFastXform<SkColorSpace::kNonStandard_GammaNamed>(s rcSpace, srcToDst,
388 d stSpace));
389 }
390 }
391
392 return std::unique_ptr<SkColorSpaceXform>(new SkDefaultXform(srcSpace, srcTo Dst, dstSpace));
393 }
394
395 //////////////////////////////////////////////////////////////////////////////// ///////////////////
396
397 static void build_src_to_dst(float srcToDstArray[12], const SkMatrix44& srcToDst Matrix) {
398 // Build the following row major matrix:
399 // rX gX bX 0
400 // rY gY bY 0
401 // rZ gZ bZ 0
402 // Swap R and B if necessary to make sure that we output SkPMColor order.
403 #ifdef SK_PMCOLOR_IS_BGRA
404 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 2);
405 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1);
406 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 0);
407 srcToDstArray[3] = 0.0f;
408 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 2);
409 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1);
410 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 0);
411 srcToDstArray[7] = 0.0f;
412 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 2);
413 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1);
414 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 0);
415 srcToDstArray[11] = 0.0f;
416 #else
417 srcToDstArray[0] = srcToDstMatrix.getFloat(0, 0);
418 srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1);
419 srcToDstArray[2] = srcToDstMatrix.getFloat(0, 2);
420 srcToDstArray[3] = 0.0f;
421 srcToDstArray[4] = srcToDstMatrix.getFloat(1, 0);
422 srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1);
423 srcToDstArray[6] = srcToDstMatrix.getFloat(1, 2);
424 srcToDstArray[7] = 0.0f;
425 srcToDstArray[8] = srcToDstMatrix.getFloat(2, 0);
426 srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1);
427 srcToDstArray[10] = srcToDstMatrix.getFloat(2, 2);
428 srcToDstArray[11] = 0.0f;
429 #endif
430 }
431
432 template <SkColorSpace::GammaNamed Dst>
433 SkFastXform<Dst>::SkFastXform(const sk_sp<SkColorSpace>& srcSpace, const SkMatri x44& srcToDst,
434 const sk_sp<SkColorSpace>& dstSpace)
435 {
436 build_src_to_dst(fSrcToDst, srcToDst);
437
438 // Build tables to transform src gamma to linear.
439 switch (srcSpace->gammaNamed()) {
440 case SkColorSpace::kSRGB_GammaNamed:
441 fSrcGammaTables[0] = fSrcGammaTables[1] = fSrcGammaTables[2] = sk_li near_from_srgb;
442 break;
443 case SkColorSpace::k2Dot2Curve_GammaNamed:
444 fSrcGammaTables[0] = fSrcGammaTables[1] = fSrcGammaTables[2] = sk_li near_from_2dot2;
445 break;
446 case SkColorSpace::kLinear_GammaNamed:
447 build_table_linear_from_gamma(fSrcGammaTableStorage, 1.0f);
448 fSrcGammaTables[0] = fSrcGammaTables[1] = fSrcGammaTables[2] = fSrcG ammaTableStorage;
449 break;
450 default: {
451 const SkGammas* gammas = as_CSB(srcSpace)->gammas();
452 SkASSERT(gammas);
453
454 for (int i = 0; i < 3; i++) {
455 const SkGammaCurve& curve = (*gammas)[i];
456
457 if (i > 0) {
458 // Check if this curve matches the first curve. In this cas e, we can
459 // share the same table pointer. Logically, this should alm ost always
460 // be true. I've never seen a profile where all three gamma curves
461 // didn't match. But it is possible that they won't.
462 // TODO (msarett):
463 // This comparison won't catch the case where each gamma cur ve has a
464 // pointer to its own look-up table, but the tables actually match.
465 // Should we perform a deep compare of gamma tables here? O r should
466 // we catch this when parsing the profile? Or should we not worry
467 // about a bit of redundant work?
468 if (curve.quickEquals((*gammas)[0])) {
469 fSrcGammaTables[i] = fSrcGammaTables[0];
470 continue;
471 }
472 }
473
474 if (curve.isNamed()) {
475 switch (curve.fNamed) {
476 case SkColorSpace::kSRGB_GammaNamed:
477 fSrcGammaTables[i] = sk_linear_from_srgb;
478 break;
479 case SkColorSpace::k2Dot2Curve_GammaNamed:
480 fSrcGammaTables[i] = sk_linear_from_2dot2;
481 break;
482 case SkColorSpace::kLinear_GammaNamed:
483 build_table_linear_from_gamma(&fSrcGammaTableStorage [i * 256], 1.0f);
484 fSrcGammaTables[i] = &fSrcGammaTableStorage[i * 256] ;
485 break;
486 default:
487 SkASSERT(false);
488 break;
489 }
490 } else if (curve.isValue()) {
491 build_table_linear_from_gamma(&fSrcGammaTableStorage[i * 256 ], curve.fValue);
492 fSrcGammaTables[i] = &fSrcGammaTableStorage[i * 256];
493 } else if (curve.isTable()) {
494 build_table_linear_from_gamma(&fSrcGammaTableStorage[i * 256 ],
495 curve.fTable.get(), curve.fTab leSize);
496 fSrcGammaTables[i] = &fSrcGammaTableStorage[i * 256];
497 } else {
498 SkASSERT(curve.isParametric());
499 build_table_linear_from_gamma(&fSrcGammaTableStorage[i * 256 ], curve.fG,
500 curve.fA, curve.fB, curve.fC, curve.fD, curve.fE,
501 curve.fF);
502 fSrcGammaTables[i] = &fSrcGammaTableStorage[i * 256];
503 }
504 }
505 }
506 }
507
508 // Build tables to transform linear to dst gamma.
509 switch (dstSpace->gammaNamed()) {
510 case SkColorSpace::kSRGB_GammaNamed:
511 case SkColorSpace::k2Dot2Curve_GammaNamed:
512 break;
513 case SkColorSpace::kLinear_GammaNamed:
514 build_table_linear_to_gamma(fDstGammaTableStorage, kDstGammaTableSiz e, 1.0f);
515 fDstGammaTables[0] = fDstGammaTables[1] = fDstGammaTables[2] = fDstG ammaTableStorage;
516 break;
517 default: {
518 const SkGammas* gammas = as_CSB(dstSpace)->gammas();
519 SkASSERT(gammas);
520
521 for (int i = 0; i < 3; i++) {
522 const SkGammaCurve& curve = (*gammas)[i];
523
524 if (i > 0) {
525 // Check if this curve matches the first curve. In this cas e, we can
526 // share the same table pointer. Logically, this should alm ost always
527 // be true. I've never seen a profile where all three gamma curves
528 // didn't match. But it is possible that they won't.
529 // TODO (msarett):
530 // This comparison won't catch the case where each gamma cur ve has a
531 // pointer to its own look-up table (but the tables actually match).
532 // Should we perform a deep compare of gamma tables here? O r should
533 // we catch this when parsing the profile? Or should we not worry
534 // about a bit of redundant work?
535 if (curve.quickEquals((*gammas)[0])) {
536 fDstGammaTables[i] = fDstGammaTables[0];
537 continue;
538 }
539 }
540
541 if (curve.isNamed()) {
542 switch (curve.fNamed) {
543 case SkColorSpace::kSRGB_GammaNamed:
544 fDstGammaTables[i] = linear_to_srgb;
545 break;
546 case SkColorSpace::k2Dot2Curve_GammaNamed:
547 fDstGammaTables[i] = linear_to_2dot2;
548 break;
549 case SkColorSpace::kLinear_GammaNamed:
550 build_table_linear_to_gamma(
551 &fDstGammaTableStorage[i * kDstGammaTableSiz e],
552 kDstGammaTableSize, 1.0f);
553 fDstGammaTables[i] = &fDstGammaTableStorage[i * kDst GammaTableSize];
554 break;
555 default:
556 SkASSERT(false);
557 break;
558 }
559 } else if (curve.isValue()) {
560 build_table_linear_to_gamma(&fDstGammaTableStorage[i * kDstG ammaTableSize],
561 kDstGammaTableSize, curve.fValue );
562 fDstGammaTables[i] = &fDstGammaTableStorage[i * kDstGammaTab leSize];
563 } else if (curve.isTable()) {
564 build_table_linear_to_gamma(&fDstGammaTableStorage[i * kDstG ammaTableSize],
565 kDstGammaTableSize, curve.fTable .get(),
566 curve.fTableSize);
567 fDstGammaTables[i] = &fDstGammaTableStorage[i * kDstGammaTab leSize];
568 } else {
569 SkASSERT(curve.isParametric());
570 build_table_linear_to_gamma(&fDstGammaTableStorage[i * kDstG ammaTableSize],
571 kDstGammaTableSize, curve.fG, cu rve.fA, curve.fB,
572 curve.fC, curve.fD, curve.fE, cu rve.fF);
573 fDstGammaTables[i] = &fDstGammaTableStorage[i * kDstGammaTab leSize];
574 }
575 }
576 }
577 }
578 }
579
580 template <>
581 void SkFastXform<SkColorSpace::kSRGB_GammaNamed>
582 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
583 {
584 SkOpts::color_xform_RGB1_to_srgb(dst, src, len, fSrcGammaTables, fSrcToDst);
585 }
586
587 template <>
588 void SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed>
589 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
590 {
591 SkOpts::color_xform_RGB1_to_2dot2(dst, src, len, fSrcGammaTables, fSrcToDst) ;
592 }
593
594 template <>
595 void SkFastXform<SkColorSpace::kNonStandard_GammaNamed>
596 ::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const
597 {
598 SkOpts::color_xform_RGB1_to_table(dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables);
599 }
600
601 //////////////////////////////////////////////////////////////////////////////// ///////////////////
602
476 SkDefaultXform::SkDefaultXform(const sk_sp<SkColorSpace>& srcSpace, const SkMatr ix44& srcToDst, 603 SkDefaultXform::SkDefaultXform(const sk_sp<SkColorSpace>& srcSpace, const SkMatr ix44& srcToDst,
477 const sk_sp<SkColorSpace>& dstSpace) 604 const sk_sp<SkColorSpace>& dstSpace)
478 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT())) 605 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
479 , fSrcToDst(srcToDst) 606 , fSrcToDst(srcToDst)
480 { 607 {
481 // Build tables to transform src gamma to linear. 608 // Build tables to transform src gamma to linear.
482 switch (srcSpace->gammaNamed()) { 609 switch (srcSpace->gammaNamed()) {
483 case SkColorSpace::kSRGB_GammaNamed: 610 case SkColorSpace::kSRGB_GammaNamed:
484 fSrcGammaTables[0] = fSrcGammaTables[1] = fSrcGammaTables[2] = sk_li near_from_srgb; 611 fSrcGammaTables[0] = fSrcGammaTables[1] = fSrcGammaTables[2] = sk_li near_from_srgb;
485 break; 612 break;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 r = fDstGammaTables[0][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[0])]; 905 r = fDstGammaTables[0][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[0])];
779 g = fDstGammaTables[1][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[1])]; 906 g = fDstGammaTables[1][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[1])];
780 b = fDstGammaTables[2][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[2])]; 907 b = fDstGammaTables[2][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[2])];
781 908
782 *dst = SkPackARGB32NoCheck(0xFF, r, g, b); 909 *dst = SkPackARGB32NoCheck(0xFF, r, g, b);
783 910
784 dst++; 911 dst++;
785 src++; 912 src++;
786 } 913 }
787 } 914 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | src/core/SkOpts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698