Index: src/core/SkColorSpaceXform.cpp |
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp |
index 216e9931ba0a8c913fd472702ca70daf1f9a3c29..0faff88286d592a3a660b4abaf4d2d3c7e7fe5bf 100644 |
--- a/src/core/SkColorSpaceXform.cpp |
+++ b/src/core/SkColorSpaceXform.cpp |
@@ -8,6 +8,7 @@ |
#include "SkColorPriv.h" |
#include "SkColorSpace_Base.h" |
#include "SkColorSpaceXform.h" |
+#include "SkOpts.h" |
static inline bool compute_gamut_xform(SkMatrix44* srcToDst, const SkMatrix44& srcToXYZ, |
const SkMatrix44& dstToXYZ) { |
@@ -36,18 +37,10 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa |
return nullptr; |
} |
- if (as_CSB(srcSpace)->gammas()->isValues() && as_CSB(dstSpace)->gammas()->isValues()) { |
- float srcGammas[3]; |
- float dstGammas[3]; |
- srcGammas[0] = as_CSB(srcSpace)->gammas()->fRed.fValue; |
- srcGammas[1] = as_CSB(srcSpace)->gammas()->fGreen.fValue; |
- srcGammas[2] = as_CSB(srcSpace)->gammas()->fBlue.fValue; |
- dstGammas[0] = 1.0f / as_CSB(dstSpace)->gammas()->fRed.fValue; |
- dstGammas[1] = 1.0f / as_CSB(dstSpace)->gammas()->fGreen.fValue; |
- dstGammas[2] = 1.0f / as_CSB(dstSpace)->gammas()->fBlue.fValue; |
- |
- return std::unique_ptr<SkColorSpaceXform>( |
- new SkGammaByValueXform(srcGammas, srcToDst, dstGammas)); |
+ if (SkColorSpace::k2Dot2Curve_GammaNamed == srcSpace->gammaNamed() && |
+ SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gammaNamed()) |
+ { |
+ return std::unique_ptr<SkColorSpaceXform>(new Sk2Dot2Xform(srcToDst)); |
} |
return std::unique_ptr<SkColorSpaceXform>( |
@@ -56,72 +49,53 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
+Sk2Dot2Xform::Sk2Dot2Xform(const SkMatrix44& srcToDst) |
+{ |
+ // Build row major 4x4 matrix: |
+ // rX gX bX 0 |
+ // rY gY bY 0 |
+ // rZ gZ bZ 0 |
+ // rQ gQ bQ 0 |
+ fSrcToDst[0] = srcToDst.getFloat(0, 0); |
+ fSrcToDst[1] = srcToDst.getFloat(0, 1); |
+ fSrcToDst[2] = srcToDst.getFloat(0, 2); |
+ fSrcToDst[3] = 0.0f; |
+ fSrcToDst[4] = srcToDst.getFloat(1, 0); |
+ fSrcToDst[5] = srcToDst.getFloat(1, 1); |
+ fSrcToDst[6] = srcToDst.getFloat(1, 2); |
+ fSrcToDst[7] = 0.0f; |
+ fSrcToDst[8] = srcToDst.getFloat(2, 0); |
+ fSrcToDst[9] = srcToDst.getFloat(2, 1); |
+ fSrcToDst[10] = srcToDst.getFloat(2, 2); |
+ fSrcToDst[11] = 0.0f; |
+ fSrcToDst[12] = srcToDst.getFloat(3, 0); |
+ fSrcToDst[13] = srcToDst.getFloat(3, 1); |
+ fSrcToDst[14] = srcToDst.getFloat(3, 2); |
+ fSrcToDst[15] = 0.0f; |
+} |
+ |
+void Sk2Dot2Xform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { |
+ SkOpts::color_xform_2Dot2_RGBA_to_8888(dst, src, len, fSrcToDst); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
static inline float byte_to_float(uint8_t v) { |
return ((float) v) * (1.0f / 255.0f); |
} |
-static inline uint8_t clamp_float_to_byte(float v) { |
+// Expand range from 0-1 to 0-255, then convert. |
+static inline uint8_t clamp_normalized_float_to_byte(float v) { |
v = v * 255.0f; |
- if (v > 255.0f) { |
+ if (v >= 254.5f) { |
return 255; |
- } else if (v <= 0.0f) { |
+ } else if (v < 0.5f) { |
return 0; |
} else { |
return (uint8_t) (v + 0.5f); |
} |
} |
-/////////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-SkGammaByValueXform::SkGammaByValueXform(float srcGammas[3], const SkMatrix44& srcToDst, |
- float dstGammas[3]) |
- : fSrcToDst(srcToDst) |
-{ |
- memcpy(fSrcGammas, srcGammas, 3 * sizeof(float)); |
- memcpy(fDstGammas, dstGammas, 3 * sizeof(float)); |
-} |
- |
-void SkGammaByValueXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { |
- while (len-- > 0) { |
- float srcFloats[3]; |
- srcFloats[0] = byte_to_float((*src >> 0) & 0xFF); |
- srcFloats[1] = byte_to_float((*src >> 8) & 0xFF); |
- srcFloats[2] = byte_to_float((*src >> 16) & 0xFF); |
- |
- // Convert to linear. |
- srcFloats[0] = pow(srcFloats[0], fSrcGammas[0]); |
- srcFloats[1] = pow(srcFloats[1], fSrcGammas[1]); |
- srcFloats[2] = pow(srcFloats[2], fSrcGammas[2]); |
- |
- // Convert to dst gamut. |
- float dstFloats[3]; |
- dstFloats[0] = srcFloats[0] * fSrcToDst.getFloat(0, 0) + |
- srcFloats[1] * fSrcToDst.getFloat(1, 0) + |
- srcFloats[2] * fSrcToDst.getFloat(2, 0) + fSrcToDst.getFloat(3, 0); |
- dstFloats[1] = srcFloats[0] * fSrcToDst.getFloat(0, 1) + |
- srcFloats[1] * fSrcToDst.getFloat(1, 1) + |
- srcFloats[2] * fSrcToDst.getFloat(2, 1) + fSrcToDst.getFloat(3, 1); |
- dstFloats[2] = srcFloats[0] * fSrcToDst.getFloat(0, 2) + |
- srcFloats[1] * fSrcToDst.getFloat(1, 2) + |
- srcFloats[2] * fSrcToDst.getFloat(2, 2) + fSrcToDst.getFloat(3, 2); |
- |
- // Convert to dst gamma. |
- dstFloats[0] = pow(dstFloats[0], fDstGammas[0]); |
- dstFloats[1] = pow(dstFloats[1], fDstGammas[1]); |
- dstFloats[2] = pow(dstFloats[2], fDstGammas[2]); |
- |
- *dst = SkPackARGB32NoCheck(((*src >> 24) & 0xFF), |
- clamp_float_to_byte(dstFloats[0]), |
- clamp_float_to_byte(dstFloats[1]), |
- clamp_float_to_byte(dstFloats[2])); |
- |
- dst++; |
- src++; |
- } |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////////// |
- |
// Interpolating lookup in a variably sized table. |
static inline float interp_lut(uint8_t byte, float* table, size_t tableSize) { |
float index = byte_to_float(byte) * (tableSize - 1); |
@@ -261,9 +235,9 @@ void SkDefaultXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_ |
} |
*dst = SkPackARGB32NoCheck(((*src >> 24) & 0xFF), |
- clamp_float_to_byte(dstFloats[0]), |
- clamp_float_to_byte(dstFloats[1]), |
- clamp_float_to_byte(dstFloats[2])); |
+ clamp_normalized_float_to_byte(dstFloats[0]), |
+ clamp_normalized_float_to_byte(dstFloats[1]), |
+ clamp_normalized_float_to_byte(dstFloats[2])); |
dst++; |
src++; |