Image.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <vector>
  9. namespace WwiseGTE
  10. {
  11. template <typename PixelType>
  12. class Image
  13. {
  14. public:
  15. // Construction and destruction.
  16. virtual ~Image()
  17. {
  18. }
  19. Image()
  20. {
  21. }
  22. Image(std::vector<int> const& dimensions)
  23. {
  24. Reconstruct(dimensions);
  25. }
  26. // Support for copy semantics.
  27. Image(Image const& image)
  28. {
  29. *this = image;
  30. }
  31. Image& operator=(Image const& image)
  32. {
  33. mDimensions = image.mDimensions;
  34. mOffsets = image.mOffsets;
  35. mPixels = image.mPixels;
  36. return *this;
  37. }
  38. // Support for move semantics.
  39. Image(Image&& image)
  40. {
  41. *this = std::move(image);
  42. }
  43. Image& operator=(Image&& image)
  44. {
  45. mDimensions = std::move(image.mDimensions);
  46. mOffsets = std::move(image.mOffsets);
  47. mPixels = std::move(image.mPixels);
  48. return *this;
  49. }
  50. // Support for changing the image dimensions. All pixel data is lost
  51. // by this operation.
  52. void Reconstruct(std::vector<int> const& dimensions)
  53. {
  54. mDimensions.clear();
  55. mOffsets.clear();
  56. mPixels.clear();
  57. if (dimensions.size() > 0)
  58. {
  59. for (auto dim : dimensions)
  60. {
  61. if (dim <= 0)
  62. {
  63. return;
  64. }
  65. }
  66. mDimensions = dimensions;
  67. mOffsets.resize(dimensions.size());
  68. size_t numPixels = 1;
  69. for (size_t d = 0; d < dimensions.size(); ++d)
  70. {
  71. numPixels *= static_cast<size_t>(mDimensions[d]);
  72. }
  73. mOffsets[0] = 1;
  74. for (size_t d = 1; d < dimensions.size(); ++d)
  75. {
  76. mOffsets[d] = static_cast<size_t>(mDimensions[d - 1]) * mOffsets[d - 1];
  77. }
  78. mPixels.resize(numPixels);
  79. }
  80. }
  81. // Access to image data.
  82. inline std::vector<int> const& GetDimensions() const
  83. {
  84. return mDimensions;
  85. }
  86. inline int GetNumDimensions() const
  87. {
  88. return static_cast<int>(mDimensions.size());
  89. }
  90. inline int GetDimension(int d) const
  91. {
  92. return mDimensions[d];
  93. }
  94. inline std::vector<size_t> const& GetOffsets() const
  95. {
  96. return mOffsets;
  97. }
  98. inline size_t GetOffset(int d) const
  99. {
  100. return mOffsets[d];
  101. }
  102. inline std::vector<PixelType> const& GetPixels() const
  103. {
  104. return mPixels;
  105. }
  106. inline std::vector<PixelType>& GetPixels()
  107. {
  108. return mPixels;
  109. }
  110. inline size_t GetNumPixels() const
  111. {
  112. return mPixels.size();
  113. }
  114. // Conversions between n-dim and 1-dim structures. The 'coord' arrays
  115. // must have GetNumDimensions() elements.
  116. size_t GetIndex(int const* coord) const
  117. {
  118. // assert: coord is array of mNumDimensions elements
  119. int const numDimensions = static_cast<int>(mDimensions.size());
  120. size_t index = coord[0];
  121. for (int d = 1; d < numDimensions; ++d)
  122. {
  123. index += mOffsets[d] * coord[d];
  124. }
  125. return index;
  126. }
  127. void GetCoordinates(size_t index, int* coord) const
  128. {
  129. // assert: coord is array of numDimensions elements
  130. int const numDimensions = static_cast<int>(mDimensions.size());
  131. for (int d = 0; d < numDimensions; ++d)
  132. {
  133. coord[d] = index % mDimensions[d];
  134. index /= mDimensions[d];
  135. }
  136. }
  137. // Access the data as a 1-dimensional array. The operator[] functions
  138. // test for valid i when iterator checking is enabled and assert on
  139. // invalid i. The Get() functions test for valid i and clamp when
  140. // invalid; these functions cannot fail.
  141. inline PixelType& operator[] (size_t i)
  142. {
  143. return mPixels[i];
  144. }
  145. inline PixelType const& operator[] (size_t i) const
  146. {
  147. return mPixels[i];
  148. }
  149. PixelType& Get(size_t i)
  150. {
  151. return (i < mPixels.size() ? mPixels[i] : mPixels.front());
  152. }
  153. PixelType const& Get(size_t i) const
  154. {
  155. return (i < mPixels.size() ? mPixels[i] : mPixels.front());
  156. }
  157. protected:
  158. std::vector<int> mDimensions;
  159. std::vector<size_t> mOffsets;
  160. std::vector<PixelType> mPixels;
  161. };
  162. }