From ded7532e57f3c98dd961b9db932163f0a4647e2e Mon Sep 17 00:00:00 2001 From: "sub.mohanty@samsung.com" Date: Tue, 21 Aug 2018 00:31:57 +0900 Subject: [PATCH] lottie/vector: added Xor operation to Rle object Change-Id: I48cb3680a22ce3fb7f07048385dd5cc518ff9c7e --- src/vector/vrle.cpp | 46 +++++++++++++++++++++++++++++++++++++++++----- src/vector/vrle.h | 20 ++++++++++++++++++-- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/vector/vrle.cpp b/src/vector/vrle.cpp index 67a5e60..1ab7393 100644 --- a/src/vector/vrle.cpp +++ b/src/vector/vrle.cpp @@ -10,6 +10,11 @@ V_BEGIN_NAMESPACE +enum class Operation { + Add, + Xor +}; + struct VRleHelper { ushort alloc; ushort size; @@ -18,7 +23,7 @@ struct VRleHelper { static void rleIntersectWithRle(VRleHelper *, int, int, VRleHelper *, VRleHelper *); static void rleIntersectWithRect(const VRect &, VRleHelper *, VRleHelper *); -static void rleAddWithRle(VRleHelper *, VRleHelper *, VRleHelper *); +static void rleOpGeneric(VRleHelper *, VRleHelper *, VRleHelper *, Operation op); static void rleSubstractWithRle(VRleHelper *, VRleHelper *, VRleHelper *); static inline uchar divBy255(int x) @@ -207,7 +212,7 @@ void VRle::VRleData::opSubstract(const VRle::VRleData &a, mBboxDirty = true; } -void VRle::VRleData::opAdd(const VRle::VRleData &a, const VRle::VRleData &b) +void VRle::VRleData::opGeneric(const VRle::VRleData &a, const VRle::VRleData &b, OpCode code) { // This routine assumes, obj1(span_y) < obj2(span_y). @@ -256,9 +261,20 @@ void VRle::VRleData::opAdd(const VRle::VRleData &a, const VRle::VRleData &b) bObj.size = b.mSpans.size() - sizeB; bObj.spans = bPtr; + Operation op = Operation::Add; + switch (code) { + case OpCode::Add: + op = Operation::Add; + break; + case OpCode::Xor: + op = Operation::Xor; + break; + default: + break; + } // run till all the spans are processed while (aObj.size && bObj.size) { - rleAddWithRle(&aObj, &bObj, &tresult); + rleOpGeneric(&aObj, &bObj, &tresult, op); if (tresult.size) { copyArrayToVector(tresult.spans, tresult.size, mSpans); } @@ -443,6 +459,23 @@ static void rleIntersectWithRect(const VRect &clip, VRleHelper *tmp_obj, result->size = result->alloc - available; } +void blitXor(VRle::Span *spans, int count, uchar *buffer, + int offsetX) +{ + uchar *ptr; + while (count--) { + int x = spans->x + offsetX; + int l = spans->len; + ptr = buffer + x; + while (l--) { + int da = *ptr; + *ptr = divBy255((255 - spans->coverage) * (da) + spans->coverage * (255 - da)); + ptr++; + } + spans++; + } +} + void blitDestinationOut(VRle::Span *spans, int count, uchar *buffer, int offsetX) { @@ -522,7 +555,7 @@ int bufferToRle(uchar *buffer, int size, int offsetX, int y, VRle::Span *out) return count; } -static void rleAddWithRle(VRleHelper *a, VRleHelper *b, VRleHelper *result) +static void rleOpGeneric(VRleHelper *a, VRleHelper *b, VRleHelper *result, Operation op) { std::array temp; VRle::Span * out = result->spans; @@ -554,7 +587,10 @@ static void rleAddWithRle(VRleHelper *a, VRleHelper *b, VRleHelper *result) std::array array = {{0}}; blit(aStart, (aPtr - aStart), array.data(), -offset); - blitSrcOver(bStart, (bPtr - bStart), array.data(), -offset); + if (op == Operation::Add) + blitSrcOver(bStart, (bPtr - bStart), array.data(), -offset); + else if (op == Operation::Xor) + blitXor(bStart, (bPtr - bStart), array.data(), -offset); VRle::Span *tResult = temp.data(); int size = bufferToRle(array.data(), std::max(aLength, bLength), offset, y, tResult); diff --git a/src/vector/vrle.h b/src/vector/vrle.h index 9a45824..e5ecc36 100644 --- a/src/vector/vrle.h +++ b/src/vector/vrle.h @@ -34,11 +34,16 @@ public: VRle operator&(const VRle &o) const; VRle operator-(const VRle &o) const; VRle operator+(const VRle &o) const; + VRle operator^(const VRle &o) const; static VRle toRle(const VRect &rect); private: struct VRleData { + enum class OpCode { + Add, + Xor + }; bool isEmpty() const { return mSpans.empty(); } void addSpan(const VRle::Span *span, int count); void updateBbox() const; @@ -48,7 +53,7 @@ private: void operator*=(int alpha); void invert(); void opIntersect(const VRect &, VRle::VRleSpanCb, void *) const; - void opAdd(const VRle::VRleData &, const VRle::VRleData &); + void opGeneric(const VRle::VRleData &, const VRle::VRleData &, OpCode code); void opSubstract(const VRle::VRleData &, const VRle::VRleData &); void opIntersect(const VRle::VRleData &, const VRle::VRleData &); void addRect(const VRect &rect); @@ -102,7 +107,18 @@ inline VRle VRle::operator+(const VRle &o) const if (o.isEmpty()) return *this; VRle result; - result.d.write().opAdd(d.read(), o.d.read()); + result.d.write().opGeneric(d.read(), o.d.read(), VRleData::OpCode::Add); + + return result; +} + +inline VRle VRle::operator^(const VRle &o) const +{ + if (isEmpty()) return o; + if (o.isEmpty()) return *this; + + VRle result; + result.d.write().opGeneric(d.read(), o.d.read(), VRleData::OpCode::Xor); return result; } -- 2.7.4