Worldstone
 All Classes Files Functions Variables Enumerations Enumerator Macros Pages
ImageView.h
Go to the documentation of this file.
1 
4 #pragma once
5 
6 #include <Platform.h>
7 #include <Vector.h>
8 #include <string.h> // memcpy & memset
9 
10 namespace WorldStone
11 {
24 template<class Color>
25 struct ImageView
26 {
27  static_assert(std::is_trivially_copyable<Color>::value, "Color must be trivially copyable for memcpy/memset");
28  Color* buffer = nullptr;
29  size_t width = 0;
30  size_t height = 0;
31  size_t stride = 0;
32 
33  ImageView() = default;
34 
35  ImageView(Color* _buffer, size_t _width, size_t _height, size_t _stride)
36  : buffer(_buffer), width(_width), height(_height), stride(_stride)
37  {
38  }
39 
41  bool isValid() const { return buffer && width && height && width <= stride; }
42 
43  bool operator==(const ImageView& rhs) const
44  {
45  return buffer == rhs.buffer && width == rhs.width && height == rhs.height &&
46  stride == rhs.stride;
47  }
48  bool operator!=(const ImageView& rhs) const { return !(*this == rhs); }
49 
51  operator ImageView<const Color>() const { return {buffer, width, height, stride}; }
52 
61  ImageView subView(size_t xOffset, size_t yOffset, size_t subWidth, size_t subHeight) const
62  {
63  if (xOffset + subWidth > width || yOffset + subHeight > height) return {};
64  return {buffer + xOffset + yOffset * stride, subWidth, subHeight, stride};
65  }
66 
72  Color& operator()(size_t x, size_t y) const { return buffer[x + y * stride]; }
73 
78  void copyTo(ImageView destination) const
79  {
80  for (size_t y = 0; y < height; y++)
81  {
82  memcpy(destination.buffer + y * destination.stride, buffer + y * stride,
83  width * sizeof(Color));
84  }
85  }
86 
95  void fill(size_t x, size_t y, size_t columns, size_t rows, Color colorValue)
96  {
97  Color* lineStart = buffer + x + y * stride;
98  for (size_t row = 0; row < rows; ++row)
99  {
100  for (size_t column = 0; column < columns; column++)
101  {
102  lineStart[column] = colorValue;
103  }
104  lineStart += stride;
105  }
106  }
107 
115  void fillBytes(size_t x, size_t y, size_t columns, size_t rows, uint8_t byteValue)
116  {
117  Color* dstPtr = buffer + x + y * stride;
118  for (size_t row = 0; row < rows; ++row)
119  {
120  memset(dstPtr, byteValue, columns * sizeof(Color));
121  dstPtr += stride;
122  }
123  }
124 };
125 
129 template<class Color>
131 {
132 public:
134  virtual ImageView<Color> getNewImage(size_t width, size_t height) = 0;
135  virtual ~IImageProvider() {}
136 };
137 
139 template<class Color>
140 class SimpleImageProvider : public IImageProvider<Color>
141 {
142  struct Image
143  {
144  size_t width = 0;
145  size_t height = 0;
146  Vector<Color> buffer;
147  Image(size_t _width, size_t _height)
148  : width(_width), height(_height), buffer(_width * _height)
149  {
150  }
151  };
152  Vector<Image> images;
153 
154 public:
156  ImageView<Color> getNewImage(size_t width, size_t height) override
157  {
158  if (!width || !height) return {};
159  // if (!width || !height) return ImageView<Color>::getInvalidView();
160  images.emplace_back(width, height);
161  return {images.back().buffer.data(), width, height, width};
162  }
163 
165  size_t getImagesNumber() const { return images.size(); }
166 
168  ImageView<Color> getImage(size_t imageIndex)
169  {
170  Image& img = images[imageIndex];
171  return {img.buffer.data(), img.width, img.height, img.width};
172  }
174  ImageView<const Color> getImage(size_t imageIndex) const
175  {
176  const Image& img = images[imageIndex];
177  return {img.buffer.data(), img.width, img.height, img.width};
178  }
179 
184  Vector<Color> moveImageBuffer(size_t imageIndex)
185  {
186  // We could swap with back() to free memory, but that would invalidate indices.
187  Image& img = images[imageIndex];
188  img.width = 0;
189  img.height = 0;
190  return std::move(img.buffer);
191  }
192 };
193 }
ImageView subView(size_t xOffset, size_t yOffset, size_t subWidth, size_t subHeight) const
Create an ImageView that is contained by the current view.
Definition: ImageView.h:61
Color * buffer
Pointer to the memory considered as the first pixel.
Definition: ImageView.h:28
Color & operator()(size_t x, size_t y) const
Access the pixel at the given coordinates.
Definition: ImageView.h:72
void copyTo(ImageView destination) const
Copy (blits) the content of an image to another.
Definition: ImageView.h:78
size_t stride
Actual width of the buffer scanlines.
Definition: ImageView.h:31
ImageView< const Color > getImage(size_t imageIndex) const
Definition: ImageView.h:174
bool isValid() const
Checks if the view seems to be valid based on its characteristics.
Definition: ImageView.h:41
void fill(size_t x, size_t y, size_t columns, size_t rows, Color colorValue)
Fills a part of the image.
Definition: ImageView.h:95
size_t width
Width of the image, can be dfferent from the one of the buffer.
Definition: ImageView.h:29
size_t getImagesNumber() const
Definition: ImageView.h:165
Vector< Color > moveImageBuffer(size_t imageIndex)
Move an image buffer out of the provider.
Definition: ImageView.h:184
A simple image provider that allocates a new buffer for each call to getNewImage() ...
Definition: ImageView.h:140
ImageView< Color > getImage(size_t imageIndex)
Definition: ImageView.h:168
A view on an image buffer of type Color.
Definition: ImageView.h:25
Just a placeholder to use if we ever want to implement our own vector type.
void fillBytes(size_t x, size_t y, size_t columns, size_t rows, uint8_t byteValue)
Fills a part of the image using a byte pattern.
Definition: ImageView.h:115
size_t height
Number of scanlines of the image.
Definition: ImageView.h:30
virtual ImageView< Color > getNewImage(size_t width, size_t height)=0
Returns an ImageView of dimensions width * height to be used by the consumer.
An interface of a class that can provide images views.
Definition: ImageView.h:130
ImageView< Color > getNewImage(size_t width, size_t height) override
Allocates a new Image of dimensions width * height.
Definition: ImageView.h:156
Platform specific tools and macros.