Chromium Code Reviews| 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); |
| + } |
| +} |