diff options
author | raftias <raftias@google.com> | 2016-12-05 14:21:45 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-08 16:02:55 +0000 |
commit | e8ea07a6127971aea8183303b9abfa9856b7a54c (patch) | |
tree | 18abfbe218cc91c892288f508161af49befd56f5 /src/core/SkColorSpace_ICC.cpp | |
parent | a9da22df9606559424853cab547784aa73b11534 (diff) |
Added some named gamma recognition to lutnType ICC profile parsing
Most CMYK images I tested had linear gamma specified as tables, which
is easily recognized and when present allows an entire SkRasterPipeline
stage to be avoided for every single channel. This is likely due to the
fact that gamma tables are required in lutntype A2B0 profiles.
BUG=skia:
Change-Id: I82b65848c4099035d61098abb66e9afe0b080930
Reviewed-on: https://skia-review.googlesource.com/5388
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Robert Aftias <raftias@google.com>
Diffstat (limited to 'src/core/SkColorSpace_ICC.cpp')
-rw-r--r-- | src/core/SkColorSpace_ICC.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/core/SkColorSpace_ICC.cpp b/src/core/SkColorSpace_ICC.cpp index d27de96c3f..04e240a6de 100644 --- a/src/core/SkColorSpace_ICC.cpp +++ b/src/core/SkColorSpace_ICC.cpp @@ -860,8 +860,22 @@ static bool parse_and_load_gamma(SkGammaNamed* gammaNamed, sk_sp<SkGammas>* gamm return true; } -static bool load_lut_gammas(sk_sp<SkGammas>* gammas, size_t numTables, size_t entriesPerTable, - size_t precision, const uint8_t* src, size_t len) { +static bool is_lut_gamma_linear(const uint8_t* src, size_t count, size_t precision) { + // check for linear gamma (this is very common in lut gammas, as they aren't optional) + const float normalizeX = 1.f / (count - 1); + for (uint32_t x = 0; x < count; ++x) { + const float y = precision == 1 ? (src[x] / 255.f) + : (read_big_endian_u16(src + 2*x) / 65535.f); + if (!color_space_almost_equal(x * normalizeX, y)) { + return false; + } + } + return true; +} + +static bool load_lut_gammas(sk_sp<SkGammas>* gammas, SkGammaNamed* gammaNamed, size_t numTables, + size_t entriesPerTable, size_t precision, const uint8_t* src, + size_t len) { if (precision != 1 && precision != 2) { SkColorSpacePrintf("Invalid gamma table precision %d\n", precision); return false; @@ -890,6 +904,14 @@ static bool load_lut_gammas(sk_sp<SkGammas>* gammas, size_t numTables, size_t en } } + if (1 == numTablesToUse) { + if (is_lut_gamma_linear(src, entriesPerTable, precision)) { + *gammaNamed = kLinear_SkGammaNamed; + return true; + } + } + *gammaNamed = kNonStandard_SkGammaNamed; + uint32_t writetableBytes; return_if_false(safe_mul(numTablesToUse, writeBytesPerChannel, &writetableBytes), "SkGammas struct is too large to allocate"); @@ -1132,13 +1154,13 @@ bool load_a2b0_lutn_type(std::vector<SkColorSpace_A2B::Element>* elements, const const size_t inputOffset = dataOffset; return_if_false(len >= inputOffset, "A2B0 lutnType tag too small for input gamma table"); sk_sp<SkGammas> inputGammas; - if (!load_lut_gammas(&inputGammas, inputChannels, inTableEntries, precision, + SkGammaNamed inputGammaNamed; + if (!load_lut_gammas(&inputGammas, &inputGammaNamed, inputChannels, inTableEntries, precision, src + inputOffset, len - inputOffset)) { SkColorSpacePrintf("Failed to read input gammas from lutnType tag.\n"); return false; } - SkASSERT(inputGammas); - const SkGammaNamed inputGammaNamed = is_named(inputGammas); + SkASSERT(inputGammas || inputGammaNamed != kNonStandard_SkGammaNamed); if (kLinear_SkGammaNamed != inputGammaNamed) { if (kNonStandard_SkGammaNamed != inputGammaNamed) { elements->push_back(SkColorSpace_A2B::Element(inputGammaNamed, inputChannels)); @@ -1168,13 +1190,13 @@ bool load_a2b0_lutn_type(std::vector<SkColorSpace_A2B::Element>* elements, const const size_t outputOffset = clutOffset + clutSize; return_if_false(len >= outputOffset, "A2B0 lutnType tag too small for output gamma table"); sk_sp<SkGammas> outputGammas; - if (!load_lut_gammas(&outputGammas, outputChannels, outTableEntries, precision, - src + outputOffset, len - outputOffset)) { + SkGammaNamed outputGammaNamed; + if (!load_lut_gammas(&outputGammas, &outputGammaNamed, outputChannels, outTableEntries, + precision, src + outputOffset, len - outputOffset)) { SkColorSpacePrintf("Failed to read output gammas from lutnType tag.\n"); return false; } - SkASSERT(outputGammas); - const SkGammaNamed outputGammaNamed = is_named(outputGammas); + SkASSERT(outputGammas || outputGammaNamed != kNonStandard_SkGammaNamed); if (kLinear_SkGammaNamed != outputGammaNamed) { if (kNonStandard_SkGammaNamed != outputGammaNamed) { elements->push_back(SkColorSpace_A2B::Element(outputGammaNamed, outputChannels)); |