diff options
author | msarett <msarett@google.com> | 2016-08-22 14:58:56 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-22 14:58:56 -0700 |
commit | 4ff08df15a8042cdb4fc90a82e1044847d0de300 (patch) | |
tree | cd47887749df6dfbd439c7170be0b65278250565 /src | |
parent | dcb406c29d72842684e67e746ddf7fe0b9a597db (diff) |
More robust check for sRGB gamma tables
This is in response to a UMA showing that 5% dst gammas are
unidentified tables. We want to see if some of these tables
should be marked as sRGB.
https://uma.googleplex.com/p/chrome/histograms?endDate=latest&dayCount=1&histograms=Blink.ColorSpace.Destination&fixupData=true&showMax=true&filters=isofficial%2Ceq%2CTrue&implicitFilters=isofficial
This check is not fast. If we find that it doesn't help
us recognize sRGB curves, we should delete it.
BUG=skia:5656
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2263233003
Review-Url: https://codereview.chromium.org/2263233003
Diffstat (limited to 'src')
-rwxr-xr-x | src/core/SkColorSpace_ICC.cpp | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/core/SkColorSpace_ICC.cpp b/src/core/SkColorSpace_ICC.cpp index 9ab1da007d..92dcc0fcf5 100755 --- a/src/core/SkColorSpace_ICC.cpp +++ b/src/core/SkColorSpace_ICC.cpp @@ -262,6 +262,14 @@ static float read_big_endian_16_dot_16(const uint8_t buf[4]) { return SkFixedToFloat(read_big_endian_i32(buf)); } +static inline float srgb_fn(float x) { + if (x <= 0.04045f) { + return x * (1.0f / 12.92f); + } + + return powf(x * (1.0f / 1.055f) + (0.055f / 1.055f), 2.4f); +} + /** * @param outData Set to the appropriate value on success. If we have table or * parametric gamma, it is the responsibility of the caller to set @@ -370,9 +378,35 @@ static SkGammas::Type parse_gamma(SkGammas::Data* outData, SkGammas::Params* out } } - // Otherwise, we will represent gamma with a table. - outData->fTable.fSize = count; - return SkGammas::Type::kTable_Type; + // Perform a more robust check for sRGB. See if the table is a close + // match to an sRGB table. This is in addition to the previous sRGB + // checks for a couple reasons: + // (1) It is much slower. + // (2) The 26 entry "sRGB" curve is actually so inaccurate that it fails + // this check. But it still wants to be sRGB. + float x = 0.0f; + float dx = 1.0f / ((float) (count - 1)); + for (uint32_t i = 0; i < count; i++) { + float y = srgb_fn(x); + + // Convert y to the same format as the table (0.16 fixed point), so we can + // compare values. + uint16_t srgbY = sk_float_round2int(y * (float) (1 << 16)); + uint16_t actualY = read_big_endian_u16((const uint8_t*) &table[i]); + + // We allow "off by 1" curves to try to not be affected by rounding decisions. + if (SkTAbs((int32_t) srgbY - (int32_t) actualY) > 1) { + // Curve is not sRGB, will use table representation. + outData->fTable.fSize = count; + return SkGammas::Type::kTable_Type; + } + + x += dx; + } + + outData->fNamed = SkColorSpace::kSRGB_GammaNamed; + return SkGammas::Type::kNamed_Type; + } case kTAG_ParaCurveType: { enum ParaCurveType { |