7#include <boost/filesystem.hpp>
30 auto const pathToTexture = boost::filesystem::path(filepath);
31 if( boost::filesystem::exists(pathToTexture) && boost::filesystem::is_regular_file(pathToTexture) )
33 boost::filesystem::path
const pathToTexture = boost::filesystem::path(filepath);
35 size_t const dot = pathToTexture.string().find_last_of(
".");
36 std::string
const fileExtension = pathToTexture.string().substr(dot + 1);
38 if( std::string{
"jpg" } == fileExtension )
44 if( std::string{
"png" } == fileExtension )
50 throw std::runtime_error(
"Unsupported texture file format!");
56 throw std::runtime_error(
"Path to texture file is incorrect.");
62 if (fileBytes.size() < 4)
63 throw std::runtime_error(
"Invalid image buffer");
66 if (fileBytes[0] == 0x89 &&
67 fileBytes[1] ==
'P' &&
68 fileBytes[2] ==
'N' &&
71 std::vector<std::uint8_t> pixelsRGBA;
73 if (!
ReadPngFromMemory(fileBytes.data(), fileBytes.size(), mWidth, mHeight, pixelsRGBA))
74 throw std::runtime_error(
"PNG memory decode failed");
83 if (fileBytes[0] == 0xFF &&
84 fileBytes[1] == 0xD8 &&
87 std::vector<std::uint8_t> pixelsRGB;
89 if (!
ReadJpegFromMemory(fileBytes.data(), fileBytes.size(), mWidth, mHeight, pixelsRGB))
90 throw std::runtime_error(
"JPEG memory decode failed");
98 throw std::runtime_error(
"Unsupported image format in memory buffer");
117 mHeight(src.mHeight),
130 mHeight = rhs.mHeight;
137 std::fill(mData.begin(), mData.end(), color);
142 if (x < mWidth && y < mHeight)
150 if (x >= mWidth || y >= mHeight)
152 LOG_ERROR(
"Out of bounds access in GetPixel");
198 if (left == 0U || bottom == 0U)
203 for (
unsigned int deltaY = 0; deltaY < bottom; ++deltaY)
205 const size_t srcRowOffset =
206 static_cast<size_t>(deltaY) *
static_cast<size_t>(fromImage.
GetWidth());
208 const size_t dstRowOffset =
209 static_cast<size_t>(y + deltaY) *
static_cast<size_t>(toImage.
GetWidth()) +
210 static_cast<size_t>(x);
213 toImage.mData.data() + dstRowOffset,
214 fromImage.mData.data() + srcRowOffset,
215 static_cast<size_t>(left) *
sizeof(
Color));
221 if (mWidth == 0 || mHeight == 0)
226 const size_t totalBytes =
227 static_cast<size_t>(mWidth) *
static_cast<size_t>(mHeight) * 4;
229 std::vector<uint8_t> result(totalBytes);
230 std::memcpy(result.data(), mData.data(), totalBytes);
237 if (mWidth == 0 || mHeight == 0)
242 const size_t pixelCount =
243 static_cast<size_t>(mWidth) *
static_cast<size_t>(mHeight);
245 std::vector<uint8_t> result(pixelCount * 3);
247 const Color* src = mData.data();
248 uint8_t* dst = result.data();
250 for (
size_t i = 0; i < pixelCount; ++i)
252 dst[i * 3 + 0] = src[i].
r;
253 dst[i * 3 + 1] = src[i].
g;
254 dst[i * 3 + 2] = src[i].
b;
268 unsigned int width = 0;
269 unsigned int height = 0;
270 std::vector<std::uint8_t> rgbImageDataVector;
272 bool result =
ReadJpegFile(filename, width, height, rgbImageDataVector);
273 if(result && (rgbImageDataVector.size() == (3U * width * height)))
292 unsigned int width = 0;
293 unsigned int height = 0;
294 std::vector<std::uint8_t> rgbaImageDataVector;
296 bool result =
ReadPngFile(filename, width, height, rgbaImageDataVector);
298 if( result && (rgbaImageDataVector.size() == (4U * width * height)) )
312 mData.resize(
static_cast<size_t>(mWidth) *
static_cast<size_t>(mHeight));
325 const size_t expectedSize =
326 static_cast<size_t>(mWidth) *
static_cast<size_t>(mHeight) * 4;
328 if (pixels.size() != expectedSize)
330 throw std::runtime_error(
"Array data size doesn't match image dimension.");
333 mData.resize(mWidth * mHeight);
335 std::memcpy(mData.data(), pixels.data(), expectedSize);
340 const size_t pixelCount =
341 static_cast<size_t>(mWidth) *
static_cast<size_t>(mHeight);
343 const size_t expectedSize = pixelCount * 3;
344 if (pixels.size() != expectedSize)
346 throw std::runtime_error(
"Array data size doesn't match image dimension.");
349 mData.resize(pixelCount);
351 const uint8_t* src = pixels.data();
352 Color* dst = mData.data();
354 for (
size_t i = 0; i < pixelCount; ++i)
356 dst[i].
r = src[i * 3 + 0];
357 dst[i].
g = src[i * 3 + 1];
358 dst[i].
b = src[i * 3 + 2];
Represents raw 2D image data stored in memory.
void CleanAllocatedMemory()
Frees allocated memory.
~ImageData()
Destructor that frees memory.
void SetPixel(unsigned int x, unsigned int y, Color color)
Sets the color of a specific pixel.
void AllocateMemory(unsigned int width, unsigned int height)
Allocates memory for internal pixel storage.
unsigned int GetWidth() const
Returns the image width.
std::vector< uint8_t > GetImageDataRGB() const
Gets raw image data in RGB format.
ImageData()
Constructs an empty image.
void LoadImageDataRGBA(std::vector< std::uint8_t > const &pixels)
Loads image data from a 32-bit RGBA buffer.
bool LoadTextureJpegFile(char const *filename)
Loads image from a JPEG file.
static void DrawImageOnImageAtPos(unsigned int const x, unsigned int const y, ImageData &toImage, ImageData &fromImage)
Overlays one image on top of another at a given position.
void Fill(Color color)
Fills the image with a solid color.
std::vector< uint8_t > GetImageDataRGBA() const
Gets raw image data in RGBA format.
ImageData & operator=(const ImageData &rhs)
Copy assignment operator.
unsigned int GetHeight() const
Returns the image height.
Color & PixelRef(unsigned int x, unsigned int y)
void LoadImageDataRGB(std::vector< std::uint8_t > const &pixels)
Loads image data from a 24-bit RGB buffer.
void WritePngFile(char const *filename)
Writes the image data to a PNG file.
void WriteJpegFile(char const *filename)
Writes the image data to a JPEG file.
const Color GetPixel(unsigned int x, unsigned int y) const
Retrieves the color of a specific pixel.
bool LoadTexturePngFile(char const *filename)
Loads image from a PNG file.
JPEG read/write backend using libjpeg.
static bool ReadJpegFromMemory(const unsigned char *memory, size_t memorySize, unsigned int &width, unsigned int &height, std::vector< std::uint8_t > &rgbImageDataVector)
Decode a JPEG image directly from a memory buffer.
static bool ReadJpegFile(char const *filename, unsigned int &width, unsigned int &height, std::vector< std::uint8_t > &rgbImageDataVector)
Reads a JPEG file into an RGB image buffer.
static void SaveTextureFileJpeg(rendering_engine::ImageData const &imageData, char const *filename)
Saves image data to a JPEG file.
PNG read/write backend using libpng.
static bool ReadPngFromMemory(const unsigned char *memory, size_t memorySize, unsigned int &width, unsigned int &height, std::vector< std::uint8_t > &rgbaImageDataVector)
Reads a PNG image from memory into RGBA image data.
static void SaveTextureFilePng(rendering_engine::ImageData const &imageData, char const *filename)
Saves image data to a PNG file.
static bool ReadPngFile(char const *filename, unsigned int &width, unsigned int &height, std::vector< std::uint8_t > &rgbaImageDataVector)
Reads a PNG file into RGBA image data.
Engine-wide logging system for runtime diagnostics and performance tracking.
Represents a color with red, green, blue, and alpha channels.