BandIteratorWindow.h
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/raster/BandIteratorWindow.h
22 
23  \brief It implements and iterator to "navigate" over a single band,
24  optimized by a window structure (e.g. 3x3, 5x5, etc). Examples
25  include filters, moving windows, morphology, etc.
26 */
27 
28 #ifndef __TERRALIB_RASTER_INTERNAL_BANDITERATORWINDOW_H
29 #define __TERRALIB_RASTER_INTERNAL_BANDITERATORWINDOW_H
30 
31 // Terralib
32 #include "../common/STLUtils.h"
33 #include "Band.h"
34 #include "BandProperty.h"
35 
36 namespace te
37 {
38  namespace rst
39  {
40 // Forward declaration.
41  class Band;
42 
43  /*!
44  \class BandIteratorWindow
45 
46  \brief It implements and iterator to "navigate" over a single band,
47  optimized by a window structure (e.g. 3x3, 5x5, etc). Examples
48  include filters, moving windows, morphology, etc.
49 
50  \ingroup rst
51 
52  \sa te::rst::Band
53  */
54  template<class T> class BandIteratorWindow
55  {
56  public:
57  /*!
58  \brief Constructor.
59 
60  \param b The band to iterate.
61  \param w The width of the window to iterate.
62  \param h The height of the window to iterate.
63  */
64  BandIteratorWindow(Band const * const b, std::size_t w, const std::size_t h);
65 
66  /*!
67  \brief Copy constructor.
68 
69  \param rhs The right-hand-side copy used to copy from.
70  */
72 
73  /*! \brief Constructor. */
75 
76  /*! \brief Destructor. */
78 
79  /*! \brief Returns the current row in iterator. */
80  unsigned int getRow() const;
81 
82  /*! \brief Returns the current column in iterator. */
83  unsigned int getColumn() const;
84 
85  /*! \brief Returns the value in current position (column, row) from iterator. */
86  T getValue() const;
87 
88  /*!
89  \brief Returns the value in a relative position to the center pixel currently pointed by iterator.
90 
91  \param r The row relative to the center pixel.
92  \param c The column relative to the center pixel.
93 
94  \warning The caller is responsible for providing correct values for the range [c x r].
95 
96  \note In a 5x5 window, the expected values for [c x r] in this method are in the interval [-2, +2].
97  */
98  T getValue(int c, int r) const;
99 
100  /*! \brief Advances to the next position. */
101  void operator++();
102 
103  /*! \brief Returns to the previous position. */
104  void operator--();
105 
107 
108  /*!
109  \brief Assignment operator.
110 
111  \param rhs The right-hand-side copy used to copy from.
112 
113  \return A reference to this object.
114  */
116 
117  /*!
118  \brief Returns an iterator referring to the first value of the band.
119 
120  \param b The band to iterate.
121  \param w The width of the window to iterate.
122  \param h The height of the window to iterate.
123  */
124  static BandIteratorWindow begin(Band const * const b, std::size_t w, const std::size_t h);
125 
126  /*!
127  \brief Returns an iterator referring to after the end of the iterator.
128 
129  \param b The band to iterate.
130  \param w The width of the window to iterate.
131  \param h The height of the window to iterate.
132  */
133  static BandIteratorWindow end(Band const * const b, std::size_t w, const std::size_t h);
134 
135  /*!
136  \brief Differece operator.
137 
138  \param rhs The right-hand side to compare.
139 
140  \return Returns true if the iterators are at different positions, or false otherwise.
141  */
142  bool operator!=(const BandIteratorWindow& rhs) const;
143 
144  /*! \brief Replaces the current bufferized blocks. */
145  void replaceBlocks();
146 
147  private:
148  /*!
149  \brief Returns the correct block where relative value is used.
150 
151  \param r The row relative to the center pixel.
152  \param c The column relative to the center pixel.
153 
154  \return The correct block.
155  */
156  T* getBlock(int c, int r) const;
157 
158  /*!
159  \brief Returns the correct index where the relative value is in the relative block.
160 
161  \param r The row relative to the center pixel.
162  \param c The column relative to the center pixel.
163 
164  \return The correct index.
165  */
166  int getRelativeIndex(int c, int r) const;
167 
168  private:
169 
170  int m_w; //!< The width of the window to iterate.
171  int m_h; //!< The height of the window to iterate.
172  int m_blkw; //!< The internal block width.
173  int m_blkh; //!< The internal block height.
174  int m_npxlsblk; //!< The maximum number of pixels inside the block.
175  int m_nblocksx; //!< The number of blocks in X direction.
176  int m_nblocksy; //!< The number of blocks in Y direction.
177  int m_nvblocksx; //!< The amount of blocks in direction X in vector of internal blocks.
178  int m_nvblocksy; //!< The amount of blocks in direction Y in vector of internal blocks.
179  int m_cblock; //!< The index of the central block;
180  int m_i; //!< The actual position inside the block.
181  int m_blkx; //!< The position in X of the current block.
182  int m_blky; //!< The position in Y of the current block.
183  int m_lastblksize; //!< The number of pixels inside the last block.
184  std::vector<T*> m_blocks; //!< A vector of internal blocks, to provide fast access to window elements.
185  Band const * m_band; //!< The band from where to get the values.
186  te::rst::GetBufferValueFPtr m_getBuff; //!< A pointer to a function that helps to extract a double or complex value from a specific buffer data type (char, int16, int32, float, ...).
187  te::rst::GetBufferValueFPtr m_getBuffI; //!< A pointer to a function that helps to extract the imaginary part value from a specific buffer data type (cint16, cint32, cfloat, cdouble).
188  te::rst::SetBufferValueFPtr m_setBuff; //!< A pointer to a function that helps to insert a double or complex value into a specific buffer data type (char, int16, int32, float, ...).
189  te::rst::SetBufferValueFPtr m_setBuffI; //!< A pointer to a function that helps to insert the imaginary part value into a specific buffer data type (cint16, cint32, cfloat, cdouble).
190  };
191 
192  template<class T> te::rst::BandIteratorWindow<T>::BandIteratorWindow(te::rst::Band const * const b, std::size_t w, const std::size_t h)
193  : m_w(w),
194  m_h(h),
195  m_blkw(b->getProperty()->m_blkw),
196  m_blkh(b->getProperty()->m_blkh),
197  m_npxlsblk(m_blkw * m_blkh),
198  m_nblocksx(b->getProperty()->m_nblocksx),
199  m_nblocksy(b->getProperty()->m_nblocksy),
200  m_nvblocksx(0),
201  m_nvblocksy(0),
202  m_cblock(0),
203  m_i(0),
204  m_blkx(0),
205  m_blky(0),
206  m_band(b),
207  m_getBuff(0),
208  m_getBuffI(0),
209  m_setBuff(0),
210  m_setBuffI(0)
211  {
214 
215  if (m_blkw > m_w)
216  {
217  if (m_blkw == (int) b->getRaster()->getNumberOfColumns())
218  m_nvblocksx = 1;
219  else
220  m_nvblocksx = 3;
221  }
222  else
223  m_nvblocksx = 1 + (m_w + m_blkw - 2) / m_blkw;
224 
225  if (m_blkh > m_h)
226  {
227  if (m_blkh == (int) b->getRaster()->getNumberOfRows())
228  m_nvblocksy = 1;
229  else
230  m_nvblocksy = 3;
231  }
232  else
233  {
234  m_nvblocksy = 1 + (m_h + m_blkh - 2) / m_blkh;
235 // apply a special case, create three blocks instead of two
236  if (m_nvblocksx == 1 && m_nvblocksy == 2)
237  m_nvblocksy++;
238  else if (m_nvblocksx == 2 && m_nvblocksy == 1)
239  m_nvblocksx++;
240  }
241 
242  for (int i = 0; i < (m_nvblocksx * m_nvblocksy); i++)
243  m_blocks.push_back(new T[m_band->getBlockSize()]);
244 
245  m_cblock = (int) m_blocks.size() / 2;
246 
248 
249  replaceBlocks();
250  }
251 
253  : m_w(rhs.m_w),
254  m_h(rhs.m_h),
255  m_blkw(rhs.m_blkw),
256  m_blkh(rhs.m_blkh),
257  m_npxlsblk(rhs.m_npxlsblk),
258  m_nblocksx(rhs.m_nblocksx),
259  m_nblocksy(rhs.m_nblocksy),
260  m_nvblocksx(rhs.m_nvblocksx),
261  m_nvblocksy(rhs.m_nvblocksy),
262  m_cblock(rhs.m_cblock),
263  m_i(rhs.m_i),
264  m_blkx(rhs.m_blkx),
265  m_blky(rhs.m_blky),
266  m_lastblksize(rhs.m_lastblksize),
267  m_band(rhs.m_band),
268  m_getBuff(rhs.m_getBuff),
269  m_getBuffI(rhs.m_getBuffI),
270  m_setBuff(rhs.m_setBuff),
271  m_setBuffI(rhs.m_setBuffI)
272  {
273  if (m_band)
274  {
276 
277  for (int i = 0; i < (m_nvblocksx * m_nvblocksy); i++)
278  m_blocks.push_back(new T[m_band->getBlockSize()]);
279 
280  replaceBlocks();
281  }
282  }
283 
285  : m_w(0),
286  m_h(0),
287  m_blkw(-1),
288  m_blkh(-1),
289  m_npxlsblk(-1),
290  m_nblocksx(-1),
291  m_nblocksy(-1),
292  m_nvblocksx(0),
293  m_nvblocksy(0),
294  m_cblock(0),
295  m_i(-1),
296  m_blkx(-1),
297  m_blky(-1),
298  m_lastblksize(-1),
299  m_blocks(0),
300  m_band(0)
301  {
302  }
303 
305  {
306  te::common::FreeContents(m_blocks);
307  }
308 
309  template<class T> unsigned int te::rst::BandIteratorWindow<T>::getRow() const
310  {
311  return m_blky * m_blkh + (m_i - (m_i % m_blkw)) / m_blkw;
312  }
313 
314  template<class T> unsigned int te::rst::BandIteratorWindow<T>::getColumn() const
315  {
316  return m_blkx * m_blkw + m_i % m_blkw;
317  }
318 
319  template<class T> T te::rst::BandIteratorWindow<T>::getValue() const
320  {
321  //return ((T*)m_blocks[m_cblock])[m_i];
322  double value;
323 
324  this->m_getBuff(this->m_i, this->m_blocks[m_cblock], &value);
325 
326  return (T) value;
327  }
328 
329  template<class T> T te::rst::BandIteratorWindow<T>::getValue(int c, int r) const
330  {
331  //return ((T*)getBlock(c, r))[getRelativeIndex(c, r)];
332  double value;
333 
334  this->m_getBuff(this->getRelativeIndex(c, r), this->getBlock(c, r), &value);
335 
336  return (T) value;
337  }
338 
340  {
341  m_i++;
342 
343  if(m_i < m_npxlsblk)
344  return;
345 
346  m_i = 0;
347 
348  m_blkx++;
349 
350  if(m_blkx < m_nblocksx)
351  {
352  replaceBlocks();
353 
354  return;
355  }
356 
357  m_blkx = 0;
358 
359  m_blky++;
360 
361  if(m_blky < m_nblocksy)
362  replaceBlocks();
363 
364  if((m_blkx == m_nblocksx - 1) && (m_blky == m_nblocksy - 1))
365  m_npxlsblk = m_lastblksize;
366  }
367 
369  {
370  m_i--;
371 
372  if(m_i >= 0)
373  return;
374 
375  m_i = m_npxlsblk - 1;
376 
377  m_blkx--;
378 
379  if(m_blkx >= 0)
380  {
381  replaceBlocks();
382 
383  return;
384  }
385 
386  m_blkx = m_nblocksx - 1;
387 
388  m_blky--;
389 
390  if(m_blky >= 0)
391  replaceBlocks();
392  else
393  m_blky = m_nblocksy;
394  }
395 
397  {
398  return *this;
399  }
400 
402  {
403  if (this != &rhs)
404  {
405  m_blkw = rhs.m_blkw;
406  m_blkh = rhs.m_blkh;
407  m_npxlsblk = rhs.m_npxlsblk;
408  m_nblocksx = rhs.m_nblocksx;
409  m_nblocksy = rhs.m_nblocksy;
410  m_nvblocksx = rhs.m_nvblocksx;
411  m_nvblocksy = rhs.m_nvblocksy;
412  m_i = rhs.m_i;
413  m_blkx = rhs.m_blkx;
414  m_blky = rhs.m_blky;
415  m_lastblksize = rhs.m_lastblksize;
416  m_band = rhs.m_band;
417 
418  te::common::FreeContents(m_blocks);
419  for (int i = 0; i < (m_nvblocksx * m_nvblocksy); i++)
420  m_blocks.push_back(new T[m_band->getBlockSize()]);
421 
422  replaceBlocks();
423  }
424 
425  return *this;
426  }
427 
428  template<class T> bool te::rst::BandIteratorWindow<T>::operator!=(const BandIteratorWindow& rhs) const
429  {
430  return (m_blky != rhs.m_blky);
431  }
432 
433  template<class T> te::rst::BandIteratorWindow<T> te::rst::BandIteratorWindow<T>::begin(te::rst::Band const * const b, std::size_t w, const std::size_t h)
434  {
435  return te::rst::BandIteratorWindow<T>(b, w, h);
436  }
437 
438  template<class T> te::rst::BandIteratorWindow<T> te::rst::BandIteratorWindow<T>::end(te::rst::Band const * const b, std::size_t w, const std::size_t h)
439  {
441 
442  it.m_blky = b->getProperty()->m_nblocksy;
443 
444  return it;
445  }
446 
448  {
449  int blk = 0;
450 
451  for (int x = (m_blkx - m_nvblocksx / 2); x <= (m_blkx + m_nvblocksx / 2); x++)
452  for (int y = (m_blky - m_nvblocksy / 2); y <= (m_blky + m_nvblocksy / 2); y++)
453  {
454  if ((x >= 0) && (x < m_nblocksx))
455  if ((y >= 0) && (y < m_nblocksy))
456  {
457  m_band->read(x, y, m_blocks[blk]);
458  blk++;
459  }
460 
461  // blk++;
462  }
463  }
464 
465  template<class T> T* te::rst::BandIteratorWindow<T>::getBlock(int c, int r) const
466  {
467  int bx = (getColumn() + c) / m_blkw;
468 
469  int by = (getRow() + r) / m_blkh;
470 
471  int blk = m_cblock + (bx - m_blkx) + (by - m_blky) * m_nvblocksx;
472 
473  return m_blocks[blk];
474  }
475 
476  template<class T> int te::rst::BandIteratorWindow<T>::getRelativeIndex(int c, int r) const
477  {
478  int cc = (getColumn() + c) % m_blkw;
479 
480  int cr = (getRow() + r) % m_blkh;
481 
482  return (cc + cr * m_blkw);
483  }
484 
485  } // end namespace rst
486 } // end namespace te
487 
488 #endif // __TERRALIB_RASTER_INTERNAL_BANDITERATORWINDOW_H
It describes one band (or dimension) of a raster.
int m_blkw
The internal block width.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
unsigned int getColumn() const
Returns the current column in iterator.
int m_nblocksy
The number of blocks in Y direction.
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
Band const * m_band
The band from where to get the values.
void(* SetBufferValueFPtr)(int index, void *buffer, const double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:40
unsigned int getRow() const
Returns the current row in iterator.
BandIteratorWindow & operator=(const BandIteratorWindow &rhs)
Assignment operator.
void operator++()
Advances to the next position.
int m_blky
The position in Y of the current block.
void(* GetBufferValueFPtr)(int index, void *buffer, double *value)
The type of function used to extract data from a buffer.
Definition: BlockUtils.h:37
int m_blkx
The position in X of the current block.
BandProperty * getProperty()
Returns the band property.
int m_blkh
The internal block height.
bool operator!=(const BandIteratorWindow &rhs) const
Differece operator.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
te::rst::GetBufferValueFPtr m_getBuffI
A pointer to a function that helps to extract the imaginary part value from a specific buffer data ty...
TERASTEREXPORT void SetBlockFunctions(GetBufferValueFPtr *gb, GetBufferValueFPtr *gbi, SetBufferValueFPtr *sb, SetBufferValueFPtr *sbi, int type)
Sets the pointers to functions that helps to extract a double or complex value from a specific buffer...
int m_h
The height of the window to iterate.
URI C++ Library.
T * getBlock(int c, int r) const
Returns the correct block where relative value is used.
int m_npxlsblk
The maximum number of pixels inside the block.
int m_i
The actual position inside the block.
It gives access to values in one band (dimension) of a raster.
int m_nvblocksy
The amount of blocks in direction Y in vector of internal blocks.
A raster band description.
Definition: Band.h:63
te::rst::GetBufferValueFPtr m_getBuff
A pointer to a function that helps to extract a double or complex value from a specific buffer data t...
static BandIteratorWindow end(Band const *const b, std::size_t w, const std::size_t h)
Returns an iterator referring to after the end of the iterator.
void replaceBlocks()
Replaces the current bufferized blocks.
int m_cblock
The index of the central block;.
BandIteratorWindow operator*()
int m_w
The width of the window to iterate.
te::rst::SetBufferValueFPtr m_setBuff
A pointer to a function that helps to insert a double or complex value into a specific buffer data ty...
virtual Raster * getRaster() const =0
Returns the associated raster.
int m_nvblocksx
The amount of blocks in direction X in vector of internal blocks.
void operator--()
Returns to the previous position.
int m_nblocksx
The number of blocks in X direction.
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
int m_lastblksize
The number of pixels inside the last block.
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
It implements and iterator to "navigate" over a single band, optimized by a window structure (e...
std::vector< T * > m_blocks
A vector of internal blocks, to provide fast access to window elements.
static BandIteratorWindow begin(Band const *const b, std::size_t w, const std::size_t h)
Returns an iterator referring to the first value of the band.
T getValue() const
Returns the value in current position (column, row) from iterator.
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
int getRelativeIndex(int c, int r) const
Returns the correct index where the relative value is in the relative block.
te::rst::SetBufferValueFPtr m_setBuffI
A pointer to a function that helps to insert the imaginary part value into a specific buffer data typ...