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

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

Issue 2043803002: Gamma sanity checks (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 6 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 | « no previous file | src/core/SkColorSpace_Base.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 "SkColorSpace.h" 8 #include "SkColorSpace.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkEndian.h" 10 #include "SkEndian.h"
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 } else if (len < tagBytes) { 420 } else if (len < tagBytes) {
421 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 421 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
422 return false; 422 return false;
423 } 423 }
424 424
425 const uint16_t* table = (const uint16_t*) (src + 12); 425 const uint16_t* table = (const uint16_t*) (src + 12);
426 if (1 == count) { 426 if (1 == count) {
427 // The table entry is the gamma (with a bias of 256). 427 // The table entry is the gamma (with a bias of 256).
428 uint16_t value = read_big_endian_short((const uint8_t*) tabl e); 428 uint16_t value = read_big_endian_short((const uint8_t*) tabl e);
429 gammas[i].fValue = value / 256.0f; 429 gammas[i].fValue = value / 256.0f;
430 if (0.0f == gammas[i].fValue) {
431 SkColorSpacePrintf("Cannot have zero gamma value");
432 return false;
433 }
430 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue) ; 434 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue) ;
431 break; 435 break;
432 } 436 }
433 437
434 // Check for frequently occurring curves and use a fast approxim ation. 438 // Check for frequently occurring curves and use a fast approxim ation.
435 // We do this by sampling a few values and see if they match our expectation. 439 // We do this by sampling a few values and see if they match our expectation.
436 // A more robust solution would be to compare each value in this curve against 440 // A more robust solution would be to compare each value in this curve against
437 // a 2.2f curve see if we remain below an error threshold. At t his time, 441 // a 2.2f curve see if we remain below an error threshold. At t his time,
438 // we haven't seen any images in the wild that make this kind of 442 // we haven't seen any images in the wild that make this kind of
439 // calculation necessary. We encounter identical gamma curves o ver and 443 // calculation necessary. We encounter identical gamma curves o ver and
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 tagBytes = 12 + 12; 514 tagBytes = 12 + 12;
511 if (len < tagBytes) { 515 if (len < tagBytes) {
512 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len); 516 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len);
513 return false; 517 return false;
514 } 518 }
515 519
516 // Y = (aX + b)^g for X >= -b/a 520 // Y = (aX + b)^g for X >= -b/a
517 // Y = 0 otherwise 521 // Y = 0 otherwise
518 g = SkFixedToFloat(read_big_endian_int(src + 12)); 522 g = SkFixedToFloat(read_big_endian_int(src + 12));
519 a = SkFixedToFloat(read_big_endian_int(src + 16)); 523 a = SkFixedToFloat(read_big_endian_int(src + 16));
524 if (0.0f == a) {
525 return false;
526 }
527
520 b = SkFixedToFloat(read_big_endian_int(src + 20)); 528 b = SkFixedToFloat(read_big_endian_int(src + 20));
521 d = -b / a; 529 d = -b / a;
522 break; 530 break;
523 } 531 }
524 case 2: 532 case 2:
525 tagBytes = 12 + 16; 533 tagBytes = 12 + 16;
526 if (len < tagBytes) { 534 if (len < tagBytes) {
527 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len); 535 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len);
528 return false; 536 return false;
529 } 537 }
530 538
531 // Y = (aX + b)^g + c for X >= -b/a 539 // Y = (aX + b)^g + c for X >= -b/a
532 // Y = c otherwise 540 // Y = c otherwise
533 g = SkFixedToFloat(read_big_endian_int(src + 12)); 541 g = SkFixedToFloat(read_big_endian_int(src + 12));
534 a = SkFixedToFloat(read_big_endian_int(src + 16)); 542 a = SkFixedToFloat(read_big_endian_int(src + 16));
543 if (0.0f == a) {
544 return false;
545 }
546
535 b = SkFixedToFloat(read_big_endian_int(src + 20)); 547 b = SkFixedToFloat(read_big_endian_int(src + 20));
536 c = SkFixedToFloat(read_big_endian_int(src + 24)); 548 c = SkFixedToFloat(read_big_endian_int(src + 24));
537 d = -b / a; 549 d = -b / a;
538 f = c; 550 f = c;
539 break; 551 break;
540 case 3: 552 case 3:
541 tagBytes = 12 + 20; 553 tagBytes = 12 + 20;
542 if (len < tagBytes) { 554 if (len < tagBytes) {
543 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len); 555 SkColorSpacePrintf("gamma tag is too small (%d b ytes)", len);
544 return false; 556 return false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 // Recognize and simplify a very common parametric represent ation of sRGB gamma. 591 // Recognize and simplify a very common parametric represent ation of sRGB gamma.
580 if (color_space_almost_equal(0.9479f, a) && 592 if (color_space_almost_equal(0.9479f, a) &&
581 color_space_almost_equal(0.0521f, b) && 593 color_space_almost_equal(0.0521f, b) &&
582 color_space_almost_equal(0.0000f, c) && 594 color_space_almost_equal(0.0000f, c) &&
583 color_space_almost_equal(0.0405f, d) && 595 color_space_almost_equal(0.0405f, d) &&
584 color_space_almost_equal(0.0774f, e) && 596 color_space_almost_equal(0.0774f, e) &&
585 color_space_almost_equal(0.0000f, f) && 597 color_space_almost_equal(0.0000f, f) &&
586 color_space_almost_equal(2.4000f, g)) { 598 color_space_almost_equal(2.4000f, g)) {
587 gammas[i].fValue = 2.2f; 599 gammas[i].fValue = 2.2f;
588 } else { 600 } else {
601 // Fail on invalid gammas.
602 if (d <= 0.0f) {
603 // Y = (aX + b)^g + c for always
604 if (0.0f == a || 0.0f == g) {
605 SkColorSpacePrintf("A or G is zero, constant gam ma function "
606 "is nonsense");
607 return false;
608 }
609 } else if (d >= 1.0f) {
610 // Y = eX + f for always
611 if (0.0f == e) {
612 SkColorSpacePrintf("E is zero, constant gamma fu nction is "
613 "nonsense");
614 return false;
615 }
616 } else if ((0.0f == a || 0.0f == g) && 0.0f == e) {
617 SkColorSpacePrintf("A or G, and E are zero, constant gamma function "
618 "is nonsense");
619 return false;
620 }
621
589 gammas[i].fG = g; 622 gammas[i].fG = g;
590 gammas[i].fA = a; 623 gammas[i].fA = a;
591 gammas[i].fB = b; 624 gammas[i].fB = b;
592 gammas[i].fC = c; 625 gammas[i].fC = c;
593 gammas[i].fD = d; 626 gammas[i].fD = d;
594 gammas[i].fE = e; 627 gammas[i].fE = e;
595 gammas[i].fF = f; 628 gammas[i].fF = f;
596 } 629 }
597 } 630 }
598 631
599 break; 632 break;
600 } 633 }
601 default: 634 default:
602 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type); 635 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
603 return false; 636 return false;
604 } 637 }
605 638
639 // Ensure that we have successfully read a gamma representation.
640 SkASSERT(gammas[i].isValue() || gammas[i].isTable() || gammas[i].isParam etric());
641
606 // Adjust src and len if there is another gamma curve to load. 642 // Adjust src and len if there is another gamma curve to load.
607 if (i != numGammas - 1) { 643 if (i != numGammas - 1) {
608 // Each curve is padded to 4-byte alignment. 644 // Each curve is padded to 4-byte alignment.
609 tagBytes = SkAlign4(tagBytes); 645 tagBytes = SkAlign4(tagBytes);
610 if (len < tagBytes) { 646 if (len < tagBytes) {
611 return false; 647 return false;
612 } 648 }
613 649
614 src += tagBytes; 650 src += tagBytes;
615 len -= tagBytes; 651 len -= tagBytes;
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 ptr32[4] = SkEndian_SwapBE32(0x000116cc); 1128 ptr32[4] = SkEndian_SwapBE32(0x000116cc);
1093 ptr += kTAG_XYZ_Bytes; 1129 ptr += kTAG_XYZ_Bytes;
1094 1130
1095 // Write copyright tag 1131 // Write copyright tag
1096 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); 1132 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag));
1097 1133
1098 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if 1134 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if
1099 // the client calls again? 1135 // the client calls again?
1100 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); 1136 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
1101 } 1137 }
OLDNEW
« no previous file with comments | « no previous file | src/core/SkColorSpace_Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698