mapnik/test/unit/imaging/image.cpp

391 lines
12 KiB
C++
Raw Permalink Normal View History

2015-05-12 20:54:58 +02:00
#include "catch.hpp"
// mapnik
2015-10-29 16:35:45 +01:00
#include <mapnik/image.hpp>
#include <mapnik/image_view.hpp>
2015-05-12 20:54:58 +02:00
#include <mapnik/image_any.hpp>
#include <mapnik/color.hpp>
#include <mapnik/image_util.hpp>
2022-01-26 23:25:53 +01:00
TEST_CASE("image class")
{
SECTION("test gray16")
2015-05-12 20:54:58 +02:00
{
2022-01-26 23:25:53 +01:00
const mapnik::image_gray16 im(4, 4);
mapnik::image_gray16 im2(im);
mapnik::image_gray16 im3(5, 5);
CHECK(im == im);
CHECK_FALSE(im == im2);
CHECK_FALSE(im2 == im3);
CHECK(im < im3);
CHECK_FALSE(im < im2);
// Check that width is correct
CHECK(im.width() == 4);
CHECK(im2.width() == 4);
// Check that height is correct
CHECK(im.height() == 4);
CHECK(im2.height() == 4);
CHECK(im(0, 0) == 0);
CHECK(im2(0, 0) == 0);
im2(0, 0) = 1;
CHECK(im2(0, 0) == 1);
im2.set(514);
CHECK(im2(0, 0) == 514);
CHECK(im2(1, 1) == 514);
// Check that size is correct
CHECK(im.size() == 32);
CHECK(im2.size() == 32);
// Check that row_size is correct
CHECK(im.row_size() == 8);
CHECK(im2.row_size() == 8);
// Check that get_premultiplied is correct
CHECK_FALSE(im.get_premultiplied());
CHECK_FALSE(im2.get_premultiplied());
// Check that set premultiplied works
im2.set_premultiplied(true);
CHECK(im2.get_premultiplied());
// Check that painted is correct
CHECK_FALSE(im.painted());
CHECK_FALSE(im2.painted());
// Check that set premultiplied works
im2.painted(true);
CHECK(im2.painted());
// Check that offset is correct
CHECK(im.get_offset() == 0.0);
CHECK(im2.get_offset() == 0.0);
// Check that set offset works
im2.set_offset(2.3);
CHECK(im2.get_offset() == 2.3);
// Check that scaling is correct
CHECK(im.get_scaling() == 1.0);
CHECK(im2.get_scaling() == 1.0);
// Check that set scaling works
im2.set_scaling(1.1);
CHECK(im2.get_scaling() == 1.1);
// CHECK that image dtype is correct
CHECK(im.get_dtype() == mapnik::image_dtype_gray16);
CHECK(im2.get_dtype() == mapnik::image_dtype_gray16);
using pixel_type = mapnik::image_view_gray16::pixel_type;
pixel_type expected_val;
// Check that all data in the view is correct
// IM
expected_val = 0;
pixel_type const* data_im = im.data();
CHECK(*data_im == expected_val);
unsigned char const* data_b = im.bytes();
CHECK(*data_b == 0);
for (std::size_t y = 0; y < im.height(); ++y)
2015-05-12 20:54:58 +02:00
{
2022-01-26 23:25:53 +01:00
std::size_t width = im.width();
pixel_type const* data_1 = im.get_row(y);
pixel_type const* data_2 = im.get_row(y, 1);
for (std::size_t x = 0; x < width; ++x)
{
CHECK(*data_1 == expected_val);
++data_1;
}
for (std::size_t x = 1; x < width; ++x)
{
CHECK(*data_2 == expected_val);
++data_2;
}
2015-05-12 20:54:58 +02:00
}
2022-01-26 23:25:53 +01:00
// IM2
expected_val = 514;
pixel_type* data_im2 = im2.data();
CHECK(*data_im2 == expected_val);
unsigned char* data_b2 = im2.bytes();
CHECK(*data_b2 == 2);
++data_b;
CHECK(*data_b2 == 2);
for (std::size_t y = 0; y < im2.height(); ++y)
2015-05-12 20:54:58 +02:00
{
2022-01-26 23:25:53 +01:00
std::size_t width = im2.width();
pixel_type const* data_1 = im2.get_row(y);
pixel_type const* data_2 = im2.get_row(y, 1);
for (std::size_t x = 0; x < width; ++x)
{
CHECK(*data_1 == expected_val);
++data_1;
}
for (std::size_t x = 1; x < width; ++x)
{
CHECK(*data_2 == expected_val);
++data_2;
}
2015-05-12 20:54:58 +02:00
}
2022-01-26 23:25:53 +01:00
// Test set row
std::vector<pixel_type> v1(im2.width(), 30);
std::vector<pixel_type> v2(im2.width() - 1, 50);
im2.set_row(0, v1.data(), v1.size());
im2.set_row(1, 1, v2.size(), v2.data());
2022-01-26 23:25:53 +01:00
CHECK(im2(0, 0) == 30);
CHECK(im2(0, 1) == 514);
CHECK(im2(1, 1) == 50);
2022-01-26 23:25:53 +01:00
} // END SECTION
2015-05-12 20:54:58 +02:00
2022-01-26 23:25:53 +01:00
SECTION("image_null")
2015-05-13 20:33:21 +02:00
{
2022-01-26 23:25:53 +01:00
mapnik::image_null im_null;
const mapnik::image_null im_null2(2, 2); // Actually doesn't really set any size
mapnik::image_null im_null3(im_null2);
mapnik::image_null im_null4(std::move(im_null3));
// All nulls are equal
CHECK(im_null == im_null4);
CHECK(im_null == im_null2);
// No null is greater
CHECK_FALSE(im_null < im_null4);
CHECK_FALSE(im_null < im_null2);
// Check defaults
CHECK(im_null.width() == 0);
CHECK(im_null.height() == 0);
CHECK(im_null.size() == 0);
CHECK(im_null.row_size() == 0);
// Setting offset does nothing
im_null.set_offset(10000000.0);
CHECK(im_null.get_offset() == 0.0);
// Setting scaling does nothing
im_null.set_scaling(123123123.0);
CHECK(im_null.get_scaling() == 1.0);
CHECK(im_null.get_dtype() == mapnik::image_dtype_null);
// Setting premultiplied does nothing
im_null.set_premultiplied(true);
CHECK_FALSE(im_null.get_premultiplied());
// Setting painted does nothing
im_null.painted(true);
CHECK_FALSE(im_null.painted());
// Should throw if we try to access or setdata.
REQUIRE_THROWS(im_null(0, 0));
REQUIRE_THROWS(im_null2(0, 0));
REQUIRE_THROWS(im_null(0, 0) = 1);
unsigned char const* e1 = im_null.bytes();
unsigned char* e2 = im_null.bytes();
CHECK(e1 == nullptr);
CHECK(e2 == nullptr);
} // END SECTION
SECTION("image any")
2015-05-13 20:33:21 +02:00
{
2022-01-26 23:25:53 +01:00
mapnik::image_null null_im;
const mapnik::image_any im_any_null(null_im);
CHECK(im_any_null.get_dtype() == mapnik::image_dtype_null);
CHECK(im_any_null.bytes() == nullptr);
mapnik::image_gray16 im(4, 4);
mapnik::fill(im, 514);
mapnik::image_any im_any(im);
CHECK(im_any.get_dtype() == mapnik::image_dtype_gray16);
unsigned char* foo = im_any.bytes();
CHECK(*foo == 2);
++foo;
CHECK(*foo == 2);
CHECK(im_any.width() == 4);
CHECK(im_any.height() == 4);
CHECK(im_any.size() == 32);
CHECK(im_any.row_size() == 8);
CHECK_FALSE(im_any.get_premultiplied());
im_any.set_offset(10.0);
CHECK(im_any.get_offset() == 10.0);
im_any.set_scaling(2.1);
CHECK(im_any.get_scaling() == 2.1);
CHECK_FALSE(im_any.painted());
} // END SECTION
SECTION("test image_any initialization")
2015-05-13 20:33:21 +02:00
{
2022-01-26 23:25:53 +01:00
{
mapnik::image_any im(4, 4);
CHECK(im.get_dtype() == mapnik::image_dtype_rgba8);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_null);
CHECK(im.get_dtype() == mapnik::image_dtype_null);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray8);
CHECK(im.get_dtype() == mapnik::image_dtype_gray8);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray8s);
CHECK(im.get_dtype() == mapnik::image_dtype_gray8s);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray16);
CHECK(im.get_dtype() == mapnik::image_dtype_gray16);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray16s);
CHECK(im.get_dtype() == mapnik::image_dtype_gray16s);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray32);
CHECK(im.get_dtype() == mapnik::image_dtype_gray32);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray32s);
CHECK(im.get_dtype() == mapnik::image_dtype_gray32s);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray32f);
CHECK(im.get_dtype() == mapnik::image_dtype_gray32f);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray64);
CHECK(im.get_dtype() == mapnik::image_dtype_gray64);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray64s);
CHECK(im.get_dtype() == mapnik::image_dtype_gray64s);
}
{
mapnik::image_any im(4, 4, mapnik::image_dtype_gray64f);
CHECK(im.get_dtype() == mapnik::image_dtype_gray64f);
}
2015-05-12 20:54:58 +02:00
2022-01-26 23:25:53 +01:00
} // END SECTION
2015-05-12 20:54:58 +02:00
2022-01-26 23:25:53 +01:00
SECTION("Image Buffer")
{
2022-01-26 23:25:53 +01:00
mapnik::detail::buffer buf_zero(0);
CHECK(buf_zero.size() == 0);
CHECK(!buf_zero);
mapnik::detail::buffer buf(10);
CHECK(buf.size() == 10);
CHECK_FALSE(!buf);
unsigned char* d = buf.data();
*d = 9;
const mapnik::detail::buffer buf2 = buf;
CHECK(buf2.size() == 10);
unsigned char const* d2 = buf2.data();
CHECK(*d2 == 9);
} // END SECTION
SECTION("Image copy/move")
{
2022-01-26 23:25:53 +01:00
mapnik::detail::buffer buf(16 * 16 * 4); // large enough to hold 16*16 RGBA image
CHECK(buf.size() == 16 * 16 * 4);
// fill buffer with 0xff
std::fill(buf.data(), buf.data() + buf.size(), 0xff);
// move buffer
mapnik::detail::buffer buf2(std::move(buf));
CHECK(buf.size() == 0);
CHECK(buf.data() == nullptr);
mapnik::image_rgba8 im(16, 16, buf2.data()); // shallow copy
std::size_t count = 0;
for (auto const& pixel : im)
{
// expect rgba(255,255,255,1.0)
CHECK(sizeof(pixel) == sizeof(mapnik::image_rgba8::pixel_type));
CHECK(pixel == 0xffffffff);
++count;
}
CHECK(count == im.width() * im.height());
CHECK(buf2.size() == im.width() * im.height() * sizeof(mapnik::image_rgba8::pixel_type));
2022-01-26 23:25:53 +01:00
// mutate buffer
// fill buffer with 0x7f - semi-transparent grey
std::fill(buf2.data(), buf2.data() + buf2.size(), 0x7f);
for (auto const& pixel : im)
{
// expect rgba(127,127,127,0.5)
CHECK(pixel == 0x7f7f7f7f);
}
2022-01-26 23:25:53 +01:00
// mutate image directly (buf)
for (auto& pixel : im)
{
pixel = mapnik::color(0, 255, 0).rgba(); // green
}
2022-01-26 23:25:53 +01:00
// move
mapnik::image_rgba8 im2(std::move(im));
CHECK(im.data() == nullptr);
CHECK(im.bytes() == nullptr);
CHECK(im.width() == 0);
CHECK(im.height() == 0);
for (auto const& pixel : im2)
{
// expect `green`
CHECK(pixel == mapnik::color(0, 255, 0).rgba());
}
2022-01-26 23:25:53 +01:00
mapnik::image_rgba8 im3(im2); // shallow copy
for (auto& pixel : im3)
{
// expect `green`
CHECK(pixel == mapnik::color(0, 255, 0).rgba());
// mutate
pixel = mapnik::color(255, 0, 0).rgba(); // red
}
for (auto const& pixel : im3)
{
// expect `red`
CHECK(pixel == mapnik::color(255, 0, 0).rgba());
}
for (auto const& pixel : im2)
{
// expect `red`
CHECK(pixel == mapnik::color(255, 0, 0).rgba());
}
}
2022-01-26 23:25:53 +01:00
SECTION("image::swap")
{
auto blue = mapnik::color(50, 50, 250).rgba();
auto orange = mapnik::color(250, 150, 0).rgba();
2016-09-07 19:23:36 +02:00
2022-01-26 23:25:53 +01:00
mapnik::image_rgba8 im;
mapnik::image_rgba8 im2(16, 16);
mapnik::image_rgba8 im3(16, 16);
2016-09-07 19:23:36 +02:00
2022-01-26 23:25:53 +01:00
im2.set(blue);
im3.set(orange);
2016-09-07 19:23:36 +02:00
2022-01-26 23:25:53 +01:00
// swap two non-empty images
CHECK_NOTHROW(im2.swap(im3));
CHECK(im2(0, 0) == orange);
CHECK(im3(0, 0) == blue);
2016-09-07 19:23:36 +02:00
2022-01-26 23:25:53 +01:00
// swap empty <-> non-empty
CHECK_NOTHROW(im.swap(im3));
CHECK(im3.data() == nullptr);
2022-08-11 22:54:50 +02:00
CHECKED_IF(im.data() != nullptr)
{
CHECK(im(0, 0) == blue);
}
2016-09-07 19:23:36 +02:00
}
} // END TEST CASE