Index: src/core/SkColorSpaceXform.cpp |
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..66a7dabd9d8cf9fce0ce8c6ebf07642da9d2738b |
--- /dev/null |
+++ b/src/core/SkColorSpaceXform.cpp |
@@ -0,0 +1,70 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkColorSpaceXform.h" |
+#include "SkHalf.h" |
+#include "SkTemplates.h" |
+ |
+SkColorSpaceXform* SkColorSpaceXform::New(sk_sp<SkColorSpace> srcSpace, |
herb_g
2016/05/05 14:44:50
Is there a reason you are forcing this to be built
msarett
2016/05/05 15:49:05
It's nice to be able to return nullptr on unimplem
|
+ sk_sp<SkColorSpace> dstSpace, Op op) { |
+ switch (op) { |
+ case kSrcToLinear_Op: |
+ if (!srcSpace) { |
+ // Cannot perform this op without a src color space. |
+ return nullptr; |
+ } |
+ |
+ if (srcSpace->fColorLUT.fTable) { |
+ // Unimplemented |
+ return nullptr; |
+ } |
+ |
+ if (srcSpace->gammas().fRed.isValue() && srcSpace->gammas().fGreen.isValue() && |
msarett
2016/05/04 22:52:49
It's technically possible for an image to have an
|
+ srcSpace->gammas().fBlue.isValue()) { |
+ SkFloat3 gammas; |
+ gammas.fVec[0] = srcSpace->gammas().fRed.fValue; |
+ gammas.fVec[1] = srcSpace->gammas().fGreen.fValue; |
+ gammas.fVec[2] = srcSpace->gammas().fBlue.fValue; |
+ return new SkGammaByValueXform(gammas); |
+ } |
+ |
+ // Unimplemented |
+ return nullptr; |
+ default: |
+ // Unimplemented |
+ return nullptr; |
+ } |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+SkGammaByValueXform::SkGammaByValueXform(const SkFloat3& gammas) |
+ : fGammas(gammas) |
+{} |
+ |
+void SkGammaByValueXform::apply(void* vdst, const void* vsrc, const SkISize& size, |
+ size_t dstRowBytes, size_t srcRowBytes) const { |
+ const uint32_t* src = (const uint32_t*) vsrc; |
+ uint64_t* dst = (uint64_t*) vdst; |
+ for (int y = 0; y < size.height(); y++) { |
+ for (int x = 0; x < size.width(); x++) { |
+ uint32_t rgba = src[x]; |
+ float r = ((rgba >> 0) & 0xFF) / 255.0f; |
+ float g = ((rgba >> 8) & 0xFF) / 255.0f; |
+ float b = ((rgba >> 16) & 0xFF) / 255.0f; |
+ float a = ((rgba >> 24) & 0xFF) / 255.0f; |
+ |
+ dst[x] = ((uint64_t) SkFloatToHalf(pow(r, fGammas.fVec[0]))) << 0 | |
+ ((uint64_t) SkFloatToHalf(pow(g, fGammas.fVec[1]))) << 16 | |
+ ((uint64_t) SkFloatToHalf(pow(b, fGammas.fVec[2]))) << 32 | |
+ ((uint64_t) SkFloatToHalf(a)) << 48; |
+ } |
+ |
+ src = SkTAddOffset<const uint32_t>(src, srcRowBytes); |
+ dst = SkTAddOffset<uint64_t>(dst, dstRowBytes); |
+ } |
+} |