It is now possible to create uninitialized images
This commit is contained in:
parent
b27068a6b6
commit
f993241e9f
38
Src/BMP.cpp
38
Src/BMP.cpp
@ -4,8 +4,15 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "BmpHeader.h"
|
#include "BmpHeader.h"
|
||||||
|
|
||||||
|
#define CHECK_IF_INITIALIZED if (!isInitialized) throw std::runtime_error("Image not initialized!");
|
||||||
|
|
||||||
namespace Leonetienne::BmpPP {
|
namespace Leonetienne::BmpPP {
|
||||||
|
|
||||||
|
BMP::BMP() {
|
||||||
|
// Do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BMP::BMP(const Eule::Vector2i &size, const Colormode& colormode)
|
BMP::BMP(const Eule::Vector2i &size, const Colormode& colormode)
|
||||||
:
|
:
|
||||||
size { size },
|
size { size },
|
||||||
@ -17,6 +24,8 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BMP::ReInitialize(const Eule::Vector2i &size) {
|
void BMP::ReInitialize(const Eule::Vector2i &size) {
|
||||||
|
isInitialized = true;
|
||||||
|
|
||||||
// Carry over new attributes
|
// Carry over new attributes
|
||||||
this->size = size;
|
this->size = size;
|
||||||
|
|
||||||
@ -28,6 +37,8 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BMP::ReInitialize(const Eule::Vector2i &size, const Colormode &colormode) {
|
void BMP::ReInitialize(const Eule::Vector2i &size, const Colormode &colormode) {
|
||||||
|
isInitialized = true;
|
||||||
|
|
||||||
// Carry over new attributes
|
// Carry over new attributes
|
||||||
this->size = size;
|
this->size = size;
|
||||||
this->colormode = colormode;
|
this->colormode = colormode;
|
||||||
@ -40,6 +51,7 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool BMP::Write(const std::string &filename) const {
|
bool BMP::Write(const std::string &filename) const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
// Create the bmp header
|
// Create the bmp header
|
||||||
BmpHeader bmpHeader;
|
BmpHeader bmpHeader;
|
||||||
@ -158,6 +170,8 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t *BMP::GetPixel(const Eule::Vector2i &position) {
|
std::uint8_t *BMP::GetPixel(const Eule::Vector2i &position) {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
const std::size_t pixelIndex =
|
const std::size_t pixelIndex =
|
||||||
(position.y * size.x + position.x) * GetNumColorChannels();
|
(position.y * size.x + position.x) * GetNumColorChannels();
|
||||||
|
|
||||||
@ -168,6 +182,8 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::uint8_t *BMP::GetPixel(const Eule::Vector2i &position) const {
|
const std::uint8_t *BMP::GetPixel(const Eule::Vector2i &position) const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
const std::size_t pixelIndex =
|
const std::size_t pixelIndex =
|
||||||
(position.y * size.x + position.x) * GetNumColorChannels();
|
(position.y * size.x + position.x) * GetNumColorChannels();
|
||||||
|
|
||||||
@ -181,7 +197,9 @@ namespace Leonetienne::BmpPP {
|
|||||||
const std::uint8_t r,
|
const std::uint8_t r,
|
||||||
const std::uint8_t g,
|
const std::uint8_t g,
|
||||||
const std::uint8_t b,
|
const std::uint8_t b,
|
||||||
const std::uint8_t a) {
|
const std::uint8_t a)
|
||||||
|
{
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
std::uint8_t* pixel = GetPixel(position);
|
std::uint8_t* pixel = GetPixel(position);
|
||||||
|
|
||||||
@ -204,22 +222,32 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t *BMP::data() {
|
std::uint8_t *BMP::data() {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
return pixelBuffer.data();
|
return pixelBuffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::uint8_t *BMP::data() const {
|
const std::uint8_t *BMP::data() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
return pixelBuffer.data();
|
return pixelBuffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Eule::Vector2i &BMP::GetDimensions() const {
|
const Eule::Vector2i &BMP::GetDimensions() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Colormode &BMP::GetColormode() const {
|
const Colormode &BMP::GetColormode() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
return colormode;
|
return colormode;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t BMP::GetNumColorChannels() const {
|
std::size_t BMP::GetNumColorChannels() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
switch (colormode) {
|
switch (colormode) {
|
||||||
case Colormode::RGB:
|
case Colormode::RGB:
|
||||||
return 3;
|
return 3;
|
||||||
@ -233,7 +261,15 @@ namespace Leonetienne::BmpPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::size_t BMP::GetPixelbufferSize() const {
|
std::size_t BMP::GetPixelbufferSize() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
return pixelBuffer.size();
|
return pixelBuffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BMP::IsInitialized() const {
|
||||||
|
return isInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CHECK_IF_INITIALIZED
|
||||||
|
12
Src/BMP.h
12
Src/BMP.h
@ -10,11 +10,9 @@ namespace Leonetienne::BmpPP {
|
|||||||
|
|
||||||
class BMP {
|
class BMP {
|
||||||
public:
|
public:
|
||||||
|
BMP();
|
||||||
explicit BMP(const Eule::Vector2i& size, const Colormode& colormode = Colormode::RGBA);
|
explicit BMP(const Eule::Vector2i& size, const Colormode& colormode = Colormode::RGBA);
|
||||||
|
|
||||||
//! Will write the bmp image to a file.
|
|
||||||
bool Write(const std::string& filename) const;
|
|
||||||
|
|
||||||
//! Will return a pointer to the first byte of a pixel at a given position
|
//! Will return a pointer to the first byte of a pixel at a given position
|
||||||
std::uint8_t* GetPixel(const Eule::Vector2i& position);
|
std::uint8_t* GetPixel(const Eule::Vector2i& position);
|
||||||
|
|
||||||
@ -48,10 +46,18 @@ namespace Leonetienne::BmpPP {
|
|||||||
//! Will return the size of the raw pixel buffer, in bytes
|
//! Will return the size of the raw pixel buffer, in bytes
|
||||||
std::size_t GetPixelbufferSize() const;
|
std::size_t GetPixelbufferSize() const;
|
||||||
|
|
||||||
|
//! Will return whether this image is initialized or not
|
||||||
|
bool IsInitialized() const;
|
||||||
|
|
||||||
|
//! Will write the bmp image to a file.
|
||||||
|
//! Returns false, if unable to open the file
|
||||||
|
bool Write(const std::string& filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Eule::Vector2i size;
|
Eule::Vector2i size;
|
||||||
Colormode colormode;
|
Colormode colormode;
|
||||||
std::vector<std::uint8_t> pixelBuffer;
|
std::vector<std::uint8_t> pixelBuffer;
|
||||||
|
bool isInitialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,5 @@ add_executable(Test
|
|||||||
|
|
||||||
BmpHeader.cpp
|
BmpHeader.cpp
|
||||||
ReInitialize.cpp
|
ReInitialize.cpp
|
||||||
|
Uninitialized.cpp
|
||||||
)
|
)
|
||||||
|
@ -30,3 +30,17 @@ TEST_CASE(__FILE__"/ReInitialize", "[ReInitialize]")
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that re-initializing images results in initialized images
|
||||||
|
TEST_CASE(__FILE__"/ReInitializingWillInitialize", "[ReInitialize]")
|
||||||
|
{
|
||||||
|
// Create uninitialized image
|
||||||
|
BMP bmp;
|
||||||
|
REQUIRE_FALSE(bmp.IsInitialized());
|
||||||
|
|
||||||
|
// Now re-initialize it
|
||||||
|
bmp.ReInitialize({800, 600});
|
||||||
|
REQUIRE(bmp.IsInitialized());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
72
Test/Uninitialized.cpp
Normal file
72
Test/Uninitialized.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#include <Bmp.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "Catch2.h"
|
||||||
|
|
||||||
|
using namespace Leonetienne::BmpPP;
|
||||||
|
|
||||||
|
// Tests that trying to interrogate any getter/Write() on an uninitialized image results in a runtime error
|
||||||
|
TEST_CASE(__FILE__"/RuntimeErrorOnUninitialized", "[Uninitialized]")
|
||||||
|
{
|
||||||
|
// Create uninitialized image
|
||||||
|
BMP bmp;
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.GetPixel({50, 60})
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.SetPixel({50, 60}, 1,2,3,4)
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.data()
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.GetDimensions()
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.GetColormode()
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.GetNumColorChannels()
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.GetPixelbufferSize()
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
bmp.Write("foo.bmp")
|
||||||
|
, std::runtime_error
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that an uninitialized image reports to be uninitialized
|
||||||
|
TEST_CASE(__FILE__"/UninitializedImageIsUninitialized", "[Uninitialized]")
|
||||||
|
{
|
||||||
|
BMP bmp;
|
||||||
|
REQUIRE_FALSE(bmp.IsInitialized());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that an image constructed via dimensions is initialized
|
||||||
|
TEST_CASE(__FILE__"/ConstructedByDimensionsIsInitialized", "[Uninitialized]")
|
||||||
|
{
|
||||||
|
BMP bmp({800, 600});
|
||||||
|
REQUIRE(bmp.IsInitialized());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user