diff --git a/RELEASE.md b/RELEASE.md index 74d799b1..8d647df4 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -11,6 +11,8 @@ - Removed the legacy ``gaus``, ``pol1``, ``scurve``, and ``scurve2`` function evaluators. Model objects are callable and provide the replacement, for example ``Gaussian()(x, par)``. +- ``NDView`` now converts to ``NDView``; + ``expand4to8bit`` and ``expand24to32bit`` accept const input views. ### Bugfixes: - Fixed broken reading of old (pre reordering) Moench03 @@ -165,4 +167,3 @@ dhanya.thattil@psi.ch - diff --git a/include/aare/NDView.hpp b/include/aare/NDView.hpp index 8c2432d4..c507b41f 100644 --- a/include/aare/NDView.hpp +++ b/include/aare/NDView.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace aare { @@ -92,6 +93,12 @@ class NDView : public ArrayExpr, Ndim> { : buffer_(buffer), strides_(c_strides(shape)), shape_(shape), size_(num_elements(shape)) {} + template , int> = 0> + NDView(const NDView &other) noexcept + : buffer_(other.buffer_), strides_(other.strides_), + shape_(other.shape_), size_(other.size_) {} + template std::enable_if_t operator()(Ix... index) { return buffer_[element_offset(strides_, index...)]; @@ -216,6 +223,8 @@ class NDView : public ArrayExpr, Ndim> { } private: + template friend class NDView; + T *buffer_{nullptr}; std::array strides_{}; std::array shape_{}; @@ -263,4 +272,4 @@ template NDView make_view(std::vector &vec) { return NDView(vec.data(), {static_cast(vec.size())}); } -} // namespace aare \ No newline at end of file +} // namespace aare diff --git a/include/aare/decode.hpp b/include/aare/decode.hpp index c3397093..a6efd187 100644 --- a/include/aare/decode.hpp +++ b/include/aare/decode.hpp @@ -35,7 +35,7 @@ uint32_t mask32to24bits(uint32_t input, BitOffset offset = {}); * @param offset Offset within the first byte to where the data starts (0-7 * bits) */ -void expand24to32bit(NDView input, NDView output, +void expand24to32bit(NDView input, NDView output, BitOffset offset = {}); /** @@ -43,7 +43,7 @@ void expand24to32bit(NDView input, NDView output, * @param input input buffer with 4 bit values packed into 8 bit * @param output output buffer with 8 bit values */ -void expand4to8bit(NDView input, NDView output); +void expand4to8bit(NDView input, NDView output); /** * @brief Apply custom weights to a 16-bit input value. Will sum up diff --git a/src/NDView.test.cpp b/src/NDView.test.cpp index b89d0cd5..1a8c6a2b 100644 --- a/src/NDView.test.cpp +++ b/src/NDView.test.cpp @@ -5,12 +5,16 @@ #include #include #include +#include #include using aare::NDView; using aare::num_elements; using aare::Shape; +static_assert(std::is_convertible_v, NDView>); +static_assert(!std::is_convertible_v, NDView>); + TEST_CASE("Calculate size from a shape") { Shape<3> shape{2, 3, 4}; REQUIRE(num_elements(shape) == 24); @@ -88,6 +92,17 @@ TEST_CASE("Element reference 1D with a const NDView") { } } +TEST_CASE("Convert a mutable NDView to a const NDView") { + std::vector vec{1, 2, 3, 4}; + NDView mutable_view(vec.data(), Shape<2>{2, 2}); + + NDView const_view = mutable_view; + + REQUIRE(const_view.data() == mutable_view.data()); + REQUIRE(const_view.shape() == mutable_view.shape()); + REQUIRE(const_view.strides() == mutable_view.strides()); +} + TEST_CASE("Element reference 2D") { std::vector vec(12); std::iota(vec.begin(), vec.end(), 0); @@ -279,4 +294,4 @@ TEST_CASE("NDView over byte") { auto v = aare::make_view(buf); REQUIRE(v.shape()[0] == 5); REQUIRE(v[0] == std::byte{0}); -} \ No newline at end of file +} diff --git a/src/decode.cpp b/src/decode.cpp index 157fed25..afe261f9 100644 --- a/src/decode.cpp +++ b/src/decode.cpp @@ -144,7 +144,7 @@ uint32_t mask32to24bits(uint32_t input, BitOffset offset) { return (input >> offset.value()) & mask24bits; } -void expand4to8bit(NDView input, NDView output) { +void expand4to8bit(NDView input, NDView output) { if (2 * input.size() != output.size()) throw std::runtime_error( @@ -162,7 +162,7 @@ void expand4to8bit(NDView input, NDView output) { } } -void expand24to32bit(NDView input, NDView output, +void expand24to32bit(NDView input, NDView output, BitOffset bit_offset) { ssize_t bytes_per_channel = 3; // 24bit diff --git a/src/decode.test.cpp b/src/decode.test.cpp index d7f3901d..bab7c38b 100644 --- a/src/decode.test.cpp +++ b/src/decode.test.cpp @@ -154,6 +154,20 @@ TEST_CASE("Expand container with 24 bit data to 32") { } } +TEST_CASE("Expand 24 bit values to 32 bit values from a const buffer") { + const uint8_t buffer[] = { + 0x0F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + }; + + aare::NDView input(buffer, {9}); + aare::NDArray out({3}); + aare::expand24to32bit(input, out.view()); + + CHECK(out(0) == 0xF); + CHECK(out(1) == 0xFF); + CHECK(out(2) == 0xFFFFFF); +} + TEST_CASE("Expand 4 bit values packed into 8 bit to 8 bit values") { { uint8_t buffer[] = { @@ -172,4 +186,25 @@ TEST_CASE("Expand 4 bit values packed into 8 bit to 8 bit values") { CHECK(out(i) == expected_output[i]); } } -} \ No newline at end of file +} + +TEST_CASE("Expand 4 bit values packed into 8 bit to 8 bit values from a const " + "buffer") { + { + const uint8_t buffer[] = { + 0x00, 0xF0, 0xFF, 0x00, 0xF0, 0xFF, + }; + + aare::NDView input(&buffer[0], {6}); + aare::NDArray out({12}); + aare::expand4to8bit(input, out.view()); + + uint8_t expected_output[] = { + 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, + 0x0, 0x0, 0x0, 0xF, 0xF, 0xF}; // assuming little endian + + for (size_t i = 0; i < 12; ++i) { + CHECK(out(i) == expected_output[i]); + } + } +}