Grok 10.0.3
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
30#include "hwy/base.h"
31#include "hwy/highway_export.h"
32
33namespace 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.
158template <typename ComponentType>
159class 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.
205template <typename ComponentType>
206class Image3 {
207 public:
208 using T = ComponentType;
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).
319class 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).
398template <class Image1, class Image2>
399HWY_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).
407static 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.
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:61
#define HWY_ABORT(format,...)
Definition: base.h:141
#define HWY_INLINE
Definition: base.h:62
#define HWY_DASSERT(condition)
Definition: base.h:191
#define HWY_MAYBE_UNUSED
Definition: base.h:73
#define HWY_ASSUME_ALIGNED(ptr, align)
Definition: base.h:97
Definition: aligned_allocator.h:170
Definition: image.h:206
ImageT planes_[kNumPlanes]
Definition: image.h:311
Image3(const Image3 &other)=delete
Image3 & operator=(Image3 &&other) noexcept
Definition: image.h:245
HWY_INLINE size_t xsize() const
Definition: image.h:281
HWY_INLINE size_t ysize() const
Definition: image.h:282
HWY_INLINE T * MutablePlaneRow(const size_t c, const size_t y) const
Definition: image.h:259
Image3(Image3 &&other) noexcept
Definition: image.h:218
Image3(const size_t xsize, const size_t ysize)
Definition: image.h:214
Image3(ImageT &&plane0, ImageT &&plane1, ImageT &&plane2)
Definition: image.h:224
Image3()
Definition: image.h:212
HWY_INLINE const T * ConstPlaneRow(const size_t c, const size_t y)
Definition: image.h:255
HWY_INLINE const T * ConstPlaneRow(const size_t c, const size_t y) const
Definition: image.h:252
HWY_INLINE const ImageT & Plane(size_t idx) const
Definition: image.h:266
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)
Definition: image.h:262
HWY_INLINE void * VoidPlaneRow(const size_t c, const size_t y) const
Definition: image.h:294
HWY_INLINE intptr_t PixelsPerRow() const
Definition: image.h:290
static constexpr size_t kNumPlanes
Definition: image.h:210
Image3 & operator=(const Image3 &other)=delete
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 intptr_t PixelsPerRow() const
Definition: image.h:194
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
HWY_INLINE const T * ConstRow(const size_t y)
Definition: image.h:177
ComponentType T
Definition: image.h:161
HWY_INLINE T * MutableRow(const size_t y) const
Definition: image.h:184
HWY_INLINE const T * ConstRow(const size_t y) const
Definition: image.h:174
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
T * MutableRow(const Image< T > *image, size_t y) const
Definition: image.h:356
T * MutablePlaneRow(Image3< T > *image, const size_t c, size_t y) const
Definition: image.h:366
size_t x0_
Definition: image.h:390
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
const T * ConstRow(const Image< T > *image, size_t y) const
Definition: image.h:351
bool IsInside(const ImageT &image) const
Definition: image.h:373
Rect(const Image &image)
Definition: image.h:336
const T * ConstPlaneRow(const Image3< T > &image, size_t c, size_t y) const
Definition: image.h:361
Rect Subrect(size_t xbegin, size_t ybegin, size_t xsize_max, size_t ysize_max)
Definition: image.h:344
Rect & operator=(const Rect &)=default
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
Definition: image.h:441
const float *const HWY_RESTRICT first_row_
Definition: image.h:463
const float *const HWY_RESTRICT last_row_
Definition: image.h:464
const float * operator()(const float *const HWY_RESTRICT row, const int64_t stride) const
Definition: image.h:447
WrapRowMirror(const View &image, size_t ysize)
Definition: image.h:444
#define HWY_CONTRIB_DLLEXPORT
Definition: highway_export.h:14
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
Padding
Definition: image.h:115
HWY_INLINE uint8_t * bytes()
Definition: image.h:93
static size_t VectorSize()
HWY_INLINE size_t xsize() const
Definition: image.h:85
HWY_INLINE const uint8_t * bytes() const
Definition: image.h:97
void Swap(ImageBase &other)
HWY_INLINE void * VoidRow(const size_t y) const
Definition: image.h:104
size_t bytes_per_row_
Definition: image.h:133
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
ImageBase & operator=(const ImageBase &other)=delete
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)
ImageBase & operator=(ImageBase &&other) noexcept=default
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