diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkColorSpaceXform.cpp | 92 | ||||
-rw-r--r-- | src/core/SkColorSpaceXform.h | 29 | ||||
-rw-r--r-- | src/core/SkOpts.cpp | 6 | ||||
-rw-r--r-- | src/core/SkOpts.h | 9 |
4 files changed, 93 insertions, 43 deletions
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp index e142011305..4c67e8d3f0 100644 --- a/src/core/SkColorSpaceXform.cpp +++ b/src/core/SkColorSpaceXform.cpp @@ -37,10 +37,16 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa return nullptr; } - if (SkColorSpace::k2Dot2Curve_GammaNamed == srcSpace->gammaNamed() && - SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gammaNamed()) + if (SkColorSpace::k2Dot2Curve_GammaNamed == dstSpace->gammaNamed() && + 0.0f == srcToDst.getFloat(3, 0) && + 0.0f == srcToDst.getFloat(3, 1) && + 0.0f == srcToDst.getFloat(3, 2)) { - return std::unique_ptr<SkColorSpaceXform>(new Sk2Dot2Xform(srcToDst)); + if (SkColorSpace::kSRGB_GammaNamed == srcSpace->gammaNamed()) { + return std::unique_ptr<SkColorSpaceXform>(new SkSRGBTo2Dot2Xform(srcToDst)); + } else if (SkColorSpace::k2Dot2Curve_GammaNamed == srcSpace->gammaNamed()) { + return std::unique_ptr<SkColorSpaceXform>(new Sk2Dot2To2Dot2Xform(srcToDst)); + } } return std::unique_ptr<SkColorSpaceXform>( @@ -49,33 +55,59 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpa /////////////////////////////////////////////////////////////////////////////////////////////////// -Sk2Dot2Xform::Sk2Dot2Xform(const SkMatrix44& srcToDst) -{ - // Build row major 4x4 matrix: +static void build_src_to_dst(float srcToDstArray[12], const SkMatrix44& srcToDstMatrix) { + // Build the following row major 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; + // Swap R and B if necessary to make sure that we output SkPMColor order. +#ifdef SK_PMCOLOR_IS_BGRA + srcToDstArray[0] = srcToDstMatrix.getFloat(0, 2); + srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1); + srcToDstArray[2] = srcToDstMatrix.getFloat(0, 0); + srcToDstArray[3] = 0.0f; + srcToDstArray[4] = srcToDstMatrix.getFloat(1, 2); + srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1); + srcToDstArray[6] = srcToDstMatrix.getFloat(1, 0); + srcToDstArray[7] = 0.0f; + srcToDstArray[8] = srcToDstMatrix.getFloat(2, 2); + srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1); + srcToDstArray[10] = srcToDstMatrix.getFloat(2, 0); + srcToDstArray[11] = 0.0f; +#else + srcToDstArray[0] = srcToDstMatrix.getFloat(0, 0); + srcToDstArray[1] = srcToDstMatrix.getFloat(0, 1); + srcToDstArray[2] = srcToDstMatrix.getFloat(0, 2); + srcToDstArray[3] = 0.0f; + srcToDstArray[4] = srcToDstMatrix.getFloat(1, 0); + srcToDstArray[5] = srcToDstMatrix.getFloat(1, 1); + srcToDstArray[6] = srcToDstMatrix.getFloat(1, 2); + srcToDstArray[7] = 0.0f; + srcToDstArray[8] = srcToDstMatrix.getFloat(2, 0); + srcToDstArray[9] = srcToDstMatrix.getFloat(2, 1); + srcToDstArray[10] = srcToDstMatrix.getFloat(2, 2); + srcToDstArray[11] = 0.0f; +#endif +} + +SkSRGBTo2Dot2Xform::SkSRGBTo2Dot2Xform(const SkMatrix44& srcToDst) +{ + build_src_to_dst(fSrcToDst, srcToDst); +} + +void SkSRGBTo2Dot2Xform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { + SkOpts::color_xform_RGB1_srgb_to_2dot2(dst, src, len, fSrcToDst); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +Sk2Dot2To2Dot2Xform::Sk2Dot2To2Dot2Xform(const SkMatrix44& srcToDst) +{ + build_src_to_dst(fSrcToDst, srcToDst); } -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); +void Sk2Dot2To2Dot2Xform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { + SkOpts::color_xform_RGB1_2dot2_to_2dot2(dst, src, len, fSrcToDst); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -86,13 +118,15 @@ static inline float byte_to_float(uint8_t v) { // Expand range from 0-1 to 0-255, then convert. static inline uint8_t clamp_normalized_float_to_byte(float v) { + // The ordering of the logic is a little strange here in order + // to make sure we convert NaNs to 0. v = v * 255.0f; if (v >= 254.5f) { return 255; - } else if (v < 0.5f) { - return 0; - } else { + } else if (v >= 0.5f) { return (uint8_t) (v + 0.5f); + } else { + return 0; } } @@ -142,7 +176,7 @@ SkDefaultXform::SkDefaultXform(const sk_sp<SkGammas>& srcGammas, const SkMatrix4 , fDstGammas(dstGammas) {} -void SkDefaultXform::xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { +void SkDefaultXform::xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const { while (len-- > 0) { // Convert to linear. // FIXME (msarett): diff --git a/src/core/SkColorSpaceXform.h b/src/core/SkColorSpaceXform.h index 3472643519..1ea608094f 100644 --- a/src/core/SkColorSpaceXform.h +++ b/src/core/SkColorSpaceXform.h @@ -26,23 +26,36 @@ public: /** * Apply the color conversion to a src buffer, storing the output in the dst buffer. - * The src is stored in RGBA_8888 and the dst is stored in 8888 platform format. - * The output is not premultiplied. + * The src is opaque and stored in RGBA_8888, and the dst is also opaque and stored + * in 8888 platform format. */ - virtual void xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const = 0; + virtual void xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const = 0; virtual ~SkColorSpaceXform() {} }; -class Sk2Dot2Xform : public SkColorSpaceXform { +class SkSRGBTo2Dot2Xform : public SkColorSpaceXform { public: - void xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const override; + void xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const override; private: - Sk2Dot2Xform(const SkMatrix44& srcToDst); + SkSRGBTo2Dot2Xform(const SkMatrix44& srcToDst); - float fSrcToDst[16]; + float fSrcToDst[12]; + + friend class SkColorSpaceXform; +}; + +class Sk2Dot2To2Dot2Xform : public SkColorSpaceXform { +public: + + void xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const override; + +private: + Sk2Dot2To2Dot2Xform(const SkMatrix44& srcToDst); + + float fSrcToDst[12]; friend class SkColorSpaceXform; }; @@ -53,7 +66,7 @@ private: class SkDefaultXform : public SkColorSpaceXform { public: - void xform_RGBA_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const override; + void xform_RGB1_8888(uint32_t* dst, const uint32_t* src, uint32_t len) const override; private: SkDefaultXform(const sk_sp<SkGammas>& srcGammas, const SkMatrix44& srcToDst, diff --git a/src/core/SkOpts.cpp b/src/core/SkOpts.cpp index 8dec3fad0f..b4145acb7a 100644 --- a/src/core/SkOpts.cpp +++ b/src/core/SkOpts.cpp @@ -77,8 +77,10 @@ namespace SkOpts { decltype(srcover_srgb_srgb) srcover_srgb_srgb = sk_default::srcover_srgb_srgb; - decltype(color_xform_2Dot2_RGBA_to_8888) color_xform_2Dot2_RGBA_to_8888 = - sk_default::color_xform_2Dot2_RGBA_to_8888; + decltype(color_xform_RGB1_srgb_to_2dot2) color_xform_RGB1_srgb_to_2dot2 = + sk_default::color_xform_RGB1_srgb_to_2dot2; + decltype(color_xform_RGB1_2dot2_to_2dot2) color_xform_RGB1_2dot2_to_2dot2 = + sk_default::color_xform_RGB1_2dot2_to_2dot2; // Each Init_foo() is defined in src/opts/SkOpts_foo.cpp. void Init_ssse3(); diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h index 0711471fb4..1c33529d52 100644 --- a/src/core/SkOpts.h +++ b/src/core/SkOpts.h @@ -69,10 +69,11 @@ namespace SkOpts { // If nsrc < ndst, we loop over src to create a pattern. extern void (*srcover_srgb_srgb)(uint32_t* dst, const uint32_t* src, int ndst, int nsrc); - // Color xform RGBA input into SkPMColor ordered 8888 pixels. Does not premultiply, and - // assumes src and dst gamma curves are both 2.2f exponentials. - extern void (*color_xform_2Dot2_RGBA_to_8888)(uint32_t* dst, const uint32_t* src, int len, - const float srcToDstMatrix[16]); + // Color xform RGB1 pixels. Does not change byte ordering. + extern void (*color_xform_RGB1_srgb_to_2dot2) (uint32_t* dst, const uint32_t* src, int len, + const float srcToDstMatrix[16]); + extern void (*color_xform_RGB1_2dot2_to_2dot2)(uint32_t* dst, const uint32_t* src, int len, + const float srcToDstMatrix[16]); } #endif//SkOpts_DEFINED |