From 330c72acbb6705b02c20c0ac3e50feebea6fee90 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 11 Mar 2024 18:09:11 -0700 Subject: [PATCH] test lib at c level. --- .gitmodules | 6 ++ lib/util.dart | 26 +++++--- scripts/compilelib.sh | 5 +- scripts/runtests.sh | 14 ++++ scripts/watch_compilelib.sh | 2 +- scripts/watch_tests.sh | 13 ++++ src/CMakeLists.txt | 46 +++++++++++-- src/extlib/cwalk | 1 + src/image.cxx | 2 +- src/image.h | 14 +++- src/tests/test_image.cxx | 126 ++++++++++++++++++++++++++++++++++++ tests/main_test.dart | 4 +- 12 files changed, 236 insertions(+), 23 deletions(-) create mode 100644 .gitmodules create mode 100755 scripts/runtests.sh create mode 100755 scripts/watch_tests.sh create mode 160000 src/extlib/cwalk create mode 100644 src/tests/test_image.cxx diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..76825fa --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "extlib/cwalk"] + path = extlib/cwalk + url = https://github.com/likle/cwalk.git +[submodule "src/extlib/cwalk"] + path = src/extlib/cwalk + url = https://github.com/likle/cwalk.git diff --git a/lib/util.dart b/lib/util.dart index 174db4a..7d9d465 100644 --- a/lib/util.dart +++ b/lib/util.dart @@ -15,14 +15,23 @@ class Uint8FlexList extends ListBase { set list(List l) { _list.removeWhere((element) => true); _list.addAll(l); + Pointer p = pointer; pointer = calloc(l.length); - _list.forEach((element) { - pointer[_list.indexOf(element)] = element as int; - }); + for (int i = 0; i < _list.length; ++i) { + pointer[i] = _list[i] as int; + } + calloc.free(p); } @override void operator []=(int index, Uint8 value) { + if (index > _list.length) { + // resize the pointer + pointer = calloc(index - 1); + for (int i = 0; i < _list.length; ++i) { + pointer[i] = _list[i] as int; + } + } _list[index] = value; pointer[index] = value as int; } @@ -37,14 +46,11 @@ class Uint8FlexList extends ListBase { static fromList(List l) { final l2 = Uint8FlexList(); + l2.list = l; + return l2; } } -Pointer readUint8Ptr(File file) { - final l = file.readAsBytesSync().cast(); - final dataPointer = calloc(l.length); - for (int i = 0; i < l.length; ++i) { - dataPointer[i] = l[i]; - } - return dataPointer; +Uint8FlexList readUint8Ptr(File file) { + return Uint8FlexList.fromList(file.readAsBytesSync().cast()); } diff --git a/scripts/compilelib.sh b/scripts/compilelib.sh index 2a4d835..9cd03c4 100755 --- a/scripts/compilelib.sh +++ b/scripts/compilelib.sh @@ -20,7 +20,10 @@ cd ${BUILD_DIR} cmake \ ${SRC_DIR}\ -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_BUILD_TYPE=Debug make +printf "\033c" + set +e \ No newline at end of file diff --git a/scripts/runtests.sh b/scripts/runtests.sh new file mode 100755 index 0000000..e579cdf --- /dev/null +++ b/scripts/runtests.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +SOURCE=${BASH_SOURCE[0]} +while [ -L "$SOURCE" ]; do + DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) + SOURCE=$(readlink "$SOURCE") + [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE +done +DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) + +BUILD_DIR=$(realpath ${DIR}/../build) + +printf '\033c' +${BUILD_DIR}/test_image \ No newline at end of file diff --git a/scripts/watch_compilelib.sh b/scripts/watch_compilelib.sh index e087ddd..ee35bd6 100755 --- a/scripts/watch_compilelib.sh +++ b/scripts/watch_compilelib.sh @@ -10,5 +10,5 @@ DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) SRC_DIR=$(realpath ${DIR}/../src) -find ${SRC_DIR} -name "*.c" -o -name "*.h" -o -name "CMakeLists.txt" | \ +find ${SRC_DIR} -name "*.c*" -o -name "*.h" -o -name "CMakeLists.txt" | \ entr -r ${DIR}/compilelib.sh \ No newline at end of file diff --git a/scripts/watch_tests.sh b/scripts/watch_tests.sh new file mode 100755 index 0000000..9065e61 --- /dev/null +++ b/scripts/watch_tests.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +SOURCE=${BASH_SOURCE[0]} +while [ -L "$SOURCE" ]; do + DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) + SOURCE=$(readlink "$SOURCE") + [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE +done +DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) + +BUILD_DIR=$(realpath ${DIR}/../build) + +echo ${BUILD_DIR}/test_image | entr -r ${DIR}/runtests.sh \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da678c8..55786d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,9 @@ # installed. You should not increase this version, as doing so will cause # the plugin to fail to compile for some customers of the plugin. cmake_minimum_required(VERSION 3.10) +project(archimedes_mobile_lib_library VERSION 0.0.1 LANGUAGES CXX) +enable_language(CXX) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) function(dump_cmake_variables) @@ -27,7 +30,6 @@ function(dump_cmake_variables) endforeach() endfunction() -project(archimedes_mobile_lib_library VERSION 0.0.1 LANGUAGES CXX) set (OPENMVG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../openMVG/src) set (FFMPEG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../ffmpeg_install/include) @@ -37,17 +39,17 @@ find_package( REQUIRED ) +find_package(JPEG REQUIRED) +find_package(TIFF REQUIRED) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/extlib/cwalk) + set(PNG_SHARED ON CACHE BOOL "" FORCE) set(PNG_STATIC OFF CACHE BOOL "" FORCE) set(PNG_EXECUTABLES OFF CACHE BOOL "" FORCE) # we only want lib set(PNG_TESTS OFF CACHE BOOL "" FORCE) # we only want lib set(SKIP_INSTALL_ALL OFF CACHE BOOL "" FORCE) # we only want lib -# find_package(PNG -# REQUIRED -# HINTS "../" -# ) - add_definitions(${PNG_DEFINITIONS}) add_library(archimedes_mobile_lib SHARED @@ -55,12 +57,15 @@ add_library(archimedes_mobile_lib SHARED ) -dump_cmake_variables("^png") +# dump_cmake_variables("") message("LIBRARIES:" ${OpenMVG_LIBRARIES}) target_link_libraries( archimedes_mobile_lib + cwalk + jpeg + tiff ${CMAKE_CURRENT_SOURCE_DIR}/../../libpng/_install/lib/libpng16.so ${CMAKE_CURRENT_SOURCE_DIR}/../../openMVG/build/_install/lib/libopenMVG_image.a ${OPENMVG_LIBRARIES} @@ -78,7 +83,34 @@ set_target_properties(archimedes_mobile_lib PUBLIC_HEADER image.h OUTPUT_NAME "archimedes_mobile_lib" ) + target_link_options(archimedes_mobile_lib PRIVATE "-Wl,-Bstatic") target_link_options(archimedes_mobile_lib PRIVATE "-Wl,-Bdynamic") +add_executable( + test_image + ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_image.cxx +) + +target_link_libraries( + test_image + cunit + cwalk + archimedes_mobile_lib + ${CMAKE_CURRENT_SOURCE_DIR}/../../libpng/_install/lib/libpng16.so + ${CMAKE_CURRENT_SOURCE_DIR}/../../openMVG/build/_install/lib/libopenMVG_image.a + ${CMAKE_CURRENT_SOURCE_DIR}/../../openMVG/build/_install/lib/libopenMVG_features.a + ${OPENMVG_LIBRARIES} +) + +set_target_properties(test_image +PROPERTIES +LINKER_LANGUAGE CXX +) + +add_test ( + NAME test_image + COMMAND test_image + ) + target_compile_definitions(archimedes_mobile_lib PUBLIC DART_SHARED_LIB) \ No newline at end of file diff --git a/src/extlib/cwalk b/src/extlib/cwalk new file mode 160000 index 0000000..f418404 --- /dev/null +++ b/src/extlib/cwalk @@ -0,0 +1 @@ +Subproject commit f418404bf395f5ad5b5dccaf9547c3e016a8dad6 diff --git a/src/image.cxx b/src/image.cxx index b643261..53d1645 100644 --- a/src/image.cxx +++ b/src/image.cxx @@ -17,7 +17,7 @@ const Frame *new_frame_from_handle(FILE *stream, int w, int h, int depth) FILE *make_buffer(const uint8_t *data, const size_t data_len) { - FILE *file = fmemopen((char *)data, data_len, "r+"); + FILE *file = fmemopen((void *) data, data_len, "r+"); if (file == NULL) { diff --git a/src/image.h b/src/image.h index 7b10a4c..c841bda 100644 --- a/src/image.h +++ b/src/image.h @@ -13,7 +13,14 @@ #include #include -extern "C" auto png_sig_cm = png_sig_cmp; +#if defined(__cplusplus) + +extern "C" { + auto png_sig_cm = png_sig_cmp; +} + +#endif // __cplusplus + typedef struct _Frame { @@ -23,6 +30,11 @@ typedef struct _Frame int depth; } Frame; +#ifdef __cplusplus +extern "C" __attribute__((visibility("default"))) __attribute((used)) +#else +__attribute__((visibility("default"))) __attribute((used)) +#endif // __cplusplus const Frame *new_frame_from_handle(FILE *, int, int, int); #ifdef __cplusplus extern "C" __attribute__((visibility("default"))) __attribute((used)) diff --git a/src/tests/test_image.cxx b/src/tests/test_image.cxx new file mode 100644 index 0000000..c67153d --- /dev/null +++ b/src/tests/test_image.cxx @@ -0,0 +1,126 @@ +#include +#include "image.h" +#include + +#define STRLEN 2048 + +FILE *imageHandle = NULL; +char frame1Path[STRLEN]; + +/* +* Read the contents of a file into an array +* path: path to the file +* contents: array we'll write to that contains the contents of the file. +*/ +size_t read_file(const char *path, uint8_t **contents) { + FILE *file = fopen(path, "rb"); + if (file == NULL) { + printf("Error: Unable to open file.\n"); + return 0; + } + + // Determine the file size + fseek(file, 0, SEEK_END); + size_t file_size = ftell(file); + rewind(file); + + // Allocate memory for the contents array + *contents = (uint8_t *) malloc(file_size); + if (*contents == NULL) { + printf("Error: Unable to allocate memory.\n"); + fclose(file); + return 0; + } + + // Read the file contents into the array + fread(*contents, 1, file_size, file); + fclose(file); + + return file_size; +} + +int setUp(void) +{ + char framesDir[STRLEN]; + char *here = __FILE__; + size_t length; + cwk_path_get_dirname(here, &length); // archimedes_mobile_lib/src/tests + cwk_path_join(here, "../../../assets/test/frames", framesDir, STRLEN); + cwk_path_join(framesDir, "0001.png", frame1Path, STRLEN); + printf("Opening file %s\n", frame1Path); + return 0; +} + +int tearDown(void) +{ + if (imageHandle) { + fclose(imageHandle); + } + return 0; +} + +void test_create_frame(void) +{ + imageHandle = fopen(frame1Path, "rw+"); + const Frame *f = new_frame_from_handle( + imageHandle, + 768, + 768, + 64 + ); + CU_ASSERT_PTR_NOT_NULL(f->stream); + CU_ASSERT(f->w == 768); +} + +void test_frame_from_data(void) +{ + uint8_t *contents = NULL; + size_t len = read_file(frame1Path, &contents); + const Frame *f = new_frame_from_data(contents, len, 768, 768, 64); + CU_ASSERT_PTR_NOT_NULL(f->stream); + CU_ASSERT(f->w == 768); +} + +void test_archimedes_get_data(void) +{ + imageHandle = fopen(frame1Path, "rw+"); + const Frame *f = new_frame_from_handle( + imageHandle, + 768, + 768, + 64 + ); + + unsigned char *image_data = NULL; + archimedes_get_image_data(f, image_data); + CU_ASSERT_PTR_NOT_NULL(image_data); +} + +int main() { + CU_pSuite pSuite = NULL; + + /* initialize the CUnit test registry */ + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); + + /* add a suite to the registry */ + pSuite = CU_add_suite("ImageSuite", setUp, tearDown); + if (NULL == pSuite) { + CU_cleanup_registry(); + return CU_get_error(); + } + + /* add the tests to the suite */ + if ((NULL == CU_add_test(pSuite, "frame can be created", test_create_frame)) || + (NULL == CU_add_test(pSuite, "frame can be created from data", test_frame_from_data))) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + /* Run all tests using the CUnit Basic interface */ + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + CU_cleanup_registry(); + return CU_get_error(); +} \ No newline at end of file diff --git a/tests/main_test.dart b/tests/main_test.dart index 5e7bfbb..d400a48 100644 --- a/tests/main_test.dart +++ b/tests/main_test.dart @@ -20,8 +20,8 @@ void main() { // Tear down code }); test('newFrame', () { - Pointer frameData = readUint8Ptr(File(firstFrame)); - // newFrame(frameData, fData.length, 768, 768, 1204); + Uint8FlexList frameData = readUint8Ptr(File(firstFrame)); + newFrame(frameData.pointer, frameData.length, 768, 768, 1204); }); }); }