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

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: fix redirect header 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
« no previous file with comments | « src/core/SkColorSpace.h ('k') | src/core/SkMatrix44.cpp » ('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 "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(SkGammas gammas, const SkFloat3x3& toXYZD50, Named na med) 19 SkColorSpace::SkColorSpace(SkGammas gammas, const SkMatrix44& toXYZD50, Named na med)
27 : fGammas(std::move(gammas)) 20 : fGammas(std::move(gammas))
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, SkGammas gammas, 26 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas,
35 const SkFloat3x3& toXYZD50, const SkFloat3& toXYZOffs et) 27 const SkMatrix44& toXYZD50)
36 : fColorLUT(std::move(colorLUT)) 28 : fColorLUT(std::move(colorLUT))
37 , fGammas(std::move(gammas)) 29 , fGammas(std::move(gammas))
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, SkGammas ga mmas) { 35 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkMatrix44& toXYZD50, SkGammas ga mmas) {
45 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named)); 36 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named));
46 } 37 }
47 38
48 const SkFloat3x3 gSRGB_toXYZD50 {{ 39 const float gSRGB_toXYZD50[] {
49 0.4358f, 0.2224f, 0.0139f, // * R 40 0.4358f, 0.2224f, 0.0139f, // * R
50 0.3853f, 0.7170f, 0.0971f, // * G 41 0.3853f, 0.7170f, 0.0971f, // * G
51 0.1430f, 0.0606f, 0.7139f, // * B 42 0.1430f, 0.0606f, 0.7139f, // * B
52 }}; 43 };
53 44
54 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 45 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
55 switch (named) { 46 switch (named) {
56 case kSRGB_Named: 47 case kSRGB_Named: {
57 return sk_sp<SkColorSpace>(new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2 f), gSRGB_toXYZD50, 48 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
49 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
50 return sk_sp<SkColorSpace>(new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2 f), srgbToxyzD50,
58 kSRGB_Named)); 51 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 if (1 == precision) { 401 if (1 == precision) {
408 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; 402 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f;
409 } else { 403 } else {
410 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f; 404 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0 f;
411 } 405 }
412 } 406 }
413 407
414 return true; 408 return true;
415 } 409 }
416 410
417 bool load_matrix(SkFloat3x3* toXYZ, SkFloat3* toXYZOffset, const uint8_t* src, s ize_t len) { 411 bool load_matrix(SkMatrix44* toXYZ, const uint8_t* src, size_t len) {
418 if (len < 48) { 412 if (len < 48) {
419 SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len); 413 SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len);
420 return false; 414 return false;
421 } 415 }
422 416
423 toXYZ->fMat[0] = SkFixedToFloat(read_big_endian_int(src)); 417 float array[16];
424 toXYZ->fMat[3] = SkFixedToFloat(read_big_endian_int(src + 4)); 418 array[ 0] = SkFixedToFloat(read_big_endian_int(src));
425 toXYZ->fMat[6] = SkFixedToFloat(read_big_endian_int(src + 8)); 419 array[ 1] = SkFixedToFloat(read_big_endian_int(src + 4));
426 toXYZ->fMat[1] = SkFixedToFloat(read_big_endian_int(src + 12)); 420 array[ 2] = SkFixedToFloat(read_big_endian_int(src + 8));
427 toXYZ->fMat[4] = SkFixedToFloat(read_big_endian_int(src + 16)); 421 array[ 3] = 0;
428 toXYZ->fMat[7] = SkFixedToFloat(read_big_endian_int(src + 20)); 422 array[ 4] = SkFixedToFloat(read_big_endian_int(src + 12));
429 toXYZ->fMat[2] = SkFixedToFloat(read_big_endian_int(src + 24)); 423 array[ 5] = SkFixedToFloat(read_big_endian_int(src + 16));
430 toXYZ->fMat[5] = SkFixedToFloat(read_big_endian_int(src + 28)); 424 array[ 6] = SkFixedToFloat(read_big_endian_int(src + 20));
431 toXYZ->fMat[8] = SkFixedToFloat(read_big_endian_int(src + 32)); 425 array[ 7] = 0;
432 toXYZOffset->fVec[0] = SkFixedToFloat(read_big_endian_int(src + 36)); 426 array[ 8] = SkFixedToFloat(read_big_endian_int(src + 24));
433 toXYZOffset->fVec[1] = SkFixedToFloat(read_big_endian_int(src + 40)); 427 array[ 9] = SkFixedToFloat(read_big_endian_int(src + 28));
434 toXYZOffset->fVec[2] = SkFixedToFloat(read_big_endian_int(src + 44)); 428 array[10] = SkFixedToFloat(read_big_endian_int(src + 32));
429 array[11] = 0;
430 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R
431 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G
432 array[14] = SkFixedToFloat(read_big_endian_int(src + 44));
433 array[15] = 1;
434 toXYZ->setColMajorf(array);
435 return true; 435 return true;
436 } 436 }
437 437
438 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammas* gammas, SkFl oat3x3* toXYZ, 438 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammas* gammas, SkMa trix44* toXYZ,
439 SkFloat3* toXYZOffset, const uint8_t* src, size_t le n) { 439 const uint8_t* src, size_t len) {
440 if (len < 32) { 440 if (len < 32) {
441 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); 441 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
442 return false; 442 return false;
443 } 443 }
444 444
445 uint32_t type = read_big_endian_uint(src); 445 uint32_t type = read_big_endian_uint(src);
446 if (kTAG_AtoBType != type) { 446 if (kTAG_AtoBType != type) {
447 // FIXME (msarett): Need to support lut8Type and lut16Type. 447 // FIXME (msarett): Need to support lut8Type and lut16Type.
448 SkColorSpacePrintf("Unsupported A to B tag type.\n"); 448 SkColorSpacePrintf("Unsupported A to B tag type.\n");
449 return false; 449 return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 uint32_t offsetToMCurves = read_big_endian_int(src + 20); 486 uint32_t offsetToMCurves = read_big_endian_int(src + 20);
487 if (0 != offsetToMCurves && offsetToMCurves < len) { 487 if (0 != offsetToMCurves && offsetToMCurves < len) {
488 if (!SkColorSpace::LoadGammas(&gammas->fRed, outputChannels, src + offse tToMCurves, 488 if (!SkColorSpace::LoadGammas(&gammas->fRed, outputChannels, src + offse tToMCurves,
489 len - offsetToMCurves)) { 489 len - offsetToMCurves)) {
490 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); 490 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n");
491 } 491 }
492 } 492 }
493 493
494 uint32_t offsetToMatrix = read_big_endian_int(src + 16); 494 uint32_t offsetToMatrix = read_big_endian_int(src + 16);
495 if (0 != offsetToMatrix && offsetToMatrix < len) { 495 if (0 != offsetToMatrix && offsetToMatrix < len) {
496 if (!load_matrix(toXYZ, toXYZOffset, src + offsetToMatrix, len - offsetT oMatrix)) { 496 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) {
497 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); 497 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
498 } 498 }
499 } 499 }
500 500
501 return true; 501 return true;
502 } 502 }
503 503
504 sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) { 504 sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) {
505 const uint8_t* ptr = (const uint8_t*) base; 505 const uint8_t* ptr = (const uint8_t*) base;
506 506
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 } 544 }
545 } 545 }
546 546
547 switch (header.fInputColorSpace) { 547 switch (header.fInputColorSpace) {
548 case kRGB_ColorSpace: { 548 case kRGB_ColorSpace: {
549 // Recognize the rXYZ, gXYZ, and bXYZ tags. 549 // Recognize the rXYZ, gXYZ, and bXYZ tags.
550 const ICCTag* r = ICCTag::Find(tags.get(), tagCount, kTAG_rXYZ); 550 const ICCTag* r = ICCTag::Find(tags.get(), tagCount, kTAG_rXYZ);
551 const ICCTag* g = ICCTag::Find(tags.get(), tagCount, kTAG_gXYZ); 551 const ICCTag* g = ICCTag::Find(tags.get(), tagCount, kTAG_gXYZ);
552 const ICCTag* b = ICCTag::Find(tags.get(), tagCount, kTAG_bXYZ); 552 const ICCTag* b = ICCTag::Find(tags.get(), tagCount, kTAG_bXYZ);
553 if (r && g && b) { 553 if (r && g && b) {
554 SkFloat3x3 toXYZ; 554 float toXYZ[9];
555 if (!load_xyz(&toXYZ.fMat[0], r->addr((const uint8_t*) base), r- >fLength) || 555 if (!load_xyz(&toXYZ[0], r->addr((const uint8_t*) base), r->fLen gth) ||
556 !load_xyz(&toXYZ.fMat[3], g->addr((const uint8_t*) base), g- >fLength) || 556 !load_xyz(&toXYZ[3], g->addr((const uint8_t*) base), g->fLen gth) ||
557 !load_xyz(&toXYZ.fMat[6], b->addr((const uint8_t*) base), b- >fLength)) 557 !load_xyz(&toXYZ[6], b->addr((const uint8_t*) base), b->fLen gth))
558 { 558 {
559 return_null("Need valid rgb tags for XYZ space"); 559 return_null("Need valid rgb tags for XYZ space");
560 } 560 }
561 561
562 // It is not uncommon to see missing or empty gamma tags. This indicates 562 // It is not uncommon to see missing or empty gamma tags. This indicates
563 // that we should use unit gamma. 563 // that we should use unit gamma.
564 SkGammas gammas; 564 SkGammas gammas;
565 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); 565 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC);
566 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); 566 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC);
567 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); 567 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC);
568 if (!r || !SkColorSpace::LoadGammas(&gammas.fRed, 1, 568 if (!r || !SkColorSpace::LoadGammas(&gammas.fRed, 1,
569 r->addr((const uint8_t*) bas e), r->fLength)) { 569 r->addr((const uint8_t*) bas e), r->fLength)) {
570 SkColorSpacePrintf("Failed to read R gamma tag.\n"); 570 SkColorSpacePrintf("Failed to read R gamma tag.\n");
571 } 571 }
572 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1, 572 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1,
573 g->addr((const uint8_t*) bas e), g->fLength)) { 573 g->addr((const uint8_t*) bas e), g->fLength)) {
574 SkColorSpacePrintf("Failed to read G gamma tag.\n"); 574 SkColorSpacePrintf("Failed to read G gamma tag.\n");
575 } 575 }
576 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1, 576 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1,
577 b->addr((const uint8_t*) bas e), b->fLength)) { 577 b->addr((const uint8_t*) bas e), b->fLength)) {
578 SkColorSpacePrintf("Failed to read B gamma tag.\n"); 578 SkColorSpacePrintf("Failed to read B gamma tag.\n");
579 } 579 }
580 return SkColorSpace::NewRGB(toXYZ, std::move(gammas)); 580 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
581 mat.set3x3ColMajorf(toXYZ);
582 return SkColorSpace::NewRGB(mat, std::move(gammas));
581 } 583 }
582 584
583 // Recognize color profile specified by A2B0 tag. 585 // Recognize color profile specified by A2B0 tag.
584 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); 586 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
585 if (a2b0) { 587 if (a2b0) {
586 SkColorLookUpTable colorLUT; 588 SkColorLookUpTable colorLUT;
587 SkGammas gammas; 589 SkGammas gammas;
588 SkFloat3x3 toXYZ; 590 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
589 SkFloat3 toXYZOffset; 591 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ,
590 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ, &toXYZOf fset,
591 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) { 592 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) {
592 return_null("Failed to parse A2B0 tag"); 593 return_null("Failed to parse A2B0 tag");
593 } 594 }
594 595
595 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas), 596 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas),
596 toXYZ, toXYZOffset)) ; 597 toXYZ));
597 } 598 }
598 599
599 } 600 }
600 default: 601 default:
601 break; 602 break;
602 } 603 }
603 604
604 return_null("ICC profile contains unsupported colorspace"); 605 return_null("ICC profile contains unsupported colorspace");
605 } 606 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpace.h ('k') | src/core/SkMatrix44.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698