aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkColorLookUpTable.cpp
diff options
context:
space:
mode:
authorGravatar raftias <raftias@google.com>2016-11-30 11:19:22 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-01 16:22:49 +0000
commit51c3fcd376c5c9972d9476b5532f6164375a38d1 (patch)
tree550b06db1cb58caf5ec966ecaf80725fa5d74468 /src/core/SkColorLookUpTable.cpp
parent14c8f82334b9b3b20316dc4ba4786d526c2a5012 (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.cpp51
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;
+}