aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkColorSpace_ICC.cpp
diff options
context:
space:
mode:
authorGravatar raftias <raftias@google.com>2016-12-05 14:21:45 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-08 16:02:55 +0000
commite8ea07a6127971aea8183303b9abfa9856b7a54c (patch)
tree18abfbe218cc91c892288f508161af49befd56f5 /src/core/SkColorSpace_ICC.cpp
parenta9da22df9606559424853cab547784aa73b11534 (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.cpp40
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));