Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
rendering_engine::ImageData Class Reference

Represents raw 2D image data stored in memory. More...

#include <image_data.hpp>

Public Member Functions

 ImageData ()
 Constructs an empty image. More...
 
 ImageData (unsigned int width, unsigned int height)
 Constructs a blank image with specified dimensions. More...
 
 ImageData (std::string filepath)
 Loads image data from a file. More...
 
 ImageData (std::vector< uint8_t > const &fileBytes)
 Constructs an image by decoding raw file bytes. More...
 
 ImageData (unsigned int width, unsigned int height, std::vector< std::uint8_t > const &pixelsRGBA)
 Constructs image from raw RGBA pixel buffer. More...
 
 ~ImageData ()
 Destructor that frees memory. More...
 
 ImageData (const ImageData &src)
 Copy constructor. More...
 
ImageDataoperator= (const ImageData &rhs)
 Copy assignment operator. More...
 
unsigned int GetWidth () const
 Returns the image width. More...
 
unsigned int GetHeight () const
 Returns the image height. More...
 
void Fill (Color color)
 Fills the image with a solid color. More...
 
void SetPixel (unsigned int x, unsigned int y, Color color)
 Sets the color of a specific pixel. More...
 
const Color GetPixel (unsigned int x, unsigned int y) const
 Retrieves the color of a specific pixel. More...
 
std::vector< uint8_t > GetImageDataRGBA () const
 Gets raw image data in RGBA format. More...
 
std::vector< uint8_t > GetImageDataRGB () const
 Gets raw image data in RGB format. More...
 
size_t GetSizeInBytes () const
 Gets the total size of the image in memory. More...
 
void WriteJpegFile (char const *filename)
 Writes the image data to a JPEG file. More...
 
void WritePngFile (char const *filename)
 Writes the image data to a PNG file. More...
 

Static Public Member Functions

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. More...
 

Protected Member Functions

void AllocateMemory (unsigned int width, unsigned int height)
 Allocates memory for internal pixel storage. More...
 
void CleanAllocatedMemory ()
 Frees allocated memory. More...
 
void LoadImageDataRGBA (std::vector< std::uint8_t > const &pixels)
 Loads image data from a 32-bit RGBA buffer. More...
 
void LoadImageDataRGB (std::vector< std::uint8_t > const &pixels)
 Loads image data from a 24-bit RGB buffer. More...
 
bool LoadTexturePngFile (char const *filename)
 Loads image from a PNG file. More...
 
bool LoadTextureJpegFile (char const *filename)
 Loads image from a JPEG file. More...
 
size_t GetLinearIndex (unsigned int x, unsigned int y) const
 
ColorPixelRef (unsigned int x, unsigned int y)
 
const ColorPixelRef (unsigned int x, unsigned int y) const
 

Detailed Description

Represents raw 2D image data stored in memory.

Definition at line 79 of file image_data.hpp.

Constructor & Destructor Documentation

◆ ImageData() [1/6]

rendering_engine::ImageData::ImageData ( )

Constructs an empty image.

Definition at line 12 of file image_data.cpp.

13 :
15{
16}
ImageData()
Constructs an empty image.
Definition: image_data.cpp:12

◆ ImageData() [2/6]

rendering_engine::ImageData::ImageData ( unsigned int  width,
unsigned int  height 
)

Constructs a blank image with specified dimensions.

Parameters
widthImage width in pixels
heightImage height in pixels

Definition at line 18 of file image_data.cpp.

19 :
20 mWidth( width ),
21 mHeight( height )
22{
23 AllocateMemory( mWidth, mHeight );
24}
void AllocateMemory(unsigned int width, unsigned int height)
Allocates memory for internal pixel storage.
Definition: image_data.cpp:308

◆ ImageData() [3/6]

rendering_engine::ImageData::ImageData ( std::string  filepath)

Loads image data from a file.

Parameters
filepathPath to the image file (JPG or PNG)

Definition at line 26 of file image_data.cpp.

