diff options
author | raftias <raftias@google.com> | 2016-11-30 11:19:22 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-01 16:22:49 +0000 |
commit | 51c3fcd376c5c9972d9476b5532f6164375a38d1 (patch) | |
tree | 550b06db1cb58caf5ec966ecaf80725fa5d74468 /src/core/SkColorLookUpTable.cpp | |
parent | 14c8f82334b9b3b20316dc4ba4786d526c2a5012 (diff) |
Added CMYK support for ICC profiles.
Changed ICC parsing/SkGammas/SkColorLookUpTable to handle non-3-channel
inputs. Parsed CMYK A2B ICC profiles. Integrated this with SkJpegCodec
(the only file that supports CMYK) and SkColorSpaceXform_A2B to allow
parsing and color xforming of ICC CMYK images.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5197
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
Change-Id: Id6619f63f04071f79cd2d84321857dfa269ad3aa
Reviewed-on: https://skia-review.googlesource.com/5197
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Matt Sarett <msarett@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Diffstat (limited to 'src/core/SkColorLookUpTable.cpp')
-rw-r--r-- | src/core/SkColorLookUpTable.cpp | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/src/core/SkColorLookUpTable.cpp b/src/core/SkColorLookUpTable.cpp index eb832b3214..e2da357234 100644 --- a/src/core/SkColorLookUpTable.cpp +++ b/src/core/SkColorLookUpTable.cpp @@ -8,7 +8,23 @@ #include "SkColorLookUpTable.h" #include "SkFloatingPoint.h" -void SkColorLookUpTable::interp3D(float dst[3], float src[3]) const { +void SkColorLookUpTable::interp(float* dst, const float* src) const { + if (fInputChannels == 3) { + interp3D(dst, src); + } else { + SkASSERT(dst != src); + // index gets initialized as the algorithm proceeds by interpDimension. + // It's just there to store the choice of low/high so far. + int index[kMaxColorChannels]; + for (uint8_t outputDimension = 0; outputDimension < kOutputChannels; ++outputDimension) { + dst[outputDimension] = interpDimension(src, fInputChannels - 1, outputDimension, + index); + } + } +} + +void SkColorLookUpTable::interp3D(float* dst, const float* src) const { + SkASSERT(3 == kOutputChannels); // Call the src components x, y, and z. const uint8_t maxX = fGridPoints[0] - 1; const uint8_t maxY = fGridPoints[1] - 1; @@ -111,3 +127,36 @@ void SkColorLookUpTable::interp3D(float dst[3], float src[3]) const { ptr++; } } + +float SkColorLookUpTable::interpDimension(const float* src, int inputDimension, + int outputDimension, + int index[kMaxColorChannels]) const { + // Base case. We've already decided whether to use the low or high point for each dimension + // which is stored inside of index[] where index[i] gives the point in the CLUT to use for + // input dimension i. + if (-1 == inputDimension) { + // compute index into CLUT and look up the colour + int outputIndex = outputDimension; + int indexMultiplier = kOutputChannels; + for (int i = fInputChannels - 1; i >= 0; --i) { + outputIndex += index[i] * indexMultiplier; + indexMultiplier *= fGridPoints[i]; + } + return table()[outputIndex]; + } + // for each dimension (input channel), try both the low and high point for it + // and then do the same recursively for the later dimensions. + // Finally, we need to LERP the results. ie LERP X then LERP Y then LERP Z. + const float x = src[inputDimension] * (fGridPoints[inputDimension] - 1); + // try the low point for this dimension + index[inputDimension] = sk_float_floor2int(x); + const float diff = x - index[inputDimension]; + // and recursively LERP all sub-dimensions with the current dimension fixed to the low point + const float lo = interpDimension(src, inputDimension - 1, outputDimension, index); + // now try the high point for this dimension + index[inputDimension] = sk_float_ceil2int(x); + // and recursively LERP all sub-dimensions with the current dimension fixed to the high point + const float hi = interpDimension(src, inputDimension - 1, outputDimension, index); + // then LERP the results based on the current dimension + return (1 - diff) * lo + diff * hi; +} |