8#include "geometry/axis_aligned_rectangle.hpp"
9#include "geometry/extent.hpp"
23 pixel_row(T *pixels,
ssize_t width) noexcept : _pixels(pixels), _width(width) {}
25 [[nodiscard]]
ssize_t width()
const noexcept
32 [[nodiscard]] T
const *
data() const noexcept
39 [[nodiscard]] T *
data() noexcept
50 return _pixels[columnNr];
59 return _pixels[columnNr];
68 [[nodiscard]] T
const &
at(
ssize_t columnNr)
const noexcept
70 tt_assert(columnNr >= 0 && columnNr < _width);
71 return _pixels[columnNr];
82 tt_assert(columnNr >= 0 && columnNr < _width);
83 return _pixels[columnNr];
105 pixel_map() noexcept : _pixels(
nullptr), _width(0), _height(0), _stride(0), _hash(0), _self_allocated(true) {}
114 _pixels(pixels), _width(width), _height(height), _stride(stride), _hash(0), _self_allocated(
false)
116 tt_assert(_stride >= _width);
117 tt_assert(_width >= 0);
118 tt_assert(_height >= 0);
120 if (pixels ==
nullptr) {
121 _self_allocated =
true;
122 _pixels =
new T[_height * _stride];
150 if (_self_allocated) {
161 _pixels(other._pixels),
162 _width(other._width),
163 _height(other._height),
164 _stride(other._stride),
166 _self_allocated(other._self_allocated)
168 if (_self_allocated) {
169 _pixels =
new T[_height * _stride];
171 for (
ssize_t y = 0; y != _height; ++y) {
172 ttlet src_row = other[y];
173 auto dst_row = (*this)[y];
174 for (
ssize_t x = 0; x != _width; ++x) {
175 dst_row[x] = src_row[x];
182 _pixels(other._pixels),
183 _width(other._width),
184 _height(other._height),
185 _stride(other._stride),
187 _self_allocated(other._self_allocated)
189 tt_axiom(
this != &other);
190 other._self_allocated =
false;
193 [[nodiscard]]
operator bool() const noexcept
195 return _pixels !=
nullptr;
198 [[nodiscard]] ssize_t width() const noexcept
203 [[nodiscard]] ssize_t height() const noexcept
208 [[nodiscard]] ssize_t stride() const noexcept
213 [[nodiscard]]
size_t hash() const noexcept
222 tt_return_on_self_assignment(other);
224 _pixels = other._pixels;
225 _width = other._width;
226 _height = other._height;
227 _stride = other._stride;
229 _self_allocated = other._self_allocated;
231 if (_self_allocated) {
232 _pixels =
new T[_height * _stride];
234 for (
ssize_t y = 0; y != _height; ++y) {
235 ttlet src_row = other[y];
236 auto dst_row = (*this)[y];
237 for (
ssize_t x = 0; x != _width; ++x) {
238 dst_row[x] = src_row[x];
248 if (_self_allocated) {
251 _pixels = other._pixels;
252 _width = other._width;
253 _height = other._height;
254 _stride = other._stride;
256 _self_allocated = other._self_allocated;
257 other._self_allocated =
false;
261 extent2 extent() const noexcept
263 return {narrow_cast<float>(_width), narrow_cast<float>(_height)};
275 tt_axiom((x >= 0) && (y >= 0));
276 tt_assert((x + width <= _width) && (y + height <= _height));
278 ttlet offset = y * _stride + x;
280 auto r =
pixel_map{_pixels + offset, width, height, _stride};
281 r._hash = (width == _width && height == _height) ? _hash : 0;
290 narrow_cast<ssize_t>(
rectangle.bottom()),
292 narrow_cast<ssize_t>(
rectangle.height()));
295 pixel_row<T>
const operator[](ssize_t rowNr)
const noexcept
297 return {_pixels + (rowNr * _stride), _width};
300 pixel_row<T> operator[](ssize_t rowNr)
noexcept
302 return {_pixels + (rowNr * _stride), _width};
305 pixel_row<T>
const at(ssize_t rowNr)
const noexcept
307 tt_assert(rowNr < _height);
308 return (*
this)[rowNr];
311 pixel_row<T> at(ssize_t rowNr)
noexcept
313 tt_assert(rowNr < _height);
314 return (*
this)[rowNr];
322 size_t h = hash_mix(_width, _height);
323 for (
ssize_t row_nr = 0; row_nr != _height; ++row_nr) {
324 ttlet &row = (*this)[row_nr];
325 for (
ssize_t col_nr = 0; col_nr != _width; ++col_nr) {
326 h = hash_mix(h, row[col_nr]);
356 bool _self_allocated;
360void copy(pixel_map<T>
const &src, pixel_map<T> &dst)
noexcept
362 ssize_t width =
std::min(src.width(), dst.width());
363 ssize_t height =
std::min(src.height(), dst.height());
365 for (ssize_t y = 0; y != height; ++y) {
366 ttlet src_row = src[y];
367 auto dst_row = dst[y];
368 for (ssize_t x = 0; x != width; ++x) {
369 dst_row[x] = src_row[x];
374template<
int KERNEL_SIZE,
typename KERNEL>
375void horizontalFilterRow(pixel_row<uint8_t> row, KERNEL kernel)
noexcept;
377template<
int KERNEL_SIZE,
typename T,
typename KERNEL>
378void horizontalFilter(pixel_map<T> &pixels, KERNEL kernel)
noexcept;
383void fill(pixel_map<T> &dst)
noexcept;
388void fill(pixel_map<T> &dst, T color)
noexcept;
393void rotate90(pixel_map<T> &dst, pixel_map<T>
const &src)
noexcept;
398void rotate270(pixel_map<T> &dst, pixel_map<T>
const &src)
noexcept;
402void mergeMaximum(pixel_map<uint8_t> &dst, pixel_map<uint8_t>
const &src)
noexcept;
410inline void makeTransparentBorder(pixel_map<T> &pixel_map)
noexcept;
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
Class which represents an rectangle.
Definition rectangle.hpp:16
A 2D canvas of pixels.
Definition pixel_map.hpp:101
pixel_map submap(ssize_t x, ssize_t y, ssize_t width, ssize_t height) const noexcept
Get a (smaller) view of the map.
Definition pixel_map.hpp:273
pixel_map(T *pixels, ssize_t width, ssize_t height) noexcept
Construct an pixel-map from memory received from an API.
Definition pixel_map.hpp:132
pixel_map(pixel_map const &other) noexcept
Copy constructor of other.
Definition pixel_map.hpp:160
pixel_map(ssize_t width, ssize_t height) noexcept
Construct an pixel-map from memory received from an API.
Definition pixel_map.hpp:146
void update_hash() noexcept
Update the hash value of the pixmap.
Definition pixel_map.hpp:320
pixel_map() noexcept
Construct an empty pixel-map.
Definition pixel_map.hpp:105
pixel_map(ssize_t width, ssize_t height, ssize_t stride) noexcept
Construct an pixel-map from memory received from an API.
Definition pixel_map.hpp:139
pixel_map & operator=(pixel_map const &other)
Disallowing copying so that life-time of selfAllocated pixels is easy to understand.
Definition pixel_map.hpp:220
pixel_map(T *pixels, ssize_t width, ssize_t height, ssize_t stride) noexcept
Construct an pixel-map from memory received from an API.
Definition pixel_map.hpp:113
A row of pixels.
Definition pixel_map.hpp:21
T const * data() const noexcept
Get a pointer to the pixel data.
Definition pixel_map.hpp:32
T const & operator[](ssize_t columnNr) const noexcept
Get a access to a pixel in the row.
Definition pixel_map.hpp:48
T * data() noexcept
Get a pointer to the pixel data.
Definition pixel_map.hpp:39
T const & at(ssize_t columnNr) const noexcept
Get a access to a pixel in the row.
Definition pixel_map.hpp:68
T & at(ssize_t columnNr) noexcept
Get a access to a pixel in the row.
Definition pixel_map.hpp:80
T & operator[](ssize_t columnNr) noexcept
Get a access to a pixel in the row.
Definition pixel_map.hpp:57