#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; }