8#include <Common/assertion.h>
22template<
typename Func,
typename T, std::
size_t N>
26 { func(pixel) } -> std::same_as<void>;
29template<
typename Func,
typename T, std::
size_t N>
33 { func(x, y, pixel) } -> std::same_as<void>;
36template<
typename Func,
typename T, std::
size_t N>
39 { func() } -> std::convertible_to<typename TFrame<T, N>::PixelType>;
42template<
typename Func,
typename T, std::
size_t N>
45 { func(x, y) } -> std::convertible_to<typename TFrame<T, N>::PixelType>;
48template<
typename Func,
typename T, std::
size_t N>
51 { func(pixel) } -> std::convertible_to<typename TFrame<T, N>::PixelType>;
54template<
typename Func,
typename T, std::
size_t N>
57 { func(x, y, pixel) } -> std::convertible_to<typename TFrame<T, N>::PixelType>;
62template<
typename T, std::
size_t N>
69template<
typename T, std::
size_t N>
74template<
typename T, std::
size_t N>
78 m_pixelData(wPx * hPx * N, 0)
81template<
typename T, std::
size_t N>
83 m_widthPx (other.m_widthPx),
84 m_heightPx (other.m_heightPx),
85 m_pixelData(other.m_pixelData)
88template<
typename T, std::
size_t N>
90 m_widthPx (other.m_widthPx),
91 m_heightPx (other.m_heightPx),
92 m_pixelData(std::move(other.m_pixelData))
95template<
typename T, std::
size_t N>
98 std::fill(m_pixelData.begin(), m_pixelData.end(), value);
101template<
typename T, std::
size_t N>
106 const uint32 regionDataWidth =
static_cast<uint32
>(N) * region.
getWidth();
109 const std::size_t offset = calcPixelDataBaseIndex(region.
getMinVertex().x(), y);
112 m_pixelData.begin() + offset,
113 m_pixelData.begin() + offset + regionDataWidth,
119template<
typename T, std::
size_t N>
123 const uint32 kernelRadiusPx)
const
125 if(isEmpty() || sampled.
isEmpty() ||
132 for(uint32 y = 0; y < sampled.
heightPx(); ++y)
134 for(uint32 x = 0; x < sampled.
widthPx(); ++x)
137 (x + 0.5) / sampled.
widthPx() * widthPx(),
138 (y + 0.5) / sampled.
heightPx() * heightPx());
148 PH_ASSERT_LE(filterMin.
x(), filterMax.
x());
149 PH_ASSERT_LE(filterMin.
y(), filterMax.
y());
155 PH_ASSERT(x0y0.
x() >= 0 && x0y0.
y() >= 0 &&
156 x1y1.
x() < widthPx() && x1y1.
y() < heightPx());
159 float64 weightSum = 0.0;
160 for(int64 ky = x0y0.
y(); ky <= x1y1.
y(); ++ky)
162 for(int64 kx = x0y0.
x(); kx <= x1y1.
x(); ++kx)
164 const float64 kernelX = (kx + 0.5) - samplePosPx.
x();
165 const float64 kernelY = (ky + 0.5) - samplePosPx.
y();
168 getPixel(
static_cast<uint32
>(kx),
static_cast<uint32
>(ky), &pixel);
169 const float64 weight = kernel.
evaluate(kernelX, kernelY);
171 for(std::size_t i = 0; i < N; ++i)
173 pixelSum[i] +=
static_cast<float64
>(pixel[i]);
182 const float64 reciWeightSum = 1.0 / weightSum;
183 for(std::size_t i = 0; i < N; ++i)
185 const float64 sampledValue = pixelSum[i] * reciWeightSum;
186 sampledPixel[i] =
static_cast<T
>(sampledValue);
191 sampledPixel = makeMonochromaticPixel(T(0));
193 sampled.
setPixel(x, y, sampledPixel);
198template<
typename T, std::
size_t N>
201 const uint32 halfWidthPx = m_widthPx / 2;
203 for(uint32 y = 0; y < m_heightPx; ++y)
205 for(uint32 x = 0; x < halfWidthPx; ++x)
207 const std::size_t leftPixelBegin = calcPixelDataBaseIndex(x, y);
208 const std::size_t rightPixelBegin = calcPixelDataBaseIndex(m_widthPx - 1 - x, y);
210 for(std::size_t i = 0; i < N; ++i)
212 std::swap(m_pixelData[leftPixelBegin + i], m_pixelData[rightPixelBegin + i]);
218template<
typename T, std::
size_t N>
221 const uint32 halfHeightPx = m_heightPx / 2;
222 const std::size_t numRowElements = m_widthPx * N;
224 for(uint32 y = 0; y < halfHeightPx; ++y)
226 const std::size_t bottomRowBegin = calcPixelDataBaseIndex(0, y);
227 const std::size_t topRowBegin = calcPixelDataBaseIndex(0, m_heightPx - 1 - y);
229 for(std::size_t i = 0; i < numRowElements; ++i)
231 std::swap(m_pixelData[bottomRowBegin + i], m_pixelData[topRowBegin + i]);
236template<
typename T, std::
size_t N>
241 m_pixelData.resize(wPx * hPx * N);
244template<
typename T, std::
size_t N>
247 setSize(sizePx.
x(), sizePx.
y());
250template<
typename T, std::
size_t N>
251template<
typename PerPixelOperation>
257template<
typename T, std::
size_t N>
258template<
typename PerPixelOperation>
264template<
typename T, std::
size_t N>
265template<
typename PerPixelOperation>
275 getPixel(x, y, &pixel);
287 setPixel(x, y, op());
291 setPixel(x, y, op(x, y));
295 setPixel(x, y, op(pixel));
299 setPixel(x, y, op(x, y, pixel));
304 PH_ASSERT_UNREACHABLE_SECTION();
311template<
typename T, std::
size_t N>
312template<
typename PerPixelOperation>
322 getPixel(x, y, &pixel);
335 PH_ASSERT_UNREACHABLE_SECTION();
342template<
typename T, std::
size_t N>
347 getPixel(coordPx.x(), coordPx.y(), &pixel);
351template<
typename T, std::
size_t N>
357 PH_ASSERT(out_pixel);
359 const std::size_t baseIndex = calcPixelDataBaseIndex(x, y);
361 for(std::size_t i = 0; i < N; ++i)
363 PH_ASSERT_LT(baseIndex + i, m_pixelData.size());
365 (*out_pixel)[i] = m_pixelData[baseIndex + i];
369template<
typename T, std::
size_t N>
372 setPixel(coordPx.
x(), coordPx.
y(), pixel);
375template<
typename T, std::
size_t N>
381 const std::size_t baseIndex = calcPixelDataBaseIndex(x, y);
383 for(std::size_t i = 0; i < N; ++i)
385 PH_ASSERT_LT(baseIndex + i, m_pixelData.size());
387 m_pixelData[baseIndex + i] = pixel[i];
391template<
typename T, std::
size_t N>
397template<
typename T, std::
size_t N>
403template<
typename T, std::
size_t N>
409template<
typename T, std::
size_t N>
414 const auto regionDataWidth = N * region.
getWidth();
417 const auto srcOffset = calcPixelDataBaseIndex(region.
getMinVertex().x(), y);
418 const auto dstOffset = (y - region.
getMinVertex().y()) * regionDataWidth;
421 m_pixelData.begin() + srcOffset,
423 out_data.begin() + dstOffset);
427template<
typename T, std::
size_t N>
430 return {m_widthPx, m_heightPx};
433template<
typename T, std::
size_t N>
439template<
typename T, std::
size_t N>
445template<
typename T, std::
size_t N>
448 return m_pixelData.empty();
451template<
typename T, std::
size_t N>
454 const uint32 y)
const
456 PH_ASSERT_LT(x, m_widthPx);
457 PH_ASSERT_LT(y, m_heightPx);
459 return (y *
static_cast<std::size_t
>(m_widthPx) + x) * N;
462template<
typename T, std::
size_t N>
465 m_widthPx = rhs.m_widthPx;
466 m_heightPx = rhs.m_heightPx;
467 m_pixelData = rhs.m_pixelData;
472template<
typename T, std::
size_t N>
475 m_widthPx = rhs.m_widthPx;
476 m_heightPx = rhs.m_heightPx;
477 m_pixelData = std::move(rhs.m_pixelData);
TPixelType< T > PixelType
Definition TFrame.h:28
uint32 heightPx() const
Definition TFrame.ipp:440
TSpan< T > getPixelData()
Get pixel data for the full frame.
Definition TFrame.ipp:398
void forEachPixel(PerPixelOperation op)
Iterate over all pixels in the frame in row-major order.
Definition TFrame.ipp:252
TFrame()
Constructs an empty frame.
Definition TFrame.ipp:70
void copyPixelData(const math::TAABB2D< uint32 > ®ion, TSpan< T > out_data) const
Copy a region of pixel data into a buffer.
Definition TFrame.ipp:410
static TPixelType< U > makeMonochromaticPixel(U value)
void sample(TFrame &sampled, const math::TMathFunction2D< float64 > &kernel, uint32 kernelRadiusPx) const
Definition TFrame.ipp:120
void fill(T value)
Definition TFrame.ipp:96
void setPixel(const math::TVector2< uint32 > &coordPx, const PixelType &pixel)
Definition TFrame.ipp:370
constexpr std::size_t numPixelComponents() const noexcept
Definition TFrame.ipp:392
void flipVertically()
Definition TFrame.ipp:219
uint32 widthPx() const
Definition TFrame.ipp:434
void flipHorizontally()
Definition TFrame.ipp:199
math::TVector2< uint32 > getSizePx() const
Definition TFrame.ipp:428
TFrame & operator=(const TFrame &rhs)
Definition TFrame.ipp:463
void setSize(uint32 wPx, uint32 hPx)
Definition TFrame.ipp:237
bool isEmpty() const
Definition TFrame.ipp:446
PixelType getPixel(const math::TVector2< uint32 > &coordPx) const
Definition TFrame.ipp:343
A 2-D Axis-Aligned Bounding Box (AABB).
Definition TAABB2D.h:26
T getWidth() const
Definition TAABB2D.ipp:138
bool isEmpty() const
Definition TAABB2D.ipp:193
const TVector2< T > & getMaxVertex() const
Definition TAABB2D.ipp:126
std::string toString() const
Definition TAABB2D.ipp:235
const TVector2< T > & getMinVertex() const
Definition TAABB2D.ipp:120
Definition TArithmeticArray.h:13
Definition TMathFunction2D.h:8
virtual Value evaluate(Value x, Value y) const =0
T & x()
Definition TVector2.ipp:38
T & y()
Definition TVector2.ipp:44
Derived floor() const
Definition TArithmeticArrayBase.ipp:447
Derived sub(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:62
T min() const
Definition TArithmeticArrayBase.ipp:364
T max() const
Definition TArithmeticArrayBase.ipp:396
Derived add(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:26
Derived ceil() const
Definition TArithmeticArrayBase.ipp:428
Miscellaneous math utilities.
The root for all renderer implementations.
Definition EEngineProject.h:6
std::span< const T, EXTENT > TSpanView
Same as TSpan, except that the objects are const-qualified. Note that for pointer types,...
Definition TSpan.h:19
std::span< T, EXTENT > TSpan
A contiguous sequence of objects of type T. Effectively the same as std::span.
Definition TSpan.h:12