aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-06-06 10:42:51 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-06 10:42:51 -0700
commita4fa4f6eb727e8b97f6d8a58d9fda4aea56bbc75 (patch)
treecea2b6a233bb2dc5511f3a20e350f412da64bf5d /src/core
parent09f5cd44ae30f7089cde0131a3d07abf4c47af67 (diff)
Gamma sanity checks
(1) Make load_gammas() return false on invalid gammas. (2) Assert that gamma always exists after loading. (3) Avoid dividing by zero. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2043803002 Review-Url: https://codereview.chromium.org/2043803002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkColorSpace.cpp36
-rw-r--r--src/core/SkColorSpace_Base.h6
2 files changed, 39 insertions, 3 deletions
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 3a81d276a8..1652de37a8 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -427,6 +427,10 @@ bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
// The table entry is the gamma (with a bias of 256).
uint16_t value = read_big_endian_short((const uint8_t*) table);
gammas[i].fValue = value / 256.0f;
+ if (0.0f == gammas[i].fValue) {
+ SkColorSpacePrintf("Cannot have zero gamma value");
+ return false;
+ }
SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue);
break;
}
@@ -525,6 +529,10 @@ bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
// Y = 0 otherwise
g = SkFixedToFloat(read_big_endian_int(src + 12));
a = SkFixedToFloat(read_big_endian_int(src + 16));
+ if (0.0f == a) {
+ return false;
+ }
+
b = SkFixedToFloat(read_big_endian_int(src + 20));
d = -b / a;
break;
@@ -540,6 +548,10 @@ bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
// Y = c otherwise
g = SkFixedToFloat(read_big_endian_int(src + 12));
a = SkFixedToFloat(read_big_endian_int(src + 16));
+ if (0.0f == a) {
+ return false;
+ }
+
b = SkFixedToFloat(read_big_endian_int(src + 20));
c = SkFixedToFloat(read_big_endian_int(src + 24));
d = -b / a;
@@ -594,6 +606,27 @@ bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
color_space_almost_equal(2.4000f, g)) {
gammas[i].fValue = 2.2f;
} else {
+ // Fail on invalid gammas.
+ if (d <= 0.0f) {
+ // Y = (aX + b)^g + c for always
+ if (0.0f == a || 0.0f == g) {
+ SkColorSpacePrintf("A or G is zero, constant gamma function "
+ "is nonsense");
+ return false;
+ }
+ } else if (d >= 1.0f) {
+ // Y = eX + f for always
+ if (0.0f == e) {
+ SkColorSpacePrintf("E is zero, constant gamma function is "
+ "nonsense");
+ return false;
+ }
+ } else if ((0.0f == a || 0.0f == g) && 0.0f == e) {
+ SkColorSpacePrintf("A or G, and E are zero, constant gamma function "
+ "is nonsense");
+ return false;
+ }
+
gammas[i].fG = g;
gammas[i].fA = a;
gammas[i].fB = b;
@@ -611,6 +644,9 @@ bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
return false;
}
+ // Ensure that we have successfully read a gamma representation.
+ SkASSERT(gammas[i].isValue() || gammas[i].isTable() || gammas[i].isParametric());
+
// Adjust src and len if there is another gamma curve to load.
if (i != numGammas - 1) {
// Each curve is padded to 4-byte alignment.
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
index b2d5818e84..68514d0ad6 100644
--- a/src/core/SkColorSpace_Base.h
+++ b/src/core/SkColorSpace_Base.h
@@ -16,20 +16,20 @@ struct SkGammaCurve {
bool isValue() const {
bool result = (0.0f != fValue);
SkASSERT(!result || (0 == fTableSize));
- SkASSERT(!result || (0.0f == fG));
+ SkASSERT(!result || (0.0f == fG && 0.0f == fE));
return result;
}
bool isTable() const {
bool result = (0 != fTableSize);
SkASSERT(!result || (0.0f == fValue));
- SkASSERT(!result || (0.0f == fG));
+ SkASSERT(!result || (0.0f == fG && 0.0f == fE));
SkASSERT(!result || fTable);
return result;
}
bool isParametric() const {
- bool result = (0.0f != fG);
+ bool result = (0.0f != fG || 0.0f != fE);
SkASSERT(!result || (0.0f == fValue));
SkASSERT(!result || (0 == fTableSize));
return result;