summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsubhransu sekhar mohanty <smohantty@subhransus-MacBook-Air.local>2018-07-08 11:17:48 +0900
committersubhransu sekhar mohanty <smohantty@subhransus-MacBook-Air.local>2018-07-08 23:17:18 +0900
commit4904ff62ef9afa35fe8320cd1d2f7bd388b3c292 (patch)
tree5150d0a2f07bd9df9896e3928fc6cb466945393c
parentf9352eaf974f85acd9f577f4ef480aaacfd6a0f0 (diff)
lottie: added + operator to sgrle class
-rw-r--r--include/sgpoint.h7
-rw-r--r--include/sgrect.h8
-rw-r--r--include/sgrle.h4
-rw-r--r--src/util/sgrle.cpp303
4 files changed, 309 insertions, 13 deletions
diff --git a/include/sgpoint.h b/include/sgpoint.h
index 73af41e..b8430f1 100644
--- a/include/sgpoint.h
+++ b/include/sgpoint.h
@@ -81,6 +81,7 @@ public:
81 inline SGPoint &operator-=(const SGPoint &p) noexcept; 81 inline SGPoint &operator-=(const SGPoint &p) noexcept;
82 constexpr inline bool operator==(const SGPoint &o) const; 82 constexpr inline bool operator==(const SGPoint &o) const;
83 constexpr inline bool operator!=(const SGPoint &o) const { return !(operator==(o)); } 83 constexpr inline bool operator!=(const SGPoint &o) const { return !(operator==(o)); }
84 friend inline SGPoint operator-(const SGPoint &p1, const SGPoint &p2);
84 inline friend SGDebug& operator<<(SGDebug& os, const SGPoint& o); 85 inline friend SGDebug& operator<<(SGDebug& os, const SGPoint& o);
85private: 86private:
86 int mx; 87 int mx;
@@ -91,6 +92,12 @@ inline SGDebug& operator<<(SGDebug& os, const SGPoint& o)
91 os<<"{P "<<o.x()<<","<<o.y()<<"}"; 92 os<<"{P "<<o.x()<<","<<o.y()<<"}";
92 return os; 93 return os;
93} 94}
95
96inline SGPoint operator-(const SGPoint &p1, const SGPoint &p2)
97{
98 return SGPoint(p1.mx-p2.mx, p1.my-p2.my);
99}
100
94constexpr inline bool SGPoint::operator ==(const SGPoint &o) const 101constexpr inline bool SGPoint::operator ==(const SGPoint &o) const
95{ 102{
96 return (mx == o.x() && my == o.y()); 103 return (mx == o.x() && my == o.y());
diff --git a/include/sgrect.h b/include/sgrect.h
index e5aa226..c3696e2 100644
--- a/include/sgrect.h
+++ b/include/sgrect.h
@@ -29,6 +29,7 @@ public:
29 inline SGRect translated(int dx, int dy) const ; 29 inline SGRect translated(int dx, int dy) const ;
30 inline void translate(int dx, int dy); 30 inline void translate(int dx, int dy);
31 inline bool contains(const SGRect &r, bool proper = false) const; 31 inline bool contains(const SGRect &r, bool proper = false) const;
32 inline bool intersects(const SGRect &r);
32 friend SG_CONSTEXPR inline bool operator==(const SGRect &, const SGRect &) noexcept; 33 friend SG_CONSTEXPR inline bool operator==(const SGRect &, const SGRect &) noexcept;
33 friend SG_CONSTEXPR inline bool operator!=(const SGRect &, const SGRect &) noexcept; 34 friend SG_CONSTEXPR inline bool operator!=(const SGRect &, const SGRect &) noexcept;
34 friend SGDebug& operator<<(SGDebug& os, const SGRect& o); 35 friend SGDebug& operator<<(SGDebug& os, const SGRect& o);
@@ -38,6 +39,13 @@ private:
38 int x2; 39 int x2;
39 int y2; 40 int y2;
40}; 41};
42
43inline bool SGRect::intersects(const SGRect &r)
44{
45 return (right() >= r.left() && left() <= r.right() &&
46 bottom() >= r.top() && top() <= r.bottom());
47}
48
41inline SGDebug& operator<<(SGDebug& os, const SGRect& o) 49inline SGDebug& operator<<(SGDebug& os, const SGRect& o)
42{ 50{
43 os<<"{R "<<o.x()<<","<<o.y()<<","<<o.width()<<","<<o.height()<<"}"; 51 os<<"{R "<<o.x()<<","<<o.y()<<","<<o.width()<<","<<o.height()<<"}";
diff --git a/include/sgrle.h b/include/sgrle.h
index 32682c0..46db345 100644
--- a/include/sgrle.h
+++ b/include/sgrle.h
@@ -35,6 +35,10 @@ public:
35 int size() const; 35 int size() const;
36 const SGRle::Span* data() const; 36 const SGRle::Span* data() const;
37 SGRle operator~() const; 37 SGRle operator~() const;
38 SGRle operator+(const SGRle &o) const;
39 SGRle operator-(const SGRle &o) const;
40 SGRle operator&(const SGRle &o) const;
41 static SGRle toRle(const SGRectF &rect);
38 friend SGRle operator*(const SGRle &, float alpha); 42 friend SGRle operator*(const SGRle &, float alpha);
39 inline friend SGRle operator*(float alpha, const SGRle &); 43 inline friend SGRle operator*(float alpha, const SGRle &);
40 friend SGDebug& operator<<(SGDebug& os, const SGRle& object); 44 friend SGDebug& operator<<(SGDebug& os, const SGRle& object);
diff --git a/src/util/sgrle.cpp b/src/util/sgrle.cpp
index 20d64b5..6c66d0e 100644
--- a/src/util/sgrle.cpp
+++ b/src/util/sgrle.cpp
@@ -6,6 +6,7 @@
6#include<array> 6#include<array>
7#include<algorithm> 7#include<algorithm>
8#include"sgdebug.h" 8#include"sgdebug.h"
9#include"sgregion.h"
9 10
10struct SGRleHelper 11struct SGRleHelper
11{ 12{
@@ -179,11 +180,145 @@ rleIntersectWithRect(const SGRect &clip,
179 result->size = result->alloc - available; 180 result->size = result->alloc - available;
180} 181}
181 182
183static void
184rleAddWithRle(SGRleHelper *tmp_clip,
185 SGRleHelper *tmp_obj,
186 SGRleHelper *result)
187{
188 SGRle::Span *out = result->spans;
189 int available = result->alloc;
190 SGRle::Span *spans = tmp_obj->spans;
191 SGRle::Span *end = tmp_obj->spans + tmp_obj->size;
192 SGRle::Span *clipSpans = tmp_clip->spans;
193 SGRle::Span *clipEnd = tmp_clip->spans + tmp_clip->size;
194 int sx1, sx2, cx1, cx2, x, len;
195
196
197 while (available && spans < end )
198 {
199 if (clipSpans >= clipEnd)
200 {
201 *out++ = *spans++;
202 available--;
203 break;
204 }
205 if (clipSpans->y < spans->y)
206 {
207 *out++ = *clipSpans++;
208 available--;
209 continue;
210 }
211 if (spans->y < clipSpans->y)
212 {
213 *out++ = *spans++;
214 available--;
215 continue;
216 }
217 sx1 = spans->x;
218 sx2 = sx1 + spans->len;
219 cx1 = (clipSpans->x);
220 cx2 = cx1 + clipSpans->len;
221
222 if (cx1 < sx1 && cx2 < sx1) {
223 *out++ = *clipSpans++;
224 available--;
225 continue;
226 } else if (sx1 < cx1 && sx2 < cx1) {
227 *out++ = *spans++;
228 available--;
229 continue;
230 } else if (spans->coverage == clipSpans->coverage) { //merge
231 out->x = SGMIN(cx1, sx1);
232 out->len = SGMAX(cx2, sx2) - out->x;
233 out->coverage = spans->coverage;
234 out->y = spans->y;
235 out++; spans++ ; clipSpans++; available--;
236 } else if (cx1 <= sx1) {
237 if (available < 3)
238 break;
239 // segment 1
240 int l = sx1 - cx1;
241 if (l) {
242 *out = *clipSpans;
243 out->len = sx1 - cx1;
244 out++; available--;
245 }
246 // segment 2
247 l = SGMIN(cx2, sx2) - sx1;
248 if (l) {
249 *out = *spans;
250 out->len = l;
251 out->coverage = divBy255(spans->coverage * clipSpans->coverage);
252 out++; available--;
253 }
254 // segment 3
255 if (cx2 <= sx2) {
256 l = sx2 - cx2;
257 if (l) {
258 *out = *spans;
259 out->len = l;
260 out->x = cx2; //+1 ?
261 }
262 } else {
263 *out = *clipSpans;
264 out->len = cx2 - sx2;
265 out->x = sx2;//+1 ?
266 }
267 clipSpans++; spans++;
268 } else if (sx1 < cx1) {
269 if (available < 3)
270 break;
271 // segment 1
272 int l = cx1 - sx1;
273 *out = *spans;
274 out->len = l;
275 out++; available--;
276
277 // segment 2
278 l = SGMIN(cx2, sx2) - cx1;
279 if (l) {
280 *out = *clipSpans;
281 out->len = l;
282 out->coverage = divBy255(spans->coverage * clipSpans->coverage);
283 out++; available--;
284 }
285 // segment 3
286 if (cx2 <= sx2) {
287 l = sx2 - cx2;
288 if (l) {
289 *out = *spans;
290 out->len = l;
291 out->x = cx2;//+1 ?
292 out++; available--;
293 }
294 } else {
295 *out = *clipSpans;
296 out->len = cx2 - sx2;
297 out->x = sx2;//+1 ?
298 out++; available--;
299 }
300 clipSpans++; spans++;
301 }
302 }
303
304 // update the span list that yet to be processed
305 tmp_obj->spans = spans;
306 tmp_obj->size = end - spans;
307
308 // update the clip list that yet to be processed
309 tmp_clip->spans = clipSpans;
310 tmp_clip->size = clipEnd - clipSpans;
311
312 // update the result
313 result->size = result->alloc - available;
314}
315
316
182 317
183class SGRleImpl 318class SGRleImpl
184{ 319{
185public: 320public:
186 inline SGRleImpl():m_bbox(),m_spans(){} 321 inline SGRleImpl():m_bbox(),m_spans(), mOffset(), mBboxDirty(true){}
187 SGRleImpl &operator=(const SGRleImpl &); 322 SGRleImpl &operator=(const SGRleImpl &);
188 void addSpan(const SGRle::Span *span, int count); 323 void addSpan(const SGRle::Span *span, int count);
189 void updateBbox(); 324 void updateBbox();
@@ -193,10 +328,14 @@ public:
193 friend SGDebug& operator<<(SGDebug& os, const SGRleImpl& object); 328 friend SGDebug& operator<<(SGDebug& os, const SGRleImpl& object);
194 void invert(); 329 void invert();
195 void alphaMul(int alpha); 330 void alphaMul(int alpha);
331 void translate(const SGPoint &pt);
332 void opAdd(const SGRleImpl &other, SGRleImpl &res);
333 SGRect bbox();
196public: 334public:
197 SGRect m_bbox; 335 SGRect m_bbox;
198 std::vector<SGRle::Span> m_spans;// array of Spanlines. 336 std::vector<SGRle::Span> m_spans;// array of Spanlines.
199 SGPoint m_offset; 337 SGPoint mOffset;
338 bool mBboxDirty;
200}; 339};
201 340
202inline static void 341inline static void
@@ -209,7 +348,7 @@ copyArrayToVector(const SGRle::Span *span, int count, std::vector<SGRle::Span> &
209 348
210SGDebug& operator<<(SGDebug& os, const SGRleImpl& o) 349SGDebug& operator<<(SGDebug& os, const SGRleImpl& o)
211{ 350{
212 os<<"[bbox="<< o.m_bbox<<"]"<<"[offset="<<o.m_offset<<"]"<< 351 os<<"[bbox="<< o.m_bbox<<"]"<<"[offset="<<o.mOffset<<"]"<<
213 "[span count ="<<o.m_spans.size()<<"]\n"; 352 "[span count ="<<o.m_spans.size()<<"]\n";
214 os<<"[rle spans = {x y len coverage}"; 353 os<<"[rle spans = {x y len coverage}";
215 for(auto sp : o.m_spans) 354 for(auto sp : o.m_spans)
@@ -218,6 +357,26 @@ SGDebug& operator<<(SGDebug& os, const SGRleImpl& o)
218 return os; 357 return os;
219} 358}
220 359
360SGRect SGRleImpl::bbox()
361{
362 updateBbox();
363 return m_bbox;
364}
365
366void SGRleImpl::translate(const SGPoint &pt)
367{
368 //take care of last offset if applied
369 mOffset = pt - mOffset;
370 int x = mOffset.x();
371 int y = mOffset.y();
372 for (auto &i : m_spans) {
373 i.x = i.x + x;
374 i.y = i.y + y;
375 }
376 updateBbox();
377 m_bbox.translate(mOffset.x(), mOffset.y());
378}
379
221void SGRleImpl::invert() 380void SGRleImpl::invert()
222{ 381{
223 for (auto &i : m_spans) { 382 for (auto &i : m_spans) {
@@ -236,7 +395,7 @@ void SGRleImpl::alphaMul(int alpha)
236 395
237void SGRleImpl::intersected(const SGRect &r, SGRleImpl &result) 396void SGRleImpl::intersected(const SGRect &r, SGRleImpl &result)
238{ 397{
239 SGRect clip = r.translated(-m_offset.x(), -m_offset.y()); 398 SGRect clip = r;
240 399
241 SGRleHelper tresult, tmp_obj; 400 SGRleHelper tresult, tmp_obj;
242 std::array<SGRle::Span,256> array; 401 std::array<SGRle::Span,256> array;
@@ -283,7 +442,7 @@ void SGRleImpl::intersected(const SGRleImpl &clip, SGRleImpl &result)
283 // run till all the spans are processed 442 // run till all the spans are processed
284 while (tmp_obj.size) 443 while (tmp_obj.size)
285 { 444 {
286 rleIntersectWithRle(&tmp_clip, -clip.m_offset.x(), -clip.m_offset.y(), &tmp_obj, &tresult); 445 rleIntersectWithRle(&tmp_clip, 0, 0, &tmp_obj, &tresult);
287 if (tresult.size) { 446 if (tresult.size) {
288 copyArrayToVector(tresult.spans, tresult.size, result.m_spans); 447 copyArrayToVector(tresult.spans, tresult.size, result.m_spans);
289 } 448 }
@@ -292,19 +451,72 @@ void SGRleImpl::intersected(const SGRleImpl &clip, SGRleImpl &result)
292 result.updateBbox(); 451 result.updateBbox();
293} 452}
294 453
454void SGRleImpl::opAdd(const SGRleImpl &other, SGRleImpl &result)
455{
456 // reserve some space for the result vector.
457 result.m_spans.reserve(m_spans.size() + other.m_spans.size());
458 // if two rle are disjoint
459 if (!m_bbox.intersects(other.m_bbox)) {
460 result.m_spans = m_spans;
461 copyArrayToVector(other.m_spans.data(), other.m_spans.size(), result.m_spans);
462 } else {
463 SGRle::Span *ptr = m_spans.data();
464 int otherY = other.m_bbox.top();
465 // 1. forward till both y intersect
466 while (ptr->y < otherY) ptr++;
467 int spanToCopy = ptr - m_spans.data();
468 copyArrayToVector(m_spans.data(), spanToCopy, result.m_spans);
469
470 // 2. calculate the intersect region
471 SGRleHelper tresult, tmp_obj, tmp_other;
472 std::array<SGRle::Span,256> array;
473
474 //setup the tresult object
475 tresult.size = array.size();
476 tresult.alloc = array.size();
477 tresult.spans = array.data();
478
479 // setup tmp object
480 tmp_obj.size = m_spans.size() - spanToCopy;
481 tmp_obj.spans = ptr;
482
483 //setup tmp clip object
484 tmp_other.size = other.m_spans.size();
485 tmp_other.spans = const_cast<SGRle::Span *>(other.m_spans.data());
486
487 // run till all the spans are processed
488 while (tmp_obj.size)
489 {
490 rleAddWithRle(&tmp_other, &tmp_obj, &tresult);
491 if (tresult.size) {
492 copyArrayToVector(tresult.spans, tresult.size, result.m_spans);
493 }
494 tresult.size = 0;
495 }
496 //3. copy the rest
497 if (tmp_other.size) {
498 copyArrayToVector(tmp_other.spans, tmp_other.size, result.m_spans);
499 }
500 }
501
502 // update result bounding box
503 SGRegion reg(m_bbox);
504 reg += other.m_bbox;
505 result.m_bbox = reg.boundingRect();
506 result.mBboxDirty = false;
507}
508
295 509
296SGRleImpl &SGRleImpl::operator=(const SGRleImpl &other) 510SGRleImpl &SGRleImpl::operator=(const SGRleImpl &other)
297{ 511{
298 m_spans = other.m_spans; 512 m_spans = other.m_spans;
299 m_bbox = other.m_bbox; 513 m_bbox = other.m_bbox;
514 mOffset = other.mOffset;
300 return *this; 515 return *this;
301} 516}
302 517
303bool SGRleImpl::operator ==(const SGRleImpl &other) const 518bool SGRleImpl::operator ==(const SGRleImpl &other) const
304{ 519{
305 if (m_offset != other.m_offset)
306 return false;
307
308 if (m_spans.size() != other.m_spans.size()) 520 if (m_spans.size() != other.m_spans.size())
309 return false; 521 return false;
310 const SGRle::Span *spans = m_spans.data(); 522 const SGRle::Span *spans = m_spans.data();
@@ -318,14 +530,16 @@ bool SGRleImpl::operator ==(const SGRleImpl &other) const
318 spans[i].coverage != o_spans[i].coverage) 530 spans[i].coverage != o_spans[i].coverage)
319 return false; 531 return false;
320 } 532 }
321
322 return true; 533 return true;
323
324} 534}
325 535
326 536
327void SGRleImpl::updateBbox() 537void SGRleImpl::updateBbox()
328{ 538{
539 if (!mBboxDirty) return;
540
541 mBboxDirty = false;
542
329 int i, l = 0, t = 0, r = 0, b = 0, sz; 543 int i, l = 0, t = 0, r = 0, b = 0, sz;
330 l = std::numeric_limits<int>::max(); 544 l = std::numeric_limits<int>::max();
331 const SGRle::Span *span = m_spans.data(); 545 const SGRle::Span *span = m_spans.data();
@@ -348,7 +562,7 @@ void SGRleImpl::updateBbox()
348void SGRleImpl::addSpan(const SGRle::Span *span, int count) 562void SGRleImpl::addSpan(const SGRle::Span *span, int count)
349{ 563{
350 copyArrayToVector(span, count, m_spans); 564 copyArrayToVector(span, count, m_spans);
351 updateBbox(); 565 mBboxDirty = true;
352} 566}
353 567
354struct SGRleData 568struct SGRleData
@@ -437,7 +651,7 @@ SGRect SGRle::boundingRect() const
437{ 651{
438 if(isEmpty()) 652 if(isEmpty())
439 return SGRect(); 653 return SGRect();
440 return d->impl.m_bbox; 654 return d->impl.bbox();
441} 655}
442 656
443bool SGRle::operator ==(const SGRle &other) const 657bool SGRle::operator ==(const SGRle &other) const
@@ -455,8 +669,12 @@ bool SGRle::operator ==(const SGRle &other) const
455 669
456void SGRle::translate(const SGPoint &p) 670void SGRle::translate(const SGPoint &p)
457{ 671{
672 if (isEmpty()) return;
673
674 if (d->impl.mOffset == p) return;
675
458 detach(); 676 detach();
459 d->impl.m_offset = p; 677 d->impl.translate(p);
460} 678}
461 679
462SGRle SGRle::intersected(const SGRect &r) const 680SGRle SGRle::intersected(const SGRect &r) const
@@ -495,6 +713,43 @@ SGRle SGRle::operator~() const
495 return result; 713 return result;
496} 714}
497 715
716SGRle SGRle::operator+(const SGRle &other) const
717{
718 if (isEmpty()) return other;
719
720 if (other.isEmpty()) return *this;
721
722 SGRle result;
723 result.detach();
724 if (boundingRect().top() < other.boundingRect().top())
725 d->impl.opAdd(other.d->impl, result.d->impl);
726 else
727 other.d->impl.opAdd(d->impl, result.d->impl);
728 return result;
729}
730
731SGRle SGRle::operator-(const SGRle &other) const
732{
733 if (isEmpty()) return ~other;
734
735 if (other.isEmpty()) return *this;
736
737 SGRle temp = ~other;
738 return *this + temp;
739}
740
741SGRle SGRle::operator&(const SGRle &o) const
742{
743 if (isEmpty() || o.isEmpty()) return SGRle();
744
745 if (!boundingRect().intersects(o.boundingRect())) return SGRle();
746
747 SGRle result;
748 result.detach();
749 d->impl.intersected(o.d->impl, result.d->impl);
750 return result;
751}
752
498 753
499 754
500void SGRle::intersected(const SGRect &r, VRleSpanCb cb, void *userData) 755void SGRle::intersected(const SGRect &r, VRleSpanCb cb, void *userData)
@@ -537,6 +792,26 @@ const SGRle::Span* SGRle::data() const
537 return d->impl.m_spans.data(); 792 return d->impl.m_spans.data();
538} 793}
539 794
795SGRle SGRle::toRle(const SGRectF &rect)
796{
797 SGRle result;
798 result.detach();
799 int x = rect.left();
800 int y = rect.top();
801 int width = rect.width();
802 int height = rect.height();
803 result.d->impl.m_spans.reserve(height);
804 SGRle::Span span;
805 for(int i=0; i < height ; i++) {
806 span.x = x;
807 span.y = y + i;
808 span.len = width;
809 span.coverage = 255;
810 result.d->impl.m_spans.push_back(span);
811 }
812 return result;
813}
814
540SGDebug& operator<<(SGDebug& os, const SGRle& o) 815SGDebug& operator<<(SGDebug& os, const SGRle& o)
541{ 816{
542 os<<"[RLE: [dptr = "<<"o.d"<<"]"<<"[ref = "<<o.d->ref.count()<<"]"<<o.d->impl<<"]"; 817 os<<"[RLE: [dptr = "<<"o.d"<<"]"<<"[ref = "<<o.d->ref.count()<<"]"<<o.d->impl<<"]";
@@ -545,3 +820,5 @@ SGDebug& operator<<(SGDebug& os, const SGRle& o)
545 820
546 821
547 822
823
824