27 :
29{
30 auto const pathToTexture = boost::filesystem::path(filepath);
31 if( boost::filesystem::exists(pathToTexture) && boost::filesystem::is_regular_file(pathToTexture) )
32 {
33 boost::filesystem::path const pathToTexture = boost::filesystem::path(filepath);
34
35 size_t const dot = pathToTexture.string().find_last_of(".");
36 std::string const fileExtension = pathToTexture.string().substr(dot + 1);
37
38 if( std::string{ "jpg" } == fileExtension )
39 {
40 LoadTextureJpegFile(pathToTexture.string().c_str());
41 }
42 else
43 {
44 if( std::string{ "png" } == fileExtension )
45 {
46 LoadTexturePngFile(pathToTexture.string().c_str());
47 }
48 else
49 {
50 throw std::runtime_error("Unsupported texture file format!");
51 }
52 }
53 }
54 else
55 {
56 throw std::runtime_error("Path to texture file is incorrect.");
57 }
58}
bool LoadTextureJpegFile(char const *filename)
Loads image from a JPEG file.
Definition: image_data.cpp:265
bool LoadTexturePngFile(char const *filename)
Loads image from a PNG file.
Definition: image_data.cpp:289

◆ ImageData() [4/6]

rendering_engine::ImageData::ImageData ( std::vector< uint8_t > const &  fileBytes)

Constructs an image by decoding raw file bytes.

This constructor allows loading an image from a memory buffer rather than a file on disk. The data is interpreted as either PNG or JPEG depending on format detection. Decoded pixel data is stored internally in 32-bit RGBA format.

Parameters
fileBytesRaw contents of an image file (PNG or JPEG).

Definition at line 60 of file image_data.cpp.

61{
62 if (fileBytes.size() < 4)
63 throw std::runtime_error("Invalid image buffer");
64
65 // PNG signature
66 if (fileBytes[0] == 0x89 &&
67 fileBytes[1] == 'P' &&
68 fileBytes[2] == 'N' &&
69 fileBytes[3] == 'G')
70 {
71 std::vector<std::uint8_t> pixelsRGBA;
72
73 if (!ReadPngFromMemory(fileBytes.data(), fileBytes.size(), mWidth, mHeight, pixelsRGBA))
74 throw std::runtime_error("PNG memory decode failed");
75
76 AllocateMemory(mWidth, mHeight);
77 Fill(Color(0, 0, 0, 255));
78 LoadImageDataRGBA(pixelsRGBA);
79 return;
80 }
81
82 // JPEG signature: FF D8 FF
83 if (fileBytes[0] == 0xFF &&
84 fileBytes[1] == 0xD8 &&
85 fileBytes[2] == 0xFF)
86 {
87 std::vector<std::uint8_t> pixelsRGB;
88
89 if (!ReadJpegFromMemory(fileBytes.data(), fileBytes.size(), mWidth, mHeight, pixelsRGB))
90 throw std::runtime_error("JPEG memory decode failed");
91
92 AllocateMemory(mWidth, mHeight);
93 LoadImageDataRGB(pixelsRGB);
94
95 return;
96 }
97
98 throw std::runtime_error("Unsupported image format in memory buffer");
99}
void LoadImageDataRGBA(std::vector< std::uint8_t > const &pixels)
Loads image data from a 32-bit RGBA buffer.
Definition: image_data.cpp:323
void Fill(Color color)
Fills the image with a solid color.
Definition: image_data.cpp:135
void LoadImageDataRGB(std::vector< std::uint8_t > const &pixels)
Loads image data from a 24-bit RGB buffer.
Definition: image_data.cpp:338
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 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.

◆ ImageData() [5/6]

rendering_engine::ImageData::ImageData ( unsigned int  width,
unsigned int  height,
std::vector< std::uint8_t > const &  pixelsRGBA 
)

Constructs image from raw RGBA pixel buffer.

Parameters
widthImage width
heightImage height
pixelsRGBAVector of RGBA pixel data (4 bytes per pixel)

Definition at line 101 of file image_data.cpp.

102 :
103ImageData::ImageData(width, height)
104{
105 Fill(Color(255, 255, 255, 255));
106 LoadImageDataRGBA( pixelsRGBA );
107}

◆ ~ImageData()

