aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkColorSpaceXform.cpp92
-rw-r--r--src/core/SkColorSpaceXform.h29
-rw-r--r--src/core/SkOpts.cpp6
-rw-r--r--src/core/SkOpts.h9
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