commit 0d482412d2db4d86d212c302f10fe219f8f37ec7
parent 8b877921633c4de88b6af83a91e90301090e75a2
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 1 Jul 2021 12:00:34 +0200
Add the scam_create_pinhole function
Diffstat:
| A | cmake/CMakeLists.txt | | | 93 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam.c | | | 105 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam.h | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam_c.h | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam_log.c | | | 122 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam_log.h | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/scam_pinhole.c | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 files changed, 644 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -0,0 +1,93 @@
+# Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+cmake_minimum_required(VERSION 2.8)
+project(scam C)
+enable_testing()
+
+set(SCAM_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+option(NO_TEST "Do not build tests" OFF)
+
+################################################################################
+# Check dependencies
+################################################################################
+find_package(RCMake 0.4 REQUIRED)
+find_package(RSys 0.9 REQUIRED)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
+include(rcmake)
+include(rcmake_runtime)
+
+include_directories(${RSys_INCLUDE_DIR})
+
+################################################################################
+# Configure and define targets
+################################################################################
+set(VERSION_MAJOR 0)
+set(VERSION_MINOR 0)
+set(VERSION_PATCH 0)
+set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+
+set(SCAM_FILES_SRC
+ scam.c
+ scam_log.c
+ scam_pinhole.c)
+set(SCAM_FILES_INC
+ scam_c.h
+ scam_log.h)
+set(SCAM_FILES_INC_API scam.h)
+set(SCAM_FILES_DOC COPYING README.md)
+
+# Prepend each file in the `SCAM_FILES_<SRC|INC>' list by `SCAM_SOURCE_DIR'
+rcmake_prepend_path(SCAM_FILES_SRC ${SCAM_SOURCE_DIR})
+rcmake_prepend_path(SCAM_FILES_INC ${SCAM_SOURCE_DIR})
+rcmake_prepend_path(SCAM_FILES_INC_API ${SCAM_SOURCE_DIR})
+rcmake_prepend_path(SCAM_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+
+add_library(scam SHARED ${SCAM_FILES_SRC} ${SCAM_FILES_INC} ${SCAM_FILES_INC_API})
+target_link_libraries(scam RSys m)
+
+set_target_properties(scam PROPERTIES
+ DEFINE_SYMBOL SCAM_SHARED_BUILD
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR})
+
+rcmake_setup_devel(scam StarCamera ${VERSION} star/scam_version.h)
+
+################################################################################
+# Add tests
+################################################################################
+if(NOT NO_TEST)
+ function(build_test _name)
+ add_executable(${_name} ${SCAM_SOURCE_DIR}/${_name}.c)
+ target_link_libraries(${_name} scam RSys)
+ endfunction()
+
+ function(new_test _name)
+ build_test(${_name})
+ add_test(${_name}_${_palette} ${_name})
+ endfunction()
+endif()
+
+################################################################################
+# Define output & install directories
+################################################################################
+install(TARGETS scam
+ ARCHIVE DESTINATION bin
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+install(FILES ${SCAM_FILES_INC_API} DESTINATION include/star)
+install(FILES ${SCAM_FILES_DOC} DESTINATION share/doc/star-camera)
+
diff --git a/src/scam.c b/src/scam.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "scam_c.h"
+#include "scam_log.h"
+
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+release_scam(ref_T* ref)
+{
+ struct scam* cam = CONTAINER_OF(ref, struct scam, ref);
+ ASSERT(ref);
+ if(cam->logger == &cam->logger__) logger_release(&cam->logger__);
+ MEM_RM(cam->allocator, cam);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+scam_ref_get(struct scam* cam)
+{
+ if(!cam) return RES_BAD_ARG;
+ ref_get(&cam->ref);
+ return RES_OK;
+}
+
+res_T
+scam_ref_put(struct scam* cam)
+{
+ if(!cam) return RES_BAD_ARG;
+ ref_put(&cam->ref, release_scam);
+ return RES_OK;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+camera_create
+ (struct logger* logger,
+ struct mem_allocator* mem_allocator,
+ const int verbose, /* Verbosity level */
+ const enum scam_type type,
+ struct scam** out_cam)
+{
+ struct scam* cam = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ ASSERT(out_cam && (unsigned)type < SCAM_TYPES_COUNT__);
+
+ allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
+ cam = MEM_CALLOC(allocator, 1, sizeof(*cam));
+ if(!cam) {
+ if(verbose) {
+ #define ERR_STR "Could not allocate the Star-Camera.\n"
+ if(logger) {
+ logger_print(logger, LOG_ERROR, ERR_STR);
+ } else {
+ fprintf(stderr, MSG_ERROR_PREFIX ERR_STR);
+ }
+ #undef ERR_STR
+ }
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&cam->ref);
+ cam->allocator = allocator;
+ cam->type = type;
+ cam->verbose = verbose;
+
+ if(logger) {
+ cam->logger = logger;
+ } else {
+ setup_log_default(cam);
+ }
+
+exit:
+ if(out_cam) *out_cam = cam;
+ return res;
+error:
+ if(cam) {
+ SCAM(ref_put(cam));
+ cam = NULL;
+ }
+ goto exit;
+}
+
diff --git a/src/scam.h b/src/scam.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SCAM_H
+#define SCAM_H
+
+#include <rsys/rsys.h>
+
+/* Library symbol management */
+#if defined(SCAM_SHARED_BUILD) /* Build shared library */
+ #define SCAM_API extern EXPORT_SYM
+#elif defined(SCAM_STATIC) /* Use/build static library */
+ #define SCAM_API extern LOCAL_SYM
+#else /* Use shared library */
+ #define SCAM_API extern IMPORT_SYM
+#endif
+
+/* Helper macro that asserts if the invocation of the suvm function `Func'
+ * returns an error. One should use this macro on scam function calls for
+ * which no explicit error checking is performed */
+#ifndef NDEBUG
+ #define SCAM(Func) ASSERT(scam_ ## Func == RES_OK)
+#else
+ #define SCAM(Func) scam_ ## Func
+#endif
+
+enum scam_type {
+ SCAM_PINHOLE,
+ SCAM_TYPES_COUNT__,
+ SCAM_NONE = SCAM_TYPES_COUNT__
+};
+
+struct scam_pinhole_args {
+ double position[3]; /* Focal point */
+ double target[3]; /* Targeted point. target-position = image plane normal */
+ double up[3]; /* Vector defining the upward orientation */
+ double aspect_ratio; /* Image plane aspect ratio (width / height) */
+ double field_of_view; /* Vertical field of view in radians */
+};
+#define SCAM_PINHOLE_ARGS_DEFAULT__ { \
+ {0,0,0}, /* Position */ \
+ {0,1,0}, /* Target */ \
+ {0,0,1}, /* Up */ \
+ 1.0, /* Aspect ratio */ \
+ 1.22173047639603070383, /* ~70 degrees */ \
+}
+static const struct scam_pinhole_args SCAM_PINHOLE_ARGS_DEFAULT =
+ SCAM_PINHOLE_ARGS_DEFAULT__;
+
+/* Forward declaration of external data types */
+struct logger;
+struct mem_allocator;
+
+/* Opaque data type */
+struct scam;
+
+/*******************************************************************************
+ * Star-Camera API
+ ******************************************************************************/
+BEGIN_DECLS
+
+SCAM_API res_T
+scam_create_pinhole
+ (struct logger* logger, /* NULL <=> use builtin logger */
+ struct mem_allocator* allocator, /* NULL <=> use default allocator */
+ const int verbose, /* Verbosity level */
+ struct scam_pinhole_args* args,
+ struct scam** camera);
+
+SCAM_API res_T
+scam_ref_get
+ (struct scam* camera);
+
+SCAM_API res_T
+scam_ref_put
+ (struct scam* camera);
+
+END_DECLS
+
+#endif /* SCAM_H */
diff --git a/src/scam_c.h b/src/scam_c.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SCAM_C_H
+#define SCAM_C_H
+
+#include "scam.h" /* For enum scam_type */
+
+#include <rsys/logger.h>
+#include <rsys/ref_count.h>
+
+struct pinhole {
+ /* Orthogonal basis of the camera */
+ double axis_x[3];
+ double axis_y[3];
+ double axis_z[3];
+
+ /* Focal point */
+ double position[3];
+};
+
+struct scam {
+ enum scam_type type;
+ union {
+ struct pinhole pinhole;
+ } param;
+
+ int verbose;
+ struct logger* logger;
+ struct logger logger__;
+
+ struct mem_allocator* allocator;
+ ref_T ref;
+};
+
+
+extern LOCAL_SYM res_T
+camera_create
+ (struct logger* logger, /* NULL <=> use builtin logger */
+ struct mem_allocator* allocator, /* NULL <=> use default allocator */
+ const int verbose, /* Verbosity level */
+ const enum scam_type type,
+ struct scam** scam);
+
+#endif /* SCAM_C_H */
diff --git a/src/scam_log.c b/src/scam_log.c
@@ -0,0 +1,122 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "scam_c.h"
+#include "scam_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/logger.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE void
+log_msg
+ (const struct scam* cam,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(cam && msg);
+ if(cam->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(cam->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
+static void
+print_info(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_INFO_PREFIX"%s", msg);
+}
+
+static void
+print_err(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_ERROR_PREFIX"%s", msg);
+}
+
+static void
+print_warn(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_WARNING_PREFIX"%s", msg);
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+setup_log_default(struct scam* cam)
+{
+ res_T res = RES_OK;
+ ASSERT(cam);
+
+ res = logger_init(cam->allocator, &cam->logger__);
+ if(res != RES_OK) {
+ if(cam->verbose) {
+ fprintf(stderr,
+ MSG_ERROR_PREFIX
+ "Could not setup the Star-Camera default logger -- %s.\n",
+ res_to_cstr(res));
+ }
+ goto error;
+ }
+ logger_set_stream(&cam->logger__, LOG_OUTPUT, print_info, NULL);
+ logger_set_stream(&cam->logger__, LOG_ERROR, print_err, NULL);
+ logger_set_stream(&cam->logger__, LOG_WARNING, print_warn, NULL);
+ cam->logger = &cam->logger__;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+void
+log_info(const struct scam* cam, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(cam && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(cam, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_err(const struct scam* cam, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(cam && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(cam, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warn(const struct scam* cam, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(cam && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(cam, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
diff --git a/src/scam_log.h b/src/scam_log.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SCAM_LOG_H
+#define SCAM_LOG_H
+
+#include <rsys/rsys.h>
+
+#define MSG_INFO_PREFIX "Star-Camera:\x1b[1m\x1b[32minfo\x1b[0m: "
+#define MSG_ERROR_PREFIX "Star-Camera:\x1b[1m\x1b[31merror\x1b[0m: "
+#define MSG_WARNING_PREFIX "Star-Camera:\x1b[1m\x1b[33mwarning\x1b[0m: "
+
+extern LOCAL_SYM res_T
+setup_log_default
+ (struct scam* cam);
+
+/* Conditionally log a message on the LOG_OUTPUT stream of the atrstm logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_info
+ (const struct scam* cam,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_ERROR stream of the scam logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_err
+ (const struct scam* cam,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_WARNING stream of the scam logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_warn
+ (const struct scam* cam,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+#endif /* SCAM_LOG_H */
diff --git a/src/scam_pinhole.c b/src/scam_pinhole.c
@@ -0,0 +1,110 @@
+/* Copyright (C) 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "scam_c.h"
+#include "scam_log.h"
+
+#include <rsys/double3.h>
+#include <rsys/math.h>
+
+#include <math.h>
+
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+static res_T
+setup_pinhole(struct scam* cam, const struct scam_pinhole_args* args)
+{
+ double x[3], y[3], z[3];
+ double img_plane_depth;
+ res_T res = RES_OK;
+ ASSERT(cam && args && cam->type == SCAM_PINHOLE);
+
+ if(args->field_of_view <= 0 || args->field_of_view >= PI) {
+ log_err(cam,
+ "pinhole camera: invalid vertical field of view: `%g'\n",
+ args->field_of_view);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(args->aspect_ratio <= 0) {
+ log_err(cam,
+ "pinhole camera: invalid aspect ratio: `%g'\n",
+ args->aspect_ratio);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(d3_normalize(z, d3_sub(z, args->target, args->position)) <= 0
+ || d3_normalize(x, d3_cross(x, z, args->up)) <= 0
+ || d3_normalize(y, d3_cross(y, z, x)) <= 0) {
+ log_err(cam,
+ "pinhole camera: invalid point of view:\n"
+ " position = %g %g %g\n"
+ " target = %g %g %g\n"
+ " up = %g %g %g\n",
+ SPLIT3(args->position), SPLIT3(args->target), SPLIT3(args->up));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ img_plane_depth = 1.0/tan(args->field_of_view*0.5);
+ d3_muld(cam->param.pinhole.axis_x, x, args->aspect_ratio);
+ d3_set(cam->param.pinhole.axis_y, y);
+ d3_muld(cam->param.pinhole.axis_z, z, img_plane_depth);
+ d3_set(cam->param.pinhole.position, args->position);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
+ * Exported function
+ ******************************************************************************/
+SCAM_API res_T
+scam_create_pinhole
+ (struct logger* logger, /* NULL <=> use builtin logger */
+ struct mem_allocator* allocator, /* NULL <=> use default allocator */
+ const int verbose, /* Verbosity level */
+ struct scam_pinhole_args* args,
+ struct scam** out_cam)
+{
+ struct scam* cam = NULL;
+ res_T res = RES_OK;
+
+ if(!out_cam) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = camera_create(logger, allocator, verbose, SCAM_PINHOLE, &cam);
+ if(res != RES_OK) goto error;
+ res = setup_pinhole(cam, args);
+ if(res != RES_OK) goto error;
+
+ exit:
+ if(out_cam) *out_cam = cam;
+ return res;
+error:
+ if(cam) {
+ SCAM(ref_put(cam));
+ cam = NULL;
+ }
+ goto exit;
+}
+