rendering_engine::ImageData::~ImageData ( )

Destructor that frees memory.

Definition at line 109 of file image_data.cpp.

110{
112}
void CleanAllocatedMemory()
Frees allocated memory.
Definition: image_data.cpp:315

◆ ImageData() [6/6]

rendering_engine::ImageData::ImageData ( const ImageData src)

Copy constructor.

Definition at line 114 of file image_data.cpp.

115 :
116 mWidth(src.mWidth),
117 mHeight(src.mHeight),
118 mData(src.mData)
119{
120}

Member Function Documentation

◆ AllocateMemory()

void rendering_engine::ImageData::AllocateMemory ( unsigned int  width,
unsigned int  height 
)
protected

Allocates memory for internal pixel storage.

Parameters
widthImage width
heightImage height

Definition at line 308 of file image_data.cpp.

309{
310 mWidth = width;
311 mHeight = height;
312 mData.resize(static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight));
313}

◆ CleanAllocatedMemory()

void rendering_engine::ImageData::CleanAllocatedMemory ( )
protected

Frees allocated memory.

Definition at line 315 of file image_data.cpp.

316{
317 mData.clear();
318
319 mWidth = 0;
320 mHeight = 0;
321}

◆ DrawImageOnImageAtPos()

void rendering_engine::ImageData::DrawImageOnImageAtPos ( unsigned int const  x,
unsigned int const  y,
ImageData toImage,
ImageData fromImage 
)
static

Overlays one image on top of another at a given position.

Parameters
xTop-left X coordinate for the overlay
yTop-left Y coordinate for the overlay
toImageDestination image
fromImageSource image

Definition at line 159 of file image_data.cpp.

160{
161 // If fromImage can not be placed entirely, it will be cropped on right and bottom side
162
163 // Source image draw from top left pixel
164
165 // At first check if point pos is inside toImage
166 if (x >= toImage.GetWidth() || y >= toImage.GetHeight())
167 {
168 return;
169 }
170
171 if (toImage.GetWidth() == 0U || toImage.GetHeight() == 0U ||
172 fromImage.GetWidth() == 0U || fromImage.GetHeight() == 0U)
173 {
174 return;
175 }
176
177 // Crop
178 unsigned int left;
179 if ((toImage.GetWidth() - x) < fromImage.GetWidth())
180 {
181 left = toImage.GetWidth() - x;
182 }
183 else
184 {
185 left = fromImage.GetWidth();
186 }
187
188 unsigned int bottom;
189 if ((toImage.GetHeight() - y) < fromImage.GetHeight())
190 {
191 bottom = toImage.GetHeight() - y;
192 }
193 else
194 {
195 bottom = fromImage.GetHeight();
196 }
197
198 if (left == 0U || bottom == 0U)
199 {
200 return;
201 }
202
203 for (unsigned int deltaY = 0; deltaY < bottom; ++deltaY)
204 {
205 const size_t srcRowOffset =
206 static_cast<size_t>(deltaY) * static_cast<size_t>(fromImage.GetWidth());
207
208 const size_t dstRowOffset =
209 static_cast<size_t>(y + deltaY) * static_cast<size_t>(toImage.GetWidth()) +
210 static_cast<size_t>(x);
211
212 std::memcpy(
213 toImage.mData.data() + dstRowOffset,
214 fromImage.mData.data() + srcRowOffset,
215 static_cast<size_t>(left) * sizeof(Color));
216 }
217}

◆ Fill()

void rendering_engine::ImageData::Fill ( Color  color)

Fills the image with a solid color.

Parameters
colorThe color to fill with

Definition at line 135 of file image_data.cpp.

136{
137 std::fill(mData.begin(), mData.end(), color);
138}

◆ GetHeight()

unsigned int rendering_engine::ImageData::GetHeight ( ) const
inline

Returns the image height.

Definition at line 145 of file image_data.hpp.

146 {
147 return mHeight;
148 }

◆ GetImageDataRGB()

std::vector< uint8_t > rendering_engine::ImageData::GetImageDataRGB ( ) const

Gets raw image data in RGB format.

Returns
A vector containing 3 bytes per pixel (RGB)

