2323
2424#include < yup_graphics/yup_graphics.h>
2525
26+ #include < memory>
27+ #include < stdexcept>
28+ #include < utility>
29+
2630using namespace yup ;
2731
2832TEST (ImageTests, RgbaBitmapStoresRGBABytesAndReturnsARGBColor)
@@ -98,6 +102,34 @@ TEST (BitmapDataTests, RgbaSetPixelWritesAtCorrectRowOffset)
98102 EXPECT_EQ (bitmap.getPixel (1 , 1 ), 0x80123456u );
99103}
100104
105+ TEST (BitmapDataTests, DefaultConstructorCreatesEmptyBitmap)
106+ {
107+ BitmapData bitmap;
108+
109+ EXPECT_EQ (bitmap.getWidth (), 0 );
110+ EXPECT_EQ (bitmap.getHeight (), 0 );
111+ EXPECT_EQ (bitmap.getPixelFormat (), PixelFormat::RGBA);
112+ EXPECT_EQ (bitmap.getPixelStride (), 4 );
113+ EXPECT_TRUE (bitmap.getRawData ().empty ());
114+
115+ EXPECT_NO_THROW (bitmap.clear ());
116+ EXPECT_NO_THROW (bitmap.fill (0xffffffff ));
117+ EXPECT_THROW (bitmap.getPixel (0 , 0 ), std::out_of_range);
118+ }
119+
120+ TEST (BitmapDataTests, ConstructorAdoptsProvidedPixelData)
121+ {
122+ auto pixels = std::unique_ptr<uint8[]> (new uint8[4 ] { 0x12 , 0x34 , 0x56 , 0x80 });
123+
124+ BitmapData bitmap (1 , 1 , PixelFormat::RGBA, std::unique_ptr<const uint8[]> (pixels.release ()));
125+
126+ EXPECT_EQ (bitmap.getRawData ().size (), 4u );
127+ EXPECT_EQ (bitmap.getPixel (0 , 0 ), 0x80123456u );
128+
129+ bitmap.setPixel (0 , 0 , 0xffabcdef );
130+ EXPECT_EQ (bitmap.getPixel (0 , 0 ), 0xffabcdefu );
131+ }
132+
101133TEST (BitmapDataTests, FillWritesExpectedBytesForRGBA)
102134{
103135 BitmapData bitmap (2 , 2 , PixelFormat::RGBA);
@@ -133,6 +165,44 @@ TEST (BitmapDataTests, FillWritesExpectedBytesForRGB)
133165 EXPECT_EQ (raw[5 ], 0x56 );
134166}
135167
168+ TEST (BitmapDataTests, FillWritesExpectedBytesForGrayscale)
169+ {
170+ BitmapData bitmap (3 , 1 , PixelFormat::Grayscale);
171+
172+ bitmap.fillColor (Color (0xff00ff00 ));
173+
174+ const auto raw = bitmap.getRawData ();
175+
176+ ASSERT_EQ (raw.size (), 3u );
177+ EXPECT_EQ (raw[0 ], 182 );
178+ EXPECT_EQ (raw[1 ], 182 );
179+ EXPECT_EQ (raw[2 ], 182 );
180+ EXPECT_EQ (bitmap.getPixel (2 , 0 ), 0xffb6b6b6u );
181+ }
182+
183+ TEST (BitmapDataTests, SetPixelColorAndGetPixelColorRoundTrip)
184+ {
185+ BitmapData bitmap (1 , 1 , PixelFormat::RGBA);
186+
187+ bitmap.setPixelColor (0 , 0 , Color (0x80123456 ));
188+
189+ EXPECT_EQ (bitmap.getPixelColor (0 , 0 ), Color (0x80123456 ));
190+ }
191+
192+ TEST (BitmapDataTests, MutableRawDataUpdatesPixelValues)
193+ {
194+ BitmapData bitmap (1 , 1 , PixelFormat::RGB);
195+
196+ auto raw = bitmap.getRawData ();
197+ ASSERT_EQ (raw.size (), 3u );
198+
199+ raw[0 ] = 0x12 ;
200+ raw[1 ] = 0x34 ;
201+ raw[2 ] = 0x56 ;
202+
203+ EXPECT_EQ (bitmap.getPixel (0 , 0 ), 0xff123456u );
204+ }
205+
136206TEST (BitmapDataTests, ClearZerosRawData)
137207{
138208 BitmapData bitmap (2 , 2 , PixelFormat::RGBA);
@@ -187,6 +257,7 @@ TEST (BitmapDataTests, ConstructorRejectsInvalidDimensions)
187257 EXPECT_THROW (BitmapData (1 , 0 , PixelFormat::RGBA), std::invalid_argument);
188258 EXPECT_THROW (BitmapData (-1 , 1 , PixelFormat::RGBA), std::invalid_argument);
189259 EXPECT_THROW (BitmapData (1 , -1 , PixelFormat::RGBA), std::invalid_argument);
260+ EXPECT_THROW (BitmapData (1 , 1 , static_cast <PixelFormat> (255 )), std::runtime_error);
190261}
191262
192263TEST (BitmapDataTests, PixelAccessRejectsOutOfRangeCoordinates)
@@ -198,6 +269,30 @@ TEST (BitmapDataTests, PixelAccessRejectsOutOfRangeCoordinates)
198269 EXPECT_THROW (bitmap.setPixel (2 , 0 , 0xffffffff ), std::out_of_range);
199270 EXPECT_THROW (bitmap.setPixel (0 , 2 , 0xffffffff ), std::out_of_range);
200271 EXPECT_THROW (bitmap.getPixel (2 , 0 ), std::out_of_range);
272+ EXPECT_THROW (bitmap.getPixelColor (0 , 2 ), std::out_of_range);
273+ }
274+
275+ TEST (ImageTests, DefaultConstructorCreatesInvalidImage)
276+ {
277+ const Image image;
278+
279+ EXPECT_FALSE (image.isValid ());
280+ }
281+
282+ TEST (ImageTests, ConstructorExposesBitmapMetadata)
283+ {
284+ Image image (3 , 2 , PixelFormat::RGB);
285+
286+ EXPECT_TRUE (image.isValid ());
287+ EXPECT_EQ (image.getWidth (), 3 );
288+ EXPECT_EQ (image.getHeight (), 2 );
289+ EXPECT_EQ (image.getPixelFormat (), PixelFormat::RGB);
290+ EXPECT_EQ (image.getPixelStride (), 3 );
291+ EXPECT_EQ (image.getRawData ().size (), 18u );
292+
293+ const auto & constImage = image;
294+ EXPECT_EQ (constImage.getBitmapData ().getWidth (), 3 );
295+ EXPECT_EQ (image.getBitmapData ().getHeight (), 2 );
201296}
202297
203298TEST (ImageTests, FillColorAndClearRoundTrip)
@@ -213,6 +308,49 @@ TEST (ImageTests, FillColorAndClearRoundTrip)
213308 EXPECT_EQ (image.getPixel (1 , 1 ), 0u );
214309}
215310
311+ TEST (ImageTests, MutableRawDataUpdatesPixelValues)
312+ {
313+ Image image (1 , 1 , PixelFormat::RGBA);
314+
315+ auto raw = image.getRawData ();
316+ ASSERT_EQ (raw.size (), 4u );
317+
318+ raw[0 ] = 0x12 ;
319+ raw[1 ] = 0x34 ;
320+ raw[2 ] = 0x56 ;
321+ raw[3 ] = 0x80 ;
322+
323+ EXPECT_EQ (image.getPixelColor (0 , 0 ), Color (0x80123456 ));
324+ }
325+
326+ TEST (ImageTests, CopyConstructorPreservesBitmapData)
327+ {
328+ Image original (1 , 1 , PixelFormat::RGBA);
329+ original.setPixel (0 , 0 , 0x80123456 );
330+
331+ Image copy (original);
332+
333+ EXPECT_TRUE (copy.isValid ());
334+ EXPECT_EQ (copy.getWidth (), 1 );
335+ EXPECT_EQ (copy.getHeight (), 1 );
336+ EXPECT_EQ (copy.getPixelFormat (), PixelFormat::RGBA);
337+ EXPECT_EQ (copy.getPixel (0 , 0 ), 0x80123456u );
338+ }
339+
340+ TEST (ImageTests, CopyAssignmentPreservesBitmapData)
341+ {
342+ Image original (1 , 1 , PixelFormat::RGB);
343+ original.setPixel (0 , 0 , 0x80123456 );
344+
345+ Image copy (2 , 2 , PixelFormat::RGBA);
346+ copy = original;
347+
348+ EXPECT_EQ (copy.getWidth (), 1 );
349+ EXPECT_EQ (copy.getHeight (), 1 );
350+ EXPECT_EQ (copy.getPixelFormat (), PixelFormat::RGB);
351+ EXPECT_EQ (copy.getPixel (0 , 0 ), 0xff123456u );
352+ }
353+
216354TEST (ImageTests, MoveConstructorTransfersBitmapData)
217355{
218356 Image source (1 , 1 , PixelFormat::RGBA);
@@ -226,3 +364,34 @@ TEST (ImageTests, MoveConstructorTransfersBitmapData)
226364 EXPECT_EQ (moved.getHeight (), 1 );
227365 EXPECT_EQ (moved.getPixel (0 , 0 ), 0x80123456u );
228366}
367+
368+ TEST (ImageTests, MoveAssignmentTransfersBitmapData)
369+ {
370+ Image source (1 , 1 , PixelFormat::RGBA);
371+ source.setPixel (0 , 0 , 0x80123456 );
372+
373+ Image moved (2 , 2 , PixelFormat::RGB);
374+ moved = std::move (source);
375+
376+ EXPECT_FALSE (source.isValid ());
377+ EXPECT_TRUE (moved.isValid ());
378+ EXPECT_EQ (moved.getWidth (), 1 );
379+ EXPECT_EQ (moved.getHeight (), 1 );
380+ EXPECT_EQ (moved.getPixel (0 , 0 ), 0x80123456u );
381+ }
382+
383+ TEST (ImageTests, ConstructorRejectsInvalidDimensions)
384+ {
385+ EXPECT_THROW (Image (0 , 1 , PixelFormat::RGBA), std::invalid_argument);
386+ EXPECT_THROW (Image (1 , 0 , PixelFormat::RGBA), std::invalid_argument);
387+ }
388+
389+ TEST (ImageTests, PixelAccessRejectsOutOfRangeCoordinates)
390+ {
391+ Image image (2 , 2 , PixelFormat::RGBA);
392+
393+ EXPECT_THROW (image.setPixel (-1 , 0 , 0xffffffff ), std::out_of_range);
394+ EXPECT_THROW (image.setPixelColor (0 , -1 , Color (0xffffffff )), std::out_of_range);
395+ EXPECT_THROW (image.getPixel (2 , 0 ), std::out_of_range);
396+ EXPECT_THROW (image.getPixelColor (0 , 2 ), std::out_of_range);
397+ }
0 commit comments