Added implementation of Rotation methods, and tests
This commit is contained in:
parent
046a694dc4
commit
316ddc4a24
87
Src/BMP.cpp
87
Src/BMP.cpp
@ -293,6 +293,93 @@ namespace Leonetienne::BmpPP {
|
|||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BMP BMP::Rotate90degClockwise() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
|
// Create a new image matching this ones metadata, but with width and height flipped
|
||||||
|
BMP bmp(Eule::Vector2i(size.y, size.x), colormode);
|
||||||
|
|
||||||
|
// Now copy over the pixels, rotating it by 90 deg
|
||||||
|
const std::size_t numChannels = GetNumChannels();
|
||||||
|
for (std::size_t y = 0; y < size.y; y++) {
|
||||||
|
for (std::size_t x = 0; x < size.x; x++) {
|
||||||
|
const std::size_t pixelIndex = (y * size.x + x) * numChannels;
|
||||||
|
const std::size_t rotatedPixelIndex = (x * size.y + (size.y - 1 - y)) * numChannels;
|
||||||
|
|
||||||
|
// Copy over the whole pixel
|
||||||
|
std::copy(
|
||||||
|
pixelBuffer.cbegin() + pixelIndex,
|
||||||
|
pixelBuffer.cbegin() + pixelIndex + numChannels,
|
||||||
|
bmp.pixelBuffer.begin() + rotatedPixelIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return it
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMP BMP::Rotate90degCounterclockwise() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
|
// Create a new image matching this ones metadata, but with width and height flipped
|
||||||
|
BMP bmp(Eule::Vector2i(size.y, size.x), colormode);
|
||||||
|
|
||||||
|
// Now copy over the pixels, rotating it by -90 deg
|
||||||
|
const std::size_t numChannels = GetNumChannels();
|
||||||
|
for (std::size_t y = 0; y < size.y; y++) {
|
||||||
|
for (std::size_t x = 0; x < size.x; x++) {
|
||||||
|
const std::size_t pixelIndex = (y * size.x + x) * numChannels;
|
||||||
|
const std::size_t rotatedPixelIndex = ((size.x - 1 - x) * size.y + y) * numChannels;
|
||||||
|
|
||||||
|
// Copy over the whole pixel
|
||||||
|
std::copy(
|
||||||
|
pixelBuffer.cbegin() + pixelIndex,
|
||||||
|
pixelBuffer.cbegin() + pixelIndex + numChannels,
|
||||||
|
bmp.pixelBuffer.begin() + rotatedPixelIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return it
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMP BMP::Rotate180deg() const {
|
||||||
|
CHECK_IF_INITIALIZED
|
||||||
|
|
||||||
|
// Basically, what we're doing here, is mirroring
|
||||||
|
// the image horizontally and vertically at the same time
|
||||||
|
|
||||||
|
// Create a new image matching this's metadata
|
||||||
|
BMP bmp(size, colormode);
|
||||||
|
|
||||||
|
// Now copy over the pixels, mirroring it horizontally and vertically
|
||||||
|
const std::size_t numChannels = GetNumChannels();
|
||||||
|
const std::size_t rowLength = size.x * numChannels;
|
||||||
|
|
||||||
|
for (std::size_t y = 0; y < size.y; y++) {
|
||||||
|
const std::size_t rowIndex = y * rowLength;
|
||||||
|
const std::size_t flippedRowIndex = (size.y - 1 - y) * rowLength;
|
||||||
|
|
||||||
|
for (std::size_t x = 0; x < size.x; x++) {
|
||||||
|
const std::size_t pixelIndex = rowIndex + x * numChannels;
|
||||||
|
const std::size_t rotatedPixelIndex = flippedRowIndex + (size.x - 1 - x) * numChannels;
|
||||||
|
|
||||||
|
// Copy over the whole pixel
|
||||||
|
std::copy(
|
||||||
|
pixelBuffer.cbegin() + pixelIndex,
|
||||||
|
pixelBuffer.cbegin() + pixelIndex + numChannels,
|
||||||
|
bmp.pixelBuffer.begin() + rotatedPixelIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// return it
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CHECK_IF_INITIALIZED
|
#undef CHECK_IF_INITIALIZED
|
||||||
|
@ -28,6 +28,7 @@ add_executable(Test
|
|||||||
MirrorHorizontally.cpp
|
MirrorHorizontally.cpp
|
||||||
MirrorVertically.cpp
|
MirrorVertically.cpp
|
||||||
SwapChannels.cpp
|
SwapChannels.cpp
|
||||||
|
Rotate.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Move test images to build dir
|
# Move test images to build dir
|
||||||
|
54
Test/Rotate.cpp
Normal file
54
Test/Rotate.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <Bmp.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "Catch2.h"
|
||||||
|
|
||||||
|
using namespace Leonetienne::BmpPP;
|
||||||
|
using namespace Eule;
|
||||||
|
|
||||||
|
// Tests that rotating works
|
||||||
|
TEST_CASE(__FILE__"/Mirroring produces the correct results", "[Rotate]")
|
||||||
|
{
|
||||||
|
SECTION("90deg clockwise") {
|
||||||
|
// Read an image
|
||||||
|
BMP bmp("base_mateya.bmp");
|
||||||
|
|
||||||
|
// Rotate it
|
||||||
|
bmp = bmp.Rotate90degClockwise();
|
||||||
|
|
||||||
|
// Read reference image
|
||||||
|
const BMP reference("base_mateya_rot_90deg.bmp");
|
||||||
|
|
||||||
|
// Assert that they are equal
|
||||||
|
REQUIRE(bmp == reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("90deg counterclockwise") {
|
||||||
|
// Read an image
|
||||||
|
BMP bmp("base_mateya.bmp");
|
||||||
|
|
||||||
|
// Rotate it
|
||||||
|
bmp = bmp.Rotate90degCounterclockwise();
|
||||||
|
|
||||||
|
// Read reference image
|
||||||
|
const BMP reference("base_mateya_rot_270deg.bmp");
|
||||||
|
|
||||||
|
// Assert that they are equal
|
||||||
|
REQUIRE(bmp == reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("180deg") {
|
||||||
|
// Read an image
|
||||||
|
BMP bmp("base_mateya.bmp");
|
||||||
|
|
||||||
|
// Rotate it
|
||||||
|
bmp = bmp.Rotate180deg();
|
||||||
|
|
||||||
|
// Read reference image
|
||||||
|
const BMP reference("base_mateya_rot_180deg.bmp");
|
||||||
|
|
||||||
|
// Assert that they are equal
|
||||||
|
REQUIRE(bmp == reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
BIN
Test/TestAssets/base_mateya.bmp
Normal file
BIN
Test/TestAssets/base_mateya.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 348 KiB |
BIN
Test/TestAssets/base_mateya_rot_180deg.bmp
Normal file
BIN
Test/TestAssets/base_mateya_rot_180deg.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 348 KiB |
BIN
Test/TestAssets/base_mateya_rot_270deg.bmp
Normal file
BIN
Test/TestAssets/base_mateya_rot_270deg.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 348 KiB |
BIN
Test/TestAssets/base_mateya_rot_90deg.bmp
Normal file
BIN
Test/TestAssets/base_mateya_rot_90deg.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 348 KiB |
Loading…
x
Reference in New Issue
Block a user