Grok  9.7.5
image.h
Go to the documentation of this file.
1 // Copyright 2020 Google LLC
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef HIGHWAY_HWY_CONTRIB_IMAGE_IMAGE_H_
17 #define HIGHWAY_HWY_CONTRIB_IMAGE_IMAGE_H_
18 
19 // SIMD/multicore-friendly planar image representation with row accessors.
20 
21 #include <inttypes.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <string.h>
25 
26 #include <cstddef>
27 #include <utility> // std::move
28 
29 #include "hwy/aligned_allocator.h"
30 #include "hwy/base.h"
31 #include "hwy/highway_export.h"
32 
33 namespace hwy {
34 
35 // Type-independent parts of Image<> - reduces code duplication and facilitates
36 // moving member function implementations to cc file.
38  // Returns required alignment in bytes for externally allocated memory.
39  static size_t VectorSize();
40 
41  // Returns distance [bytes] between the start of two consecutive rows, a
42  // multiple of VectorSize but NOT kAlias (see implementation).
43  static size_t BytesPerRow(const size_t xsize, const size_t sizeof_t);
44 
45  // No allocation (for output params or unused images)
47  : xsize_(0),
48  ysize_(0),
49  bytes_per_row_(0),
50  bytes_(nullptr, AlignedFreer(&AlignedFreer::DoNothing, nullptr)) {}
51 
52  // Allocates memory (this is the common case)
53  ImageBase(size_t xsize, size_t ysize, size_t sizeof_t);
54 
55  // References but does not take ownership of external memory. Useful for
56  // interoperability with other libraries. `aligned` must be aligned to a
57  // multiple of VectorSize() and `bytes_per_row` must also be a multiple of
58  // VectorSize() or preferably equal to BytesPerRow().
59  ImageBase(size_t xsize, size_t ysize, size_t bytes_per_row, void* aligned);
60 
61  // Copy construction/assignment is forbidden to avoid inadvertent copies,
62  // which can be very expensive. Use CopyImageTo() instead.
63  ImageBase(const ImageBase& other) = delete;
64  ImageBase& operator=(const ImageBase& other) = delete;
65 
66  // Move constructor (required for returning Image from function)
67  ImageBase(ImageBase&& other) noexcept = default;
68 
69  // Move assignment (required for std::vector)
70  ImageBase& operator=(ImageBase&& other) noexcept = default;
71 
72  void Swap(ImageBase& other);
73 
74  // Useful for pre-allocating image with some padding for alignment purposes
75  // and later reporting the actual valid dimensions. Caller is responsible
76  // for ensuring xsize/ysize are <= the original dimensions.
77  void ShrinkTo(const size_t xsize, const size_t ysize) {
78  xsize_ = static_cast<uint32_t>(xsize);
79  ysize_ = static_cast<uint32_t>(ysize);
80  // NOTE: we can't recompute bytes_per_row for more compact storage and
81  // better locality because that would invalidate the image contents.
82  }
83 
84  // How many pixels.
85  HWY_INLINE size_t xsize() const { return xsize_; }
86  HWY_INLINE size_t ysize() const { return ysize_; }
87 
88  // NOTE: do not use this for copying rows - the valid xsize may be much less.
89  HWY_INLINE size_t bytes_per_row() const { return bytes_per_row_; }
90 
91  // Raw access to byte contents, for interfacing with other libraries.
92  // Unsigned char instead of char to avoid surprises (sign extension).
93  HWY_INLINE uint8_t* bytes() {
94  void* p = bytes_.get();
95  return static_cast<uint8_t * HWY_RESTRICT>(HWY_ASSUME_ALIGNED(p, 64));
96  }
97  HWY_INLINE const uint8_t* bytes() const {
98  const void* p = bytes_.get();
99  return static_cast<const uint8_t * HWY_RESTRICT>(HWY_ASSUME_ALIGNED(p, 64));
100  }
101 
102  protected:
103  // Returns pointer to the start of a row.
104  HWY_INLINE void* VoidRow(const size_t y) const {
105 #if HWY_IS_ASAN || HWY_IS_MSAN || HWY_IS_TSAN
106  if (y >= ysize_) {
107  HWY_ABORT("Row(%" PRIu64 ") >= %u\n", static_cast<uint64_t>(y), ysize_);
108  }
109 #endif
110 
111  void* row = bytes_.get() + y * bytes_per_row_;
112  return HWY_ASSUME_ALIGNED(row, 64);
113  }
114 
115  enum class Padding {
116  // Allow Load(d, row + x) for x = 0; x < xsize(); x += Lanes(d). Default.
117  kRoundUp,
118  // Allow LoadU(d, row + x) for x <= xsize() - 1. This requires an extra
119  // vector to be initialized. If done by default, this would suppress
120  // legitimate msan warnings. We therefore require users to explicitly call
121  // InitializePadding before using unaligned loads (e.g. convolution).
122  kUnaligned
123  };
124 
125  // Initializes the minimum bytes required to suppress msan warnings from
126  // legitimate (according to Padding mode) vector loads/stores on the right
127  // border, where some lanes are uninitialized and assumed to be unused.
128  void InitializePadding(size_t sizeof_t, Padding padding);
129 
130  // (Members are non-const to enable assignment during move-assignment.)
131  uint32_t xsize_; // In valid pixels, not including any padding.
132  uint32_t ysize_;
133  size_t bytes_per_row_; // Includes padding.
135 };
136 
137 // Single channel, aligned rows separated by padding. T must be POD.
138 //
139 // 'Single channel' (one 2D array per channel) simplifies vectorization
140 // (repeating the same operation on multiple adjacent components) without the
141 // complexity of a hybrid layout (8 R, 8 G, 8 B, ...). In particular, clients
142 // can easily iterate over all components in a row and Image requires no
143 // knowledge of the pixel format beyond the component type "T".
144 //
145 // 'Aligned' means each row is aligned to the L1 cache line size. This prevents
146 // false sharing between two threads operating on adjacent rows.
147 //
148 // 'Padding' is still relevant because vectors could potentially be larger than
149 // a cache line. By rounding up row sizes to the vector size, we allow
150 // reading/writing ALIGNED vectors whose first lane is a valid sample. This
151 // avoids needing a separate loop to handle remaining unaligned lanes.
152 //
153 // This image layout could also be achieved with a vector and a row accessor
154 // function, but a class wrapper with support for "deleter" allows wrapping
155 // existing memory allocated by clients without copying the pixels. It also
156 // provides convenient accessors for xsize/ysize, which shortens function
157 // argument lists. Supports move-construction so it can be stored in containers.
158 template <typename ComponentType>
159 class Image : public ImageBase {
160  public:
161  using T = ComponentType;
162 
163  Image() = default;
164  Image(const size_t xsize, const size_t ysize)
165  : ImageBase(xsize, ysize, sizeof(T)) {}
166  Image(const size_t xsize, const size_t ysize, size_t bytes_per_row,
167  void* aligned)
168  : ImageBase(xsize, ysize, bytes_per_row, aligned) {}
169 
172  }
173 
174  HWY_INLINE const T* ConstRow(const size_t y) const {
175  return static_cast<const T*>(VoidRow(y));
176  }
177  HWY_INLINE const T* ConstRow(const size_t y) {
178  return static_cast<const T*>(VoidRow(y));
179  }
180 
181  // Returns pointer to non-const. This allows passing const Image* parameters
182  // when the callee is only supposed to fill the pixels, as opposed to
183  // allocating or resizing the image.
184  HWY_INLINE T* MutableRow(const size_t y) const {
185  return static_cast<T*>(VoidRow(y));
186  }
187  HWY_INLINE T* MutableRow(const size_t y) {
188  return static_cast<T*>(VoidRow(y));
189  }
190 
191  // Returns number of pixels (some of which are padding) per row. Useful for
192  // computing other rows via pointer arithmetic. WARNING: this must
193  // NOT be used to determine xsize.
194  HWY_INLINE intptr_t PixelsPerRow() const {
195  return static_cast<intptr_t>(bytes_per_row_ / sizeof(T));
196  }
197 };
198 
200 
201 // A bundle of 3 same-sized images. To fill an existing Image3 using
202 // single-channel producers, we also need access to each const Image*. Const
203 // prevents breaking the same-size invariant, while still allowing pixels to be
204 // changed via MutableRow.
205 template <typename ComponentType>
206 class Image3 {
207  public:
208  using T = ComponentType;
209  using ImageT = Image<T>;
210  static constexpr size_t kNumPlanes = 3;
211 
213 
214  Image3(const size_t xsize, const size_t ysize)
216  ImageT(xsize, ysize)} {}
217 
218  Image3(Image3&& other) noexcept {
219  for (size_t i = 0; i < kNumPlanes; i++) {
220  planes_[i] = std::move(other.planes_[i]);
221  }
222  }
223 
224  Image3(ImageT&& plane0, ImageT&& plane1, ImageT&& plane2) {
225  if (!SameSize(plane0, plane1) || !SameSize(plane0, plane2)) {
226  HWY_ABORT("Not same size: %" PRIu64 " x %" PRIu64 ", %" PRIu64
227  " x %" PRIu64 ", %" PRIu64 " x %" PRIu64 "\n",
228  static_cast<uint64_t>(plane0.xsize()),
229  static_cast<uint64_t>(plane0.ysize()),
230  static_cast<uint64_t>(plane1.xsize()),
231  static_cast<uint64_t>(plane1.ysize()),
232  static_cast<uint64_t>(plane2.xsize()),
233  static_cast<uint64_t>(plane2.ysize()));
234  }
235  planes_[0] = std::move(plane0);
236  planes_[1] = std::move(plane1);
237  planes_[2] = std::move(plane2);
238  }
239 
240  // Copy construction/assignment is forbidden to avoid inadvertent copies,
241  // which can be very expensive. Use CopyImageTo instead.
242  Image3(const Image3& other) = delete;
243  Image3& operator=(const Image3& other) = delete;
244 
245  Image3& operator=(Image3&& other) noexcept {
246  for (size_t i = 0; i < kNumPlanes; i++) {
247  planes_[i] = std::move(other.planes_[i]);
248  }
249  return *this;
250  }
251 
252  HWY_INLINE const T* ConstPlaneRow(const size_t c, const size_t y) const {
253  return static_cast<const T*>(VoidPlaneRow(c, y));
254  }
255  HWY_INLINE const T* ConstPlaneRow(const size_t c, const size_t y) {
256  return static_cast<const T*>(VoidPlaneRow(c, y));
257  }
258 
259  HWY_INLINE T* MutablePlaneRow(const size_t c, const size_t y) const {
260  return static_cast<T*>(VoidPlaneRow(c, y));
261  }
262  HWY_INLINE T* MutablePlaneRow(const size_t c, const size_t y) {
263  return static_cast<T*>(VoidPlaneRow(c, y));
264  }
265 
266  HWY_INLINE const ImageT& Plane(size_t idx) const { return planes_[idx]; }
267 
268  void Swap(Image3& other) {
269  for (size_t c = 0; c < 3; ++c) {
270  other.planes_[c].Swap(planes_[c]);
271  }
272  }
273 
274  void ShrinkTo(const size_t xsize, const size_t ysize) {
275  for (ImageT& plane : planes_) {
276  plane.ShrinkTo(xsize, ysize);
277  }
278  }
279 
280  // Sizes of all three images are guaranteed to be equal.
281  HWY_INLINE size_t xsize() const { return planes_[0].xsize(); }
282  HWY_INLINE size_t ysize() const { return planes_[0].ysize(); }
283  // Returns offset [bytes] from one row to the next row of the same plane.
284  // WARNING: this must NOT be used to determine xsize, nor for copying rows -
285  // the valid xsize may be much less.
286  HWY_INLINE size_t bytes_per_row() const { return planes_[0].bytes_per_row(); }
287  // Returns number of pixels (some of which are padding) per row. Useful for
288  // computing other rows via pointer arithmetic. WARNING: this must NOT be used
289  // to determine xsize.
290  HWY_INLINE intptr_t PixelsPerRow() const { return planes_[0].PixelsPerRow(); }
291 
292  private:
293  // Returns pointer to the start of a row.
294  HWY_INLINE void* VoidPlaneRow(const size_t c, const size_t y) const {
295 #if HWY_IS_ASAN || HWY_IS_MSAN || HWY_IS_TSAN
296  if (c >= kNumPlanes || y >= ysize()) {
297  HWY_ABORT("PlaneRow(%" PRIu64 ", %" PRIu64 ") >= %" PRIu64 "\n",
298  static_cast<uint64_t>(c), static_cast<uint64_t>(y),
299  static_cast<uint64_t>(ysize()));
300  }
301 #endif
302  // Use the first plane's stride because the compiler might not realize they
303  // are all equal. Thus we only need a single multiplication for all planes.
304  const size_t row_offset = y * planes_[0].bytes_per_row();
305  const void* row = planes_[c].bytes() + row_offset;
306  return static_cast<const T * HWY_RESTRICT>(
308  }
309 
310  private:
312 };
313 
315 
316 // Rectangular region in image(s). Factoring this out of Image instead of
317 // shifting the pointer by x0/y0 allows this to apply to multiple images with
318 // different resolutions. Can compare size via SameSize(rect1, rect2).
319 class Rect {
320  public:
321  // Most windows are xsize_max * ysize_max, except those on the borders where
322  // begin + size_max > end.
323  constexpr Rect(size_t xbegin, size_t ybegin, size_t xsize_max,
324  size_t ysize_max, size_t xend, size_t yend)
325  : x0_(xbegin),
326  y0_(ybegin),
327  xsize_(ClampedSize(xbegin, xsize_max, xend)),
328  ysize_(ClampedSize(ybegin, ysize_max, yend)) {}
329 
330  // Construct with origin and known size (typically from another Rect).
331  constexpr Rect(size_t xbegin, size_t ybegin, size_t xsize, size_t ysize)
332  : x0_(xbegin), y0_(ybegin), xsize_(xsize), ysize_(ysize) {}
333 
334  // Construct a rect that covers a whole image.
335  template <typename Image>
336  explicit Rect(const Image& image)
337  : Rect(0, 0, image.xsize(), image.ysize()) {}
338 
339  Rect() : Rect(0, 0, 0, 0) {}
340 
341  Rect(const Rect&) = default;
342  Rect& operator=(const Rect&) = default;
343 
344  Rect Subrect(size_t xbegin, size_t ybegin, size_t xsize_max,
345  size_t ysize_max) {
346  return Rect(x0_ + xbegin, y0_ + ybegin, xsize_max, ysize_max, x0_ + xsize_,
347  y0_ + ysize_);
348  }
349 
350  template <typename T>
351  const T* ConstRow(const Image<T>* image, size_t y) const {
352  return image->ConstRow(y + y0_) + x0_;
353  }
354 
355  template <typename T>
356  T* MutableRow(const Image<T>* image, size_t y) const {
357  return image->MutableRow(y + y0_) + x0_;
358  }
359 
360  template <typename T>
361  const T* ConstPlaneRow(const Image3<T>& image, size_t c, size_t y) const {
362  return image.ConstPlaneRow(c, y + y0_) + x0_;
363  }
364 
365  template <typename T>
366  T* MutablePlaneRow(Image3<T>* image, const size_t c, size_t y) const {
367  return image->MutablePlaneRow(c, y + y0_) + x0_;
368  }
369 
370  // Returns true if this Rect fully resides in the given image. ImageT could be
371  // Image<T> or Image3<T>; however if ImageT is Rect, results are nonsensical.
372  template <class ImageT>
373  bool IsInside(const ImageT& image) const {
374  return (x0_ + xsize_ <= image.xsize()) && (y0_ + ysize_ <= image.ysize());
375  }
376 
377  size_t x0() const { return x0_; }
378  size_t y0() const { return y0_; }
379  size_t xsize() const { return xsize_; }
380  size_t ysize() const { return ysize_; }
381 
382  private:
383  // Returns size_max, or whatever is left in [begin, end).
384  static constexpr size_t ClampedSize(size_t begin, size_t size_max,
385  size_t end) {
386  return (begin + size_max <= end) ? size_max
387  : (end > begin ? end - begin : 0);
388  }
389 
390  size_t x0_;
391  size_t y0_;
392 
393  size_t xsize_;
394  size_t ysize_;
395 };
396 
397 // Works for any image-like input type(s).
398 template <class Image1, class Image2>
399 HWY_MAYBE_UNUSED bool SameSize(const Image1& image1, const Image2& image2) {
400  return image1.xsize() == image2.xsize() && image1.ysize() == image2.ysize();
401 }
402 
403 // Mirrors out of bounds coordinates and returns valid coordinates unchanged.
404 // We assume the radius (distance outside the image) is small compared to the
405 // image size, otherwise this might not terminate.
406 // The mirror is outside the last column (border pixel is also replicated).
407 static HWY_INLINE HWY_MAYBE_UNUSED size_t Mirror(int64_t x,
408  const int64_t xsize) {
409  HWY_DASSERT(xsize != 0);
410 
411  // TODO(janwas): replace with branchless version
412  while (x < 0 || x >= xsize) {
413  if (x < 0) {
414  x = -x - 1;
415  } else {
416  x = 2 * xsize - 1 - x;
417  }
418  }
419  return static_cast<size_t>(x);
420 }
421 
422 // Wrap modes for ensuring X/Y coordinates are in the valid range [0, size):
423 
424 // Mirrors (repeating the edge pixel once). Useful for convolutions.
425 struct WrapMirror {
426  HWY_INLINE size_t operator()(const int64_t coord, const size_t size) const {
427  return Mirror(coord, static_cast<int64_t>(size));
428  }
429 };
430 
431 // Returns the same coordinate, for when we know "coord" is already valid (e.g.
432 // interior of an image).
434  HWY_INLINE size_t operator()(const int64_t coord, size_t /*size*/) const {
435  return static_cast<size_t>(coord);
436  }
437 };
438 
439 // Similar to Wrap* but for row pointers (reduces Row() multiplications).
440 
442  public:
443  template <class View>
444  WrapRowMirror(const View& image, size_t ysize)
445  : first_row_(image.ConstRow(0)), last_row_(image.ConstRow(ysize - 1)) {}
446 
447  const float* operator()(const float* const HWY_RESTRICT row,
448  const int64_t stride) const {
449  if (row < first_row_) {
450  const int64_t num_before = first_row_ - row;
451  // Mirrored; one row before => row 0, two before = row 1, ...
452  return first_row_ + num_before - stride;
453  }
454  if (row > last_row_) {
455  const int64_t num_after = row - last_row_;
456  // Mirrored; one row after => last row, two after = last - 1, ...
457  return last_row_ - num_after + stride;
458  }
459  return row;
460  }
461 
462  private:
463  const float* const HWY_RESTRICT first_row_;
464  const float* const HWY_RESTRICT last_row_;
465 };
466 
468  HWY_INLINE const float* operator()(const float* const HWY_RESTRICT row,
469  int64_t /*stride*/) const {
470  return row;
471  }
472 };
473 
474 } // namespace hwy
475 
476 #endif // HIGHWAY_HWY_CONTRIB_IMAGE_IMAGE_H_
#define HWY_ALIGNMENT
Definition: aligned_allocator.h:32
#define HWY_RESTRICT
Definition: base.h:63
#define HWY_ABORT(format,...)
Definition: base.h:143
#define HWY_INLINE
Definition: base.h:64
#define HWY_DASSERT(condition)
Definition: base.h:193
#define HWY_MAYBE_UNUSED
Definition: base.h:75
#define HWY_ASSUME_ALIGNED(ptr, align)
Definition: base.h:99
Definition: aligned_allocator.h:170
Definition: image.h:206
ImageT planes_[kNumPlanes]
Definition: image.h:311
Image3(const Image3 &other)=delete
HWY_INLINE const T * ConstPlaneRow(const size_t c, const size_t y)
Definition: image.h:255
HWY_INLINE const ImageT & Plane(size_t idx) const
Definition: image.h:266
HWY_INLINE const T * ConstPlaneRow(const size_t c, const size_t y) const
Definition: image.h:252
HWY_INLINE T * MutablePlaneRow(const size_t c, const size_t y)
Definition: image.h:262
HWY_INLINE size_t xsize() const
Definition: image.h:281
HWY_INLINE void * VoidPlaneRow(const size_t c, const size_t y) const
Definition: image.h:294
HWY_INLINE size_t ysize() const
Definition: image.h:282
Image3(Image3 &&other) noexcept
Definition: image.h:218
Image3(const size_t xsize, const size_t ysize)
Definition: image.h:214
Image3 & operator=(const Image3 &other)=delete
Image3(ImageT &&plane0, ImageT &&plane1, ImageT &&plane2)
Definition: image.h:224
Image3()
Definition: image.h:212
Image3 & operator=(Image3 &&other) noexcept
Definition: image.h:245
ComponentType T
Definition: image.h:208
void ShrinkTo(const size_t xsize, const size_t ysize)
Definition: image.h:274
HWY_INLINE T * MutablePlaneRow(const size_t c, const size_t y) const
Definition: image.h:259
HWY_INLINE intptr_t PixelsPerRow() const
Definition: image.h:290
static constexpr size_t kNumPlanes
Definition: image.h:210
HWY_INLINE size_t bytes_per_row() const
Definition: image.h:286
void Swap(Image3 &other)
Definition: image.h:268
Definition: image.h:159
Image()=default
HWY_INLINE T * MutableRow(const size_t y) const
Definition: image.h:184
HWY_INLINE const T * ConstRow(const size_t y)
Definition: image.h:177
HWY_INLINE intptr_t PixelsPerRow() const
Definition: image.h:194
HWY_INLINE const T * ConstRow(const size_t y) const
Definition: image.h:174
void InitializePaddingForUnalignedAccesses()
Definition: image.h:170
HWY_INLINE T * MutableRow(const size_t y)
Definition: image.h:187
Image(const size_t xsize, const size_t ysize, size_t bytes_per_row, void *aligned)
Definition: image.h:166
ComponentType T
Definition: image.h:161
Image(const size_t xsize, const size_t ysize)
Definition: image.h:164
Definition: image.h:319
constexpr Rect(size_t xbegin, size_t ybegin, size_t xsize_max, size_t ysize_max, size_t xend, size_t yend)
Definition: image.h:323
size_t x0_
Definition: image.h:390
const T * ConstPlaneRow(const Image3< T > &image, size_t c, size_t y) const
Definition: image.h:361
size_t xsize() const
Definition: image.h:379
static constexpr size_t ClampedSize(size_t begin, size_t size_max, size_t end)
Definition: image.h:384
bool IsInside(const ImageT &image) const
Definition: image.h:373
Rect(const Image &image)
Definition: image.h:336
Rect Subrect(size_t xbegin, size_t ybegin, size_t xsize_max, size_t ysize_max)
Definition: image.h:344
T * MutableRow(const Image< T > *image, size_t y) const
Definition: image.h:356
Rect & operator=(const Rect &)=default
const T * ConstRow(const Image< T > *image, size_t y) const
Definition: image.h:351
size_t xsize_
Definition: image.h:393
size_t y0_
Definition: image.h:391
constexpr Rect(size_t xbegin, size_t ybegin, size_t xsize, size_t ysize)
Definition: image.h:331
Rect()
Definition: image.h:339
size_t ysize() const
Definition: image.h:380
Rect(const Rect &)=default
size_t ysize_
Definition: image.h:394
size_t x0() const
Definition: image.h:377
size_t y0() const
Definition: image.h:378
T * MutablePlaneRow(Image3< T > *image, const size_t c, size_t y) const
Definition: image.h:366
Definition: image.h:441
const float * operator()(const float *const HWY_RESTRICT row, const int64_t stride) const
Definition: image.h:447
const float *const HWY_RESTRICT first_row_
Definition: image.h:463
const float *const HWY_RESTRICT last_row_
Definition: image.h:464
WrapRowMirror(const View &image, size_t ysize)
Definition: image.h:444
#define HWY_CONTRIB_DLLEXPORT
Definition: highway_export.h:20
Definition: aligned_allocator.h:27
HWY_MAYBE_UNUSED bool SameSize(const Image1 &image1, const Image2 &image2)
Definition: image.h:399
static HWY_INLINE HWY_MAYBE_UNUSED size_t Mirror(int64_t x, const int64_t xsize)
Definition: image.h:407
std::unique_ptr< T, AlignedFreer > AlignedFreeUniquePtr
Definition: aligned_allocator.h:193
Definition: image.h:37
ImageBase & operator=(ImageBase &&other) noexcept=default
Padding
Definition: image.h:115
static size_t VectorSize()
HWY_INLINE size_t xsize() const
Definition: image.h:85
HWY_INLINE void * VoidRow(const size_t y) const
Definition: image.h:104
HWY_INLINE uint8_t * bytes()
Definition: image.h:93
HWY_INLINE const uint8_t * bytes() const
Definition: image.h:97
void Swap(ImageBase &other)
size_t bytes_per_row_
Definition: image.h:133
ImageBase & operator=(const ImageBase &other)=delete
void ShrinkTo(const size_t xsize, const size_t ysize)
Definition: image.h:77
ImageBase()
Definition: image.h:46
HWY_INLINE size_t ysize() const
Definition: image.h:86
static size_t BytesPerRow(const size_t xsize, const size_t sizeof_t)
uint32_t xsize_
Definition: image.h:131
AlignedFreeUniquePtr< uint8_t[]> bytes_
Definition: image.h:134
ImageBase(size_t xsize, size_t ysize, size_t bytes_per_row, void *aligned)
ImageBase(ImageBase &&other) noexcept=default
uint32_t ysize_
Definition: image.h:132
ImageBase(const ImageBase &other)=delete
void InitializePadding(size_t sizeof_t, Padding padding)
HWY_INLINE size_t bytes_per_row() const
Definition: image.h:89
ImageBase(size_t xsize, size_t ysize, size_t sizeof_t)
Definition: image.h:425
HWY_INLINE size_t operator()(const int64_t coord, const size_t size) const
Definition: image.h:426
Definition: image.h:467
HWY_INLINE const float * operator()(const float *const HWY_RESTRICT row, int64_t) const
Definition: image.h:468
Definition: image.h:433
HWY_INLINE size_t operator()(const int64_t coord, size_t) const
Definition: image.h:434