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

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

Issue 2177173003: Delete SkDefaultXform, handle edge cases in SkColorSpaceXform_Base (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Use less space on Google3 Created 4 years, 4 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/opts/SkColorXform_opts.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"
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 v = v * 255.0f; 257 v = v * 255.0f;
258 if (v >= 254.5f) { 258 if (v >= 254.5f) {
259 return 255; 259 return 255;
260 } else if (v >= 0.5f) { 260 } else if (v >= 0.5f) {
261 return (uint8_t) (v + 0.5f); 261 return (uint8_t) (v + 0.5f);
262 } else { 262 } else {
263 return 0; 263 return 0;
264 } 264 }
265 } 265 }
266 266
267 static const int kDstGammaTableSize =
268 SkColorSpaceXform_Base<SkColorSpace::kNonStandard_GammaNamed>::kDstGamma TableSize;
269
267 static void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 270 static void build_table_linear_to_gamma(uint8_t* outTable, float exponent) {
268 float toGammaExp = 1.0f / exponent; 271 float toGammaExp = 1.0f / exponent;
269 272
270 for (int i = 0; i < SkDefaultXform::kDstGammaTableSize; i++) { 273 for (int i = 0; i < kDstGammaTableSize; i++) {
271 float x = ((float) i) * (1.0f / ((float) (SkDefaultXform::kDstGammaTable Size - 1))); 274 float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1)));
272 outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 275 outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp));
273 } 276 }
274 } 277 }
275 278
276 // Inverse table lookup. Ex: what index corresponds to the input value? This w ill 279 // Inverse table lookup. Ex: what index corresponds to the input value? This w ill
277 // have strange results when the table is non-increasing. But any sane gamma 280 // have strange results when the table is non-increasing. But any sane gamma
278 // function will be increasing. 281 // function will be increasing.
279 static float inverse_interp_lut(float input, const float* table, int tableSize) { 282 static float inverse_interp_lut(float input, const float* table, int tableSize) {
280 if (input <= table[0]) { 283 if (input <= table[0]) {
281 return table[0]; 284 return table[0];
(...skipping 12 matching lines...) Expand all
294 } 297 }
295 298
296 // Should be unreachable, since we'll return before the loop if input is 299 // Should be unreachable, since we'll return before the loop if input is
297 // larger than the last entry. 300 // larger than the last entry.
298 SkASSERT(false); 301 SkASSERT(false);
299 return 0.0f; 302 return 0.0f;
300 } 303 }
301 304
302 static void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 305 static void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable,
303 int inTableSize) { 306 int inTableSize) {
304 for (int i = 0; i < SkDefaultXform::kDstGammaTableSize; i++) { 307 for (int i = 0; i < kDstGammaTableSize; i++) {
305 float x = ((float) i) * (1.0f / ((float) (SkDefaultXform::kDstGammaTable Size - 1))); 308 float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1)));
306 float y = inverse_interp_lut(x, inTable, inTableSize); 309 float y = inverse_interp_lut(x, inTable, inTableSize);
307 outTable[i] = clamp_normalized_float_to_byte(y); 310 outTable[i] = clamp_normalized_float_to_byte(y);
308 } 311 }
309 } 312 }
310 313
311 static float inverse_parametric(float x, float g, float a, float b, float c, flo at d, float e, 314 static float inverse_parametric(float x, float g, float a, float b, float c, flo at d, float e,
312 float f) { 315 float f) {
313 // We need to take the inverse of the following piecewise function. 316 // We need to take the inverse of the following piecewise function.
314 // Y = (aX + b)^g + c for X >= d 317 // Y = (aX + b)^g + c for X >= d
315 // Y = eX + f otherwise 318 // Y = eX + f otherwise
(...skipping 18 matching lines...) Expand all
334 // The gamma curve for this segment is constant, so the inverse is undef ined. 337 // The gamma curve for this segment is constant, so the inverse is undef ined.
335 // Since this is the upper segment, guess one. 338 // Since this is the upper segment, guess one.
336 return 1.0f; 339 return 1.0f;
337 } 340 }
338 341
339 return (powf(x - c, 1.0f / g) - b) / a; 342 return (powf(x - c, 1.0f / g) - b) / a;
340 } 343 }
341 344
342 static void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 345 static void build_table_linear_to_gamma(uint8_t* outTable, float g, float a,
343 float b, float c, float d, float e, floa t f) { 346 float b, float c, float d, float e, floa t f) {
344 for (int i = 0; i < SkDefaultXform::kDstGammaTableSize; i++) { 347 for (int i = 0; i < kDstGammaTableSize; i++) {
345 float x = ((float) i) * (1.0f / ((float) (SkDefaultXform::kDstGammaTable Size - 1))); 348 float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1)));
346 float y = inverse_parametric(x, g, a, b, c, d, e, f); 349 float y = inverse_parametric(x, g, a, b, c, d, e, f);
347 outTable[i] = clamp_normalized_float_to_byte(y); 350 outTable[i] = clamp_normalized_float_to_byte(y);
348 } 351 }
349 } 352 }
350 353
351 //////////////////////////////////////////////////////////////////////////////// /////////////////// 354 //////////////////////////////////////////////////////////////////////////////// ///////////////////
352 355
353 template <typename T> 356 template <typename T>
354 struct GammaFns { 357 struct GammaFns {
355 const T* fSRGBTable; 358 const T* fSRGBTable;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 // It would be really weird for a dst profile to have a color LUT. I do n't think 460 // It would be really weird for a dst profile to have a color LUT. I do n't think
458 // we need to support this. 461 // we need to support this.
459 return nullptr; 462 return nullptr;
460 } 463 }
461 464
462 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 465 SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor);
463 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) { 466 if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) {
464 return nullptr; 467 return nullptr;
465 } 468 }
466 469
467 if (0.0f == srcToDst.getFloat(3, 0) && 470 switch (dstSpace->gammaNamed()) {
468 0.0f == srcToDst.getFloat(3, 1) && 471 case SkColorSpace::kSRGB_GammaNamed:
469 0.0f == srcToDst.getFloat(3, 2) && 472 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
470 !as_CSB(srcSpace)->colorLUT()) 473 <SkColorSpace::kSRGB_GammaNamed>(srcSpace, srcToDst, dstSpac e));
471 { 474 case SkColorSpace::k2Dot2Curve_GammaNamed:
472 switch (dstSpace->gammaNamed()) { 475 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
473 case SkColorSpace::kSRGB_GammaNamed: 476 <SkColorSpace::k2Dot2Curve_GammaNamed>(srcSpace, srcToDst, d stSpace));
474 return std::unique_ptr<SkColorSpaceXform>( 477 default:
475 new SkFastXform<SkColorSpace::kSRGB_GammaNamed>(srcSpace , srcToDst, 478 return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
476 dstSpace )); 479 <SkColorSpace::kNonStandard_GammaNamed>(srcSpace, srcToDst, dstSpace));
477 case SkColorSpace::k2Dot2Curve_GammaNamed:
478 return std::unique_ptr<SkColorSpaceXform>(
479 new SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed>(sr cSpace, srcToDst,
480 ds tSpace));
481 default:
482 return std::unique_ptr<SkColorSpaceXform>(
483 new SkFastXform<SkColorSpace::kNonStandard_GammaNamed>(s rcSpace, srcToDst,
484 d stSpace));
485 }
486 } 480 }
487
488 return std::unique_ptr<SkColorSpaceXform>(new SkDefaultXform(srcSpace, srcTo Dst, dstSpace));
489 } 481 }
490 482
491 //////////////////////////////////////////////////////////////////////////////// /////////////////// 483 //////////////////////////////////////////////////////////////////////////////// ///////////////////
492 484
493 template <SkColorSpace::GammaNamed Dst>
494 SkFastXform<Dst>::SkFastXform(const sk_sp<SkColorSpace>& srcSpace, const SkMatri x44& srcToDst,
495 const sk_sp<SkColorSpace>& dstSpace)
496 {
497 srcToDst.asRowMajorf(fSrcToDst);
498 build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kT oLinear);
499 build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, SkDefaultXform::k DstGammaTableSize,
500 dstSpace, kFromLinear);
501 }
502
503 template <>
504 void SkFastXform<SkColorSpace::kSRGB_GammaNamed>
505 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
506 {
507 SkOpts::color_xform_RGB1_to_srgb(dst, src, len, fSrcGammaTables, fSrcToDst);
508 }
509
510 template <>
511 void SkFastXform<SkColorSpace::k2Dot2Curve_GammaNamed>
512 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
513 {
514 SkOpts::color_xform_RGB1_to_2dot2(dst, src, len, fSrcGammaTables, fSrcToDst) ;
515 }
516
517 template <>
518 void SkFastXform<SkColorSpace::kNonStandard_GammaNamed>
519 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
520 {
521 SkOpts::color_xform_RGB1_to_table(dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables);
522 }
523
524 template <SkColorSpace::GammaNamed T>
525 void SkFastXform<T>
526 ::applyToF16(RGBAF16* dst, const RGBA32* src, int len) const
527 {
528 SkOpts::color_xform_RGB1_to_linear(dst, src, len, fSrcGammaTables, fSrcToDst );
529 }
530
531 //////////////////////////////////////////////////////////////////////////////// ///////////////////
532
533 SkDefaultXform::SkDefaultXform(const sk_sp<SkColorSpace>& srcSpace, const SkMatr ix44& srcToDst,
534 const sk_sp<SkColorSpace>& dstSpace)
535 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
536 , fSrcToDst(srcToDst)
537 {
538 build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kT oLinear);
539 build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, SkDefaultXform::k DstGammaTableSize,
540 dstSpace, kFromLinear);
541 }
542
543 static float byte_to_float(uint8_t byte) { 485 static float byte_to_float(uint8_t byte) {
544 return ((float) byte) * (1.0f / 255.0f); 486 return ((float) byte) * (1.0f / 255.0f);
545 } 487 }
546 488
547 // Clamp to the 0-1 range. 489 // Clamp to the 0-1 range.
548 static float clamp_normalized_float(float v) { 490 static float clamp_normalized_float(float v) {
549 if (v > 1.0f) { 491 if (v > 1.0f) {
550 return 1.0f; 492 return 1.0f;
551 } else if ((v < 0.0f) || (v != v)) { 493 } else if ((v < 0.0f) || (v != v)) {
552 return 0.0f; 494 return 0.0f;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 582 }
641 583
642 // Increment the table ptr in order to handle the next component. 584 // Increment the table ptr in order to handle the next component.
643 // Note that this is the how table is designed: all of nXXX 585 // Note that this is the how table is designed: all of nXXX
644 // variables are multiples of 3 because there are 3 output 586 // variables are multiples of 3 because there are 3 output
645 // components. 587 // components.
646 ptr++; 588 ptr++;
647 } 589 }
648 } 590 }
649 591
650 void SkDefaultXform::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) con st { 592 static void handle_color_lut(uint32_t* dst, const uint32_t* src, int len,
593 SkColorLookUpTable* colorLUT) {
651 while (len-- > 0) { 594 while (len-- > 0) {
652 uint8_t r = (*src >> 0) & 0xFF, 595 uint8_t r = (*src >> 0) & 0xFF,
653 g = (*src >> 8) & 0xFF, 596 g = (*src >> 8) & 0xFF,
654 b = (*src >> 16) & 0xFF; 597 b = (*src >> 16) & 0xFF;
655 598
656 if (fColorLUT) { 599 float in[3];
657 float in[3]; 600 float out[3];
658 float out[3]; 601 in[0] = byte_to_float(r);
602 in[1] = byte_to_float(g);
603 in[2] = byte_to_float(b);
604 interp_3d_clut(out, in, colorLUT);
659 605
660 in[0] = byte_to_float(r); 606 r = sk_float_round2int(255.0f * clamp_normalized_float(out[0]));
661 in[1] = byte_to_float(g); 607 g = sk_float_round2int(255.0f * clamp_normalized_float(out[1]));
662 in[2] = byte_to_float(b); 608 b = sk_float_round2int(255.0f * clamp_normalized_float(out[2]));
609 *dst = SkPackARGB_as_RGBA(0xFF, r, g, b);
663 610
664 interp_3d_clut(out, in, fColorLUT.get()); 611 src++;
665
666 r = sk_float_round2int(255.0f * clamp_normalized_float(out[0]));
667 g = sk_float_round2int(255.0f * clamp_normalized_float(out[1]));
668 b = sk_float_round2int(255.0f * clamp_normalized_float(out[2]));
669 }
670
671 // Convert to linear.
672 float srcFloats[3];
673 srcFloats[0] = fSrcGammaTables[0][r];
674 srcFloats[1] = fSrcGammaTables[1][g];
675 srcFloats[2] = fSrcGammaTables[2][b];
676
677 // Convert to dst gamut.
678 float dstFloats[3];
679 dstFloats[0] = srcFloats[0] * fSrcToDst.getFloat(0, 0) +
680 srcFloats[1] * fSrcToDst.getFloat(1, 0) +
681 srcFloats[2] * fSrcToDst.getFloat(2, 0) + fSrcToDst.getFl oat(3, 0);
682 dstFloats[1] = srcFloats[0] * fSrcToDst.getFloat(0, 1) +
683 srcFloats[1] * fSrcToDst.getFloat(1, 1) +
684 srcFloats[2] * fSrcToDst.getFloat(2, 1) + fSrcToDst.getFl oat(3, 1);
685 dstFloats[2] = srcFloats[0] * fSrcToDst.getFloat(0, 2) +
686 srcFloats[1] * fSrcToDst.getFloat(1, 2) +
687 srcFloats[2] * fSrcToDst.getFloat(2, 2) + fSrcToDst.getFl oat(3, 2);
688
689 // Clamp to 0-1.
690 dstFloats[0] = clamp_normalized_float(dstFloats[0]);
691 dstFloats[1] = clamp_normalized_float(dstFloats[1]);
692 dstFloats[2] = clamp_normalized_float(dstFloats[2]);
693
694 // Convert to dst gamma.
695 r = fDstGammaTables[0][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[0])];
696 g = fDstGammaTables[1][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[1])];
697 b = fDstGammaTables[2][sk_float_round2int((kDstGammaTableSize - 1) * dst Floats[2])];
698
699 *dst = SkPackARGB32NoCheck(0xFF, r, g, b);
700
701 dst++; 612 dst++;
702 src++;
703 } 613 }
704 } 614 }
705 615
706 void SkDefaultXform::applyToF16(RGBAF16* dst, const RGBA32* src, int len) const { 616 //////////////////////////////////////////////////////////////////////////////// ///////////////////
707 // FIXME (msarett): 617
708 // Planning to delete SkDefaultXform. Not going to bother to implement this . 618 template <SkColorSpace::GammaNamed Dst>
709 memset(dst, 0, len * sizeof(RGBAF16)); 619 SkColorSpaceXform_Base<Dst>::SkColorSpaceXform_Base(const sk_sp<SkColorSpace>& s rcSpace,
620 const SkMatrix44& srcToDst,
621 const sk_sp<SkColorSpace>& d stSpace)
622 : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
623 {
624 srcToDst.asRowMajorf(fSrcToDst);
625 build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kT oLinear);
626 build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, kDstGammaTableSiz e,
627 dstSpace, kFromLinear);
710 } 628 }
629
630 template <>
631 void SkColorSpaceXform_Base<SkColorSpace::kSRGB_GammaNamed>
632 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
633 {
634 if (fColorLUT) {
635 handle_color_lut(dst, src, len, fColorLUT.get());
636 src = dst;
637 }
638
639 SkOpts::color_xform_RGB1_to_srgb(dst, src, len, fSrcGammaTables, fSrcToDst);
640 }
641
642 template <>
643 void SkColorSpaceXform_Base<SkColorSpace::k2Dot2Curve_GammaNamed>
644 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
645 {
646 if (fColorLUT) {
647 handle_color_lut(dst, src, len, fColorLUT.get());
648 src = dst;
649 }
650
651 SkOpts::color_xform_RGB1_to_2dot2(dst, src, len, fSrcGammaTables, fSrcToDst) ;
652 }
653
654 template <>
655 void SkColorSpaceXform_Base<SkColorSpace::kNonStandard_GammaNamed>
656 ::applyTo8888(SkPMColor* dst, const RGBA32* src, int len) const
657 {
658 if (fColorLUT) {
659 handle_color_lut(dst, src, len, fColorLUT.get());
660 src = dst;
661 }
662
663 SkOpts::color_xform_RGB1_to_table(dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables);
664 }
665
666 template <SkColorSpace::GammaNamed T>
667 void SkColorSpaceXform_Base<T>
668 ::applyToF16(RGBAF16* dst, const RGBA32* src, int len) const
669 {
670 if (fColorLUT) {
671 size_t storageBytes = len * sizeof(RGBA32);
672 #if defined(GOOGLE3)
673 // Stack frame size is limited in GOOGLE3.
674 SkAutoSMalloc<256 * sizeof(RGBA32)> storage(storageBytes);
675 #else
676 SkAutoSMalloc<1024 * sizeof(RGBA32)> storage(storageBytes);
677 #endif
678
679 handle_color_lut((RGBA32*) storage.get(), src, len, fColorLUT.get());
680 src = (const RGBA32*) storage.get();
681 }
682
683 SkOpts::color_xform_RGB1_to_linear(dst, src, len, fSrcGammaTables, fSrcToDst );
684 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpaceXform.h ('k') | src/opts/SkColorXform_opts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698