Definition at line 235 of file image_data.cpp.

236{
237 if (mWidth == 0 || mHeight == 0)
238 {
239 return {};
240 }
241
242 const size_t pixelCount =
243 static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight);
244
245 std::vector<uint8_t> result(pixelCount * 3);
246
247 const Color* src = mData.data();
248 uint8_t* dst = result.data();
249
250 for (size_t i = 0; i < pixelCount; ++i)
251 {
252 dst[i * 3 + 0] = src[i].r;
253 dst[i * 3 + 1] = src[i].g;
254 dst[i * 3 + 2] = src[i].b;
255 }
256
257 return result;
258}

◆ GetImageDataRGBA()

std::vector< uint8_t > rendering_engine::ImageData::GetImageDataRGBA ( ) const

Gets raw image data in RGBA format.

Returns
A vector containing 4 bytes per pixel (RGBA)

Definition at line 219 of file image_data.cpp.

220{
221 if (mWidth == 0 || mHeight == 0)
222 {
223 return {};
224 }
225
226 const size_t totalBytes =
227 static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight) * 4;
228
229 std::vector<uint8_t> result(totalBytes);
230 std::memcpy(result.data(), mData.data(), totalBytes);
231
232 return result;
233}

◆ GetLinearIndex()

size_t rendering_engine::ImageData::GetLinearIndex ( unsigned int  x,
unsigned int  y 
) const
inlineprotected

Definition at line 246 of file image_data.hpp.

247 {
248 return static_cast<size_t>(y) * static_cast<size_t>(mWidth) + static_cast<size_t>(x);
249 }

◆ GetPixel()

const Color rendering_engine::ImageData::GetPixel ( unsigned int  x,
unsigned int  y 
) const

Retrieves the color of a specific pixel.

Parameters
xX coordinate
yY coordinate
Returns
The color of the pixel

Definition at line 148 of file image_data.cpp.

149{
150 if (x >= mWidth || y >= mHeight)
151 {
152 LOG_ERROR("Out of bounds access in GetPixel");
153 return Color{};
154 }
155
156 return PixelRef(x, y);
157}
Color & PixelRef(unsigned int x, unsigned int y)
Definition: image_data.hpp:251
#define LOG_ERROR(msg)
Definition: logger.hpp:41

◆ GetSizeInBytes()

size_t rendering_engine::ImageData::GetSizeInBytes ( ) const
inline

Gets the total size of the image in memory.

Returns
Size in bytes

Definition at line 197 of file image_data.hpp.

198 {
199 return static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight) * sizeof(Color);
200 }

◆ GetWidth()

unsigned int rendering_engine::ImageData::GetWidth ( ) const
inline

Returns the image width.

Definition at line 137 of file image_data.hpp.

138 {
139 return mWidth;
140 }

◆ LoadImageDataRGB()

void rendering_engine::ImageData::LoadImageDataRGB ( std::vector< std::uint8_t > const &  pixels)
protected

Loads image data from a 24-bit RGB buffer.

Definition at line 338 of file image_data.cpp.

339{
340 const size_t pixelCount =
341 static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight);
342
343 const size_t expectedSize = pixelCount * 3;
344 if (pixels.size() != expectedSize)
345 {
346 throw std::runtime_error("Array data size doesn't match image dimension.");
347 }
348
349 mData.resize(pixelCount);
350
351 const uint8_t* src = pixels.data();
352 Color* dst = mData.data();
353
354 for (size_t i = 0; i < pixelCount; ++i)
355 {
356 dst[i].r = src[i * 3 + 0];
357 dst[i].g = src[i * 3 + 1];
358 dst[i].b = src[i * 3 + 2];
359 dst[i].a = 255;
360 }
361}

◆ LoadImageDataRGBA()

void rendering_engine::ImageData::LoadImageDataRGBA ( std::vector< std::uint8_t > const &  pixels)
protected

Loads image data from a 32-bit RGBA buffer.

Definition at line 323 of file image_data.cpp.

