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
This commit is contained in:
msarett 2016-06-06 10:42:51 -07:00 committed by Commit bot
parent 09f5cd44ae
commit a4fa4f6eb7
2 changed files with 39 additions and 3 deletions

View File

@ -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.

View File

@ -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;