diff --git a/CMakeLists.txt b/CMakeLists.txt index 119bcd7..72d27fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,6 +120,7 @@ if(AARE_USE_WARNINGS) endif() if(AARE_TESTS) + enable_testing() add_subdirectory(tests) endif() diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 9db8c47..b350a89 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -21,6 +21,7 @@ if(AARE_TESTS) set(TestSources ${CMAKE_CURRENT_SOURCE_DIR}/test/defs.test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/DType.test.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/Frame.test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/ProducerConsumerQueue.test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/NDArray.test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/NDView.test.cpp diff --git a/core/include/aare/Frame.hpp b/core/include/aare/Frame.hpp index 73fd59a..211e4dc 100644 --- a/core/include/aare/Frame.hpp +++ b/core/include/aare/Frame.hpp @@ -26,13 +26,24 @@ class Frame { Frame(ssize_t rows, ssize_t cols, ssize_t m_bitdepth); Frame(std::byte *fp, ssize_t rows, ssize_t cols, ssize_t m_bitdepth); std::byte *get(int row, int col); - template void set(int row, int col, T data); - // std::vector> get_array(); + + + //TODO! can we, or even want to remove the template? + template + void set(int row, int col, T data) { + assert(sizeof(T) == m_bitdepth/8); + if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { + throw std::out_of_range("Invalid row or column index"); + } + std::memcpy(m_data+(row*m_cols + col)*(m_bitdepth/8), &data, m_bitdepth/8); + } + ssize_t rows() const { return m_rows; } ssize_t cols() const { return m_cols; } ssize_t bitdepth() const { return m_bitdepth; } - inline ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; } - std::byte *_get_data() { return m_data; } + ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; } + std::byte *data() const { return m_data; } + Frame &operator=(Frame &other) { m_rows = other.rows(); m_cols = other.cols(); diff --git a/core/src/Frame.cpp b/core/src/Frame.cpp index ecc7751..cd06e75 100644 --- a/core/src/Frame.cpp +++ b/core/src/Frame.cpp @@ -14,6 +14,7 @@ Frame::Frame(std::byte* bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth): Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth): m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) { m_data = new std::byte[rows*cols*bitdepth/8]; + std::memset(m_data, 0, rows*cols*bitdepth/8); } @@ -26,29 +27,5 @@ std::byte* Frame::get(int row, int col) { return m_data+(row*m_cols + col)*(m_bitdepth/8); } -template -void Frame::set(int row, int col, T data) { - assert(sizeof(T) == m_bitdepth/8); - if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { - std::cerr << "Invalid row or column index" << std::endl; - return; - } - std::memcpy(m_data+(row*m_cols + col)*(m_bitdepth/8), &data, m_bitdepth/8); -} - -template void Frame::set(int row, int col, uint16_t data); -template void Frame::set(int row, int col, uint32_t data); - - -// std::vector> Frame::get_array() { -// std::vector> array; -// for (int i = 0; i < m_rows; i++) { -// std::vector row; -// row.assign(m_data + i*m_cols, m_data + (i+1)*m_cols); -// array.push_back(row); -// } - -// return array; -// } } // namespace aare diff --git a/core/test/Frame.test.cpp b/core/test/Frame.test.cpp new file mode 100644 index 0000000..4052ac7 --- /dev/null +++ b/core/test/Frame.test.cpp @@ -0,0 +1,105 @@ +#include "aare/Frame.hpp" +#include + +using aare::Frame; + +TEST_CASE("Construct a frame"){ + ssize_t rows = 10; + ssize_t cols = 10; + ssize_t bitdepth = 8; + + Frame frame(rows, cols, bitdepth); + + REQUIRE(frame.rows() == rows); + REQUIRE(frame.cols() == cols); + REQUIRE(frame.bitdepth() == bitdepth); + REQUIRE(frame.size() == rows*cols*bitdepth/8); + + + // data should be initialized to 0 + for (int i = 0; i < rows; i++){ + for (int j = 0; j < cols; j++){ + uint8_t *data = (uint8_t*)frame.get(i, j); + REQUIRE(data != nullptr); + REQUIRE(*data == 0); + } + } +} + +TEST_CASE("Set a value in a 8 bit frame"){ + ssize_t rows = 10; + ssize_t cols = 10; + ssize_t bitdepth = 8; + + Frame frame(rows, cols, bitdepth); + + // set a value + uint8_t value = 255; + frame.set(5, 7, value); + + + // only the value we did set should be non-zero + for (int i = 0; i < rows; i++){ + for (int j = 0; j < cols; j++){ + uint8_t *data = (uint8_t*)frame.get(i, j); + REQUIRE(data != nullptr); + if (i == 5 && j == 7){ + REQUIRE(*data == value); + } else { + REQUIRE(*data == 0); + } + } + } +} + +TEST_CASE("Set a value in a 64 bit frame"){ + ssize_t rows = 10; + ssize_t cols = 10; + ssize_t bitdepth = 64; + + Frame frame(rows, cols, bitdepth); + + // set a value + uint64_t value = 255; + frame.set(5, 7, value); + + + // only the value we did set should be non-zero + for (int i = 0; i < rows; i++){ + for (int j = 0; j < cols; j++){ + uint64_t *data = (uint64_t*)frame.get(i, j); + REQUIRE(data != nullptr); + if (i == 5 && j == 7){ + REQUIRE(*data == value); + } else { + REQUIRE(*data == 0); + } + } + } +} + + +TEST_CASE("Move construct a frame"){ + ssize_t rows = 10; + ssize_t cols = 10; + ssize_t bitdepth = 8; + + Frame frame(rows, cols, bitdepth); + std::byte* data = frame.data(); + + Frame frame2(std::move(frame)); + + //state of the moved from object + REQUIRE(frame.rows() == 0); + REQUIRE(frame.cols() == 0); + REQUIRE(frame.bitdepth() == 0); + REQUIRE(frame.size() == 0); + REQUIRE(frame.data() == nullptr); + + //state of the moved to object + REQUIRE(frame2.rows() == rows); + REQUIRE(frame2.cols() == cols); + REQUIRE(frame2.bitdepth() == bitdepth); + REQUIRE(frame2.size() == rows*cols*bitdepth/8); + REQUIRE(frame2.data() == data); +} \ No newline at end of file diff --git a/file_io/src/NumpyFile.cpp b/file_io/src/NumpyFile.cpp index e153b5f..ab7e602 100644 --- a/file_io/src/NumpyFile.cpp +++ b/file_io/src/NumpyFile.cpp @@ -38,14 +38,14 @@ void NumpyFile::write(Frame &frame) { throw std::runtime_error("File not open for writing"); } fseek(fp, 0, SEEK_END); - fwrite(frame._get_data(), frame.size(), 1, fp); + fwrite(frame.data(), frame.size(), 1, fp); } Frame NumpyFile::get_frame(size_t frame_number) { Frame frame(m_header.shape[1], m_header.shape[2], m_header.dtype.bitdepth()); - get_frame_into(frame_number, frame._get_data()); + get_frame_into(frame_number, frame.data()); return frame; } void NumpyFile::get_frame_into(size_t frame_number, std::byte *image_buf) { diff --git a/file_io/src/RawFile.cpp b/file_io/src/RawFile.cpp index e3e52d4..0fd23ce 100644 --- a/file_io/src/RawFile.cpp +++ b/file_io/src/RawFile.cpp @@ -5,7 +5,7 @@ namespace aare{ Frame RawFile::get_frame(size_t frame_number) { auto f = Frame(this->m_rows, this->m_cols, this->m_bitdepth); - std::byte *frame_buffer = f._get_data(); + std::byte *frame_buffer = f.data(); get_frame_into(frame_number, frame_buffer); return f; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5ea4be9..f85749a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,6 +24,7 @@ set_target_properties(tests PROPERTIES include(CTest) include(Catch) +catch_discover_tests(tests) set(TestSources ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp @@ -34,11 +35,10 @@ target_sources(tests PRIVATE ${TestSources} ) # target_include_directories(tests PRIVATE ${CMAKE_SOURCE_DIR}/include/common) target_link_libraries(tests PRIVATE core aare_compiler_flags utils) -catch_discover_tests(tests - # WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/data -) + #configure a header to pass test file paths get_filename_component(TEST_FILE_PATH ${PROJECT_SOURCE_DIR}/data ABSOLUTE) configure_file(test_config.hpp.in test_config.hpp) -target_include_directories(tests PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file +target_include_directories(tests PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +