32 #ifndef SPL_Sequence2_hpp
33 #define SPL_Sequence2_hpp
43 #define SPL_SEQUENCE2_USE_NEW_CONV
45 #if defined(SPL_SEQUENCE2_DEBUG)
46 #define SPL_SEQUENCE2_INLINE
49 #define SPL_SEQUENCE2_INLINE inline
57 #include <SPL/config.hpp>
124 Sequence2(
int startX,
int startY,
int width,
int height);
130 Sequence2(
int startX,
int startY,
int width,
int height,
const T& data);
136 template <
class InputIterator>
137 Sequence2(
int startX,
int startY,
int width,
int height,
149 template <
class OtherT>
182 template <
class OtherT>
294 ConstIterator
begin()
const;
305 ConstIterator
end()
const;
317 ConstXIterator
rowBegin(
int y)
const;
329 ConstXIterator
rowEnd(
int y)
const;
341 ConstYIterator
colBegin(
int x)
const;
353 ConstYIterator
colEnd(
int x)
const;
396 std::ostream&
output(std::ostream& out,
int fieldWidth)
const;
415 void fill(
const T& value);
427 friend std::ostream& operator<<(std::ostream& out, const Sequence2<U>&);
457 void combineDomains(
int firstStartX,
int firstStartY,
int firstEndX,
458 int firstEndY,
int secondStartX,
int secondStartY,
int secondEndX,
459 int secondEndY,
int& startX,
int& startY,
int& endX,
int& endY);
475 int width,
int height) : startX_(startX), startY_(startY),
478 assert(width >= 0 && height >= 0);
483 int width,
int height,
const T& value) : startX_(startX), startY_(startY),
484 data_(width, height, value)
486 assert(width >= 0 && height >= 0);
490 template <
class InputIterator>
492 int width,
int height, InputIterator data) : startX_(startX),
493 startY_(startY), data_(width, height, data)
495 assert(width >= 0 && height >= 0);
501 startX_(f.startX_), startY_(f.startY_), data_(f.data_)
507 startX_(0), startY_(0), data_(data)
514 startX_(startX), startY_(startY), data_(data)
524 template <
class OtherT>
526 startX_(f.startX_), startY_(f.startY_), data_(f.data_)
545 template <
class OtherT>
564 assert((!getSize() && !f.
getSize()) ||
577 assert((!getSize() && !f.
getSize()) ||
590 assert((!getSize() && !f.
getSize()) ||
603 assert((!getSize() && !f.
getSize()) ||
662 return startX_ + getWidth();
668 return startY_ + getHeight();
674 return data_.getWidth();
680 return data_.getHeight();
686 return data_.getWidth() * data_.getHeight();
692 return data_.isShared();
702 assert(x >= startX_ && x < getEndX() && y >= startY_ && y < getEndY());
703 return data_(x - startX_, y - startY_);
709 assert(x >= startX_ && x < getEndX() && y >= startY_ && y < getEndY());
710 return data_(x - startX_, y - startY_);
721 return data_.begin();
727 return data_.begin();
747 assert(y >= startY_ && y < getEndY());
748 return data_.rowBegin(y - startY_);
755 assert(y >= startY_ && y < getEndY());
756 return data_.rowBegin(y - startY_);
763 assert(y >= startY_ && y < getEndY());
764 return data_.rowEnd(y - startY_);
771 assert(y >= startY_ && y < getEndY());
772 return data_.rowEnd(y - startY_);
779 assert(x >= startX_ && x < getEndX());
780 return data_.colBegin(x - startX_);
787 assert(x >= startX_ && x < getEndX());
788 return data_.colBegin(x - startX_);
795 assert(x >= startX_ && x < getEndX());
796 return data_.colEnd(x - startX_);
803 assert(x >= startX_ && x < getEndX());
804 return data_.colEnd(x - startX_);
818 assert(getSize() > 0);
825 assert(getSize() > 0);
842 out << startX_ <<
" " << startY_ <<
" ";
843 data_.output(out, fieldWidth);
863 std::ostream& operator<<(std::ostream& out, const Sequence2<T>& f)
865 out << f.getStartX() <<
" " << f.getStartY() <<
" ";
887 if (!(in >> startX)) {
890 if (!(in >> startY)) {
893 if (!(in >> width)) {
896 if (!(in >> height)) {
899 typename std::vector<T> data;
900 data.reserve(width * height);
901 for (
int y = 0; y < height; ++y) {
902 for (
int x = 0; x < width; ++x) {
904 if (!(in >> value)) {
907 data.push_back(value);
910 f =
Sequence2<T>(startX, startY, width, height, data.begin());
1026 Sequence2<T> result(startX, startY, endX - startX, endY - startY, T(0));
1027 int xMin = std::max(f.
getStartX(), startX);
1028 int xMax = std::min(f.
getEndX(), endX) - 1;
1029 int yMin = std::max(f.
getStartY(), startY);
1030 int yMax = std::min(f.
getEndY(), endY) - 1;
1031 for (
int y = yMin; y <= yMax; ++y) {
1032 for (
int x = xMin; x <= xMax; ++x) {
1033 result(x, y) += f(x, y);
1037 xMax = std::min(g.
getEndX(), endX) - 1;
1039 yMax = std::min(g.
getEndY(), endY) - 1;
1040 for (
int y = yMin; y <= yMax; ++y) {
1041 for (
int x = xMin; x <= xMax; ++x) {
1042 result(x, y) += g(x, y);
1191 while (src != f.
end()) {
1192 if (
absVal((*src) - (*dst)) > threshold) {
1219 int width,
int height)
1223 if (!width || !height) {
1228 for (
int i = 0; i < height; ++i) {
1233 SPL::copy_n(src, width, dst);
1249 int deltaX,
int deltaY)
1278 if (x >= f.getStartX() && x < f.getEndX() &&
1279 y >= f.getStartY() && y < f.getEndY()) {
1286 if (x < f.getStartX()) {
1288 }
else if (x >= f.getEndX()) {
1289 x = f.getEndX() - 1;
1291 if (y < f.getStartY()) {
1293 }
else if (y >= f.getEndY()) {
1294 y = f.getEndY() - 1;
1299 if (x < f.getStartX() || x >= f.getEndX()) {
1300 x = f.getStartX() +
mod(x - f.getStartX(), f.getWidth());
1302 if (y < f.getStartY() || y >= f.getEndY()) {
1303 y = f.getStartY() +
mod(y - f.getStartY(), f.getHeight());
1305 assert(x >= f.getStartX() && x < f.getEndX());
1306 assert(y >= f.getStartY() && y < f.getEndY());
1310 if (x < f.getStartX() || x >= f.getEndX()) {
1311 int tmp =
mod(x - f.getStartX(), 2 * f.getWidth() - 2);
1312 x = f.getStartX() + std::min(tmp, 2 * f.getWidth() - 2 - tmp);
1314 if (y < f.getStartY() || y >= f.getEndY()) {
1315 int tmp =
mod(y - f.getStartY(), 2 * f.getHeight() - 2);
1316 y = f.getStartY() + std::min(tmp, 2 * f.getHeight() - 2 - tmp);
1318 assert(x >= f.getStartX() && x < f.getEndX());
1319 assert(y >= f.getStartY() && y < f.getEndY());
1338 Sequence2<T> convolveSeparableFull(
const Sequence2<T>& f,
1339 const Sequence1<T>& horzFilt,
const Sequence1<T>& vertFilt)
1341 if (!horzFilt.getSize() || !vertFilt.getSize()) {
1342 return Sequence2<T>();
1346 Sequence2<T> tmpResult(f.getStartX() + horzFilt.getStartInd(),
1347 f.getStartY(), f.getWidth() + horzFilt.getSize() - 1,
1349 for (
int y = f.getStartY(); y < f.getEndY(); ++y) {
1350 convolveHelper(f.rowBegin(y), f.rowEnd(y), horzFilt.begin(),
1351 horzFilt.end(), tmpResult.rowBegin(y), T());
1355 Sequence2<T> result(tmpResult.getStartX(), tmpResult.getStartY() +
1356 vertFilt.getStartInd(), tmpResult.getWidth(), tmpResult.getHeight() +
1357 vertFilt.getSize() - 1);
1358 for (
int x = tmpResult.getStartX(); x < tmpResult.getEndX(); ++x) {
1359 convolveHelper(tmpResult.colBegin(x), tmpResult.colEnd(x),
1360 vertFilt.begin(), vertFilt.end(), result.colBegin(x), T());
1374 Sequence2<T> convolveSeparableSameDomainZeroExt(
const Sequence2<T>& f,
1375 const Sequence1<T>& horzFilt,
const Sequence1<T>& vertFilt)
1377 if (!horzFilt.getSize() || !vertFilt.getSize()) {
1378 return Sequence2<T>();
1385 Sequence2<T> tmpResult(f.getStartX(), f.getStartY(), f.getWidth(),
1387 if (horzFilt.getStartInd() >= 0) {
1388 shift = horzFilt.getStartInd();
1392 skip = -horzFilt.getStartInd();
1394 for (
int y = f.getStartY(); y < f.getEndY(); ++y) {
1395 convolveHelper2(f.rowBegin(y), f.rowEnd(y), horzFilt.begin(),
1396 horzFilt.end(), tmpResult.rowBegin(y) + shift, skip,
1397 tmpResult.getWidth() - shift, T());
1401 if (vertFilt.getStartInd() >= 0) {
1402 shift = vertFilt.getStartInd();
1406 skip = -vertFilt.getStartInd();
1408 Sequence2<T> result(tmpResult.getStartX(), tmpResult.getStartY(),
1409 tmpResult.getWidth(), tmpResult.getHeight());
1410 for (
int x = tmpResult.getStartX(); x < tmpResult.getEndX(); ++x) {
1411 convolveHelper2(tmpResult.colBegin(x), tmpResult.colEnd(x),
1412 vertFilt.begin(), vertFilt.end(), result.colBegin(x) + shift,
1413 skip, result.getHeight() - shift, T());
1455 for (
int y = result.getStartY(); y < result.getEndY(); ++y) {
1456 for (
int x = result.getStartX(); x < result.getEndX(); ++x) {
1460 sum += getExtSeqValue(f, x - i, y - j, mode) * g(i, j);
1479 #if defined(SPL_SEQUENCE2_USE_NEW_CONV)
1482 return convolveSeparableFull(f, horzFilt, vertFilt);
1485 return convolveSeparableSameDomainZeroExt(f, horzFilt, vertFilt);
1495 result =
convolve(result, vertFilt0, mode);
1510 assert(factorX >= 1 && factorY >= 1);
1518 for (
int i = 0; i < height; ++i) {
1522 result.rowBegin(result.getStartY() + i);
1523 int n = result.getWidth();
1525 *dstIter = *srcIter;
1544 return upsample(f, factorX, factorY, 0, 0);
1558 assert(factorX >= 1 && factorY >= 1);
1559 assert(padX >= 0 && padX < factorX);
1560 assert(padY >= 0 && padY < factorY);
1569 while (rowCount > 0) {
1575 *dstIter = *srcIter;
1578 for (
int k = (count > 1) * (factorX - 1); k > 0; --k) {
1584 for (
int k = padX; k > 0; --k) {
1591 for (
int k = (rowCount > 1) * (factorY - 1); k > 0; --k) {
1598 for (
int k = padY; k > 0; --k) {
1599 assert(dstY < result.
getEndY());
1625 int numPhasesX,
int typeY,
int numPhasesY)
1627 assert(numPhasesX >= 2);
1628 assert(numPhasesY >= 2);
1630 for (
int j = 0; j < numPhasesY; ++j) {
1631 for (
int i = 0; i < numPhasesX; ++i) {
1632 int offsetX = getCosetOffset(typeX, numPhasesX, i);
1633 int offsetY = getCosetOffset(typeY, numPhasesY, j);
1635 numPhasesX, numPhasesY);
1656 const int numPhasesX = comps.getWidth();
1657 const int numPhasesY = comps.getHeight();
1658 assert(numPhasesX >= 2);
1659 assert(numPhasesY >= 2);
1661 for (
int j = 0; j < numPhasesY; ++j) {
1662 for (
int i = 0; i < numPhasesX; ++i) {
1663 int offsetX = getCosetOffset(typeX, numPhasesX, i);
1664 int offsetY = getCosetOffset(typeY, numPhasesY, j);
1667 numPhasesY), -offsetX, -offsetY));
long roundTowardZeroDiv(long x, long y)
Compute a quotient with the result rounded towards zero.
Definition: math.hpp:152
This file contains the Array2 template class and its supporting code.
T & operator()(int x, int y)
Get a mutable reference to the specified element in the sequence.
Definition: Sequence2.hpp:707
int getEndY() const
Get the y-coordinate of the end index for the sequence.
Definition: Sequence2.hpp:666
Array2< T >::YIterator YIterator
The mutable iterator for the elements in a column of the sequence.
Definition: Sequence2.hpp:110
void swapArray(Array2< T > &data)
Swap the data for the underlying array and the specified array.
Definition: Sequence2.hpp:925
A one-dimensional sequence class with lazy copying and reference counting.
Definition: Sequence1.hpp:85
T ElemType
The type of the element in the sequence.
Definition: Sequence2.hpp:92
Sequence2< T > convolveSeparable(const Sequence2< T > &f, const Sequence1< T > &horzFilt, const Sequence1< T > &vertFilt, int mode=ConvolveMode::full)
Compute the convolution of a sequence with two 1-D filters (i.e., convolution with a separable filter...
Definition: Sequence2.hpp:1475
#define SPL_SEQUENCE2_INLINE
Allow the inlining of functions.
Definition: Sequence2.hpp:50
Definition: Arcball.hpp:48
int getStartY() const
Get the y-coordinate of the start index for the sequence.
Definition: Sequence2.hpp:654
ConstIterator end() const
Get a const iterator for one past the last element in the sequence.
Definition: Sequence2.hpp:731
T mod(T x, T y)
Compute the remainder after division.
Definition: math.hpp:184
T absVal(T x)
The absolute value function.
Definition: math.hpp:73
int getStartX() const
Get the x-coordinate of the start index for the sequence.
Definition: Sequence2.hpp:648
ConstXIterator rowEnd(int y) const
Get a const iterator for one past the end in the specified row of the sequence.
Definition: Sequence2.hpp:761
void fill(const T &value)
Get a copy of the underlying array.
Definition: Sequence2.hpp:919
int getWidth() const
Get the width of the sequence.
Definition: Sequence2.hpp:672
T max() const
Get the maximum element in the sequence.
Definition: Sequence2.hpp:823
Sequence2 & operator+=(const Sequence2 &f)
Add another sequence to this one.
Definition: Sequence2.hpp:560
ConstYIterator colEnd(int x) const
Get a const iterator for one past the end in the specified column of the sequence.
Definition: Sequence2.hpp:793
std::vector< T >::const_iterator ConstXIterator
A constant iterator for elements of a row in the array.
Definition: Array2.hpp:231
static const int full
The full convolution result (i.e., the same as "full" in MATLAB)
Definition: Sequence.hpp:57
SPL_SEQUENCE2_INLINE bool approxEqual(const Sequence2< T > &f, const Sequence2< T > &g, T threshold=1e-9)
Test two sequences for approximate equality.
Definition: Sequence2.hpp:1173
SPL_SEQUENCE2_INLINE Sequence2< T > operator/(const Sequence2< T > &f, const T &value)
Divide a sequence by a scalar.
Definition: Sequence2.hpp:1126
Sequence2 & operator*=(const Sequence2 &f)
Multiply elementwise this sequence by another one.
Definition: Sequence2.hpp:586
ConstYIterator colBegin(int x) const
Get a const iterator for the first element in the specified column of the sequence.
Definition: Sequence2.hpp:777
SPL_SEQUENCE2_INLINE Sequence2< T > operator+(const Sequence2< T > &f, const T &value)
Add a value to a sequence.
Definition: Sequence2.hpp:1070
long ceilDiv(long x, long y)
Compute the ceiling of a quotient.
Definition: math.hpp:212
static const int sameDomainPerExt
Periodic extension.
Definition: Sequence.hpp:66
int getHeight() const
Get the height of the sequence.
Definition: Sequence2.hpp:678
static const int sameDomainConstExt
Constant extension.
Definition: Sequence.hpp:63
~Sequence2()
The destructor.
Definition: Sequence2.hpp:519
bool operator==(const Sequence2< T > &f, const Sequence2< T > &g)
Test two sequences for equality.
Definition: Sequence2.hpp:1141
Array2< T >::ConstYIterator ConstYIterator
The const iterator for the elements in a column of the sequence.
Definition: Sequence2.hpp:107
This file contains various mathematical functions/code.
Sequence2< T > subsequence(const Sequence2< T > &f, int startX, int startY, int width, int height)
Extract a subsequence from a sequence.
Definition: Sequence2.hpp:1218
Array2< Sequence2< T > > polyphaseSplit(const Sequence2< T > &seq, int typeX, int numPhasesX, int typeY, int numPhasesY)
Split a sequence into its polyphase components.
Definition: Sequence2.hpp:1624
Sequence2 & operator=(const Sequence2 &f)
The assignment operator.
Definition: Sequence2.hpp:535
Common header for sequence classes.
int getStartInd() const
Get the start index for the sequence.
Definition: Sequence1.hpp:606
std::vector< T >::iterator Iterator
A mutable iterator for all elements in the array.
Definition: Array2.hpp:222
std::istream & operator>>(std::istream &in, Sequence2< T > &f)
Input a sequence from a stream.
Definition: Sequence2.hpp:881
Array2< T >::XIterator XIterator
The mutable iterator for the elements in a row of the sequence.
Definition: Sequence2.hpp:104
ConstXIterator rowBegin(int y) const
Get a const iterator for the first element in the specified row of the sequence.
Definition: Sequence2.hpp:745
YIter< T > YIterator
A mutable iterator for elements of a column in the array.
Definition: Array2.hpp:234
static const int sameDomainSymExt0
Symmetric periodic extension.
Definition: Sequence.hpp:69
Sequence2 & translate(int x, int y)
Translate (i.e., shift) a sequence by the specified displacement.
Definition: Sequence2.hpp:937
Sequence2 & operator-=(const Sequence2 &f)
Subtract another sequence from this one.
Definition: Sequence2.hpp:573
This file contains code for the Sequence1 template class.
SPL_SEQUENCE2_INLINE Sequence2< T > operator-(const Sequence2< T > &f, const T &value)
Subtract a value from a sequence.
Definition: Sequence2.hpp:1084
A two-dimensional array class with lazy copying and reference counting.
Definition: Array2.hpp:83
Sequence2()
The default constructor.
Definition: Sequence2.hpp:468
Array2< T >::Iterator Iterator
The mutable iterator for all elements in the sequence.
Definition: Sequence2.hpp:98
static const int sameDomainZeroExt
The same as "same" in MATLAB.
Definition: Sequence.hpp:60
T min() const
Get the minimum element in the sequence.
Definition: Sequence2.hpp:816
YIter< const T > ConstYIterator
A constant iterator for elements of a column in the array.
Definition: Array2.hpp:237
int getSize() const
Get the number of elements in the sequence.
Definition: Sequence2.hpp:684
Sequence2< T > polyphaseJoin(const Array2< Sequence2< T > > &comps, int typeX, int typeY)
Reassemble a sequence from its polyphase components.
Definition: Sequence2.hpp:1653
Sequence2< T > upsample(const Sequence2< T > &f, int factorX, int factorY, int padX, int padY)
Upsample a sequence in each of the horizontal and vertical directions by the specified factors...
Definition: Sequence2.hpp:1555
SPL_SEQUENCE2_INLINE Sequence2< T > translate(const Sequence2< T > &f, int deltaX, int deltaY)
Translate a sequence by the specified amount.
Definition: Sequence2.hpp:1248
SPL_SEQUENCE2_INLINE bool operator!=(const Sequence2< T > &f, const Sequence2< T > &g)
Test two sequences for inequality.
Definition: Sequence2.hpp:1163
Sequence2< T > convolve(const Sequence2< T > &f, const Sequence2< T > &g, int mode)
Compute the convolution of two sequences.
Definition: Sequence2.hpp:1424
int getSize() const
Get the length of the sequence.
Definition: Sequence1.hpp:618
Array2< T > getArray() const
Get a copy of the underlying array.
Definition: Sequence2.hpp:931
Iterator XIterator
A mutable iterator for elements of a row in the array.
Definition: Array2.hpp:228
T sum() const
Get the sum of the elements in the sequence.
Definition: Sequence2.hpp:830
Sequence2 & operator/=(const Sequence2 &f)
Divide elementwise this sequence by another one.
Definition: Sequence2.hpp:599
Sequence2< T > add(const Sequence2< T > &f, const Sequence2< T > &g)
Compute the sum of two sequences with potentially differing domains.
Definition: Sequence2.hpp:1017
A two-dimensional sequence class with lazy copying and reference counting.
Definition: Sequence2.hpp:83
std::vector< T >::const_iterator ConstIterator
A constant iterator for all elements in the array.
Definition: Array2.hpp:225
SPL_SEQUENCE2_INLINE Sequence2< T > operator*(const Sequence2< T > &f, const T &value)
Compute a scalar multiple of a sequence.
Definition: Sequence2.hpp:1112
Sequence2< double > RealSequence2
Real sequence.
Definition: Sequence2.hpp:1678
int getEndX() const
Get the x-coordinate of the end index for the sequence.
Definition: Sequence2.hpp:660
Array2< T >::ConstXIterator ConstXIterator
The const iterator for the elements in a row of the sequence.
Definition: Sequence2.hpp:101
Sequence2< int > IntSequence2
Integer sequence.
Definition: Sequence2.hpp:1681
Array2< T >::ConstIterator ConstIterator
The const iterator for all elements in the sequence.
Definition: Sequence2.hpp:95
ConstIterator begin() const
Get a const iterator for the first element in the sequence.
Definition: Sequence2.hpp:718
bool isShared() const
Is the array for this sequence shared with another array?
Definition: Sequence2.hpp:690
ConstIterator begin() const
Get an iterator referencing the first element in the sequence.
Definition: Sequence1.hpp:652
std::ostream & output(std::ostream &out, int fieldWidth) const
Output a sequence to the specified stream using the given field width for each sequence element...
Definition: Sequence2.hpp:840
Sequence2< T > downsample(const Sequence2< T > &f, int factorX, int factorY)
Downsample a sequence in each of the horizontal and vertical directions by the specified factors...
Definition: Sequence2.hpp:1508