From 2c92e07f337e42cf58970443f9de678f85a9b2a4 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Thu, 19 Oct 2023 22:50:07 -0700 Subject: The great renaming: switch to "module style" --- src/brussel.engine/Image.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/brussel.engine/Image.cpp (limited to 'src/brussel.engine/Image.cpp') diff --git a/src/brussel.engine/Image.cpp b/src/brussel.engine/Image.cpp new file mode 100644 index 0000000..3673acc --- /dev/null +++ b/src/brussel.engine/Image.cpp @@ -0,0 +1,101 @@ +#include "Image.hpp" + +#include +#include +#include + +Image::Image() + : mSize{} + , mChannels{ 0 } { +} + +bool Image::InitFromImageFile(const char* filePath, int desiredChannels) { + // Dimensions of the image in + int width, height; + // Number of channels that the image has, we'll get `desiredChannels` channels in our output (if it's non-0, which is the default argument) + int channels; + + // NOTE: don't free, the data is passed to std::unique_ptr + auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, desiredChannels); + if (!result) { + return false; + } + + mData.reset(result); + mSize = { width, height }; + mChannels = desiredChannels == 0 ? channels : desiredChannels; + return true; +} + +bool Image::InitFromImageData(std::span data, int desiredChannels) { + int width, height; + int channels; + + // NOTE: don't free, the data is passed to std::unique_ptr + auto result = (uint8_t*)stbi_load_from_memory(data.data(), data.size(), &width, &height, &channels, desiredChannels); + if (!result) { + return false; + } + + mData.reset(result); + mSize = { width, height }; + mChannels = desiredChannels == 0 ? channels : desiredChannels; + return true; +} + +bool Image::InitFromPixels(std::span pixels, glm::ivec2 dimensions, int channels) { + mData = std::make_unique(pixels.size()); + std::memcpy(mData.get(), pixels.data(), pixels.size()); + mSize = dimensions; + mChannels = channels; + return true; +} + +bool Image::InitFromPixels(std::unique_ptr pixels, glm::ivec2 dimensions, int channels) { + mData = std::move(pixels); + mSize = dimensions; + mChannels = channels; + return true; +} + +RgbaColor Image::GetPixel(int x, int y) const { + size_t offset = (y * mSize.x + x) * mChannels; + RgbaColor color; + color.r = mData.get()[offset + 0]; + color.g = mData.get()[offset + 1]; + color.b = mData.get()[offset + 2]; + color.a = mData.get()[offset + 3]; + return color; +} + +void Image::SetPixel(int x, int y, RgbaColor color) { + size_t offset = (y * mSize.x + x) * mChannels; + mData.get()[offset + 0] = color.r; + mData.get()[offset + 1] = color.g; + mData.get()[offset + 2] = color.b; + mData.get()[offset + 3] = color.a; +} + +uint8_t* Image::GetDataPtr() const { + return mData.get(); +} + +size_t Image::GetDataLength() const { + return mSize.x * mSize.y * mChannels * sizeof(uint8_t); +} + +std::span Image::GetData() const { + return { mData.get(), GetDataLength() }; +} + +glm::ivec2 Image::GetSize() const { + return mSize; +} + +int Image::GetChannels() const { + return mChannels; +} + +bool Image::IsEmpty() const { + return mSize.x == 0 || mSize.y == 0; +} -- cgit v1.2.3-70-g09d2