83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <algorithm>
|
|
|
|
namespace pdfengine {
|
|
|
|
struct PixelRGBA {
|
|
uint8_t r = 0;
|
|
uint8_t g = 0;
|
|
uint8_t b = 0;
|
|
uint8_t a = 255;
|
|
};
|
|
|
|
class ImagePixelBuffer {
|
|
public:
|
|
ImagePixelBuffer() = default;
|
|
ImagePixelBuffer(int width, int height, int channels = 4)
|
|
: m_width(width), m_height(height), m_channels(channels) {
|
|
if (width > 0 && height > 0 && channels > 0) {
|
|
m_pixels.resize(static_cast<size_t>(width) * height * channels, 0);
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] int width() const noexcept { return m_width; }
|
|
[[nodiscard]] int height() const noexcept { return m_height; }
|
|
[[nodiscard]] int channels() const noexcept { return m_channels; }
|
|
[[nodiscard]] size_t stride() const noexcept { return static_cast<size_t>(m_width) * m_channels; }
|
|
[[nodiscard]] size_t size() const noexcept { return m_pixels.size(); }
|
|
[[nodiscard]] bool empty() const noexcept { return m_pixels.empty(); }
|
|
|
|
[[nodiscard]] const uint8_t* data() const noexcept { return m_pixels.data(); }
|
|
[[nodiscard]] uint8_t* data() noexcept { return m_pixels.data(); }
|
|
|
|
[[nodiscard]] const std::vector<uint8_t>& vector() const noexcept { return m_pixels; }
|
|
[[nodiscard]] std::vector<uint8_t>& vector() noexcept { return m_pixels; }
|
|
|
|
void resize(int width, int height, int channels = 4) {
|
|
m_width = width;
|
|
m_height = height;
|
|
m_channels = channels;
|
|
if (width > 0 && height > 0 && channels > 0) {
|
|
m_pixels.assign(static_cast<size_t>(width) * height * channels, 0);
|
|
} else {
|
|
m_pixels.clear();
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] PixelRGBA getPixel(int x, int y) const noexcept {
|
|
if (x < 0 || x >= m_width || y < 0 || y >= m_height || m_channels < 4) {
|
|
return {};
|
|
}
|
|
size_t idx = (static_cast<size_t>(y) * m_width + x) * m_channels;
|
|
if (idx + 3 < m_pixels.size()) {
|
|
return PixelRGBA{m_pixels[idx], m_pixels[idx + 1], m_pixels[idx + 2], m_pixels[idx + 3]};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
void setPixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept {
|
|
if (x < 0 || x >= m_width || y < 0 || y >= m_height || m_channels < 4) {
|
|
return;
|
|
}
|
|
size_t idx = (static_cast<size_t>(y) * m_width + x) * m_channels;
|
|
if (idx + 3 < m_pixels.size()) {
|
|
m_pixels[idx + 0] = r;
|
|
m_pixels[idx + 1] = g;
|
|
m_pixels[idx + 2] = b;
|
|
m_pixels[idx + 3] = a;
|
|
}
|
|
}
|
|
|
|
private:
|
|
int m_width = 0;
|
|
int m_height = 0;
|
|
int m_channels = 4;
|
|
std::vector<uint8_t> m_pixels;
|
|
};
|
|
|
|
} // namespace pdfengine
|