Blender  V3.3
array_nd.h
Go to the documentation of this file.
1 // Copyright (c) 2007, 2008 libmv authors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20 
21 #ifndef LIBMV_IMAGE_ARRAY_ND_H
22 #define LIBMV_IMAGE_ARRAY_ND_H
23 
24 #include <cassert>
25 #include <cstdio>
26 #include <cstring>
27 
28 #include "libmv/image/tuple.h"
29 
30 namespace libmv {
31 
32 class BaseArray {};
33 
35 template <typename T, int N>
36 class ArrayND : public BaseArray {
37  public:
38  typedef T Scalar;
39 
42 
44  ArrayND() : data_(NULL), own_data_(true) { Resize(Index(0)); }
45 
47  ArrayND(const Index& shape) : data_(NULL), own_data_(true) { Resize(shape); }
48 
50  ArrayND(int* shape) : data_(NULL), own_data_(true) { Resize(shape); }
51 
53  ArrayND(const ArrayND<T, N>& b) : data_(NULL), own_data_(true) {
54  ResizeLike(b);
55  std::memcpy(Data(), b.Data(), sizeof(T) * Size());
56  }
57 
58  ArrayND(int s0) : data_(NULL), own_data_(true) { Resize(s0); }
59  ArrayND(int s0, int s1) : data_(NULL), own_data_(true) { Resize(s0, s1); }
60  ArrayND(int s0, int s1, int s2) : data_(NULL), own_data_(true) {
61  Resize(s0, s1, s2);
62  }
63 
64  ArrayND(T* data, int s0, int s1, int s2)
65  : shape_(0), strides_(0), data_(data), own_data_(false) {
66  Resize(s0, s1, s2);
67  }
68 
71  if (own_data_) {
72  delete[] data_;
73  }
74  }
75 
78  assert(this != &b);
79  ResizeLike(b);
80  std::memcpy(Data(), b.Data(), sizeof(T) * Size());
81  return *this;
82  }
83 
84  const Index& Shapes() const { return shape_; }
85 
86  const Index& Strides() const { return strides_; }
87 
89  void Resize(const Index& new_shape) {
90  if (data_ != NULL && shape_ == new_shape) {
91  // Don't bother realloacting if the shapes match.
92  return;
93  }
94  shape_.Reset(new_shape);
95  strides_(N - 1) = 1;
96  for (int i = N - 1; i > 0; --i) {
97  strides_(i - 1) = strides_(i) * shape_(i);
98  }
99  if (own_data_) {
100  delete[] data_;
101  data_ = NULL;
102  if (Size() > 0) {
103  data_ = new T[Size()];
104  }
105  }
106  }
107 
108  template <typename D>
109  void ResizeLike(const ArrayND<D, N>& other) {
110  Resize(other.Shape());
111  }
112 
114  void Resize(const int* new_shape_array) { Resize(Index(new_shape_array)); }
115 
117  void Resize(int s0) {
118  assert(N == 1);
119  int shape[] = {s0};
120  Resize(shape);
121  }
122 
124  void Resize(int s0, int s1) {
125  int shape[N] = {s0, s1};
126  for (int i = 2; i < N; ++i) {
127  shape[i] = 1;
128  }
129  Resize(shape);
130  }
131 
132  // Match Eigen2's API.
133  void resize(int rows, int cols) { Resize(rows, cols); }
134 
136  void Resize(int s0, int s1, int s2) {
137  assert(N == 3);
138  int shape[] = {s0, s1, s2};
139  Resize(shape);
140  }
141 
142  template <typename D>
143  void CopyFrom(const ArrayND<D, N>& other) {
144  ResizeLike(other);
145  T* data = Data();
146  const D* other_data = other.Data();
147  for (int i = 0; i < Size(); ++i) {
148  data[i] = T(other_data[i]);
149  }
150  }
151 
152  void Fill(T value) {
153  for (int i = 0; i < Size(); ++i) {
154  Data()[i] = value;
155  }
156  }
157 
158  // Match Eigen's API.
159  void fill(T value) {
160  for (int i = 0; i < Size(); ++i) {
161  Data()[i] = value;
162  }
163  }
164 
166  const Index& Shape() const { return shape_; }
167 
169  int Shape(int axis) const { return shape_(axis); }
170 
172  int Stride(int axis) const { return strides_(axis); }
173 
175  int Size() const {
176  int size = 1;
177  for (int i = 0; i < N; ++i)
178  size *= Shape(i);
179  return size;
180  }
181 
183  int MemorySizeInBytes() const { return sizeof(*this) + Size() * sizeof(T); }
184 
186  T* Data() { return data_; }
187 
189  const T* Data() const { return data_; }
190 
192  int Offset(const Index& index) const {
193  int offset = 0;
194  for (int i = 0; i < N; ++i)
195  offset += index(i) * Stride(i);
196  return offset;
197  }
198 
200  int Offset(int i0) const {
201  assert(N == 1);
202  return i0 * Stride(0);
203  }
204 
206  int Offset(int i0, int i1) const {
207  assert(N == 2);
208  return i0 * Stride(0) + i1 * Stride(1);
209  }
210 
212  int Offset(int i0, int i1, int i2) const {
213  assert(N == 3);
214  return i0 * Stride(0) + i1 * Stride(1) + i2 * Stride(2);
215  }
216 
218  T& operator()(const Index& index) {
219  // TODO(pau) Boundary checking in debug mode.
220  return *(Data() + Offset(index));
221  }
222 
224  T& operator()(int i0) { return *(Data() + Offset(i0)); }
225 
227  T& operator()(int i0, int i1) {
228  assert(0 <= i0 && i0 < Shape(0));
229  assert(0 <= i1 && i1 < Shape(1));
230  return *(Data() + Offset(i0, i1));
231  }
232 
234  T& operator()(int i0, int i1, int i2) {
235  assert(0 <= i0 && i0 < Shape(0));
236  assert(0 <= i1 && i1 < Shape(1));
237  assert(0 <= i2 && i2 < Shape(2));
238  return *(Data() + Offset(i0, i1, i2));
239  }
240 
242  const T& operator()(const Index& index) const {
243  return *(Data() + Offset(index));
244  }
245 
247  const T& operator()(int i0) const { return *(Data() + Offset(i0)); }
248 
250  const T& operator()(int i0, int i1) const {
251  assert(0 <= i0 && i0 < Shape(0));
252  assert(0 <= i1 && i1 < Shape(1));
253  return *(Data() + Offset(i0, i1));
254  }
255 
257  const T& operator()(int i0, int i1, int i2) const {
258  return *(Data() + Offset(i0, i1, i2));
259  }
260 
262  bool Contains(const Index& index) const {
263  for (int i = 0; i < N; ++i)
264  if (index(i) < 0 || index(i) >= Shape(i))
265  return false;
266  return true;
267  }
268 
270  bool Contains(int i0) const { return 0 <= i0 && i0 < Shape(0); }
271 
273  bool Contains(int i0, int i1) const {
274  return 0 <= i0 && i0 < Shape(0) && 0 <= i1 && i1 < Shape(1);
275  }
276 
278  bool Contains(int i0, int i1, int i2) const {
279  return 0 <= i0 && i0 < Shape(0) && 0 <= i1 && i1 < Shape(1) && 0 <= i2 &&
280  i2 < Shape(2);
281  }
282 
283  bool operator==(const ArrayND<T, N>& other) const {
284  if (shape_ != other.shape_)
285  return false;
286  if (strides_ != other.strides_)
287  return false;
288  for (int i = 0; i < Size(); ++i) {
289  if (this->Data()[i] != other.Data()[i])
290  return false;
291  }
292  return true;
293  }
294 
295  bool operator!=(const ArrayND<T, N>& other) const {
296  return !(*this == other);
297  }
298 
299  ArrayND<T, N> operator*(const ArrayND<T, N>& other) const {
300  assert(Shape() = other.Shape());
301  ArrayND<T, N> res;
302  res.ResizeLike(*this);
303  for (int i = 0; i < res.Size(); ++i) {
304  res.Data()[i] = Data()[i] * other.Data()[i];
305  }
306  return res;
307  }
308 
309  protected:
312 
315 
318 
320  bool own_data_;
321 };
322 
324 template <typename T>
325 class Array3D : public ArrayND<T, 3> {
326  typedef ArrayND<T, 3> Base;
327 
328  public:
329  Array3D() : Base() {}
330  Array3D(int height, int width, int depth = 1) : Base(height, width, depth) {}
331  Array3D(T* data, int height, int width, int depth = 1)
332  : Base(data, height, width, depth) {}
333 
334  void Resize(int height, int width, int depth = 1) {
336  }
337 
338  int Height() const { return Base::Shape(0); }
339  int Width() const { return Base::Shape(1); }
340  int Depth() const { return Base::Shape(2); }
341 
342  // Match Eigen2's API so that Array3D's and Mat*'s can work together via
343  // template magic.
344  int rows() const { return Height(); }
345  int cols() const { return Width(); }
346  int depth() const { return Depth(); }
347 
348  int Get_Step() const { return Width() * Depth(); }
349 
351  T& operator()(int i0, int i1, int i2 = 0) {
352  assert(0 <= i0 && i0 < Height());
353  assert(0 <= i1 && i1 < Width());
354  return Base::operator()(i0, i1, i2);
355  }
356  const T& operator()(int i0, int i1, int i2 = 0) const {
357  assert(0 <= i0 && i0 < Height());
358  assert(0 <= i1 && i1 < Width());
359  return Base::operator()(i0, i1, i2);
360  }
361 };
362 
368 
369 void SplitChannels(const Array3Df& input,
370  Array3Df* channel0,
371  Array3Df* channel1,
372  Array3Df* channel2);
373 
374 void PrintArray(const Array3Df& array);
375 
382 void FloatArrayToScaledByteArray(const Array3Df& float_array,
383  Array3Du* byte_array,
384  bool automatic_range_detection = false);
385 
387 void ByteArrayToScaledFloatArray(const Array3Du& byte_array,
388  Array3Df* float_array);
389 
390 template <typename AArrayType, typename BArrayType, typename CArrayType>
391 void MultiplyElements(const AArrayType& a, const BArrayType& b, CArrayType* c) {
392  // This function does an element-wise multiply between
393  // the two Arrays A and B, and stores the result in C.
394  // A and B must have the same dimensions.
395  assert(a.Shape() == b.Shape());
396  c->ResizeLike(a);
397 
398  // To perform the multiplcation, a "current" index into the N-dimensions of
399  // the A and B matrix specifies which elements are being multiplied.
400  typename CArrayType::Index index;
401 
402  // The index starts at the maximum value for each dimension
403  const typename CArrayType::Index& cShape = c->Shape();
404  for (int i = 0; i < CArrayType::Index::SIZE; ++i)
405  index(i) = cShape(i) - 1;
406 
407  // After each multiplication, the highest-dimensional index is reduced.
408  // if this reduces it less than zero, it resets to its maximum value
409  // and decrements the index of the next lower dimension.
410  // This ripple-action continues until the entire new array has been
411  // calculated, indicated by dimension zero having a negative index.
412  while (index(0) >= 0) {
413  (*c)(index) = a(index) * b(index);
414 
415  int dimension = CArrayType::Index::SIZE - 1;
416  index(dimension) = index(dimension) - 1;
417  while (dimension > 0 && index(dimension) < 0) {
418  index(dimension) = cShape(dimension) - 1;
419  index(dimension - 1) = index(dimension - 1) - 1;
420  --dimension;
421  }
422  }
423 }
424 
425 template <typename TA, typename TB, typename TC>
427  const ArrayND<TB, 3>& b,
428  ArrayND<TC, 3>* c) {
429  // Specialization for N==3
430  c->ResizeLike(a);
431  assert(a.Shape(0) == b.Shape(0));
432  assert(a.Shape(1) == b.Shape(1));
433  assert(a.Shape(2) == b.Shape(2));
434  for (int i = 0; i < a.Shape(0); ++i) {
435  for (int j = 0; j < a.Shape(1); ++j) {
436  for (int k = 0; k < a.Shape(2); ++k) {
437  (*c)(i, j, k) = TC(a(i, j, k) * b(i, j, k));
438  }
439  }
440  }
441 }
442 
443 template <typename TA, typename TB, typename TC>
445  const Array3D<TB>& b,
446  Array3D<TC>* c) {
447  // Specialization for N==3
448  c->ResizeLike(a);
449  assert(a.Shape(0) == b.Shape(0));
450  assert(a.Shape(1) == b.Shape(1));
451  assert(a.Shape(2) == b.Shape(2));
452  for (int i = 0; i < a.Shape(0); ++i) {
453  for (int j = 0; j < a.Shape(1); ++j) {
454  for (int k = 0; k < a.Shape(2); ++k) {
455  (*c)(i, j, k) = TC(a(i, j, k) * b(i, j, k));
456  }
457  }
458  }
459 }
460 
461 } // namespace libmv
462 
463 #endif // LIBMV_IMAGE_ARRAY_ND_H
#define D
#define SIZE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
3D array (row, column, channel).
Definition: array_nd.h:325
int Get_Step() const
Definition: array_nd.h:348
void Resize(int height, int width, int depth=1)
Definition: array_nd.h:334
T & operator()(int i0, int i1, int i2=0)
Enable accessing with 2 indices for grayscale images.
Definition: array_nd.h:351
int Depth() const
Definition: array_nd.h:340
int rows() const
Definition: array_nd.h:344
int depth() const
Definition: array_nd.h:346
Array3D(int height, int width, int depth=1)
Definition: array_nd.h:330
Array3D(T *data, int height, int width, int depth=1)
Definition: array_nd.h:331
int Height() const
Definition: array_nd.h:338
const T & operator()(int i0, int i1, int i2=0) const
Definition: array_nd.h:356
int cols() const
Definition: array_nd.h:345
int Width() const
Definition: array_nd.h:339
A multidimensional array class.
Definition: array_nd.h:36
ArrayND(int *shape)
Create an array with the specified shape.
Definition: array_nd.h:50
const T & operator()(int i0, int i1, int i2) const
3D specialization.
Definition: array_nd.h:257
bool own_data_
Flag if this Array either own or reference the data.
Definition: array_nd.h:320
void resize(int rows, int cols)
Definition: array_nd.h:133
void Resize(const Index &new_shape)
Create an array of shape s.
Definition: array_nd.h:89
const T * Data() const
Constant pointer to the first element of the array.
Definition: array_nd.h:189
T * data_
Pointer to the first element of the array.
Definition: array_nd.h:317
ArrayND()
Create an empty array.
Definition: array_nd.h:44
const T & operator()(int i0) const
1D specialization.
Definition: array_nd.h:247
ArrayND(const ArrayND< T, N > &b)
Copy constructor.
Definition: array_nd.h:53
T & operator()(int i0, int i1, int i2)
3D specialization.
Definition: array_nd.h:234
void ResizeLike(const ArrayND< D, N > &other)
Definition: array_nd.h:109
int MemorySizeInBytes() const
Return the total amount of memory used by the array.
Definition: array_nd.h:183
bool Contains(int i0, int i1) const
2D specialization.
Definition: array_nd.h:273
void CopyFrom(const ArrayND< D, N > &other)
Definition: array_nd.h:143
void Fill(T value)
Definition: array_nd.h:152
ArrayND(int s0, int s1)
Definition: array_nd.h:59
~ArrayND()
Destructor deletes pixel data.
Definition: array_nd.h:70
ArrayND(T *data, int s0, int s1, int s2)
Definition: array_nd.h:64
void Resize(const int *new_shape_array)
Resizes the array to shape s. All data is lost.
Definition: array_nd.h:114
const T & operator()(int i0, int i1) const
2D specialization.
Definition: array_nd.h:250
void Resize(int s0, int s1)
Resize a 2D array to shape (s0,s1).
Definition: array_nd.h:124
ArrayND & operator=(const ArrayND< T, N > &b)
Assignation copies pixel data.
Definition: array_nd.h:77
void Resize(int s0, int s1, int s2)
Resize a 3D array to shape (s0,s1,s2).
Definition: array_nd.h:136
T & operator()(int i0)
1D specialization.
Definition: array_nd.h:224
const Index & Shape() const
Return a tuple containing the length of each axis.
Definition: array_nd.h:166
void Resize(int s0)
Resize a 1D array to length s0.
Definition: array_nd.h:117
Tuple< int, N > Index
Type for the multidimensional indices.
Definition: array_nd.h:41
const T & operator()(const Index &index) const
Return a constant reference to the element at position index.
Definition: array_nd.h:242
T & operator()(const Index &index)
Return a reference to the element at position index.
Definition: array_nd.h:218
ArrayND(int s0)
Definition: array_nd.h:58
const Index & Strides() const
Definition: array_nd.h:86
int Shape(int axis) const
Return the length of an axis.
Definition: array_nd.h:169
ArrayND(int s0, int s1, int s2)
Definition: array_nd.h:60
bool operator==(const ArrayND< T, N > &other) const
Definition: array_nd.h:283
bool operator!=(const ArrayND< T, N > &other) const
Definition: array_nd.h:295
ArrayND< T, N > operator*(const ArrayND< T, N > &other) const
Definition: array_nd.h:299
T & operator()(int i0, int i1)
2D specialization.
Definition: array_nd.h:227
const Index & Shapes() const
Definition: array_nd.h:84
bool Contains(const Index &index) const
True if index is inside array.
Definition: array_nd.h:262
int Offset(const Index &index) const
Distance between the first element and the element at position index.
Definition: array_nd.h:192
int Offset(int i0, int i1, int i2) const
3D specialization.
Definition: array_nd.h:212
void fill(T value)
Definition: array_nd.h:159
int Stride(int axis) const
Return the distance between neighboring elements along axis.
Definition: array_nd.h:172
bool Contains(int i0) const
1D specialization.
Definition: array_nd.h:270
int Size() const
Return the number of elements of the array.
Definition: array_nd.h:175
bool Contains(int i0, int i1, int i2) const
3D specialization.
Definition: array_nd.h:278
Index strides_
How to jump to neighbors in each dimension.
Definition: array_nd.h:314
int Offset(int i0, int i1) const
2D specialization.
Definition: array_nd.h:206
int Offset(int i0) const
1D specialization.
Definition: array_nd.h:200
T * Data()
Pointer to the first element of the array.
Definition: array_nd.h:186
ArrayND(const Index &shape)
Create an array with the specified shape.
Definition: array_nd.h:47
Index shape_
The number of element in each dimension.
Definition: array_nd.h:311
void Reset(const Tuple< D, N > &b)
Definition: tuple.h:53
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_global KernelShaderEvalInput * input
#define N
#define T
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
void SplitChannels(const Array3Df &input, Array3Df *channel0, Array3Df *channel1, Array3Df *channel2)
Definition: array_nd.cc:68
void ByteArrayToScaledFloatArray(const Array3Du &byte_array, Array3Df *float_array)
Convert a byte array into a float array by dividing values by 255.
Definition: array_nd.cc:56
Array3D< unsigned char > Array3Du
Definition: array_nd.h:363
void PrintArray(const Array3Df &array)
Definition: array_nd.cc:85
Array3D< int > Array3Di
Definition: array_nd.h:365
Array3D< unsigned int > Array3Dui
Definition: array_nd.h:364
Array3D< float > Array3Df
Definition: array_nd.h:366
Array3D< short > Array3Ds
Definition: array_nd.h:367
void FloatArrayToScaledByteArray(const Array3Df &float_array, Array3Du *byte_array, bool automatic_range_detection)
Definition: array_nd.cc:27
void MultiplyElements(const AArrayType &a, const BArrayType &b, CArrayType *c)
Definition: array_nd.h:391
static const pxr::TfToken b("b", pxr::TfToken::Immortal)