324{
325 const size_t expectedSize =
326 static_cast<size_t>(mWidth) * static_cast<size_t>(mHeight) * 4;
327
328 if (pixels.size() != expectedSize)
329 {
330 throw std::runtime_error("Array data size doesn't match image dimension.");
331 }
332
333 mData.resize(mWidth * mHeight);
334
335 std::memcpy(mData.data(), pixels.data(), expectedSize);
336}

◆ LoadTextureJpegFile()

bool rendering_engine::ImageData::LoadTextureJpegFile ( char const *  filename)
protected

Loads image from a JPEG file.

Definition at line 265 of file image_data.cpp.

266{
268 unsigned int width = 0;
269 unsigned int height = 0;
270 std::vector<std::uint8_t> rgbImageDataVector;
271
272 bool result = ReadJpegFile(filename, width, height, rgbImageDataVector);
273 if(result && (rgbImageDataVector.size() == (3U * width * height)))
274 {
275 mWidth = width;
276 mHeight = height;
277 AllocateMemory(width, height);
278 LoadImageDataRGB(rgbImageDataVector);
279 }
280
281 return result;
282}
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.

◆ LoadTexturePngFile()

bool rendering_engine::ImageData::LoadTexturePngFile ( char const *  filename)
protected

Loads image from a PNG file.

Definition at line 289 of file image_data.cpp.

290{
292 unsigned int width = 0;
293 unsigned int height = 0;
294 std::vector<std::uint8_t> rgbaImageDataVector;
295
296 bool result = ReadPngFile(filename, width, height, rgbaImageDataVector);
297
298 if( result && (rgbaImageDataVector.size() == (4U * width * height)) )
299 {
300 mWidth = width;
301 mHeight = height;
302 AllocateMemory(width, height);
303 LoadImageDataRGBA(rgbaImageDataVector);
304 }
305 return true;
306}
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.

◆ operator=()

ImageData & rendering_engine::ImageData::operator= ( const ImageData rhs)

Copy assignment operator.

Definition at line 122 of file image_data.cpp.

123{
124 if (this == &rhs)
125 {
126 return *this;
127 }
128
129 mWidth = rhs.mWidth;
130 mHeight = rhs.mHeight;
131 mData = rhs.mData;
132 return *this;
133}

◆ PixelRef() [1/2]

Color & rendering_engine::ImageData::PixelRef ( unsigned int  x,
unsigned int  y 
)
inlineprotected

Definition at line 251 of file image_data.hpp.

252 {
253 return mData[GetLinearIndex(x, y)];
254 }
size_t GetLinearIndex(unsigned int x, unsigned int y) const
Definition: image_data.hpp:246

◆ PixelRef() [2/2]

const Color & rendering_engine::ImageData::PixelRef ( unsigned int  x,
unsigned int  y 
) const
inlineprotected

Definition at line 256 of file image_data.hpp.

257 {
258 return mData[GetLinearIndex(x, y)];
259 }

◆ SetPixel()

void rendering_engine::ImageData::SetPixel ( unsigned int  x,
unsigned int  y,
Color  color 
)

Sets the color of a specific pixel.

Parameters
xX coordinate
yY coordinate
colorThe color to set

Definition at line 140 of file image_data.cpp.

141{
142 if (x < mWidth && y < mHeight)
143 {
144 PixelRef(x, y) = color;
145 }
146}

◆ WriteJpegFile()

void rendering_engine::ImageData::WriteJpegFile ( char const *  filename)

Writes the image data to a JPEG file.

Parameters
filenamePath to output file

Definition at line 260 of file image_data.cpp.

261{
262 SaveTextureFileJpeg(*this, filename);
263}
static void SaveTextureFileJpeg(rendering_engine::ImageData const &imageData, char const *filename)
Saves image data to a JPEG file.

◆ WritePngFile()

void rendering_engine::ImageData::WritePngFile ( char const *  filename)

Writes the image data to a PNG file.

Parameters
filenamePath to output file

Definition at line 284 of file image_data.cpp.

285{
286 SaveTextureFilePng(*this, filename);
287}
static void SaveTextureFilePng(rendering_engine::ImageData const &imageData, char const *filename)
Saves image data to a PNG file.

The documentation for this class was generated from the following files: