| 451 | } |
| 452 | |
| 453 | void DecodeTriangles(coding::InDeltasT const & deltas, m2::PointU const & basePoint, m2::PointU const & maxPoint, |
| 454 | coding::OutPointsT & points) |
| 455 | { |
| 456 | size_t const count = deltas.size(); |
| 457 | ASSERT_GREATER(count, 2, ()); |
| 458 | |
| 459 | m2::PointD const maxPointD(maxPoint); |
| 460 | |
| 461 | points.push_back(coding::DecodePointDeltaFromUint(deltas[0], basePoint)); |
| 462 | points.push_back(coding::DecodePointDeltaFromUint(deltas[1], points.back())); |
| 463 | points.push_back(coding::DecodePointDeltaFromUint(deltas[2] >> 2, points.back())); |
| 464 | |
| 465 | std::stack<size_t> st; |
| 466 | |
| 467 | size_t ind = 2; |
| 468 | uint8_t treeBits = deltas[2] & 3; |
| 469 | |
| 470 | for (size_t i = 3; i < count;) |
| 471 | { |
| 472 | // points 0, 1 - is a common edge |
| 473 | // point 2 - is an opposite point for new triangle to calculate prediction |
| 474 | size_t trg[3]; |
| 475 | |
| 476 | if (treeBits & 1) |
| 477 | { |
| 478 | // common edge is 1->2 |
| 479 | trg[0] = ind; |
| 480 | trg[1] = ind - 1; |
| 481 | trg[2] = ind - 2; |
| 482 | |
| 483 | // push to stack for further processing |
| 484 | if (treeBits & 2) |
| 485 | st.push(ind); |
| 486 | } |
| 487 | else if (treeBits & 2) |
| 488 | { |
| 489 | // common edge is 2->0 |
| 490 | trg[0] = ind - 2; |
| 491 | trg[1] = ind; |
| 492 | trg[2] = ind - 1; |
| 493 | } |
| 494 | else |
| 495 | { |
| 496 | // end of chain - pop current from stack |
| 497 | ASSERT(!st.empty(), ()); |
| 498 | ind = st.top(); |
| 499 | st.pop(); |
| 500 | treeBits = 2; |
| 501 | continue; |
| 502 | } |
| 503 | |
| 504 | // push points |
| 505 | points.push_back(points[trg[0]]); |
| 506 | points.push_back(points[trg[1]]); |
| 507 | points.push_back(coding::DecodePointDeltaFromUint( |
| 508 | deltas[i] >> 2, coding::PredictPointInTriangle(maxPointD, points[trg[0]], points[trg[1]], points[trg[2]]))); |
| 509 | |
| 510 | // next step |
nothing calls this directly
no test coverage detected