GteImage2.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Imagics/GteImage.h>
11 #include <array>
12 
13 namespace gte
14 {
15 
16 template <typename PixelType>
17 class Image2 : public Image<PixelType>
18 {
19 public:
20  // Construction and destruction. The last constructor must have positive
21  // dimensions; otherwise, the image is empty.
22  virtual ~Image2();
23  Image2();
24  Image2(int dimension0, int dimension1);
25 
26  // Support for copy semantics.
27  Image2(Image2 const& image);
28  Image2& operator= (Image2 const& image);
29 
30  // Support for move semantics.
31  Image2(Image2&& image);
32  Image2& operator= (Image2&& image);
33 
34  // Support for changing the image dimensions. All pixel data is lost by
35  // this operation.
36  void Reconstruct(int dimension0, int dimension1);
37 
38  // Conversion between 1-dimensional indices and 2-dimensional coordinates.
39  inline size_t GetIndex(int x, int y) const;
40  inline size_t GetIndex(std::array<int, 2> const& coord) const;
41  inline void GetCoordinates(size_t index, int& x, int& y) const;
42  inline std::array<int, 2> GetCoordinates(size_t index) const;
43 
44  // Access the data as a 2-dimensional array. The operator() functions
45  // test for valid (x,y) when iterator checking is enabled and assert on
46  // invalid (x,y). The Get() functions test for valid (x,y) and clamp
47  // when invalid; these functions cannot fail.
48  inline PixelType& operator() (int x, int y);
49  inline PixelType const& operator() (int x, int y) const;
50  inline PixelType& operator() (std::array<int, 2> const& coord);
51  inline PixelType const& operator() (std::array<int,2> const& coord) const;
52  inline PixelType& Get(int x, int y);
53  inline PixelType const& Get(int x, int y) const;
54  inline PixelType& Get(std::array<int, 2> coord);
55  inline PixelType const& Get(std::array<int, 2> coord) const;
56 
57  // In the following discussion, u and v are in {-1,1}. Given a pixel
58  // (x,y), the 4-connected neighbors have relative offsets (u,0) and
59  // (0,v). The 8-connected neighbors include the 4-connected neighbors
60  // and have additional relative offsets (u,v). The corner neighbors
61  // have relative offsets (0,0), (1,0), (0,1), and (1,1) in that order.
62  // The full neighborhood is the set of 3x3 pixels centered at (x,y).
63 
64  // The neighborhoods can be accessed as 1-dimensional indices using these
65  // functions. The first four functions provide 1-dimensional indices
66  // relative to any pixel location; these depend only on the image
67  // dimensions. The last four functions provide 1-dimensional indices
68  // for the actual pixels in the neighborhood; no clamping is used when
69  // (x,y) is on the boundary.
70  void GetNeighborhood(std::array<int, 4>& nbr) const;
71  void GetNeighborhood(std::array<int, 8>& nbr) const;
72  void GetCorners(std::array<int, 4>& nbr) const;
73  void GetFull(std::array<int, 9>& nbr) const;
74  void GetNeighborhood(int x, int y, std::array<size_t, 4>& nbr) const;
75  void GetNeighborhood(int x, int y, std::array<size_t, 8>& nbr) const;
76  void GetCorners(int x, int y, std::array<size_t, 4>& nbr) const;
77  void GetFull(int x, int y, std::array<size_t, 9>& nbr) const;
78 
79  // The neighborhoods can be accessed as 2-tuples using these functions.
80  // The first four functions provide 2-tuples relative to any pixel
81  // location; these depend only on the image dimensions. The last four
82  // functions provide 2-tuples for the actual pixels in the neighborhood;
83  // no clamping is used when (x,y) is on the boundary.
84  void GetNeighborhood(std::array<std::array<int, 2>, 4>& nbr) const;
85  void GetNeighborhood(std::array<std::array<int, 2>, 8>& nbr) const;
86  void GetCorners(std::array<std::array<int, 2>, 4>& nbr) const;
87  void GetFull(std::array<std::array<int, 2>, 9>& nbr) const;
88  void GetNeighborhood(int x, int y, std::array<std::array<size_t, 2>, 4>& nbr) const;
89  void GetNeighborhood(int x, int y, std::array<std::array<size_t, 2>, 8>& nbr) const;
90  void GetCorners(int x, int y, std::array<std::array<size_t, 2>, 4>& nbr) const;
91  void GetFull(int x, int y, std::array<std::array<size_t, 2>, 9>& nbr) const;
92 };
93 
94 
95 template <typename PixelType>
97 {
98 }
99 
100 template <typename PixelType>
102 {
103 }
104 
105 template <typename PixelType>
106 Image2<PixelType>::Image2(int dimension0, int dimension1)
107  :
108  Image<PixelType>(std::vector<int>{ dimension0, dimension1 })
109 {
110 }
111 
112 template <typename PixelType>
114  :
115  Image<PixelType>(image)
116 {
117 }
118 
119 template <typename PixelType>
121 {
123  return *this;
124 }
125 
126 template <typename PixelType>
128 {
129  *this = std::move(image);
130 }
131 
132 template <typename PixelType>
134 {
136  return *this;
137 }
138 
139 template <typename PixelType>
140 void Image2<PixelType>::Reconstruct(int dimension0, int dimension1)
141 {
142  Image<PixelType>::Reconstruct(std::vector<int>{ dimension0, dimension1 });
143 }
144 
145 template <typename PixelType> inline
146 size_t Image2<PixelType>::GetIndex(int x, int y) const
147 {
148 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
149  if (0 <= x && x < mDimensions[0]
150  && 0 <= y && y < mDimensions[1])
151  {
152  return static_cast<size_t>(x) +
153  static_cast<size_t>(this->mDimensions[0]) * static_cast<size_t>(y);
154  }
155  LogError("Invalid coordinates (" + std::to_string(x) + "," +
156  std::to_string(y) + ").");
157  return 0;
158 #else
159  return static_cast<size_t>(x) +
160  static_cast<size_t>(this->mDimensions[0]) * static_cast<size_t>(y);
161 #endif
162 }
163 
164 template <typename PixelType> inline
165 size_t Image2<PixelType>::GetIndex(std::array<int, 2> const& coord) const
166 {
167 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
168  if (0 <= coord[0] && coord[0] < this->mDimensions[0]
169  && 0 <= coord[1] && coord[1] < this->mDimensions[1])
170  {
171  return static_cast<size_t>(coord[0]) +
172  static_cast<size_t>(this->mDimensions[0]) * static_cast<size_t>(coord[1]);
173  }
174  LogError("Invalid coordinates (" + std::to_string(coord[0]) + "," +
175  std::to_string(coord[1]) + ").");
176  return 0;
177 #else
178  return static_cast<size_t>(coord[0]) +
179  static_cast<size_t>(this->mDimensions[0]) * static_cast<size_t>(coord[1]);
180 #endif
181 }
182 
183 template <typename PixelType> inline
184 void Image2<PixelType>::GetCoordinates(size_t index, int& x, int& y) const
185 {
186 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
187  if (index < mNumPixels)
188  {
189  x = static_cast<int>(index % this->mDimensions[0]);
190  y = static_cast<int>(index / this->mDimensions[0]);
191  }
192  else
193  {
194  LogError("Invalid index " + std::to_string(index) + ".");
195  x = 0;
196  y = 0;
197  }
198 #else
199  x = static_cast<int>(index % this->mDimensions[0]);
200  y = static_cast<int>(index / this->mDimensions[0]);
201 #endif
202 }
203 
204 template <typename PixelType> inline
205 std::array<int, 2> Image2<PixelType>::GetCoordinates(size_t index) const
206 {
207  std::array<int, 2> coord;
208 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
209  if (index < mNumPixels)
210  {
211  coord[0] = static_cast<int>(index % this->mDimensions[0]);
212  coord[1] = static_cast<int>(index / this->mDimensions[0]);
213  }
214  else
215  {
216  LogError("Invalid index " + std::to_string(index) + ".");
217  coord[0] = 0;
218  coord[1] = 0;
219  }
220 #else
221  coord[0] = static_cast<int>(index % this->mDimensions[0]);
222  coord[1] = static_cast<int>(index / this->mDimensions[0]);
223 #endif
224  return coord;
225 }
226 
227 template <typename PixelType> inline
228 PixelType& Image2<PixelType>::operator() (int x, int y)
229 {
230 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
231  if (0 <= x && x < this->mDimensions[0]
232  && 0 <= y && y < this->mDimensions[1])
233  {
234  return this->mPixels[x + this->mDimensions[0] * y];
235  }
236  LogError("Invalid coordinates (" + std::to_string(x) + "," +
237  std::to_string(y) + ").");
238  return this->mPixels[0];
239 #else
240  return this->mPixels[x + this->mDimensions[0] * y];
241 #endif
242 }
243 
244 template <typename PixelType> inline
245 PixelType const& Image2<PixelType>::operator() (int x, int y) const
246 {
247 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
248  if (0 <= x && x < this->mDimensions[0]
249  && 0 <= y && y < this->mDimensions[1])
250  {
251  return this->mPixels[x + this->mDimensions[0] * y];
252  }
253  LogError("Invalid coordinates (" + std::to_string(x) + "," +
254  std::to_string(y) + ").");
255  return this->mPixels[0];
256 #else
257  return this->mPixels[x + this->mDimensions[0] * y];
258 #endif
259 }
260 
261 template <typename PixelType> inline
262 PixelType& Image2<PixelType>::operator() (std::array<int, 2> const& coord)
263 {
264 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
265  if (0 <= coord[0] && coord[0] < this->mDimensions[0]
266  && 0 <= coord[1] && coord[1] < this->mDimensions[1])
267  {
268  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
269  }
270  LogError("Invalid coordinates (" + std::to_string(coord[0]) + "," +
271  std::to_string(coord[1]) + ").");
272  return this->mPixels[0];
273 #else
274  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
275 #endif
276 }
277 
278 template <typename PixelType> inline
279 PixelType const& Image2<PixelType>::operator() (std::array<int, 2> const& coord) const
280 {
281 #if defined(GTE_IMAGICS_ASSERT_ON_INVALID_INDEX)
282  if (0 <= coord[0] && coord[0] < this->mDimensions[0]
283  && 0 <= coord[1] && coord[1] < this->mDimensions[1])
284  {
285  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
286  }
287  LogError("Invalid coordinates (" + std::to_string(coord[0]) + "," +
288  std::to_string(coord[1]) + ").");
289  return this->mPixels[0];
290 #else
291  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
292 #endif
293 }
294 
295 template <typename PixelType>
296 PixelType& Image2<PixelType>::Get(int x, int y)
297 {
298  // Clamp to valid (x,y).
299  if (x < 0)
300  {
301  x = 0;
302  }
303  else if (x >= this->mDimensions[0])
304  {
305  x = this->mDimensions[0] - 1;
306  }
307 
308  if (y < 0)
309  {
310  y = 0;
311  }
312  else if (y >= this->mDimensions[1])
313  {
314  y = this->mDimensions[1] - 1;
315  }
316 
317  return this->mPixels[x + this->mDimensions[0] * y];
318 }
319 
320 template <typename PixelType>
321 PixelType const& Image2<PixelType>::Get(int x, int y) const
322 {
323  // Clamp to valid (x,y).
324  if (x < 0)
325  {
326  x = 0;
327  }
328  else if (x >= this->mDimensions[0])
329  {
330  x = this->mDimensions[0] - 1;
331  }
332 
333  if (y < 0)
334  {
335  y = 0;
336  }
337  else if (y >= this->mDimensions[1])
338  {
339  y = this->mDimensions[1] - 1;
340  }
341 
342  return this->mPixels[x + this->mDimensions[0] * y];
343 }
344 
345 template <typename PixelType>
346 PixelType& Image2<PixelType>::Get(std::array<int, 2> coord)
347 {
348  // Clamp to valid (x,y).
349  for (int i = 0; i < 2; ++i)
350  {
351  if (coord[i] < 0)
352  {
353  coord[i] = 0;
354  }
355  else if (coord[i] >= this->mDimensions[i])
356  {
357  coord[i] = this->mDimensions[i] - 1;
358  }
359  }
360 
361  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
362 }
363 
364 template <typename PixelType>
365 PixelType const& Image2<PixelType>::Get(std::array<int, 2> coord) const
366 {
367  // Clamp to valid (x,y).
368  for (int i = 0; i < 2; ++i)
369  {
370  if (coord[i] < 0)
371  {
372  coord[i] = 0;
373  }
374  else if (coord[i] >= this->mDimensions[i])
375  {
376  coord[i] = this->mDimensions[i] - 1;
377  }
378  }
379 
380  return this->mPixels[coord[0] + this->mDimensions[0] * coord[1]];
381 }
382 
383 template <typename PixelType>
384 void Image2<PixelType>::GetNeighborhood(std::array<int, 4>& nbr) const
385 {
386  int dim0 = this->mDimensions[0];
387  nbr[0] = -1; // (x-1,y)
388  nbr[1] = +1; // (x+1,y)
389  nbr[2] = -dim0; // (x,y-1)
390  nbr[3] = +dim0; // (x,y+1)
391 }
392 
393 template <typename PixelType>
394 void Image2<PixelType>::GetNeighborhood(std::array<int, 8>& nbr) const
395 {
396  int dim0 = this->mDimensions[0];
397  nbr[0] = -1; // (x-1,y)
398  nbr[1] = +1; // (x+1,y)
399  nbr[2] = -dim0; // (x,y-1)
400  nbr[3] = +dim0; // (x,y+1)
401  nbr[4] = -1 - dim0; // (x-1,y-1)
402  nbr[5] = +1 - dim0; // (x+1,y-1)
403  nbr[6] = -1 + dim0; // (x-1,y+1)
404  nbr[7] = +1 + dim0; // (x+1,y+1)
405 }
406 
407 template <typename PixelType>
408 void Image2<PixelType>::GetCorners(std::array<int, 4>& nbr) const
409 {
410  int dim0 = this->mDimensions[0];
411  nbr[0] = 0; // (x,y)
412  nbr[1] = 1; // (x+1,y)
413  nbr[2] = dim0; // (x,y+1)
414  nbr[3] = dim0 + 1; // (x+1,y+1)
415 }
416 
417 template <typename PixelType>
418 void Image2<PixelType>::GetFull(std::array<int, 9>& nbr) const
419 {
420  int dim0 = this->mDimensions[0];
421  nbr[0] = -1 - dim0; // (x-1,y-1)
422  nbr[1] = -dim0; // (x,y-1)
423  nbr[2] = +1 - dim0; // (x+1,y-1)
424  nbr[3] = -1; // (x-1,y)
425  nbr[4] = 0; // (x,y)
426  nbr[5] = +1; // (x+1,y)
427  nbr[6] = -1 + dim0; // (x-1,y+1)
428  nbr[7] = +dim0; // (x,y+1)
429  nbr[8] = +1 + dim0; // (x+1,y+1)
430 }
431 
432 template <typename PixelType>
433 void Image2<PixelType>::GetNeighborhood(int x, int y, std::array<size_t, 4>& nbr) const
434 {
435  size_t index = GetIndex(x, y);
436  std::array<int, 4> inbr;
437  GetNeighborhood(inbr);
438  for (int i = 0; i < 4; ++i)
439  {
440  nbr[i] = index + inbr[i];
441  }
442 }
443 
444 template <typename PixelType>
445 void Image2<PixelType>::GetNeighborhood(int x, int y, std::array<size_t, 8>& nbr) const
446 {
447  size_t index = GetIndex(x, y);
448  std::array<int, 8> inbr;
449  GetNeighborhood(inbr);
450  for (int i = 0; i < 8; ++i)
451  {
452  nbr[i] = index + inbr[i];
453  }
454 }
455 
456 template <typename PixelType>
457 void Image2<PixelType>::GetCorners(int x, int y, std::array<size_t, 4>& nbr) const
458 {
459  size_t index = GetIndex(x, y);
460  std::array<int, 4> inbr;
461  GetCorners(inbr);
462  for (int i = 0; i < 4; ++i)
463  {
464  nbr[i] = index + inbr[i];
465  }
466 }
467 
468 template <typename PixelType>
469 void Image2<PixelType>::GetFull(int x, int y, std::array<size_t, 9>& nbr) const
470 {
471  size_t index = GetIndex(x, y);
472  std::array<int, 9> inbr;
473  GetFull(inbr);
474  for (int i = 0; i < 9; ++i)
475  {
476  nbr[i] = index + inbr[i];
477  }
478 }
479 
480 template <typename PixelType>
481 void Image2<PixelType>::GetNeighborhood(std::array<std::array<int, 2>, 4>& nbr) const
482 {
483  nbr[0] = { { -1, 0 } };
484  nbr[1] = { { +1, 0 } };
485  nbr[2] = { { 0, -1 } };
486  nbr[3] = { { 0, +1 } };
487 }
488 
489 template <typename PixelType>
490 void Image2<PixelType>::GetNeighborhood(std::array<std::array<int, 2>, 8>& nbr) const
491 {
492  nbr[0] = { { -1, -1 } };
493  nbr[1] = { { 0, -1 } };
494  nbr[2] = { { +1, -1 } };
495  nbr[3] = { { -1, 0 } };
496  nbr[4] = { { +1, 0 } };
497  nbr[5] = { { -1, +1 } };
498  nbr[6] = { { 0, +1 } };
499  nbr[7] = { { +1, +1 } };
500 }
501 
502 template <typename PixelType>
503 void Image2<PixelType>::GetCorners(std::array<std::array<int, 2>, 4>& nbr) const
504 {
505  nbr[0] = { { 0, 0 } };
506  nbr[1] = { { 1, 0 } };
507  nbr[2] = { { 0, 1 } };
508  nbr[3] = { { 1, 1 } };
509 }
510 
511 template <typename PixelType>
512 void Image2<PixelType>::GetFull(std::array<std::array<int, 2>, 9>& nbr) const
513 {
514  nbr[0] = { { -1, -1 } };
515  nbr[1] = { { 0, -1 } };
516  nbr[2] = { { +1, -1 } };
517  nbr[3] = { { -1, 0 } };
518  nbr[4] = { { 0, 0 } };
519  nbr[5] = { { +1, 0 } };
520  nbr[6] = { { -1, +1 } };
521  nbr[7] = { { 0, +1 } };
522  nbr[8] = { { +1, +1 } };
523 }
524 
525 template <typename PixelType>
526 void Image2<PixelType>::GetNeighborhood(int x, int y, std::array<std::array<size_t, 2>, 4>& nbr) const
527 {
528  std::array<std::array<int, 2>, 4> inbr;
529  GetNeighborhood(inbr);
530  for (int i = 0; i < 4; ++i)
531  {
532  nbr[i][0] = static_cast<size_t>(x) + inbr[i][0];
533  nbr[i][1] = static_cast<size_t>(y) + inbr[i][1];
534  }
535 }
536 
537 template <typename PixelType>
538 void Image2<PixelType>::GetNeighborhood(int x, int y, std::array<std::array<size_t, 2>, 8>& nbr) const
539 {
540  std::array<std::array<int, 2>, 8> inbr;
541  GetNeighborhood(inbr);
542  for (int i = 0; i < 8; ++i)
543  {
544  nbr[i][0] = static_cast<size_t>(x) + inbr[i][0];
545  nbr[i][1] = static_cast<size_t>(y) + inbr[i][1];
546  }
547 }
548 
549 template <typename PixelType>
550 void Image2<PixelType>::GetCorners(int x, int y, std::array<std::array<size_t, 2>, 4>& nbr) const
551 {
552  std::array<std::array<int, 2>, 4> inbr;
553  GetCorners(inbr);
554  for (int i = 0; i < 4; ++i)
555  {
556  nbr[i][0] = static_cast<size_t>(x) + inbr[i][0];
557  nbr[i][1] = static_cast<size_t>(y) + inbr[i][1];
558  }
559 }
560 
561 template <typename PixelType>
562 void Image2<PixelType>::GetFull(int x, int y, std::array<std::array<size_t, 2>, 9>& nbr) const
563 {
564  std::array<std::array<int, 2>, 9> inbr;
565  GetFull(inbr);
566  for (int i = 0; i < 9; ++i)
567  {
568  nbr[i][0] = static_cast<size_t>(x) + inbr[i][0];
569  nbr[i][1] = static_cast<size_t>(y) + inbr[i][1];
570  }
571 }
572 
573 }
std::vector< int > mDimensions
Definition: GteImage.h:68
Image2 & operator=(Image2 const &image)
Definition: GteImage2.h:120
size_t GetIndex(int x, int y) const
Definition: GteImage2.h:146
Image & operator=(Image const &image)
Definition: GteImage.h:97
void GetFull(std::array< int, 9 > &nbr) const
Definition: GteImage2.h:418
PixelType & Get(int x, int y)
Definition: GteImage2.h:296
GLenum GLenum GLsizei void * image
Definition: glext.h:2724
GLuint coord
Definition: glext.h:5871
GLint GLenum GLint x
Definition: glcorearb.h:404
virtual ~Image2()
Definition: GteImage2.h:96
void Reconstruct(int dimension0, int dimension1)
Definition: GteImage2.h:140
void GetCoordinates(size_t index, int &x, int &y) const
Definition: GteImage2.h:184
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
#define LogError(message)
Definition: GteLogger.h:92
PixelType & operator()(int x, int y)
Definition: GteImage2.h:228
void Reconstruct(std::vector< int > const &dimensions)
Definition: GteImage.h:121
GLenum array
Definition: glext.h:6669
GLuint index
Definition: glcorearb.h:781
void GetNeighborhood(std::array< int, 4 > &nbr) const
Definition: GteImage2.h:384
std::vector< PixelType > mPixels
Definition: GteImage.h:70
GLint y
Definition: glcorearb.h:98
void GetCorners(std::array< int, 4 > &nbr) const
Definition: GteImage2.h:408


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00