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

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

Issue 1943833002: return 4x4 matrix from SkColorSpace (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 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
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 "SkAtomics.h" 8 #include "SkAtomics.h"
9 #include "SkColorSpace.h" 9 #include "SkColorSpace.h"
10 10
11 void SkFloat3::dump() const { 11 void SkFloat3::dump() const {
12 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]); 12 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]);
13 } 13 }
14 14
15 void SkFloat3x3::dump() const {
16 SkDebugf("[%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f]\n",
17 fMat[0], fMat[1], fMat[2],
18 fMat[3], fMat[4], fMat[5],
19 fMat[6], fMat[7], fMat[8]);
20 }
21
22 //////////////////////////////////////////////////////////////////////////////// ////////////////// 15 //////////////////////////////////////////////////////////////////////////////// //////////////////
23 16
24 static int32_t gUniqueColorSpaceID; 17 static int32_t gUniqueColorSpaceID;
25 18
26 SkColorSpace::SkColorSpace(const SkFloat3& gamma, const SkFloat3x3& toXYZD50, Na med named) 19 SkColorSpace::SkColorSpace(const SkFloat3& gamma, const SkMatrix44& toXYZD50, Na med named)
27 : fGamma(gamma) 20 : fGamma(gamma)
28 , fToXYZD50(toXYZD50) 21 , fToXYZD50(toXYZD50)
29 , fToXYZOffset({{ 0.0f, 0.0f, 0.0f }})
30 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 22 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
31 , fNamed(named) 23 , fNamed(named)
32 {} 24 {}
33 25
34 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, const SkFloat3& gamma, 26 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, const SkFloat3& gamma,
35 const SkFloat3x3& toXYZD50, const SkFloat3& toXYZOffs et) 27 const SkMatrix44& toXYZD50)
36 : fColorLUT(std::move(colorLUT)) 28 : fColorLUT(std::move(colorLUT))
37 , fGamma(gamma) 29 , fGamma(gamma)
38 , fToXYZD50(toXYZD50) 30 , fToXYZD50(toXYZD50)
39 , fToXYZOffset(toXYZOffset)
40 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 31 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
41 , fNamed(kUnknown_Named) 32 , fNamed(kUnknown_Named)
42 {} 33 {}
43 34
44 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, const SkFlo at3& gamma) { 35 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkMatrix44& toXYZD50, const SkFlo at3& gamma) {
45 return sk_sp<SkColorSpace>(new SkColorSpace(gamma, toXYZD50, kUnknown_Named) ); 36 return sk_sp<SkColorSpace>(new SkColorSpace(gamma, toXYZD50, kUnknown_Named) );
46 } 37 }
47 38
48 const SkFloat3 gSRGB_gamma {{ 2.2f, 2.2f, 2.2f }}; 39 const SkFloat3 gSRGB_gamma {{ 2.2f, 2.2f, 2.2f }};
49 const SkFloat3x3 gSRGB_toXYZD50 {{ 40 const float gSRGB_toXYZD50[9] {
50 0.4358f, 0.2224f, 0.0139f, // * R 41 0.4358f, 0.2224f, 0.0139f, // * R
51 0.3853f, 0.7170f, 0.0971f, // * G 42 0.3853f, 0.7170f, 0.0971f, // * G
52 0.1430f, 0.0606f, 0.7139f, // * B 43 0.1430f, 0.0606f, 0.7139f, // * B
53 }}; 44 };
54 45
55 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 46 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
56 switch (named) { 47 switch (named) {
57 case kSRGB_Named: 48 case kSRGB_Named: {
58 return sk_sp<SkColorSpace>(new SkColorSpace(gSRGB_gamma, gSRGB_toXYZ D50, kSRGB_Named)); 49 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
50 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
51 return sk_sp<SkColorSpace>(new SkColorSpace(gSRGB_gamma, srgbToxyzD5 0, kSRGB_Named));
52 }
59 default: 53 default:
60 break; 54 break;
61 } 55 }
62 return nullptr; 56 return nullptr;
63 } 57 }
64 58
65 //////////////////////////////////////////////////////////////////////////////// /////////////////// 59 //////////////////////////////////////////////////////////////////////////////// ///////////////////
66 60
67 #include "SkFixed.h" 61 #include "SkFixed.h"
68 #include "SkTemplates.h" 62 #include "SkTemplates.h"
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 if (1 == precision) { 407 if (1 == precision) {
414 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; 408 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f;
415 } else { 409 } else {
416 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f; 410 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f;
417 } 411 }
418 } 412 }
419 413
420 return true; 414 return true;
421 } 415 }
422 416
423 bool load_matrix(SkFloat3x3* toXYZ, SkFloat3* toXYZOffset, const uint8_t* src, s ize_t len) { 417 bool load_matrix(SkMatrix44* toXYZ, const uint8_t* src, size_t len) {
424 if (len < 48) { 418 if (len < 48) {
425 SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len); 419 SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len);
426 return false; 420 return false;
427 } 421 }
428 422
429 toXYZ->fMat[0] = SkFixedToFloat(read_big_endian_int(src)); 423 float array[16];
430 toXYZ->fMat[3] = SkFixedToFloat(read_big_endian_int(src + 4)); 424 array[ 0] = SkFixedToFloat(read_big_endian_int(src));
431 toXYZ->fMat[6] = SkFixedToFloat(read_big_endian_int(src + 8)); 425 array[ 1] = SkFixedToFloat(read_big_endian_int(src + 4));
432 toXYZ->fMat[1] = SkFixedToFloat(read_big_endian_int(src + 12)); 426 array[ 2] = SkFixedToFloat(read_big_endian_int(src + 8));
433 toXYZ->fMat[4] = SkFixedToFloat(read_big_endian_int(src + 16)); 427 array[ 3] = 0;
434 toXYZ->fMat[7] = SkFixedToFloat(read_big_endian_int(src + 20)); 428 array[ 4] = SkFixedToFloat(read_big_endian_int(src + 12));
435 toXYZ->fMat[2] = SkFixedToFloat(read_big_endian_int(src + 24)); 429 array[ 5] = SkFixedToFloat(read_big_endian_int(src + 16));
436 toXYZ->fMat[5] = SkFixedToFloat(read_big_endian_int(src + 28)); 430 array[ 6] = SkFixedToFloat(read_big_endian_int(src + 20));
437 toXYZ->fMat[8] = SkFixedToFloat(read_big_endian_int(src + 32)); 431 array[ 7] = 0;
438 toXYZOffset->fVec[0] = SkFixedToFloat(read_big_endian_int(src + 36)); 432 array[ 8] = SkFixedToFloat(read_big_endian_int(src + 24));
439 toXYZOffset->fVec[1] = SkFixedToFloat(read_big_endian_int(src + 40)); 433 array[ 9] = SkFixedToFloat(read_big_endian_int(src + 28));
440 toXYZOffset->fVec[2] = SkFixedToFloat(read_big_endian_int(src + 44)); 434 array[10] = SkFixedToFloat(read_big_endian_int(src + 32));
435 array[11] = 0;
436 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R
437 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G
438 array[14] = SkFixedToFloat(read_big_endian_int(src + 44));
439 array[15] = 1;
440 toXYZ->setColMajorf(array);
441 return true; 441 return true;
442 } 442 }
443 443
444 bool load_a2b0(SkColorLookUpTable* colorLUT, SkFloat3* gamma, SkFloat3x3* toXYZ, 444 bool load_a2b0(SkColorLookUpTable* colorLUT, SkFloat3* gamma, SkMatrix44* toXYZ,
445 SkFloat3* toXYZOffset, const uint8_t* src, size_t len) { 445 const uint8_t* src, size_t len) {
446 if (len < 32) { 446 if (len < 32) {
447 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); 447 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
448 return false; 448 return false;
449 } 449 }
450 450
451 uint32_t type = read_big_endian_uint(src); 451 uint32_t type = read_big_endian_uint(src);
452 if (kTAG_AtoBType != type) { 452 if (kTAG_AtoBType != type) {
453 // FIXME (msarett): Need to support lut8Type and lut16Type. 453 // FIXME (msarett): Need to support lut8Type and lut16Type.
454 SkColorSpacePrintf("Unsupported A to B tag type.\n"); 454 SkColorSpacePrintf("Unsupported A to B tag type.\n");
455 return false; 455 return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 uint32_t offsetToMCurves = read_big_endian_int(src + 20); 492 uint32_t offsetToMCurves = read_big_endian_int(src + 20);
493 if (0 != offsetToMCurves && offsetToMCurves < len) { 493 if (0 != offsetToMCurves && offsetToMCurves < len) {
494 if (!load_gammas(gamma->fVec, outputChannels, src + offsetToMCurves, len - offsetToMCurves)) 494 if (!load_gammas(gamma->fVec, outputChannels, src + offsetToMCurves, len - offsetToMCurves))
495 { 495 {
496 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); 496 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n");
497 } 497 }
498 } 498 }
499 499
500 uint32_t offsetToMatrix = read_big_endian_int(src + 16); 500 uint32_t offsetToMatrix = read_big_endian_int(src + 16);
501 if (0 != offsetToMatrix && offsetToMatrix < len) { 501 if (0 != offsetToMatrix && offsetToMatrix < len) {
502 if (!load_matrix(toXYZ, toXYZOffset, src + offsetToMatrix, len - offsetT oMatrix)) { 502 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) {
503 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); 503 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
504 } 504 }
505 } 505 }
506 506
507 return true; 507 return true;
508 } 508 }
509 509
510 sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) { 510 sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) {
511 const uint8_t* ptr = (const uint8_t*) base; 511 const uint8_t* ptr = (const uint8_t*) base;
512 512
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 } 550 }
551 } 551 }
552 552
553 switch (header.fInputColorSpace) { 553 switch (header.fInputColorSpace) {
554 case kRGB_ColorSpace: { 554 case kRGB_ColorSpace: {
555 // Recognize the rXYZ, gXYZ, and bXYZ tags. 555 // Recognize the rXYZ, gXYZ, and bXYZ tags.
556 const ICCTag* r = ICCTag::Find(tags.get(), tagCount, kTAG_rXYZ); 556 const ICCTag* r = ICCTag::Find(tags.get(), tagCount, kTAG_rXYZ);
557 const ICCTag* g = ICCTag::Find(tags.get(), tagCount, kTAG_gXYZ); 557 const ICCTag* g = ICCTag::Find(tags.get(), tagCount, kTAG_gXYZ);
558 const ICCTag* b = ICCTag::Find(tags.get(), tagCount, kTAG_bXYZ); 558 const ICCTag* b = ICCTag::Find(tags.get(), tagCount, kTAG_bXYZ);
559 if (r && g && b) { 559 if (r && g && b) {
560 SkFloat3x3 toXYZ; 560 float toXYZ[9];
561 if (!load_xyz(&toXYZ.fMat[0], r->addr((const uint8_t*) base), r- >fLength) || 561 if (!load_xyz(&toXYZ[0], r->addr((const uint8_t*) base), r->fLen gth) ||
562 !load_xyz(&toXYZ.fMat[3], g->addr((const uint8_t*) base), g- >fLength) || 562 !load_xyz(&toXYZ[3], g->addr((const uint8_t*) base), g->fLen gth) ||
563 !load_xyz(&toXYZ.fMat[6], b->addr((const uint8_t*) base), b- >fLength)) 563 !load_xyz(&toXYZ[6], b->addr((const uint8_t*) base), b->fLen gth))
564 { 564 {
565 return_null("Need valid rgb tags for XYZ space"); 565 return_null("Need valid rgb tags for XYZ space");
566 } 566 }
567 567
568 // It is not uncommon to see missing or empty gamma tags. This indicates 568 // It is not uncommon to see missing or empty gamma tags. This indicates
569 // that we should use unit gamma. 569 // that we should use unit gamma.
570 SkFloat3 gamma {{ 1.0f, 1.0f, 1.0f }}; 570 SkFloat3 gamma {{ 1.0f, 1.0f, 1.0f }};
571 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); 571 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC);
572 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); 572 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC);
573 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); 573 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC);
574 if (!r || 574 if (!r ||
575 !load_gammas(&gamma.fVec[0], 1, r->addr((const uint8_t*) bas e), r->fLength)) 575 !load_gammas(&gamma.fVec[0], 1, r->addr((const uint8_t*) bas e), r->fLength))
576 { 576 {
577 SkColorSpacePrintf("Failed to read R gamma tag.\n"); 577 SkColorSpacePrintf("Failed to read R gamma tag.\n");
578 } 578 }
579 if (!g || 579 if (!g ||
580 !load_gammas(&gamma.fVec[1], 1, g->addr((const uint8_t*) bas e), g->fLength)) 580 !load_gammas(&gamma.fVec[1], 1, g->addr((const uint8_t*) bas e), g->fLength))
581 { 581 {
582 SkColorSpacePrintf("Failed to read G gamma tag.\n"); 582 SkColorSpacePrintf("Failed to read G gamma tag.\n");
583 } 583 }
584 if (!b || 584 if (!b ||
585 !load_gammas(&gamma.fVec[2], 1, b->addr((const uint8_t*) bas e), b->fLength)) 585 !load_gammas(&gamma.fVec[2], 1, b->addr((const uint8_t*) bas e), b->fLength))
586 { 586 {
587 SkColorSpacePrintf("Failed to read B gamma tag.\n"); 587 SkColorSpacePrintf("Failed to read B gamma tag.\n");
588 } 588 }
589 return SkColorSpace::NewRGB(toXYZ, gamma); 589
590 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
591 mat.set3x3ColMajorf(toXYZ);
592 return SkColorSpace::NewRGB(mat, gamma);
590 } 593 }
591 594
592 // Recognize color profile specified by A2B0 tag. 595 // Recognize color profile specified by A2B0 tag.
593 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); 596 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
594 if (a2b0) { 597 if (a2b0) {
595 SkColorLookUpTable colorLUT; 598 SkColorLookUpTable colorLUT;
596 SkFloat3 gamma; 599 SkFloat3 gamma;
597 SkFloat3x3 toXYZ; 600 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
598 SkFloat3 toXYZOffset; 601 if (!load_a2b0(&colorLUT, &gamma, &toXYZ, a2b0->addr((const uint 8_t*) base),
599 if (!load_a2b0(&colorLUT, &gamma, &toXYZ, &toXYZOffset, 602 a2b0->fLength)) {
600 a2b0->addr((const uint8_t*) base), a2b0->fLength)) {
601 return_null("Failed to parse A2B0 tag"); 603 return_null("Failed to parse A2B0 tag");
602 } 604 }
603 605
604 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), gamma, toXYZ, 606 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), gamma, toXYZ));
605 toXYZOffset));
606 } 607 }
607 608
608 } 609 }
609 default: 610 default:
610 break; 611 break;
611 } 612 }
612 613
613 return_null("ICC profile contains unsupported colorspace"); 614 return_null("ICC profile contains unsupported colorspace");
614 } 615 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpace.h ('k') | src/core/SkMatrix44.cpp » ('j') | tests/ColorSpaceTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698