diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 276 | ||||
| -rw-r--r-- | src/cameras/uca-mock-camera.c | 415 | ||||
| -rw-r--r-- | src/cameras/uca-mock-camera.h | 67 | ||||
| -rw-r--r-- | src/cameras/uca-pco-camera.c | 1396 | ||||
| -rw-r--r-- | src/cameras/uca-pco-camera.h | 93 | ||||
| -rw-r--r-- | src/cameras/uca-pf-camera.c | 349 | ||||
| -rw-r--r-- | src/cameras/uca-pf-camera.h | 76 | ||||
| -rw-r--r-- | src/cameras/uca-pylon-camera.c | 391 | ||||
| -rw-r--r-- | src/cameras/uca-pylon-camera.h | 74 | ||||
| -rw-r--r-- | src/cameras/uca-ufo-camera.c | 495 | ||||
| -rw-r--r-- | src/cameras/uca-ufo-camera.h | 78 | ||||
| -rw-r--r-- | src/uca-camera.c | 560 | ||||
| -rw-r--r-- | src/uca-camera.h | 62 | ||||
| -rw-r--r-- | src/uca-docs.xml.in | 4 | ||||
| -rw-r--r-- | src/uca-plugin-manager.c | 345 | ||||
| -rw-r--r-- | src/uca-plugin-manager.h | 65 | ||||
| -rw-r--r-- | src/uca.types.in | 2 | 
17 files changed, 895 insertions, 3853 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 033587e..160c52b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,130 +1,15 @@  cmake_minimum_required(VERSION 2.8) +project(uca C)  # --- Set sources -------------------------------------------------------------  set(uca_SRCS      uca-camera.c +    uca-plugin-manager.c      )  set(uca_HDRS -    uca-camera.h) - -set(cameras) - -# --- Find packages and libraries --------------------------------------------- -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - -# --- Find camera interfaces -find_package(PCO) -find_package(PF) -find_package(IPE) -find_package(Pylon) -find_package(DEXELA) - -# --- Find frame grabber interfaces -find_package(FgLib5) -find_package(ClSerMe4) - -# --- Miscellanous packages -find_package(PkgConfig) -find_program(GLIB2_MKENUMS glib-mkenums REQUIRED) -pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED) -pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) - -set(uca_LIBS -    ${GLIB2_LIBRARIES}  -    ${GOBJECT2_LIBRARIES}) - -# --- Build options ----------------------------------------------------------- -option(HAVE_MOCK_CAMERA "Camera: Dummy" ON) - - -# --- Add sources if camera/framegrabber access sources are available --------- -if (PF_FOUND) -    option(HAVE_PHOTON_FOCUS "Camera: Photon Focus MV2-D1280-640-CL-8" ON) - -    if (HAVE_PHOTON_FOCUS AND CLSERME4_FOUND AND FGLIB5_FOUND) -        list(APPEND uca_SRCS cameras/uca-pf-camera.c) -        list(APPEND uca_HDRS cameras/uca-pf-camera.h) -        list(APPEND cameras "Pf") - -        set(uca_LIBS ${uca_LIBS}  -            ${CLSERME4_LIBRARY}  -            ${FGLIB5_LIBRARY}  -            ${PF_LIBRARIES}) - -        include_directories(${PF_INCLUDE_DIRS} -            ${CLSERME4_INCLUDE_DIR} -            ${FGLIB5_INCLUDE_DIR}) -    endif() -endif() - -if (PCO_FOUND AND CLSERME4_FOUND AND FGLIB5_FOUND) -    option(HAVE_PCO_CL "Camera: CameraLink-based pco" ON) - -    if (HAVE_PCO_CL) -        list(APPEND uca_SRCS cameras/uca-pco-camera.c) -        list(APPEND uca_HDRS cameras/uca-pco-camera.h) -        list(APPEND cameras "Pco") - -        set(uca_LIBS ${uca_LIBS} -            ${PCO_LIBRARIES} -            ${CLSERME4_LIBRARY} -            ${FGLIB5_LIBRARY}) - -        include_directories( -            ${PCO_INCLUDE_DIRS} -            ${CLSERME4_INCLUDE_DIR} -            ${FGLIB5_INCLUDE_DIR}) -    endif() -endif() - -if (IPE_FOUND) -    option(HAVE_UFO_CAMERA "Camera: Custom based on Xilinx FPGA" ON) - -    if (HAVE_UFO_CAMERA) -        list(APPEND uca_SRCS cameras/uca-ufo-camera.c) -        list(APPEND uca_HDRS cameras/uca-ufo-camera.h) -        list(APPEND cameras "Ufo") - -        set(uca_LIBS ${uca_LIBS} ${IPE_LIBRARIES}) - -        include_directories(${IPE_INCLUDE_DIRS}) -    endif() -endif() - -if (PYLON_FOUND) -  option(HAVE_PYLON_CAMERA "Camera: Pylon based (Basler)" ON) - -  if (HAVE_PYLON_CAMERA) -        list(APPEND uca_SRCS cameras/uca-pylon-camera.c) -        list(APPEND uca_HDRS cameras/uca-pylon-camera.h) -        list(APPEND cameras "Pylon") -        set(uca_LIBS ${uca_LIBS} ${LIBPYLONCAM_LIBRARIES}) - -        include_directories(${LIBPYLONCAM_INCLUDEDIR}) -        link_directories(${LIBPYLONCAM_LIBDIR}) -  endif() -endif() - -if (DEXELA_FOUND) -    option(HAVE_DEXELA_CL "Camera: CameraLink-based dexela detector" ON) - -    if (HAVE_DEXELA_CL) -        list(APPEND uca_SRCS cameras/uca-dexela-camera.c) -        list(APPEND uca_HDRS cameras/uca-dexela-camera.h) -        list(APPEND cameras "Ufo") - -        set(uca_LIBS ${uca_LIBS} ${DEXELA_LIBRARIES}) - -        include_directories(${DEXELA_INCLUDE_DIRS}) -    endif() -endif() - -if (HAVE_MOCK_CAMERA) -    list(APPEND uca_SRCS cameras/uca-mock-camera.c) -    list(APPEND uca_HDRS cameras/uca-mock-camera.h) -    list(APPEND cameras "Mock") -endif() +    uca-camera.h +    uca-plugin-manager.h)  # --- Generate enum file  add_custom_command( @@ -132,9 +17,9 @@ add_custom_command(      COMMAND ${GLIB2_MKENUMS}      ARGS          --template uca-enums.h.template -        ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h +        ${UCA_ENUM_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -    DEPENDS ${uca_HDRS}  +    DEPENDS ${UCA_ENUM_HDRS}              ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.h.template)  add_custom_command( @@ -142,39 +27,94 @@ add_custom_command(      COMMAND ${GLIB2_MKENUMS}      ARGS          --template uca-enums.c.template -        ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c +        ${UCA_ENUM_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -    DEPENDS ${uca_HDRS}  +    DEPENDS ${UCA_ENUM_HDRS}              ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h              ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.c.template      ) -# --- Configure step + +# --- Configure --------------------------------------------------------------- + +find_program(INTROSPECTION_SCANNER "g-ir-scanner") +find_program(INTROSPECTION_COMPILER "g-ir-compiler") +  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in -    ${CMAKE_CURRENT_BINARY_DIR}/config.h) +               ${CMAKE_CURRENT_BINARY_DIR}/config.h) + +set(prefix      ${CMAKE_INSTALL_PREFIX}) +if (CI_INSTALL_PREFIX) +    set(prefix  ${CI_INSTALL_PREFIX}) +endif() + +set(exec_prefix "\${prefix}") +set(libdir      ${prefix}/${LIB_INSTALL_DIR}) +set(includedir  "\${prefix}/include") +set(VERSION     ${UCA_VERSION_STRING}) + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uca.pc.in" +               "${CMAKE_CURRENT_BINARY_DIR}/uca.pc" @ONLY IMMEDIATE) -include_directories( -    ${CMAKE_CURRENT_BINARY_DIR} -    ${CMAKE_CURRENT_SOURCE_DIR} -    ${CMAKE_CURRENT_SOURCE_DIR}/cameras -    ${GLIB2_INCLUDE_DIRS} -    ${GOBJECT2_INCLUDE_DIRS})  # --- Build target ------------------------------------------------------------ -add_definitions("-std=c99 -Wall") -add_library(uca SHARED  -    ${uca_SRCS}  +add_library(uca SHARED +    ${uca_SRCS}      ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c)  set_target_properties(uca PROPERTIES        VERSION ${UCA_ABI_VERSION}        SOVERSION ${UCA_VERSION_MAJOR}) -target_link_libraries(uca -    ${uca_LIBS}) +target_link_libraries(uca ${UCA_DEPS}) + + +# --- Build introspection files ----------------------------------------------- + +if (INTROSPECTION_SCANNER AND INTROSPECTION_COMPILER) +    option(WITH_GIR "Build introspection files" ON) + +    if (WITH_GIR) +        set(GIR_PREFIX "Uca-${UCA_ABI_VERSION}") +        set(GIR_XML "${GIR_PREFIX}.gir") +        set(GIR_TYPELIB "${GIR_PREFIX}.typelib") +        set(_gir_input) + +        foreach(_src ${uca_SRCS} ${uca_HDRS}) +            list(APPEND _gir_input "${CMAKE_CURRENT_SOURCE_DIR}/${_src}") +        endforeach() + +        add_custom_command(OUTPUT ${GIR_XML} +            COMMAND ${INTROSPECTION_SCANNER} +                    --namespace=Uca +                    --nsversion=${UCA_ABI_VERSION} +                    --library=uca +                    --no-libtool +                    --include=GObject-2.0 +                    --include=GModule-2.0 +                    --output ${GIR_XML} +                    --warn-all +                    ${_gir_input} +            DEPENDS ${uca_SRCS} +            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +        add_custom_command(OUTPUT ${GIR_TYPELIB} +            COMMAND ${INTROSPECTION_COMPILER} +                    -o ${GIR_TYPELIB} +                    ${GIR_XML} +            DEPENDS ${GIR_XML} +            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +        add_custom_target(gir ALL DEPENDS ${GIR_XML} ${GIR_TYPELIB}) +        add_dependencies(gir uca) + +    endif() +endif() +  # --- Build documentation ----------------------------------------------------- +  pkg_check_modules(GTK_DOC gtk-doc)  if(GTK_DOC_FOUND) @@ -185,11 +125,12 @@ if(GTK_DOC_FOUND)          set(docs_out "${docs_dir}/reference")          file(MAKE_DIRECTORY ${docs_out}) -        set(reference_files  +        set(reference_files              "${docs_out}/index.html"              "${docs_out}/api-index-full.html"              "${docs_out}/ch01.html"              "${docs_out}/UcaCamera.html" +            "${docs_out}/UcaPluginManager.html"              "${docs_out}/style.css"              "${docs_out}/uca.devhelp2"              "${docs_out}/home.png" @@ -197,18 +138,6 @@ if(GTK_DOC_FOUND)              "${docs_out}/right.png"              "${docs_out}/up.png") -        # Put in uca-docs.xml and uca.types all cameras that are built -        set(_xml_doc_input) -        set(_types_input) -        foreach (_cam ${cameras}) -            # add camera to the installed documentation -            list(APPEND reference_files "${docs_out}/Uca${_cam}Camera.html") - -            string(TOLOWER ${_cam} _cam) -            set(_xml_doc_input "${_xml_doc_input}\n<xi:include href=\"xml/uca-${_cam}-camera.xml\"/>") -            set(_types_input "${_types_input}\nuca_${_cam}_camera_get_type") -        endforeach() -          configure_file(${CMAKE_CURRENT_SOURCE_DIR}/uca-docs.xml.in              ${docs_out}/uca-docs.xml) @@ -264,42 +193,36 @@ endif()  # --- Install target ---------------------------------------------------------- -# check for 64 bit -if (CMAKE_SIZEOF_VOID_P EQUAL 8) -  set(LIB_INSTALL_DIR "lib64") -else() -  set(LIB_INSTALL_DIR "lib") -endif()  install(TARGETS uca -    LIBRARY DESTINATION ${LIB_INSTALL_DIR}) +        LIBRARY DESTINATION ${LIB_INSTALL_DIR} +        COMPONENT libraries) -install(FILES ${uca_HDRS}  -    DESTINATION include/uca) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/uca.pc +        DESTINATION lib/pkgconfig +        COMPONENT libraries) -# --- install pkg-config file -set(prefix      ${CMAKE_INSTALL_PREFIX}) -if (CI_INSTALL_PREFIX) -    set(prefix  ${CI_INSTALL_PREFIX}) -endif() +install(FILES ${uca_HDRS} +        DESTINATION include/uca +        COMPONENT headers) -set(exec_prefix "\${prefix}") -set(libdir      ${prefix}/${LIB_INSTALL_DIR}) -set(includedir  "\${prefix}/include") -set(VERSION     ${UCA_VERSION_STRING}) +if(WITH_GIR) +    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_XML} +            DESTINATION share/gir-1.0 +            COMPONENT libraries) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uca.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/uca.pc" @ONLY IMMEDIATE) +    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_TYPELIB} +            DESTINATION ${LIB_INSTALL_DIR}/girepository-1.0 +            COMPONENT libraries) +endif() -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/uca.pc DESTINATION lib/pkgconfig) +# --- Generate package description --------------------------------------------  set(CPACK_PACKAGE_DESCRIPTION "Unified Camera Access library") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Abstract interface for different camera classes and frame grabber devices") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GObject-based library for accessing scientific cameras")  set(CPACK_PACKAGE_NAME "libuca") -# --- Distro specific -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1)") -  # this doesn't work when building RPMs on Jenkins  set(CPACK_SET_DESTDIR ON) @@ -310,13 +233,12 @@ set(CPACK_PACKAGE_VERSION_MINOR ${UCA_VERSION_MINOR})  set(CPACK_PACKAGE_VERSION_PATCH ${UCA_VERSION_PATCH})  set(VERSION ${UCA_VERSION_STRING}) -set(CPACK_GENERATOR "DEB;RPM;") +set(CPACK_GENERATOR "RPM;") +  set(CPACK_SOURCE_GENERATOR "TGZ")  set(CPACK_SOURCE_IGNORE_FILES ".git" "tags" ".bzr" ".swp")  set(CPACK_SOURCE_PACKAGE_FILE_NAME "libuca-${UCA_VERSION_STRING}" CACHE INTERNAL "tarball basename") -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${UCA_VERSION_STRING}-${CPACK_PACKAGE_RELEASE}.${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${UCA_VERSION_STRING}-${CMAKE_SYSTEM_PROCESSOR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../libuca.spec.in" -               "${CMAKE_CURRENT_BINARY_DIR}/../libuca.spec" @ONLY IMMEDIATE)  include(CPack) diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c deleted file mode 100644 index 59c5ae8..0000000 --- a/src/cameras/uca-mock-camera.c +++ /dev/null @@ -1,415 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <string.h> -#include "uca-mock-camera.h" - -#define UCA_MOCK_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraPrivate)) - -G_DEFINE_TYPE(UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA) - -enum { -    PROP_FRAMERATE = N_BASE_PROPERTIES, -    N_PROPERTIES -}; - -static const gint mock_overrideables[] = { -    PROP_NAME, -    PROP_SENSOR_WIDTH, -    PROP_SENSOR_HEIGHT, -    PROP_SENSOR_BITDEPTH, -    PROP_SENSOR_HORIZONTAL_BINNING, -    PROP_SENSOR_HORIZONTAL_BINNINGS, -    PROP_SENSOR_VERTICAL_BINNING, -    PROP_SENSOR_VERTICAL_BINNINGS, -    PROP_TRIGGER_MODE, -    PROP_EXPOSURE_TIME, -    PROP_ROI_X, -    PROP_ROI_Y, -    PROP_ROI_WIDTH, -    PROP_ROI_HEIGHT, -    PROP_ROI_HEIGHT_MULTIPLIER, -    PROP_ROI_WIDTH_MULTIPLIER, -    PROP_SENSOR_MAX_FRAME_RATE, -    PROP_HAS_STREAMING, -    PROP_HAS_CAMRAM_RECORDING, -    0, -}; - -static GParamSpec *mock_properties[N_PROPERTIES] = { NULL, }; - -struct _UcaMockCameraPrivate { -    guint width; -    guint height; -    guint roi_x, roi_y, roi_width, roi_height; -    gfloat frame_rate; -    gfloat max_frame_rate; -    gdouble exposure_time; -    guint8 *dummy_data; -    guint current_frame; - -    gboolean thread_running; - -    GThread *grab_thread; -    GValueArray *binnings; -}; - -static const char g_digits[10][20] = { -    /* 0 */ -    { 0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0xff, 0x00, 0x00, 0xff, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0x00 }, -    /* 1 */ -    { 0x00, 0x00, 0xff, 0x00, -      0x00, 0xff, 0xff, 0x00, -      0x00, 0x00, 0xff, 0x00, -      0x00, 0x00, 0xff, 0x00, -      0x00, 0x00, 0xff, 0x00 }, -    /* 2 */ -    { 0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0x00, 0xff, 0x00, -      0x00, 0xff, 0x00, 0x00, -      0xff, 0xff, 0xff, 0xff }, -    /* 3 */ -    { 0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0x00, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0x00 }, -    /* 4 */ -    { 0xff, 0x00, 0x00, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0xff, 0xff, 0xff, 0xff, -      0x00, 0x00, 0x00, 0xff, -      0x00, 0x00, 0x00, 0xff }, -    /* 5 */ -    { 0xff, 0xff, 0xff, 0xff, -      0xff, 0x00, 0x00, 0x00, -      0x00, 0xff, 0xff, 0x00, -      0x00, 0x00, 0x00, 0xff, -      0xff, 0xff, 0xff, 0x00 }, -    /* 6 */ -    { 0x00, 0xff, 0xff, 0xff, -      0xff, 0x00, 0x00, 0x00, -      0xff, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0x00 }, -    /* 7 */ -    { 0xff, 0xff, 0xff, 0xff, -      0x00, 0x00, 0x00, 0xff, -      0x00, 0x00, 0xff, 0x00, -      0x00, 0xff, 0x00, 0x00, -      0xff, 0x00, 0x00, 0x00 }, -    /* 8 */ -    { 0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0x00 }, -    /* 9 */ -    { 0x00, 0xff, 0xff, 0x00, -      0xff, 0x00, 0x00, 0xff, -      0x00, 0xff, 0xff, 0xff, -      0x00, 0x00, 0x00, 0xff, -      0xff, 0xff, 0xff, 0x00 } -}; - -static const guint DIGIT_WIDTH = 4; -static const guint DIGIT_HEIGHT = 5; - -static void print_number(gchar *buffer, guint number, guint x, guint y, guint width) -{ -    for (int i = 0; i < DIGIT_WIDTH; i++) { -        for (int j = 0; j < DIGIT_HEIGHT; j++) { -            buffer[(y+j)*width + (x+i)] = g_digits[number][j*DIGIT_WIDTH+i]; -        } -    } -} - -static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer) -{ -    guint number = priv->current_frame; -    guint divisor = 100000000; -    int x = 10; -    while (divisor > 1) { -        print_number(buffer, number / divisor, x, 10, priv->width); -        number = number % divisor; -        divisor = divisor / 10; -        x += DIGIT_WIDTH + 1; -    } -} - -/** - * uca_mock_camera_new: - * @error: Location for error - * - * Create a new #UcaMockCamera object. - * - * Returns: A newly created #UcaMockCamera object - */ -UcaMockCamera *uca_mock_camera_new(GError **error) -{ -    UcaMockCamera *camera = g_object_new(UCA_TYPE_MOCK_CAMERA, NULL); -    return camera; -} - -static gpointer mock_grab_func(gpointer data) -{ -    UcaMockCamera *mock_camera = UCA_MOCK_CAMERA(data); -    g_return_val_if_fail(UCA_IS_MOCK_CAMERA(mock_camera), NULL); - -    UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(mock_camera); -    UcaCamera *camera = UCA_CAMERA(mock_camera); -    const gulong sleep_time = (gulong) G_USEC_PER_SEC / priv->frame_rate; - -    while (priv->thread_running) { -        camera->grab_func(priv->dummy_data, camera->user_data); -        g_usleep(sleep_time); -    } - -    return NULL; -} - -static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error) -{ -    gboolean transfer_async = FALSE; -    UcaMockCameraPrivate *priv; -    g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); - -    priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera); -    /* TODO: check that roi_x + roi_width < priv->width */ -    priv->dummy_data = (guint8 *) g_malloc0(priv->roi_width * priv->roi_height); - -    g_object_get(G_OBJECT(camera), -            "transfer-asynchronously", &transfer_async, -            NULL); - -    /* -     * In case asynchronous transfer is requested, we start a new thread that -     * invokes the grab callback, otherwise nothing will be done here. -     */ -    if (transfer_async) { -        GError *tmp_error = NULL; -        priv->thread_running = TRUE; -        priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error);  - -        if (tmp_error != NULL) { -            priv->thread_running = FALSE; -            g_propagate_error(error, tmp_error); -        } -    } -} - -static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error) -{ -    gboolean transfer_async = FALSE; -    UcaMockCameraPrivate *priv; -    g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); - -    priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera); -    g_free(priv->dummy_data); -    priv->dummy_data = NULL; - -    g_object_get(G_OBJECT(camera), -            "transfer-asynchronously", &transfer_async, -            NULL); - -    if (transfer_async) { -        priv->thread_running = FALSE;     -        g_thread_join(priv->grab_thread); -    } -} - -static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **error) -{ -    g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); -    g_return_if_fail(data != NULL); - -    UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera); - -    if (*data == NULL) -        *data = g_malloc0(priv->width * priv->height); - -    g_memmove(*data, priv->dummy_data, priv->width * priv->height); -    print_current_frame(priv, *data); -    priv->current_frame++; -} - -static void uca_mock_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ -    g_return_if_fail(UCA_IS_MOCK_CAMERA(object)); -    UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_EXPOSURE_TIME: -            priv->exposure_time = g_value_get_double(value); -            break; -        case PROP_FRAMERATE: -            priv->frame_rate = g_value_get_float(value); -            break; -        case PROP_ROI_X: -            priv->roi_x = g_value_get_uint(value); -            break; -        case PROP_ROI_Y: -            priv->roi_y = g_value_get_uint(value); -            break; -        case PROP_ROI_WIDTH: -            priv->roi_width = g_value_get_uint(value); -            break; -        case PROP_ROI_HEIGHT: -            priv->roi_height = g_value_get_uint(value); -            break; -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            return; -    } -} - -static void uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ -    UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_NAME: -            g_value_set_string(value, "mock camera"); -            break; -        case PROP_SENSOR_WIDTH: -            g_value_set_uint(value, priv->width); -            break; -        case PROP_SENSOR_HEIGHT: -            g_value_set_uint(value, priv->height); -            break; -        case PROP_SENSOR_BITDEPTH: -            g_value_set_uint(value, 8); -            break; -        case PROP_SENSOR_HORIZONTAL_BINNING: -            g_value_set_uint(value, 1); -            break; -        case PROP_SENSOR_HORIZONTAL_BINNINGS: -            g_value_set_boxed(value, priv->binnings); -            break; -        case PROP_SENSOR_VERTICAL_BINNING: -            g_value_set_uint(value, 1); -            break; -        case PROP_SENSOR_VERTICAL_BINNINGS: -            g_value_set_boxed(value, priv->binnings); -            break; -        case PROP_EXPOSURE_TIME: -            g_value_set_double(value, priv->exposure_time); -            break; -        case PROP_TRIGGER_MODE: -            g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO); -            break; -        case PROP_ROI_X: -            g_value_set_uint(value, priv->roi_x); -            break; -        case PROP_ROI_Y: -            g_value_set_uint(value, priv->roi_y); -            break; -        case PROP_ROI_WIDTH: -            g_value_set_uint(value, priv->roi_width); -            break; -        case PROP_ROI_HEIGHT: -            g_value_set_uint(value, priv->roi_height); -            break; -        case PROP_ROI_WIDTH_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_ROI_HEIGHT_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_SENSOR_MAX_FRAME_RATE: -            g_value_set_float(value, priv->max_frame_rate); -            break; -        case PROP_HAS_STREAMING: -            g_value_set_boolean(value, TRUE); -            break; -        case PROP_HAS_CAMRAM_RECORDING: -            g_value_set_boolean(value, FALSE); -            break; -        case PROP_FRAMERATE: -            g_value_set_float(value, priv->frame_rate); -            break; -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            break; -    } -} - -static void uca_mock_camera_finalize(GObject *object) -{ -    UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object); - -    if (priv->thread_running) { -        priv->thread_running = FALSE;     -        g_thread_join(priv->grab_thread); -    } - -    g_free(priv->dummy_data); -    g_value_array_free(priv->binnings); - -    G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object); -} - -static void uca_mock_camera_class_init(UcaMockCameraClass *klass) -{ -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -    gobject_class->set_property = uca_mock_camera_set_property; -    gobject_class->get_property = uca_mock_camera_get_property; -    gobject_class->finalize = uca_mock_camera_finalize; - -    UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); -    camera_class->start_recording = uca_mock_camera_start_recording; -    camera_class->stop_recording = uca_mock_camera_stop_recording; -    camera_class->grab = uca_mock_camera_grab; - -    for (guint i = 0; mock_overrideables[i] != 0; i++) -        g_object_class_override_property(gobject_class, mock_overrideables[i], uca_camera_props[mock_overrideables[i]]); - -    mock_properties[PROP_FRAMERATE] =  -        g_param_spec_float("frame-rate", -                "Frame rate", -                "Number of frames per second that are taken", -                1.0f, 100.0f, 100.0f, -                G_PARAM_READWRITE); - -    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++) -        g_object_class_install_property(gobject_class, id, mock_properties[id]); - -    g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate)); -} - -static void uca_mock_camera_init(UcaMockCamera *self) -{ -    self->priv = UCA_MOCK_CAMERA_GET_PRIVATE(self); -    self->priv->roi_x = 0; -    self->priv->roi_y = 0; -    self->priv->width = self->priv->roi_width = 640; -    self->priv->height = self->priv->roi_height = 480; -    self->priv->frame_rate = self->priv->max_frame_rate = 100000.0f; -    self->priv->grab_thread = NULL; -    self->priv->current_frame = 0; - -    self->priv->binnings = g_value_array_new(1); -    GValue val = {0}; -    g_value_init(&val, G_TYPE_UINT); -    g_value_set_uint(&val, 1); -    g_value_array_append(self->priv->binnings, &val); -} diff --git a/src/cameras/uca-mock-camera.h b/src/cameras/uca-mock-camera.h deleted file mode 100644 index 92030f8..0000000 --- a/src/cameras/uca-mock-camera.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#ifndef __UCA_MOCK_CAMERA_H -#define __UCA_MOCK_CAMERA_H - -#include <glib-object.h> -#include "uca-camera.h" - -G_BEGIN_DECLS - -#define UCA_TYPE_MOCK_CAMERA             (uca_mock_camera_get_type()) -#define UCA_MOCK_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCamera)) -#define UCA_IS_MOCK_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_MOCK_CAMERA)) -#define UCA_MOCK_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_MOCK_CAMERA, UfoMockCameraClass)) -#define UCA_IS_MOCK_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_MOCK_CAMERA)) -#define UCA_MOCK_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraClass)) - -typedef struct _UcaMockCamera           UcaMockCamera; -typedef struct _UcaMockCameraClass      UcaMockCameraClass; -typedef struct _UcaMockCameraPrivate    UcaMockCameraPrivate; - -/** - * UcaMockCamera: - * - * Creates #UcaMockCamera instances by loading corresponding shared objects. The - * contents of the #UcaMockCamera structure are private and should only be - * accessed via the provided API. - */ -struct _UcaMockCamera { -    /*< private >*/ -    UcaCamera parent; - -    UcaMockCameraPrivate *priv; -}; - -/** - * UcaMockCameraClass: - * - * #UcaMockCamera class - */ -struct _UcaMockCameraClass { -    /*< private >*/ -    UcaCameraClass parent; -}; - -UcaMockCamera *uca_mock_camera_new(GError **error); - -GType uca_mock_camera_get_type(void); - -G_END_DECLS - -#endif diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c deleted file mode 100644 index a56392f..0000000 --- a/src/cameras/uca-pco-camera.c +++ /dev/null @@ -1,1396 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <libpco/libpco.h> -#include <libpco/sc2_defs.h> -#include <fgrab_prototyp.h> -#include "uca-camera.h" -#include "uca-pco-camera.h" -#include "uca-enums.h" - -#define FG_TRY_PARAM(fg, camobj, param, val_addr, port)     \ -    { int r = Fg_setParameter(fg, param, val_addr, port);   \ -        if (r != FG_OK) {                                   \ -            g_set_error(error, UCA_PCO_CAMERA_ERROR,        \ -                    UCA_PCO_CAMERA_ERROR_FG_GENERAL,        \ -                    "%s", Fg_getLastErrorDescription(fg));  \ -            g_object_unref(camobj);                         \ -            return NULL;                                    \ -        } } - -#define FG_SET_ERROR(err, fg, err_type)                 \ -    if (err != FG_OK) {                                 \ -        g_set_error(error, UCA_PCO_CAMERA_ERROR,        \ -                err_type,                               \ -                "%s", Fg_getLastErrorDescription(fg));  \ -        return;                                         \ -    } - -#define HANDLE_PCO_ERROR(err)                       \ -    if ((err) != PCO_NOERROR) {                     \ -        g_set_error(error, UCA_PCO_CAMERA_ERROR,    \ -                UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL,\ -                "libpco error %x", err);            \ -        return;                                     \ -    } -     -#define UCA_PCO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraPrivate)) - -G_DEFINE_TYPE(UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA) - -#define TIMEBASE_INVALID 0xDEAD - -/** - * UcaPcoCameraRecordMode: - * @UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE: Store all frames and stop if necessary - * @UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER: Store frames in ring-buffer fashion - *      and overwrite if necessary - */ - -/** - * UcaPcoCameraAcquireMode: - * @UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO: Take all images - * @UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL: Use <acq enbl> signal - */ - -/** - * UcaPcoCameraTimestamp: - * @UCA_PCO_CAMERA_TIMESTAMP_NONE: Don't embed any timestamp - * @UCA_PCO_CAMERA_TIMESTAMP_BINARY: Embed a BCD-coded timestamp in the first - *     bytes - * @UCA_PCO_CAMERA_TIMESTAMP_ASCII: Embed a visible ASCII timestamp in the image - */ - -/** - * UcaPcoCameraError: - * @UCA_PCO_CAMERA_ERROR_LIBPCO_INIT: Initializing libpco failed - * @UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL: General libpco error - * @UCA_PCO_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported - * @UCA_PCO_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed - * @UCA_PCO_CAMERA_ERROR_FG_GENERAL: General framegrabber error - * @UCA_PCO_CAMERA_ERROR_FG_ACQUISITION: Framegrabber acquisition error - */ -GQuark uca_pco_camera_error_quark() -{ -    return g_quark_from_static_string("uca-pco-camera-error-quark"); -} - -enum { -    PROP_SENSOR_EXTENDED = N_BASE_PROPERTIES, -    PROP_SENSOR_WIDTH_EXTENDED, -    PROP_SENSOR_HEIGHT_EXTENDED, -    PROP_SENSOR_TEMPERATURE, -    PROP_SENSOR_PIXELRATES, -    PROP_SENSOR_PIXELRATE, -    PROP_SENSOR_ADCS, -    PROP_SENSOR_MAX_ADCS, -    PROP_DELAY_TIME, -    PROP_HAS_DOUBLE_IMAGE_MODE, -    PROP_DOUBLE_IMAGE_MODE, -    PROP_OFFSET_MODE, -    PROP_RECORD_MODE, -    PROP_ACQUIRE_MODE, -    PROP_COOLING_POINT, -    PROP_COOLING_POINT_MIN, -    PROP_COOLING_POINT_MAX, -    PROP_COOLING_POINT_DEFAULT, -    PROP_NOISE_FILTER, -    PROP_TIMESTAMP_MODE, -    N_PROPERTIES -}; - -static gint base_overrideables[] = { -    PROP_NAME, -    PROP_SENSOR_WIDTH, -    PROP_SENSOR_HEIGHT, -    PROP_SENSOR_BITDEPTH, -    PROP_SENSOR_HORIZONTAL_BINNING, -    PROP_SENSOR_HORIZONTAL_BINNINGS, -    PROP_SENSOR_VERTICAL_BINNING, -    PROP_SENSOR_VERTICAL_BINNINGS, -    PROP_SENSOR_MAX_FRAME_RATE, -    PROP_EXPOSURE_TIME, -    PROP_TRIGGER_MODE, -    PROP_ROI_X, -    PROP_ROI_Y, -    PROP_ROI_WIDTH, -    PROP_ROI_HEIGHT, -    PROP_ROI_WIDTH_MULTIPLIER, -    PROP_ROI_HEIGHT_MULTIPLIER, -    PROP_HAS_STREAMING, -    PROP_HAS_CAMRAM_RECORDING, -    0 -}; - -static GParamSpec *pco_properties[N_PROPERTIES] = { NULL, }; - -/* - * This structure defines type-specific properties of PCO cameras. - */ -typedef struct { -    int camera_type; -    const char *so_file; -    int cl_type; -    int cl_format; -    gfloat max_frame_rate; -    gboolean has_camram; -} pco_cl_map_entry; - -struct _UcaPcoCameraPrivate { -    pco_handle pco; -    pco_cl_map_entry *camera_description; - -    Fg_Struct *fg; -    guint fg_port; -    dma_mem *fg_mem; - -    guint frame_width; -    guint frame_height; -    gsize num_bytes; -    guint16 *grab_buffer; - -    guint16 width, height; -    guint16 width_ex, height_ex; -    guint16 binning_h, binning_v; -    guint16 roi_x, roi_y; -    guint16 roi_width, roi_height; -    guint16 roi_horizontal_steps, roi_vertical_steps; -    GValueArray *horizontal_binnings; -    GValueArray *vertical_binnings; -    GValueArray *pixelrates; - -    /* The time bases are given as pco time bases (TIMEBASE_NS and so on) */ -    guint16 delay_timebase; -    guint16 exposure_timebase; - -    frameindex_t last_frame; -    guint16 active_segment; -    guint num_recorded_images; -    guint current_image; -}; - -static pco_cl_map_entry pco_cl_map[] = {  -    { CAMERATYPE_PCO_EDGE,       "libFullAreaGray8.so",  FG_CL_8BIT_FULL_10,        FG_GRAY,     30.0f, FALSE }, -    { CAMERATYPE_PCO4000,        "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT,    FG_GRAY16,    5.0f, TRUE  }, -    { CAMERATYPE_PCO_DIMAX_STD,  "libFullAreaGray16.so", FG_CL_SINGLETAP_8_BIT,     FG_GRAY16, 1279.0f, TRUE  }, -    { 0, NULL, 0, 0, 0.0f, FALSE } -}; - -static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type) -{ -    pco_cl_map_entry *entry = pco_cl_map; - -    while (entry->camera_type != 0) { -        if (entry->camera_type == camera_type) -            return entry; -        entry++;  -    } - -    return NULL; -} - -static guint fill_binnings(UcaPcoCameraPrivate *priv) -{ -    uint16_t *horizontal = NULL; -    uint16_t *vertical = NULL; -    guint num_horizontal, num_vertical; - -    guint err = pco_get_possible_binnings(priv->pco,  -            &horizontal, &num_horizontal,  -            &vertical, &num_vertical); - -    GValue val = {0}; -    g_value_init(&val, G_TYPE_UINT); - -    if (err == PCO_NOERROR) { -        priv->horizontal_binnings = g_value_array_new(num_horizontal); -        priv->vertical_binnings = g_value_array_new(num_vertical); - -        for (guint i = 0; i < num_horizontal; i++) { -            g_value_set_uint(&val, horizontal[i]); -            g_value_array_append(priv->horizontal_binnings, &val); -        } - -        for (guint i = 0; i < num_vertical; i++) { -            g_value_set_uint(&val, vertical[i]); -            g_value_array_append(priv->vertical_binnings, &val); -        } -    } - -    free(horizontal); -    free(vertical); -    return err; -} - -static void fill_pixelrates(UcaPcoCameraPrivate *priv, guint32 rates[4], gint num_rates) -{ -    GValue val = {0}; -    g_value_init(&val, G_TYPE_UINT); -    priv->pixelrates = g_value_array_new(num_rates); - -    for (gint i = 0; i < num_rates; i++) { -        g_value_set_uint(&val, (guint) rates[i]);  -        g_value_array_append(priv->pixelrates, &val); -    } -} - -static guint override_temperature_range(UcaPcoCameraPrivate *priv) -{ -    int16_t default_temp, min_temp, max_temp; -    guint err = pco_get_cooling_range(priv->pco, &default_temp, &min_temp, &max_temp); - -    if (err == PCO_NOERROR) { -        GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT]; -        spec->minimum = min_temp; -        spec->maximum = max_temp; -        spec->default_value = default_temp; -    } -    else -        g_warning("Unable to retrieve cooling range"); - -    return err; -} - -static void property_override_default_guint_value (GObjectClass *oclass, const gchar *property_name, guint new_default) -{ -    GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (g_object_class_find_property (oclass, property_name)); - -    if (pspec != NULL) -        pspec->default_value = new_default; -    else -        g_warning ("pspec for %s not found\n", property_name); -} - -static void override_maximum_adcs(UcaPcoCameraPrivate *priv) -{ -    GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_SENSOR_ADCS]; -    spec->maximum = pco_get_maximum_number_of_adcs(priv->pco); -} - -static gdouble convert_timebase(guint16 timebase) -{ -    switch (timebase) { -        case TIMEBASE_NS: -            return 1e-9; -        case TIMEBASE_US: -            return 1e-6; -        case TIMEBASE_MS: -            return 1e-3; -        default: -            g_warning("Unknown timebase"); -    } -    return 1e-3; -} - -static void read_timebase(UcaPcoCameraPrivate *priv) -{ -    pco_get_timebase(priv->pco, &priv->delay_timebase, &priv->exposure_timebase); -} - -static gdouble get_suitable_timebase(gdouble time) -{ -    if (time * 1e3 >= 1.0) -        return TIMEBASE_MS; -    if (time * 1e6 >= 1.0) -        return TIMEBASE_US; -    if (time * 1e9 >= 1.0) -        return TIMEBASE_NS; -    return TIMEBASE_INVALID; -} - -UcaPcoCamera *uca_pco_camera_new(GError **error) -{ -    pco_handle pco = pco_init(); - -    if (pco == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, -                "Initializing libpco failed"); -        return NULL; -    } - -    UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    priv->pco = pco; - -    pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); -    pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); -    pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); -    pco_set_auto_transfer(pco, 1); - -    guint16 roi[4]; -    pco_get_roi(priv->pco, roi); -    pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps); - -    priv->roi_x = roi[0] - 1; -    priv->roi_y = roi[1] - 1; -    priv->roi_width = roi[2] - roi[0] + 1; -    priv->roi_height = roi[3] - roi[1] + 1; - -    guint16 camera_type, camera_subtype; -    pco_get_camera_type(priv->pco, &camera_type, &camera_subtype); -    pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type); -    priv->camera_description = map_entry; - -    if (map_entry == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, -                "Camera type is not supported"); -        g_object_unref(camera); -        return NULL; -    } - -    priv->fg_port = PORT_A; -    priv->fg = Fg_Init(map_entry->so_file, priv->fg_port); - -    if (priv->fg == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT, -                "%s", Fg_getLastErrorDescription(priv->fg)); -        g_object_unref(camera); -        return NULL; -    } - -    const guint32 fg_height = priv->height; -    const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; - -    FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port); - -    int val = FREE_RUN; -    FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port); - -    fill_binnings(priv); - -    /* -     * Here we override property ranges because we didn't know them at property -     * installation time. -     */ -    GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera)); -    property_override_default_guint_value (camera_class, "roi-width", priv->width); -    property_override_default_guint_value (camera_class, "roi-height", priv->height); - -    guint32 rates[4] = {0}; -    gint num_rates = 0; - -    if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) { -        GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera)); - -        fill_pixelrates(priv, rates, num_rates); -        property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]); -    } - -    override_temperature_range (priv); -    override_maximum_adcs (priv); - -    return camera; -} - -static int fg_callback(frameindex_t frame, struct fg_apc_data *apc) -{ -    UcaCamera *camera = UCA_CAMERA(apc); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    gpointer data = Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem); - -    if (priv->camera_description->camera_type != CAMERATYPE_PCO_EDGE) -        camera->grab_func(data, camera->user_data); -    else { -        pco_get_reorder_func(priv->pco)(priv->grab_buffer, data, priv->frame_width, priv->frame_height); -        camera->grab_func(priv->grab_buffer, camera->user_data); -    } - -    return 0; -} - -static gboolean setup_fg_callback(UcaCamera *camera) -{ -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    struct FgApcControl ctrl; - -    /* Jeez, as if a NULL pointer would not be good enough. */ -    ctrl.data = (struct fg_apc_data *) camera; -    ctrl.version = 0; -    ctrl.func = &fg_callback; -    ctrl.flags = FG_APC_DEFAULTS; -    ctrl.timeout = 1; - -    if (priv->grab_buffer) -        g_free(priv->grab_buffer); - -    priv->grab_buffer = g_malloc0(priv->frame_width * priv->frame_height * sizeof(guint16)); - -    return Fg_registerApcHandler(priv->fg, priv->fg_port, &ctrl, FG_APC_CONTROL_BASIC) == FG_OK; -} - -static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); -    guint err = PCO_NOERROR; - -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    guint16 binned_width, binned_height; -    gboolean use_extended = FALSE; -    gboolean transfer_async = FALSE; - -    g_object_get (camera, "sensor-extended", &use_extended, NULL); - -    if (use_extended) { -        binned_width = priv->width_ex; -        binned_height = priv->height_ex; -    } -    else { -        binned_width = priv->width; -        binned_height = priv->height; -    } - -    binned_width /= priv->binning_h; -    binned_height /= priv->binning_v; - -    if ((priv->roi_x + priv->roi_width > binned_width) || (priv->roi_y + priv->roi_height > binned_height)) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, -                "ROI of size %ix%i @ (%i, %i) is outside of (binned) sensor size %ix%i\n", -                priv->roi_width, priv->roi_height, priv->roi_x, priv->roi_y, binned_width, binned_height); -        return; -    } - -    /* -     * All parameters are valid. Now, set them on the camera. -     */ -    guint16 roi[4] = { priv->roi_x + 1, priv->roi_y + 1, priv->roi_x + priv->roi_width, priv->roi_y + priv->roi_height }; - -    if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, -                "Could not set ROI via pco_set_roi()"); -        return; -    } - -    g_object_get(G_OBJECT(camera), "transfer-asynchronously", &transfer_async, NULL); - -    /* -     * FIXME: We cannot set the binning here as this breaks communication with -     * the camera. Setting the binning works _before_ initializing the frame -     * grabber though. However, it is rather inconvenient to initialize and -     * de-initialize the frame grabber for each recording sequence. -     */ - -    /* if (pco_set_binning(priv->pco, priv->binning_h, priv->binning_v) != PCO_NOERROR) */ -    /*     g_warning("Cannot set binning\n"); */ - -    if (priv->frame_width != priv->roi_width || priv->frame_height != priv->roi_height || priv->fg_mem == NULL) { -        guint fg_width = priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE ? 2 * priv->roi_width : priv->roi_width; - -        priv->frame_width = priv->roi_width; -        priv->frame_height = priv->roi_height; -        priv->num_bytes = 2; - -        Fg_setParameter(priv->fg, FG_WIDTH, &fg_width, priv->fg_port); -        Fg_setParameter(priv->fg, FG_HEIGHT, &priv->frame_height, priv->fg_port); - -        if (priv->fg_mem) -            Fg_FreeMemEx(priv->fg, priv->fg_mem); - -        const guint num_buffers = 2; -        priv->fg_mem = Fg_AllocMemEx(priv->fg,  -                num_buffers * priv->frame_width * priv->frame_height * sizeof(uint16_t), num_buffers); - -        if (priv->fg_mem == NULL) { -            g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT, -                    "%s", Fg_getLastErrorDescription(priv->fg)); -            g_object_unref(camera); -            return; -        } -    } - -    if (transfer_async) -        setup_fg_callback(camera); - -    if ((priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) || -        (priv->camera_description->camera_type == CAMERATYPE_PCO4000)) -        pco_clear_active_segment(priv->pco); - -    priv->last_frame = 0; - -    err = pco_arm_camera(priv->pco); -    HANDLE_PCO_ERROR(err); - -    err = pco_start_recording(priv->pco); -    HANDLE_PCO_ERROR(err); - -    err = Fg_AcquireEx(priv->fg, priv->fg_port, GRAB_INFINITE, ACQ_STANDARD, priv->fg_mem); -    FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_ACQUISITION); -} - -static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - -    guint err = pco_stop_recording(priv->pco); -    HANDLE_PCO_ERROR(err); - -    err = Fg_stopAcquireEx(priv->fg, priv->fg_port, priv->fg_mem, STOP_SYNC); -    FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_ACQUISITION); - -    err = Fg_setStatusEx(priv->fg, FG_UNBLOCK_ALL, 0, priv->fg_port, priv->fg_mem); -    if (err == FG_INVALID_PARAMETER) -        g_warning(" Unable to unblock all\n"); -} - -static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - -    /*  -     * TODO: Check if readout mode is possible. This is not the case for the -     * edge.  -     */ - -    guint err = pco_get_active_segment(priv->pco, &priv->active_segment); -    HANDLE_PCO_ERROR(err); - -    err = pco_get_num_images(priv->pco, priv->active_segment, &priv->num_recorded_images); -    HANDLE_PCO_ERROR(err); - -    priv->current_image = 1; -} - -static void uca_pco_camera_trigger(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - -    /* TODO: Check if we can trigger */ -    guint32 success = 0; -    pco_force_trigger(priv->pco, &success); - -    if (!success) -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, -                "Could not trigger frame acquisition");  -} - -static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error) -{ -    static const gint MAX_TIMEOUT = G_MAXINT; - -    g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - -    gboolean is_readout = FALSE; -    g_object_get(G_OBJECT(camera), "is-readout", &is_readout, NULL); - -    if (is_readout) { -        if (priv->current_image == priv->num_recorded_images) { -            *data = NULL; -            return; -        } - -        /* -         * No joke, the pco firmware allows to read a range of images but -         * implements only reading single images ... -         */ -        pco_read_images(priv->pco, priv->active_segment, priv->current_image, priv->current_image); -        priv->current_image++; -    } - -    pco_request_image(priv->pco); -    priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, MAX_TIMEOUT, priv->fg_mem); -     -    if (priv->last_frame <= 0) { -        guint err = FG_OK + 1; -        FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_GENERAL); -    } - -    guint16 *frame = Fg_getImagePtrEx(priv->fg, priv->last_frame, priv->fg_port, priv->fg_mem); - -    if (*data == NULL) -        *data = g_malloc0(priv->frame_width * priv->frame_height * priv->num_bytes);  - -    if (priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE) -        pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height); -    else -        memcpy((gchar *) *data, (gchar *) frame, priv->frame_width * priv->frame_height * priv->num_bytes); -} - -static void uca_pco_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_SENSOR_EXTENDED: -            { -                guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD;  -                pco_set_sensor_format(priv->pco, format); -            } -            break; - -        case PROP_ROI_X: -            priv->roi_x = g_value_get_uint(value); -            break; - -        case PROP_ROI_Y: -            priv->roi_y = g_value_get_uint(value); -            break; - -        case PROP_ROI_WIDTH: -            { -                guint width = g_value_get_uint(value); -                 -                if (width % priv->roi_horizontal_steps) -                    g_warning("ROI width %i is not a multiple of %i", width, priv->roi_horizontal_steps); -                else -                    priv->roi_width = width; -            } -            break; - -        case PROP_ROI_HEIGHT: -            { -                guint height = g_value_get_uint(value); -                 -                if (height % priv->roi_vertical_steps) -                    g_warning("ROI height %i is not a multiple of %i", height, priv->roi_vertical_steps); -                else -                    priv->roi_height = height; -            } -            break; - -        case PROP_SENSOR_HORIZONTAL_BINNING: -            priv->binning_h = g_value_get_uint(value); -            break; - -        case PROP_SENSOR_VERTICAL_BINNING: -            priv->binning_v = g_value_get_uint(value); -            break; - -        case PROP_EXPOSURE_TIME: -            { -                const gdouble time = g_value_get_double(value); -                  -                if (priv->exposure_timebase == TIMEBASE_INVALID) -                    read_timebase(priv); - -                /* -                 * Lets check if we can express the time in the current time -                 * base. If not, we need to adjust that. -                 */ -                guint16 suitable_timebase = get_suitable_timebase(time); - -                if (suitable_timebase == TIMEBASE_INVALID) { -                    g_warning("Cannot set such a small exposure time");  -                } -                else { -                    if (suitable_timebase != priv->exposure_timebase) { -                        priv->exposure_timebase = suitable_timebase; -                        if (pco_set_timebase(priv->pco, priv->delay_timebase, suitable_timebase) != PCO_NOERROR) -                            g_warning("Cannot set exposure time base"); -                    } - -                    gdouble timebase = convert_timebase(suitable_timebase); -                    guint32 timesteps = time / timebase; -                    if (pco_set_exposure_time(priv->pco, timesteps) != PCO_NOERROR) -                        g_warning("Cannot set exposure time"); -                } -            } -            break; - -        case PROP_DELAY_TIME: -            { -                const gdouble time = g_value_get_double(value); -                  -                if (priv->delay_timebase == TIMEBASE_INVALID) -                    read_timebase(priv); - -                /* -                 * Lets check if we can express the time in the current time -                 * base. If not, we need to adjust that. -                 */ -                guint16 suitable_timebase = get_suitable_timebase(time); - -                if (suitable_timebase == TIMEBASE_INVALID) { -                    if (time == 0.0) { -                        /* -                         * If we want to suppress any pre-exposure delays, we -                         * can set the 0 seconds in whatever time base that is -                         * currently active. -                         */ -                        if (pco_set_delay_time(priv->pco, 0) != PCO_NOERROR) -                            g_warning("Cannot set zero delay time"); -                    } -                    else -                        g_warning("Cannot set such a small exposure time");  -                } -                else { -                    if (suitable_timebase != priv->delay_timebase) { -                        priv->delay_timebase = suitable_timebase; -                        if (pco_set_timebase(priv->pco, suitable_timebase, priv->exposure_timebase) != PCO_NOERROR) -                            g_warning("Cannot set delay time base"); -                    } - -                    gdouble timebase = convert_timebase(suitable_timebase); -                    guint32 timesteps = time / timebase; -                    if (pco_set_delay_time(priv->pco, timesteps) != PCO_NOERROR) -                        g_warning("Cannot set delay time"); -                } -            } -            break; - -        case PROP_SENSOR_ADCS: -            { -                const guint num_adcs = g_value_get_uint(value);  -                if (pco_set_adc_mode(priv->pco, num_adcs) != PCO_NOERROR) -                    g_warning("Cannot set the number of ADCs per pixel\n"); -            } -            break; - -        case PROP_SENSOR_PIXELRATE: -            { -                guint desired_pixel_rate = g_value_get_uint(value); -                guint32 pixel_rate = 0; - -                for (guint i = 0; i < priv->pixelrates->n_values; i++) { -                    if (g_value_get_uint(g_value_array_get_nth(priv->pixelrates, i)) == desired_pixel_rate) { -                        pixel_rate = desired_pixel_rate;     -                        break; -                    } -                } - -                if (pixel_rate != 0) { -                    if (pco_set_pixelrate(priv->pco, pixel_rate) != PCO_NOERROR) -                        g_warning("Cannot set pixel rate"); -                } -                else -                    g_warning("%i Hz is not possible. Please check the \"sensor-pixelrates\" property", desired_pixel_rate); -            } -            break; - -        case PROP_DOUBLE_IMAGE_MODE: -            if (!pco_is_double_image_mode_available(priv->pco)) -                g_warning("Double image mode is not available on this pco model"); -            else -                pco_set_double_image_mode(priv->pco, g_value_get_boolean(value)); -            break; - -        case PROP_OFFSET_MODE: -            pco_set_offset_mode(priv->pco, g_value_get_boolean(value)); -            break; - -        case PROP_COOLING_POINT: -            { -                int16_t temperature = (int16_t) g_value_get_int(value);  -                pco_set_cooling_temperature(priv->pco, temperature); -            } -            break; - -        case PROP_RECORD_MODE: -            { -                /* TODO: setting this is not possible for the edge */ -                UcaPcoCameraRecordMode mode = (UcaPcoCameraRecordMode) g_value_get_enum(value); - -                if (mode == UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE) -                    pco_set_record_mode(priv->pco, RECORDER_SUBMODE_SEQUENCE); -                else if (mode == UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER) -                    pco_set_record_mode(priv->pco, RECORDER_SUBMODE_RINGBUFFER); -                else -                    g_warning("Unknown record mode"); -            } -            break; - -        case PROP_ACQUIRE_MODE: -            { -                UcaPcoCameraAcquireMode mode = (UcaPcoCameraAcquireMode) g_value_get_enum(value); -                unsigned int err = PCO_NOERROR; - -                if (mode == UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO) -                    err = pco_set_acquire_mode(priv->pco, ACQUIRE_MODE_AUTO); -                else if (mode == UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL) -                    err = pco_set_acquire_mode(priv->pco, ACQUIRE_MODE_EXTERNAL); -                else -                    g_warning("Unknown acquire mode"); - -                if (err != PCO_NOERROR) -                    g_warning("Cannot set acquire mode"); -            } -            break; - -        case PROP_TRIGGER_MODE: -            { -                UcaCameraTrigger trigger_mode = (UcaCameraTrigger) g_value_get_enum(value); - -                switch (trigger_mode) { -                    case UCA_CAMERA_TRIGGER_AUTO: -                        pco_set_trigger_mode(priv->pco, TRIGGER_MODE_AUTOTRIGGER); -                        break; -                    case UCA_CAMERA_TRIGGER_INTERNAL: -                        pco_set_trigger_mode(priv->pco, TRIGGER_MODE_SOFTWARETRIGGER); -                        break; -                    case UCA_CAMERA_TRIGGER_EXTERNAL: -                        pco_set_trigger_mode(priv->pco, TRIGGER_MODE_EXTERNALTRIGGER); -                        break; -                } -            } -            break; - -        case PROP_NOISE_FILTER: -            { -                guint16 filter_mode = g_value_get_boolean(value) ? NOISE_FILTER_MODE_ON : NOISE_FILTER_MODE_OFF; -                pco_set_noise_filter_mode(priv->pco, filter_mode); -            } -            break; - -        case PROP_TIMESTAMP_MODE: -            { -                guint16 modes[] = { -                    TIMESTAMP_MODE_OFF,             /* 0 */  -                    TIMESTAMP_MODE_BINARY,          /* 1 = 1 << 0 */  -                    TIMESTAMP_MODE_ASCII,           /* 2 = 1 << 1 */  -                    TIMESTAMP_MODE_BINARYANDASCII,  /* 3 = 1 << 0 | 1 << 1 */  -                };  -                pco_set_timestamp_mode(priv->pco, modes[g_value_get_flags(value)]); -            } -            break; - -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            return; -    } -} - -static void uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_SENSOR_EXTENDED: -            { -                guint16 format;  -                pco_get_sensor_format(priv->pco, &format); -                g_value_set_boolean(value, format == SENSORFORMAT_EXTENDED); -            } -            break; - -        case PROP_SENSOR_WIDTH:  -            g_value_set_uint(value, priv->width); -            break; - -        case PROP_SENSOR_HEIGHT:  -            g_value_set_uint(value, priv->height); -            break; - -        case PROP_SENSOR_WIDTH_EXTENDED:  -            g_value_set_uint(value, priv->width_ex < priv->width ? priv->width : priv->width_ex); -            break; - -        case PROP_SENSOR_HEIGHT_EXTENDED:  -            g_value_set_uint(value, priv->height_ex < priv->height ? priv->height : priv->height_ex); -            break; - -        case PROP_SENSOR_HORIZONTAL_BINNING: -            g_value_set_uint(value, priv->binning_h); -            break; - -        case PROP_SENSOR_HORIZONTAL_BINNINGS: -            g_value_set_boxed(value, priv->horizontal_binnings); -            break; - -        case PROP_SENSOR_VERTICAL_BINNING: -            g_value_set_uint(value, priv->binning_v); -            break; - -        case PROP_SENSOR_VERTICAL_BINNINGS: -            g_value_set_boxed(value, priv->vertical_binnings); -            break; - -        case PROP_SENSOR_MAX_FRAME_RATE: -            g_value_set_float(value, priv->camera_description->max_frame_rate); -            break; - -        case PROP_SENSOR_BITDEPTH: -            g_value_set_uint(value, 16); -            break; - -        case PROP_SENSOR_TEMPERATURE: -            { -                gint32 ccd, camera, power;                  -                pco_get_temperature(priv->pco, &ccd, &camera, &power); -                g_value_set_double(value, ccd / 10.0); -            } -            break; - -        case PROP_SENSOR_ADCS: -            { -                /* -                 * Up to now, the ADC mode corresponds directly to the number of -                 * ADCs in use. -                 */ -                pco_adc_mode mode;  -                if (pco_get_adc_mode(priv->pco, &mode) != PCO_NOERROR) -                    g_warning("Cannot read number of ADCs per pixel"); -                g_value_set_uint(value, mode); -            } -            break; - -        case PROP_SENSOR_MAX_ADCS: -            { -                GParamSpecUInt *spec = (GParamSpecUInt *) pco_properties[PROP_SENSOR_ADCS]; -                g_value_set_uint(value, spec->maximum); -            } -            break; - -        case PROP_SENSOR_PIXELRATES: -            g_value_set_boxed(value, priv->pixelrates); -            break; - -        case PROP_SENSOR_PIXELRATE: -            { -                guint32 pixelrate;  -                pco_get_pixelrate(priv->pco, &pixelrate); -                g_value_set_uint(value, pixelrate); -            } -            break; - -        case PROP_EXPOSURE_TIME: -            { -                uint32_t exposure_time; -                pco_get_exposure_time(priv->pco, &exposure_time); - -                if (priv->exposure_timebase == TIMEBASE_INVALID) -                    read_timebase(priv); - -                g_value_set_double(value, convert_timebase(priv->exposure_timebase) * exposure_time); -            } -            break; - -        case PROP_DELAY_TIME: -            { -                uint32_t delay_time; -                pco_get_delay_time(priv->pco, &delay_time); - -                if (priv->delay_timebase == TIMEBASE_INVALID) -                    read_timebase(priv); - -                g_value_set_double(value, convert_timebase(priv->delay_timebase) * delay_time); -            } -            break; - -        case PROP_HAS_DOUBLE_IMAGE_MODE: -            g_value_set_boolean(value, pco_is_double_image_mode_available(priv->pco)); -            break; - -        case PROP_DOUBLE_IMAGE_MODE: -            if (!pco_is_double_image_mode_available(priv->pco)) -                g_warning("Double image mode is not available on this pco model"); -            else { -                bool on; -                pco_get_double_image_mode(priv->pco, &on); -                g_value_set_boolean(value, on); -            } -            break; - -        case PROP_OFFSET_MODE: -            { -                bool on; -                pco_get_offset_mode(priv->pco, &on); -                g_value_set_boolean(value, on); -            } -            break; - -        case PROP_HAS_STREAMING: -            g_value_set_boolean(value, TRUE); -            break; - -        case PROP_HAS_CAMRAM_RECORDING: -            g_value_set_boolean(value, priv->camera_description->has_camram); -            break; - -        case PROP_RECORD_MODE: -            { -                guint16 mode; -                pco_get_record_mode(priv->pco, &mode); - -                if (mode == RECORDER_SUBMODE_SEQUENCE) -                    g_value_set_enum(value, UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE); -                else if (mode == RECORDER_SUBMODE_RINGBUFFER) -                    g_value_set_enum(value, UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER); -                else -                    g_warning("pco record mode not handled"); -            } -            break; - -        case PROP_ACQUIRE_MODE: -            { -                guint16 mode; -                pco_get_acquire_mode(priv->pco, &mode); - -                if (mode == ACQUIRE_MODE_AUTO) -                    g_value_set_enum(value, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO); -                else if (mode == ACQUIRE_MODE_EXTERNAL) -                    g_value_set_enum(value, UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL); -                else -                    g_warning("pco acquire mode not handled"); -            } -            break; - -        case PROP_TRIGGER_MODE: -            { -                guint16 mode;                  -                pco_get_trigger_mode(priv->pco, &mode); - -                switch (mode) { -                    case TRIGGER_MODE_AUTOTRIGGER: -                        g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO); -                        break; -                    case TRIGGER_MODE_SOFTWARETRIGGER: -                        g_value_set_enum(value, UCA_CAMERA_TRIGGER_INTERNAL); -                        break; -                    case TRIGGER_MODE_EXTERNALTRIGGER: -                        g_value_set_enum(value, UCA_CAMERA_TRIGGER_EXTERNAL); -                        break; -                    default: -                        g_warning("pco trigger mode not handled"); -                } -            } -            break; - -        case PROP_ROI_X: -            g_value_set_uint(value, priv->roi_x); -            break; - -        case PROP_ROI_Y: -            g_value_set_uint(value, priv->roi_y); -            break; - -        case PROP_ROI_WIDTH: -            g_value_set_uint(value, priv->roi_width); -            break; - -        case PROP_ROI_HEIGHT: -            g_value_set_uint(value, priv->roi_height); -            break; - -        case PROP_ROI_WIDTH_MULTIPLIER: -            g_value_set_uint(value, priv->roi_horizontal_steps); -            break; - -        case PROP_ROI_HEIGHT_MULTIPLIER: -            g_value_set_uint(value, priv->roi_vertical_steps); -            break; - -        case PROP_NAME:  -            { -                gchar *name = NULL; -                pco_get_name(priv->pco, &name); -                g_value_set_string(value, name); -                g_free(name); -            } -            break; - -        case PROP_COOLING_POINT: -            { -                int16_t temperature;  -                if (pco_get_cooling_temperature(priv->pco, &temperature) != PCO_NOERROR) -                    g_warning("Cannot read cooling temperature\n"); -                g_value_set_int(value, temperature); -            } -            break; - -        case PROP_COOLING_POINT_MIN: -            { -                GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT]; -                g_value_set_int(value, spec->minimum); -            } -            break; - -        case PROP_COOLING_POINT_MAX: -            { -                GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT]; -                g_value_set_int(value, spec->maximum); -            } -            break; - -        case PROP_COOLING_POINT_DEFAULT: -            { -                GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT]; -                g_value_set_int(value, spec->default_value); -            } -            break; - -        case PROP_NOISE_FILTER: -            { -                guint16 mode; -                pco_get_noise_filter_mode(priv->pco, &mode); -                g_value_set_boolean(value, mode != NOISE_FILTER_MODE_OFF); -            } -            break; - -        case PROP_TIMESTAMP_MODE: -            { -                guint16 mode;  -                pco_get_timestamp_mode(priv->pco, &mode); - -                switch (mode) { -                    case TIMESTAMP_MODE_OFF: -                        g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_NONE); -                        break; -                    case TIMESTAMP_MODE_BINARY: -                        g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_BINARY); -                        break; -                    case TIMESTAMP_MODE_BINARYANDASCII: -                        g_value_set_flags(value,  -                                UCA_PCO_CAMERA_TIMESTAMP_BINARY | UCA_PCO_CAMERA_TIMESTAMP_ASCII); -                        break; -                    case TIMESTAMP_MODE_ASCII: -                        g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_ASCII); -                        break; -                } -            } -            break; - -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            break; -    } -} - -static void uca_pco_camera_finalize(GObject *object) -{ -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object); - -    if (priv->horizontal_binnings) -        g_value_array_free(priv->horizontal_binnings); - -    if (priv->vertical_binnings) -        g_value_array_free(priv->vertical_binnings); - -    if (priv->pixelrates) -        g_value_array_free(priv->pixelrates); - -    if (priv->fg) { -        if (priv->fg_mem) -            Fg_FreeMemEx(priv->fg, priv->fg_mem); - -        Fg_FreeGrabber(priv->fg); -    } - -    if (priv->pco) -        pco_destroy(priv->pco); - -    g_free(priv->grab_buffer); - -    G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object); -} - -static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) -{ -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -    gobject_class->set_property = uca_pco_camera_set_property; -    gobject_class->get_property = uca_pco_camera_get_property; -    gobject_class->finalize = uca_pco_camera_finalize; - -    UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); -    camera_class->start_recording = uca_pco_camera_start_recording; -    camera_class->stop_recording = uca_pco_camera_stop_recording; -    camera_class->start_readout = uca_pco_camera_start_readout; -    camera_class->trigger = uca_pco_camera_trigger; -    camera_class->grab = uca_pco_camera_grab; - -    for (guint i = 0; base_overrideables[i] != 0; i++) -        g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]); - -    /** -     * UcaPcoCamera:sensor-extended: -     * -     * Activate larger sensor area that contains surrounding pixels for dark -     * references and dummies. Use #UcaPcoCamera:sensor-width-extended and -     * #UcaPcoCamera:sensor-height-extended to query the resolution of the -     * larger area. -     */ -    pco_properties[PROP_SENSOR_EXTENDED] =  -        g_param_spec_boolean("sensor-extended", -            "Use extended sensor format", -            "Use extended sensor format", -            FALSE, G_PARAM_READWRITE); - -    pco_properties[PROP_SENSOR_WIDTH_EXTENDED] =  -        g_param_spec_uint("sensor-width-extended", -            "Width of extended sensor", -            "Width of the extended sensor in pixels", -            1, G_MAXUINT, 1, -            G_PARAM_READABLE); - -    pco_properties[PROP_SENSOR_HEIGHT_EXTENDED] =  -        g_param_spec_uint("sensor-height-extended", -            "Height of extended sensor", -            "Height of the extended sensor in pixels", -            1, G_MAXUINT, 1, -            G_PARAM_READABLE); - -    /** -     * UcaPcoCamera:sensor-pixelrate: -     * -     * Read and write the pixel rate or clock of the sensor in terms of Hertz. -     * Make sure to query the possible pixel rates through the -     * #UcaPcoCamera:sensor-pixelrates property. Any other value will be -     * rejected by the camera. -     */ -    pco_properties[PROP_SENSOR_PIXELRATE] =  -        g_param_spec_uint("sensor-pixelrate", -            "Pixel rate", -            "Pixel rate", -            1, G_MAXUINT, 1, -            G_PARAM_READWRITE); - -    pco_properties[PROP_SENSOR_PIXELRATES] =  -        g_param_spec_value_array("sensor-pixelrates", -            "Array of possible sensor pixel rates", -            "Array of possible sensor pixel rates", -            pco_properties[PROP_SENSOR_PIXELRATE], -            G_PARAM_READABLE); - -    pco_properties[PROP_NAME] =  -        g_param_spec_string("name", -            "Name of the camera", -            "Name of the camera", -            "", G_PARAM_READABLE); - -    pco_properties[PROP_SENSOR_TEMPERATURE] = -        g_param_spec_double("sensor-temperature", -            "Temperature of the sensor", -            "Temperature of the sensor in degree Celsius", -            -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, -            G_PARAM_READABLE); - -    pco_properties[PROP_HAS_DOUBLE_IMAGE_MODE] =  -        g_param_spec_boolean("has-double-image-mode", -            "Is double image mode supported by this model", -            "Is double image mode supported by this model", -            FALSE, G_PARAM_READABLE); - -    pco_properties[PROP_DOUBLE_IMAGE_MODE] =  -        g_param_spec_boolean("double-image-mode", -            "Use double image mode", -            "Use double image mode", -            FALSE, G_PARAM_READWRITE); - -    pco_properties[PROP_OFFSET_MODE] =  -        g_param_spec_boolean("offset-mode", -            "Use offset mode", -            "Use offset mode", -            FALSE, G_PARAM_READWRITE); - -    pco_properties[PROP_RECORD_MODE] =  -        g_param_spec_enum("record-mode",  -            "Record mode", -            "Record mode", -            UCA_TYPE_PCO_CAMERA_RECORD_MODE, UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE, -            G_PARAM_READWRITE); - -    pco_properties[PROP_ACQUIRE_MODE] =  -        g_param_spec_enum("acquire-mode",  -            "Acquire mode", -            "Acquire mode", -            UCA_TYPE_PCO_CAMERA_ACQUIRE_MODE, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO, -            G_PARAM_READWRITE); -     -    pco_properties[PROP_DELAY_TIME] = -        g_param_spec_double("delay-time", -            "Delay time", -            "Delay before starting actual exposure", -            0.0, G_MAXDOUBLE, 0.0, -            G_PARAM_READWRITE); - -    pco_properties[PROP_NOISE_FILTER] =  -        g_param_spec_boolean("noise-filter", -            "Noise filter", -            "Noise filter", -            FALSE, G_PARAM_READWRITE); - -    /** -     * UcaPcoCamera:cooling-point: -     * -     * The value range is set arbitrarily, because we are not yet connected to -     * the camera and just don't know the cooling range. We override these -     * values in #uca_pco_camera_new(). -     */ -    pco_properties[PROP_COOLING_POINT] =  -        g_param_spec_int("cooling-point", -            "Cooling point of the camera", -            "Cooling point of the camera in degree celsius", -            0, 10, 5, G_PARAM_READWRITE); - -    pco_properties[PROP_COOLING_POINT_MIN] =  -        g_param_spec_int("cooling-point-min", -            "Minimum cooling point", -            "Minimum cooling point in degree celsius", -            G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - -    pco_properties[PROP_COOLING_POINT_MAX] =  -        g_param_spec_int("cooling-point-max", -            "Maximum cooling point", -            "Maximum cooling point in degree celsius", -            G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - -    pco_properties[PROP_COOLING_POINT_DEFAULT] =  -        g_param_spec_int("cooling-point-default", -            "Default cooling point", -            "Default cooling point in degree celsius", -            G_MININT, G_MAXINT, 0, G_PARAM_READABLE); -     -    pco_properties[PROP_SENSOR_ADCS] =  -        g_param_spec_uint("sensor-adcs", -            "Number of ADCs to use", -            "Number of ADCs to use", -            1, 2, 1,  -            G_PARAM_READWRITE); - -    pco_properties[PROP_SENSOR_MAX_ADCS] =  -        g_param_spec_uint("sensor-max-adcs", -            "Maximum number of ADCs", -            "Maximum number of ADCs that can be set with \"sensor-adcs\"", -            1, G_MAXUINT, 1,  -            G_PARAM_READABLE); - -    pco_properties[PROP_TIMESTAMP_MODE] = -        g_param_spec_flags("timestamp-mode", -            "Timestamp mode", -            "Timestamp mode", -            UCA_TYPE_PCO_CAMERA_TIMESTAMP, UCA_PCO_CAMERA_TIMESTAMP_NONE, -            G_PARAM_READWRITE); - -    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++) -        g_object_class_install_property(gobject_class, id, pco_properties[id]); - -    g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate)); -} - -static void uca_pco_camera_init(UcaPcoCamera *self) -{ -    self->priv = UCA_PCO_CAMERA_GET_PRIVATE(self); -    self->priv->fg = NULL; -    self->priv->fg_mem = NULL; -    self->priv->pco = NULL; -    self->priv->horizontal_binnings = NULL; -    self->priv->vertical_binnings = NULL; -    self->priv->pixelrates = NULL; -    self->priv->camera_description = NULL; -    self->priv->last_frame = 0; -    self->priv->grab_buffer = NULL; - -    self->priv->delay_timebase = TIMEBASE_INVALID; -    self->priv->exposure_timebase = TIMEBASE_INVALID; -} diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h deleted file mode 100644 index fdb709a..0000000 --- a/src/cameras/uca-pco-camera.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#ifndef __UCA_PCO_CAMERA_H -#define __UCA_PCO_CAMERA_H - -#include <glib-object.h> -#include "uca-camera.h" - -G_BEGIN_DECLS - -#define UCA_TYPE_PCO_CAMERA             (uca_pco_camera_get_type()) -#define UCA_PCO_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCamera)) -#define UCA_IS_PCO_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PCO_CAMERA)) -#define UCA_PCO_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass)) -#define UCA_IS_PCO_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PCO_CAMERA)) -#define UCA_PCO_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass)) - -#define UCA_PCO_CAMERA_ERROR uca_pco_camera_error_quark() -typedef enum { -    UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, -    UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, -    UCA_PCO_CAMERA_ERROR_UNSUPPORTED, -    UCA_PCO_CAMERA_ERROR_FG_INIT, -    UCA_PCO_CAMERA_ERROR_FG_GENERAL, -    UCA_PCO_CAMERA_ERROR_FG_ACQUISITION -} UcaPcoCameraError; - -typedef struct _UcaPcoCamera           UcaPcoCamera; -typedef struct _UcaPcoCameraClass      UcaPcoCameraClass; -typedef struct _UcaPcoCameraPrivate    UcaPcoCameraPrivate; - -typedef enum { -    UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE, -    UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER, -} UcaPcoCameraRecordMode; - -typedef enum { -    UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO, -    UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL -} UcaPcoCameraAcquireMode; - -typedef enum { -    UCA_PCO_CAMERA_TIMESTAMP_NONE       = 0, -    UCA_PCO_CAMERA_TIMESTAMP_BINARY     = 1 << 0, -    UCA_PCO_CAMERA_TIMESTAMP_ASCII      = 1 << 1 -} UcaPcoCameraTimestamp; - -/** - * UcaPcoCamera: - * - * Creates #UcaPcoCamera instances by loading corresponding shared objects. The - * contents of the #UcaPcoCamera structure are private and should only be - * accessed via the provided API. - */ -struct _UcaPcoCamera { -    /*< private >*/ -    UcaCamera parent; - -    UcaPcoCameraPrivate *priv; -}; - -/** - * UcaPcoCameraClass: - * - * #UcaPcoCamera class - */ -struct _UcaPcoCameraClass { -    /*< private >*/ -    UcaCameraClass parent; -}; - -UcaPcoCamera *uca_pco_camera_new(GError **error); - -GType uca_pco_camera_get_type(void); - -G_END_DECLS - -#endif diff --git a/src/cameras/uca-pf-camera.c b/src/cameras/uca-pf-camera.c deleted file mode 100644 index 5bc8c6b..0000000 --- a/src/cameras/uca-pf-camera.c +++ /dev/null @@ -1,349 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fgrab_struct.h> -#include <fgrab_prototyp.h> -#include <libpf/pfcam.h> -#include <errno.h> -#include "uca-camera.h" -#include "uca-pf-camera.h" - -#define FG_TRY_PARAM(fg, camobj, param, val_addr, port)     \ -    { int r = Fg_setParameter(fg, param, val_addr, port);   \ -        if (r != FG_OK) {                                   \ -            g_set_error(error, UCA_PF_CAMERA_ERROR,         \ -                    UCA_PF_CAMERA_ERROR_FG_GENERAL,         \ -                    "%s", Fg_getLastErrorDescription(fg));  \ -            g_object_unref(camobj);                         \ -            return NULL;                                    \ -        } } - -#define FG_SET_ERROR(err, fg, err_type)                 \ -    if (err != FG_OK) {                                 \ -        g_set_error(error, UCA_PF_CAMERA_ERROR,         \ -                err_type,                               \ -                "%s", Fg_getLastErrorDescription(fg));  \ -        return;                                         \ -    } - -#define UCA_PF_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraPrivate)) - -G_DEFINE_TYPE(UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA) - -/** - * UcaPfCameraError: - * @UCA_PF_CAMERA_ERROR_INIT: Initializing pcilib failed - * @UCA_PF_CAMERA_ERROR_FG_GENERAL: Frame grabber errors - * @UCA_PF_CAMERA_ERROR_FG_ACQUISITION: Acquisition errors related to the frame - *      grabber - * @UCA_PF_CAMERA_ERROR_START_RECORDING: Starting failed - * @UCA_PF_CAMERA_ERROR_STOP_RECORDING: Stopping failed - */ -GQuark uca_pf_camera_error_quark() -{ -    return g_quark_from_static_string("uca-pf-camera-error-quark"); -} - -static gint base_overrideables[] = { -    PROP_NAME, -    PROP_SENSOR_WIDTH, -    PROP_SENSOR_HEIGHT, -    PROP_SENSOR_BITDEPTH, -    PROP_SENSOR_HORIZONTAL_BINNING, -    PROP_SENSOR_HORIZONTAL_BINNINGS, -    PROP_SENSOR_VERTICAL_BINNING, -    PROP_SENSOR_VERTICAL_BINNINGS, -    PROP_SENSOR_MAX_FRAME_RATE, -    PROP_EXPOSURE_TIME, -    PROP_ROI_X, -    PROP_ROI_Y, -    PROP_ROI_WIDTH, -    PROP_ROI_HEIGHT, -    PROP_ROI_WIDTH_MULTIPLIER, -    PROP_ROI_HEIGHT_MULTIPLIER, -    PROP_HAS_STREAMING, -    PROP_HAS_CAMRAM_RECORDING, -    0 -}; - -enum { -    PROP_FOO = N_BASE_PROPERTIES, -    N_PROPERTIES -}; - - -struct _UcaPfCameraPrivate { -    guint roi_width; -    guint roi_height; -    guint last_frame; - -    Fg_Struct *fg; -    guint fg_port; -    dma_mem *fg_mem; -}; - -UcaPfCamera *uca_pf_camera_new(GError **error) -{ -    static const gchar *so_file = "libFullAreaGray8.so"; -    static const int camera_link_type = FG_CL_8BIT_FULL_8; -    static const int camera_format = FG_GRAY; - -    /* -    gint num_ports; -    if (pfPortInit(&num_ports) < 0) { -        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, -                "Could not initialize ports");  -        return NULL; -    } - -    if (pfDeviceOpen(0) < 0) { -        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, -                "Could not open device");  -        return NULL; -    } -    */ - -    UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL); -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); - -    priv->fg_port = PORT_A; -    priv->fg = Fg_Init(so_file, priv->fg_port); - -    /* TODO: get this from the camera */ -    priv->roi_width = 1280; -    priv->roi_height = 1024; - -    if (priv->fg == NULL) { -        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, -                "%s", Fg_getLastErrorDescription(priv->fg)); -        g_object_unref(camera); -        return NULL; -    } - -    FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &camera_link_type, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &camera_format, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &priv->roi_width, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &priv->roi_height, priv->fg_port); - -    return camera; -} - -/* - * We just embed our private structure here. - */ -struct { -    UcaCamera *camera; -} fg_apc_data; - -static int me4_callback(frameindex_t frame, struct fg_apc_data *apc) -{ -    UcaCamera *camera = UCA_CAMERA(apc); -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); -    camera->grab_func(Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem), camera->user_data); -    return 0; -} - -static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PF_CAMERA(camera)); -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); -    guint err = FG_OK; - -    if (priv->fg_mem == NULL) { -        const guint num_buffers = 2; -        priv->fg_mem = Fg_AllocMemEx(priv->fg, num_buffers * priv->roi_width * priv->roi_height, num_buffers); - -        if (priv->fg_mem == NULL) { -            g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_FG_ACQUISITION, -                    "%s", Fg_getLastErrorDescription(priv->fg)); -            g_object_unref(camera); -            return; -        } -    } - -    gboolean transfer_async = FALSE; -    g_object_get(G_OBJECT(camera), -            "transfer-asynchronously", &transfer_async, -            NULL); - -    if (transfer_async) { -        struct FgApcControl ctrl = { -            .version = 0, -            .data = (struct fg_apc_data *) camera, -            .func = &me4_callback, -            .flags = FG_APC_DEFAULTS, -            .timeout = 1 -        }; - -        err = Fg_registerApcHandler(priv->fg, priv->fg_port, &ctrl, FG_APC_CONTROL_BASIC); -        FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION); -    } - -    err = Fg_AcquireEx(priv->fg, priv->fg_port, GRAB_INFINITE, ACQ_STANDARD, priv->fg_mem); -    FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION); -} - -static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PF_CAMERA(camera)); -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); - -    guint err = Fg_stopAcquireEx(priv->fg, priv->fg_port, priv->fg_mem, STOP_SYNC); -    FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION); - -    err = Fg_setStatusEx(priv->fg, FG_UNBLOCK_ALL, 0, priv->fg_port, priv->fg_mem); -    if (err == FG_INVALID_PARAMETER) -        g_print(" Unable to unblock all\n"); -} - -static void uca_pf_camera_start_readout(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PF_CAMERA(camera)); -    g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED, -            "This photon focus camera does not support recording to internal memory"); -} - -static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error) -{ -    g_return_if_fail(UCA_IS_PF_CAMERA(camera)); -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); - -    priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, 5, priv->fg_mem); -     -    if (priv->last_frame <= 0) { -        guint err = FG_OK + 1; -        FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_GENERAL); -    } - -    guint16 *frame = Fg_getImagePtrEx(priv->fg, priv->last_frame, priv->fg_port, priv->fg_mem); - -    if (*data == NULL) -        *data = g_malloc0(priv->roi_width * priv->roi_height); - -    memcpy((gchar *) *data, (gchar *) frame, priv->roi_width * priv->roi_height); -} - -static void uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ -    switch (property_id) { -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            return; -    } -} - -static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ -    switch (property_id) { -        case PROP_SENSOR_WIDTH:  -            g_value_set_uint(value, 1280); -            break; -        case PROP_SENSOR_HEIGHT:  -            g_value_set_uint(value, 1024); -            break; -        case PROP_SENSOR_BITDEPTH: -            g_value_set_uint(value, 8); -            break; -        case PROP_SENSOR_HORIZONTAL_BINNING: -            break; -        case PROP_SENSOR_HORIZONTAL_BINNINGS: -            break; -        case PROP_SENSOR_VERTICAL_BINNING: -            break; -        case PROP_SENSOR_VERTICAL_BINNINGS: -            break; -        case PROP_SENSOR_MAX_FRAME_RATE: -            g_value_set_float(value, 488.0); -            break; -        case PROP_HAS_STREAMING: -            g_value_set_boolean(value, TRUE); -            break; -        case PROP_HAS_CAMRAM_RECORDING: -            g_value_set_boolean(value, FALSE); -            break; -        case PROP_EXPOSURE_TIME: -            break; -        case PROP_ROI_X: -            g_value_set_uint(value, 0); -            break; -        case PROP_ROI_Y: -            g_value_set_uint(value, 0); -            break; -        case PROP_ROI_WIDTH: -            g_value_set_uint(value, 1280); -            break; -        case PROP_ROI_HEIGHT: -            g_value_set_uint(value, 1024); -            break; -        case PROP_ROI_WIDTH_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_ROI_HEIGHT_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_NAME:  -            g_value_set_string(value, "Photon Focus MV2-D1280-640-CL"); -            break; -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            break; -    } -} - -static void uca_pf_camera_finalize(GObject *object) -{ -    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(object); - -    if (priv->fg) { -        if (priv->fg_mem) -            Fg_FreeMemEx(priv->fg, priv->fg_mem); - -        Fg_FreeGrabber(priv->fg); -    } - -    G_OBJECT_CLASS(uca_pf_camera_parent_class)->finalize(object); -} - -static void uca_pf_camera_class_init(UcaPfCameraClass *klass) -{ -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -    gobject_class->set_property = uca_pf_camera_set_property; -    gobject_class->get_property = uca_pf_camera_get_property; -    gobject_class->finalize = uca_pf_camera_finalize; - -    UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); -    camera_class->start_recording = uca_pf_camera_start_recording; -    camera_class->stop_recording = uca_pf_camera_stop_recording; -    camera_class->start_readout = uca_pf_camera_start_readout; -    camera_class->grab = uca_pf_camera_grab; - -    for (guint i = 0; base_overrideables[i] != 0; i++) -        g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]); - -    g_type_class_add_private(klass, sizeof(UcaPfCameraPrivate)); -} - -static void uca_pf_camera_init(UcaPfCamera *self) -{ -    self->priv = UCA_PF_CAMERA_GET_PRIVATE(self); -    self->priv->fg = NULL; -    self->priv->fg_mem = NULL; -    self->priv->last_frame = 0; -} diff --git a/src/cameras/uca-pf-camera.h b/src/cameras/uca-pf-camera.h deleted file mode 100644 index 7e3fe2c..0000000 --- a/src/cameras/uca-pf-camera.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#ifndef __UCA_PF_CAMERA_H -#define __UCA_PF_CAMERA_H - -#include <glib-object.h> -#include "uca-camera.h" - -G_BEGIN_DECLS - -#define UCA_TYPE_PF_CAMERA             (uca_pf_camera_get_type()) -#define UCA_PF_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PF_CAMERA, UcaPfCamera)) -#define UCA_IS_PF_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PF_CAMERA)) -#define UCA_PF_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PF_CAMERA, UcaPfCameraClass)) -#define UCA_IS_PF_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PF_CAMERA)) -#define UCA_PF_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraClass)) - -#define UCA_PF_CAMERA_ERROR uca_pf_camera_error_quark() -typedef enum { -    UCA_PF_CAMERA_ERROR_INIT, -    UCA_PF_CAMERA_ERROR_FG_GENERAL, -    UCA_PF_CAMERA_ERROR_FG_ACQUISITION, -    UCA_PF_CAMERA_ERROR_START_RECORDING, -    UCA_PF_CAMERA_ERROR_STOP_RECORDING -} UcaPfCameraError; - -typedef struct _UcaPfCamera           UcaPfCamera; -typedef struct _UcaPfCameraClass      UcaPfCameraClass; -typedef struct _UcaPfCameraPrivate    UcaPfCameraPrivate; - -/** - * UcaPfCamera: - * - * Creates #UcaPfCamera instances by loading corresponding shared objects. The - * contents of the #UcaPfCamera structure are private and should only be - * accessed via the provided API. - */ -struct _UcaPfCamera { -    /*< private >*/ -    UcaCamera parent; - -    UcaPfCameraPrivate *priv; -}; - -/** - * UcaPfCameraClass: - * - * #UcaPfCamera class - */ -struct _UcaPfCameraClass { -    /*< private >*/ -    UcaCameraClass parent; -}; - -UcaPfCamera *uca_pf_camera_new(GError **error); - -GType uca_pf_camera_get_type(void); - -G_END_DECLS - -#endif diff --git a/src/cameras/uca-pylon-camera.c b/src/cameras/uca-pylon-camera.c deleted file mode 100644 index 541b69b..0000000 --- a/src/cameras/uca-pylon-camera.c +++ /dev/null @@ -1,391 +0,0 @@ -/* Copyright (C) 2012 Volker Kaiser <volker.kaiser@softwareschneiderei> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <libpyloncam/pylon_camera.h> -#include "uca-camera.h" -#include "uca-pylon-camera.h" - -#define UCA_PYLON_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCameraPrivate)) - -G_DEFINE_TYPE(UcaPylonCamera, uca_pylon_camera, UCA_TYPE_CAMERA) - -/** - * UcapylonCameraError: - * @UCA_PYLON_CAMERA_ERROR_LIBPYLON_INIT: Initializing libpylon failed - * @UCA_PYLON_CAMERA_ERROR_LIBPYLON_GENERAL: General libpylon error - * @UCA_PYLON_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported - * @UCA_PYLON_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed - * @UCA_PYLON_CAMERA_ERROR_FG_GENERAL: General framegrabber error - * @UCA_PYLON_CAMERA_ERROR_FG_ACQUISITION: Framegrabber acquisition error - */ -GQuark uca_pylon_camera_error_quark() -{ -    return g_quark_from_static_string("uca-pylon-camera-error-quark"); -} - -enum { -    PROP_ROI_WIDTH_DEFAULT = N_BASE_PROPERTIES, -    PROP_ROI_HEIGHT_DEFAULT, -    PROP_GAIN, -    N_PROPERTIES -}; - -static gint base_overrideables[] = { -    PROP_NAME, -    PROP_SENSOR_WIDTH, -    PROP_SENSOR_HEIGHT, -    PROP_SENSOR_BITDEPTH, -    PROP_SENSOR_HORIZONTAL_BINNING, -    PROP_SENSOR_HORIZONTAL_BINNINGS, -    PROP_SENSOR_VERTICAL_BINNING, -    PROP_SENSOR_VERTICAL_BINNINGS, -    PROP_SENSOR_MAX_FRAME_RATE, -    PROP_TRIGGER_MODE, -    PROP_EXPOSURE_TIME, -    PROP_ROI_X, -    PROP_ROI_Y, -    PROP_ROI_WIDTH, -    PROP_ROI_HEIGHT, -    PROP_ROI_WIDTH_MULTIPLIER, -    PROP_ROI_HEIGHT_MULTIPLIER, -    PROP_HAS_STREAMING, -    PROP_HAS_CAMRAM_RECORDING, -    0 -}; - -static GParamSpec *pylon_properties[N_PROPERTIES] = { NULL, }; - - -struct _UcaPylonCameraPrivate { -    guint bit_depth; -    gsize num_bytes; - -    guint width; -    guint height; -    guint16 roi_x, roi_y; -    guint16 roi_width, roi_height; -    GValueArray *binnings; -}; - - -static void pylon_get_roi(GObject *object, GError** error) -{ -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object); -    pylon_camera_get_roi(&priv->roi_x, &priv->roi_y, &priv->roi_width, &priv->roi_height, error); -} - -static void pylon_set_roi(GObject *object, GError** error) -{ -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object); -    pylon_camera_set_roi(priv->roi_x, priv->roi_y, priv->roi_width, priv->roi_height, error); -} - -UcaPylonCamera *uca_pylon_camera_new(GError **error) -{ -    UcaPylonCamera *camera = g_object_new(UCA_TYPE_PYLON_CAMERA, NULL); -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera); - -    pylon_camera_new("/usr/local/lib64", "141.52.111.110", error); - -    if (*error != NULL) -        return NULL; - -    pylon_camera_get_sensor_size(&priv->width, &priv->height, error); - -    if (*error != NULL) -        return NULL; - -    return camera; -} - -static void uca_pylon_camera_start_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PYLON_CAMERA(camera)); -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera); - -    priv->num_bytes = 2; -    pylon_camera_start_acquision(error); - -} - -static void uca_pylon_camera_stop_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_PYLON_CAMERA(camera)); -    pylon_camera_stop_acquision(error); -} - -static void uca_pylon_camera_grab(UcaCamera *camera, gpointer *data, GError **error) -{ -    g_return_if_fail(UCA_IS_PYLON_CAMERA(camera)); -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera); - -    if (*data == NULL) { -        *data = g_malloc0(priv->width * priv->height * priv->num_bytes); -    } -    pylon_camera_grab(data, error); -} - -static void uca_pylon_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object); -    GError* error = NULL; - -    switch (property_id) { -        case PROP_SENSOR_HORIZONTAL_BINNING: -          /* intentional fall-through*/ -        case PROP_SENSOR_VERTICAL_BINNING: -          /* intentional fall-through*/ -        case PROP_TRIGGER_MODE: -          break; - -        case PROP_ROI_X: -          { -              priv->roi_x = g_value_get_uint(value); -              pylon_set_roi(object, &error); -          } -          break; - -        case PROP_ROI_Y: -          { -              priv->roi_y = g_value_get_uint(value); -              pylon_set_roi(object, &error); -          } -          break; - -        case PROP_ROI_WIDTH: -          { -              priv->roi_width = g_value_get_uint(value); -              pylon_set_roi(object, &error); -          } -          break; - -        case PROP_ROI_HEIGHT: -          { -              priv->roi_height = g_value_get_uint(value); -              pylon_set_roi(object, &error); -          } -          break; - -        case PROP_EXPOSURE_TIME: -          pylon_camera_set_exposure_time(g_value_get_double(value), &error); -          break; - -        case PROP_GAIN: -            pylon_camera_set_gain(g_value_get_int(value), &error); -            break; - -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            return; -    } -} - -static void uca_pylon_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object); -    GError* error = NULL; - -    switch (property_id) { -        case PROP_SENSOR_WIDTH: -            pylon_camera_get_sensor_size(&priv->width, &priv->height, &error); -            g_value_set_uint(value, priv->width); -            break; - -        case PROP_SENSOR_HEIGHT: -            pylon_camera_get_sensor_size(&priv->width, &priv->height, &error); -            g_value_set_uint(value, priv->height); -            break; - -        case PROP_SENSOR_BITDEPTH: -            pylon_camera_get_bit_depth(&priv->bit_depth, &error); -            g_value_set_uint(value, priv->bit_depth); -            break; - -        case PROP_SENSOR_HORIZONTAL_BINNING: -            g_value_set_uint(value, 1); -            break; - -        case PROP_SENSOR_HORIZONTAL_BINNINGS: -            g_value_set_boxed(value, priv->binnings); -            break; - -        case PROP_SENSOR_VERTICAL_BINNING: -            g_value_set_uint(value, 1); -            break; - -        case PROP_SENSOR_VERTICAL_BINNINGS: -            g_value_set_boxed(value, priv->binnings); -            break; - -        case PROP_SENSOR_MAX_FRAME_RATE: -            g_value_set_float(value, 0.0); -            break; - -        case PROP_TRIGGER_MODE: -            g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO); -            break; - -        case PROP_HAS_STREAMING: -            g_value_set_boolean(value, FALSE); -            break; - -        case PROP_HAS_CAMRAM_RECORDING: -            g_value_set_boolean(value, FALSE); -            break; - -        case PROP_ROI_X: -            { -                pylon_get_roi(object, &error); -                g_value_set_uint(value, priv->roi_x); -            } -            break; - -        case PROP_ROI_Y: -            { -                pylon_get_roi(object, &error); -                g_value_set_uint(value, priv->roi_y); -            } -            break; - -        case PROP_ROI_WIDTH: -            { -                pylon_get_roi(object, &error); -                g_value_set_uint(value, priv->roi_width); -            } -            break; - -        case PROP_ROI_HEIGHT: -            { -                pylon_get_roi(object, &error); -                g_value_set_uint(value, priv->roi_height); -            } -            break; - -        case PROP_ROI_WIDTH_DEFAULT: -            pylon_camera_get_sensor_size(&priv->width, &priv->height, &error); -            g_value_set_uint(value, priv->width); -            break; - -        case PROP_ROI_HEIGHT_DEFAULT: -            pylon_camera_get_sensor_size(&priv->width, &priv->height, &error); -            g_value_set_uint(value, priv->height); -            break; - -        case PROP_GAIN: -            { -                gint gain=0; -                pylon_camera_get_gain(&gain, &error); -                g_value_set_int(value, gain); -            } -            break; - -        case PROP_ROI_WIDTH_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; - -        case PROP_ROI_HEIGHT_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; - -        case PROP_EXPOSURE_TIME: -            { -                gdouble exp_time = 0.0; -                pylon_camera_get_exposure_time(&exp_time, &error); -                g_value_set_double(value, exp_time); -            } -            break; - -        case PROP_NAME: -            g_value_set_string(value, "Pylon Camera"); -            break; - -        default: -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            break; -    } -} - -static void uca_pylon_camera_finalize(GObject *object) -{ -    UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object); -    g_value_array_free(priv->binnings); - -    G_OBJECT_CLASS(uca_pylon_camera_parent_class)->finalize(object); -} - -static void uca_pylon_camera_class_init(UcaPylonCameraClass *klass) -{ -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -    gobject_class->set_property = uca_pylon_camera_set_property; -    gobject_class->get_property = uca_pylon_camera_get_property; -    gobject_class->finalize = uca_pylon_camera_finalize; - -    UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); -    camera_class->start_recording = uca_pylon_camera_start_recording; -    camera_class->stop_recording = uca_pylon_camera_stop_recording; -    camera_class->grab = uca_pylon_camera_grab; - -    for (guint i = 0; base_overrideables[i] != 0; i++) -        g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]); - -    pylon_properties[PROP_NAME] = -        g_param_spec_string("name", -            "Name of the camera", -            "Name of the camera", -            "", G_PARAM_READABLE); - -    pylon_properties[PROP_ROI_WIDTH_DEFAULT] = -        g_param_spec_uint("roi-width-default", -            "ROI width default value", -            "ROI width default value", -            0, G_MAXUINT, 0, -            G_PARAM_READABLE); - -    pylon_properties[PROP_ROI_HEIGHT_DEFAULT] = -        g_param_spec_uint("roi-height-default", -            "ROI height default value", -            "ROI height default value", -            0, G_MAXUINT, 0, -            G_PARAM_READABLE); - -    pylon_properties[PROP_GAIN] = -        g_param_spec_int("gain", -            "gain", -            "gain", -            0, G_MAXINT, 0, -            G_PARAM_READWRITE); - -    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++) -        g_object_class_install_property(gobject_class, id, pylon_properties[id]); - -    g_type_class_add_private(klass, sizeof(UcaPylonCameraPrivate)); -} - -static void uca_pylon_camera_init(UcaPylonCamera *self) -{ -    self->priv = UCA_PYLON_CAMERA_GET_PRIVATE(self); - -    /* binnings */ -    GValue val = {0}; -    g_value_init(&val, G_TYPE_UINT); -    g_value_set_uint(&val, 1); -    self->priv->binnings  = g_value_array_new(1); -    g_value_array_append(self->priv->binnings, &val); -} diff --git a/src/cameras/uca-pylon-camera.h b/src/cameras/uca-pylon-camera.h deleted file mode 100644 index eebf63c..0000000 --- a/src/cameras/uca-pylon-camera.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#ifndef __UCA_PYLON_CAMERA_H -#define __UCA_PYLON_CAMERA_H - -#include <glib-object.h> -#include "uca-camera.h" - -G_BEGIN_DECLS - -#define UCA_TYPE_PYLON_CAMERA             (uca_pylon_camera_get_type()) -#define UCA_PYLON_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCamera)) -#define UCA_IS_PYLON_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PYLON_CAMERA)) -#define UCA_PYLON_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_PYLON_CAMERA, UfoPylonCameraClass)) -#define UCA_IS_PYLON_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PYLON_CAMERA)) -#define UCA_PYLON_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCameraClass)) - -#define UCA_PYLON_CAMERA_ERROR uca_pylon_camera_error_quark() -typedef enum { -    UCA_PYLON_CAMERA_ERROR_LIBPYLON_INIT, -    UCA_PYLON_CAMERA_ERROR_LIBPYLON_GENERAL, -    UCA_PYLON_CAMERA_ERROR_UNSUPPORTED, -} UcaPylonCameraError; - -typedef struct _UcaPylonCamera           UcaPylonCamera; -typedef struct _UcaPylonCameraClass      UcaPylonCameraClass; -typedef struct _UcaPylonCameraPrivate    UcaPylonCameraPrivate; - -/** - * UcaPylonCamera: - * - * Creates #UcaPylonCamera instances by loading corresponding shared objects. The - * contents of the #UcaPylonCamera structure are private and should only be - * accessed via the provided API. - */ -struct _UcaPylonCamera { -    /*< private >*/ -    UcaCamera parent; - -    UcaPylonCameraPrivate *priv; -}; - -/** - * UcaPylonCameraClass: - * - * #UcaPylonCamera class - */ -struct _UcaPylonCameraClass { -    /*< private >*/ -    UcaCameraClass parent; -}; - -UcaPylonCamera *uca_pylon_camera_new(GError **error); - -GType uca_pylon_camera_get_type(void); - -G_END_DECLS - -#endif diff --git a/src/cameras/uca-ufo-camera.c b/src/cameras/uca-ufo-camera.c deleted file mode 100644 index 5f59f4a..0000000 --- a/src/cameras/uca-ufo-camera.c +++ /dev/null @@ -1,495 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <pcilib.h> -#include <errno.h> -#include "uca-camera.h" -#include "uca-ufo-camera.h" - -#define PCILIB_SET_ERROR(err, err_type)                 \ -    if (err != 0) {                                     \ -        g_set_error(error, UCA_UFO_CAMERA_ERROR,        \ -                err_type,                               \ -                "pcilib: %s", strerror(err));           \ -        return;                                         \ -    } - -#define UCA_UFO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCameraPrivate)) - -G_DEFINE_TYPE(UcaUfoCamera, uca_ufo_camera, UCA_TYPE_CAMERA) - -static const guint SENSOR_WIDTH = 2048; -static const guint SENSOR_HEIGHT = 1088; -static const gdouble EXPOSURE_TIME_SCALE = 2.69e6; - -/** - * UcaUfoCameraError: - * @UCA_UFO_CAMERA_ERROR_INIT: Initializing pcilib failed - * @UCA_UFO_CAMERA_ERROR_START_RECORDING: Starting failed - * @UCA_UFO_CAMERA_ERROR_STOP_RECORDING: Stopping failed - * @UCA_UFO_CAMERA_ERROR_TRIGGER: Triggering a frame failed - * @UCA_UFO_CAMERA_ERROR_NEXT_EVENT: No event happened - * @UCA_UFO_CAMERA_ERROR_NO_DATA: No data was transmitted - * @UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED: Data is potentially corrupted - */ -GQuark uca_ufo_camera_error_quark() -{ -    return g_quark_from_static_string("uca-ufo-camera-error-quark"); -} - -enum { -    PROP_SENSOR_TEMPERATURE = N_BASE_PROPERTIES, -    PROP_FPGA_TEMPERATURE, -    PROP_UFO_START, -    N_MAX_PROPERTIES = 512 -}; - -static gint base_overrideables[] = { -    PROP_NAME, -    PROP_SENSOR_WIDTH, -    PROP_SENSOR_HEIGHT, -    PROP_SENSOR_HORIZONTAL_BINNING, -    PROP_SENSOR_VERTICAL_BINNING, -    PROP_SENSOR_MAX_FRAME_RATE, -    PROP_SENSOR_BITDEPTH, -    PROP_EXPOSURE_TIME, -    PROP_ROI_X, -    PROP_ROI_Y, -    PROP_ROI_WIDTH, -    PROP_ROI_HEIGHT, -    PROP_ROI_WIDTH_MULTIPLIER, -    PROP_ROI_HEIGHT_MULTIPLIER, -    PROP_HAS_STREAMING, -    PROP_HAS_CAMRAM_RECORDING, -    PROP_TRIGGER_MODE, -    0, -}; - -typedef struct _RegisterInfo { -    gchar  *name; -    guint   cached_value; -} RegisterInfo; - -static GParamSpec *ufo_properties[N_MAX_PROPERTIES] = { NULL, }; - -static guint N_PROPERTIES; -static GHashTable *ufo_property_table; /* maps from prop_id to RegisterInfo* */ - -struct _UcaUfoCameraPrivate { -    pcilib_t           *handle; -    pcilib_timeout_t    timeout; -    guint               n_bits; -    enum { -        FPGA_48MHZ = 0, -        FPGA_40MHZ -    }                   frequency; -}; - -static void -error_handler (const char *format, ...) -{ -    va_list args; -    gchar *message; - -    va_start (args, format); -    message = g_strdup_vprintf (format, args); -    g_warning ("%s", message); -    va_end (args); -} - -static guint -read_register_value (pcilib_t *handle, const gchar *name) -{ -    pcilib_register_value_t reg_value; - -    pcilib_read_register(handle, NULL, name, ®_value); -    return (guint) reg_value; -} - -static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) -{ -    UcaCamera *camera = UCA_CAMERA(user); -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera); -    size_t error = 0; - -    void *buffer = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &error); - -    if (buffer == NULL) { -        pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL); -        return PCILIB_STREAMING_CONTINUE; -    } - -    camera->grab_func(buffer, camera->user_data); -    pcilib_return_data(priv->handle, event_id, PCILIB_EVENT_DATA, buffer); -    pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL); - -    return PCILIB_STREAMING_CONTINUE; -} - -UcaUfoCamera *uca_ufo_camera_new(GError **error) -{ -    pcilib_model_t model = PCILIB_MODEL_DETECT; -    pcilib_model_description_t *model_description; -    pcilib_t *handle = pcilib_open("/dev/fpga0", model); -    guint prop = PROP_UFO_START; -    guint adc_resolution; - -    if (handle == NULL) { -        g_set_error(error, UCA_UFO_CAMERA_ERROR, UCA_UFO_CAMERA_ERROR_INIT, -                "Initializing pcilib failed"); -        return NULL; -    } - -    pcilib_set_error_handler(&error_handler, &error_handler); - -    /* Generate properties from model description */ -    model_description = pcilib_get_model_description(handle); -    ufo_property_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - -    for (guint i = 0; model_description->registers[i].name != NULL; i++) { -        GParamFlags flags = 0; -        RegisterInfo *reg_info; -        gchar *prop_name; -        pcilib_register_description_t *reg; -        pcilib_register_value_t value; - -        reg = &model_description->registers[i]; - -        switch (reg->mode) { -            case PCILIB_REGISTER_R: -                flags = G_PARAM_READABLE; -                break; -            case PCILIB_REGISTER_W: -            case PCILIB_REGISTER_W1C: -                flags = G_PARAM_WRITABLE; -                break; -            case PCILIB_REGISTER_RW: -            case PCILIB_REGISTER_RW1C: -                flags = G_PARAM_READWRITE; -                break; -        } - -        pcilib_read_register (handle, NULL, reg->name, &value); -        reg_info = g_new0 (RegisterInfo, 1); -        reg_info->name = g_strdup (reg->name); -        reg_info->cached_value = (guint32) value; - -        g_hash_table_insert (ufo_property_table, GINT_TO_POINTER (prop), reg_info); -        prop_name = g_strdup_printf ("ufo-%s", reg->name); - -        ufo_properties[prop++] = g_param_spec_uint ( -                prop_name, reg->description, reg->description, -                0, G_MAXUINT, reg->defvalue, flags); - -        g_free (prop_name); -    } - -    N_PROPERTIES = prop; - -    UcaUfoCamera *camera = g_object_new(UCA_TYPE_UFO_CAMERA, NULL); -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera); - -    priv->frequency = read_register_value (handle, "bit_mode"); -    adc_resolution = read_register_value (handle, "adc_resolution"); - -    switch (adc_resolution) { -        case 0: -            priv->n_bits = 10; -            break; -        case 1: -            priv->n_bits = 11; -            break; -        case 2: -            priv->n_bits = 12; -            break; -    } - -    priv->handle = handle; - -    return camera; -} - -static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error) -{ -    UcaUfoCameraPrivate *priv; -    gdouble exposure_time; -    int     err; - -    g_return_if_fail(UCA_IS_UFO_CAMERA(camera)); - -    priv = UCA_UFO_CAMERA_GET_PRIVATE(camera); -    err = pcilib_start(priv->handle, PCILIB_EVENT_DATA, PCILIB_EVENT_FLAGS_DEFAULT); -    PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING); - -    gboolean transfer_async = FALSE; -    g_object_get(G_OBJECT(camera), -            "transfer-asynchronously", &transfer_async, -            "exposure-time", &exposure_time, -            NULL); - -    priv->timeout = ((pcilib_timeout_t) (exposure_time * 1000 + 50.0) * 1000); - -    if (transfer_async) { -        pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL); -        pcilib_stream(priv->handle, &event_callback, camera); -    } -} - -static void uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_UFO_CAMERA(camera)); -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera); -    int err = pcilib_stop(priv->handle, PCILIB_EVENT_FLAGS_DEFAULT); -    PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING); -} - -static void uca_ufo_camera_start_readout(UcaCamera *camera, GError **error) -{ -    g_return_if_fail(UCA_IS_UFO_CAMERA(camera)); -    g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED, -            "Ufo camera does not support recording to internal memory"); -} - -static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error) -{ -    g_return_if_fail(UCA_IS_UFO_CAMERA(camera)); -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera); -    pcilib_event_id_t   event_id; -    pcilib_event_info_t event_info; -    size_t err; - -    const gsize size = SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16); - -    err = pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL); -    PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_TRIGGER); - -    err = pcilib_get_next_event(priv->handle, priv->timeout, &event_id, sizeof(pcilib_event_info_t), &event_info); -    PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NEXT_EVENT); - -    if (*data == NULL) -        *data = g_malloc0(SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16)); - -    gpointer src = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &err); - -    if (src == NULL) -        PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NO_DATA); - -    /* -     * Apparently, we checked that err equals total size in previous version. -     * This is problematic because errno is positive and size could be equal -     * even when an error condition is met, e.g. with a very small ROI. However, -     * we don't know if src will always be NULL when an error occured. -     */ -    /* assert(err == size); */ - -    memcpy(*data, src, size); - -    /* -     * Another problem here. What does this help us? At this point we have -     * already overwritten the original buffer but can only know here if the -     * data is corrupted. -     */ -    err = pcilib_return_data(priv->handle, event_id, PCILIB_EVENT_DATA, data); -    PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED); -} - -static void -uca_ufo_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_EXPOSURE_TIME: -            { -                const guint frequency = priv->frequency == FPGA_40MHZ ? 40 : 48; -                pcilib_register_value_t reg_value = (pcilib_register_value_t) 129 / frequency * 1000 * 1000 * g_value_get_double(value); -                pcilib_write_register(priv->handle, NULL, "cmosis_exp_time", reg_value); -            } -            break; -        case PROP_ROI_X: -        case PROP_ROI_Y: -        case PROP_ROI_WIDTH: -        case PROP_ROI_HEIGHT: -            g_debug("ROI feature not implemented yet"); -            break; - -        default: -            { -                RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id)); - -                if (reg_info != NULL) { -                    pcilib_register_value_t reg_value; - -                    reg_value = g_value_get_uint (value); -                    pcilib_write_register(priv->handle, NULL, reg_info->name, reg_value); -                    pcilib_read_register (priv->handle, NULL, reg_info->name, ®_value); -                    reg_info->cached_value = (guint) reg_value; -                } -                else -                    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            } -            return; -    } -} - - -static void -uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object); - -    switch (property_id) { -        case PROP_SENSOR_WIDTH: -            g_value_set_uint(value, SENSOR_WIDTH); -            break; -        case PROP_SENSOR_HEIGHT: -            g_value_set_uint(value, SENSOR_HEIGHT); -            break; -        case PROP_SENSOR_BITDEPTH: -            g_value_set_uint (value, priv->n_bits); -            break; -        case PROP_SENSOR_HORIZONTAL_BINNING: -            g_value_set_uint(value, 1); -            break; -        case PROP_SENSOR_VERTICAL_BINNING: -            g_value_set_uint(value, 1); -            break; -        case PROP_SENSOR_MAX_FRAME_RATE: -            g_value_set_float(value, 340.0); -            break; -        case PROP_SENSOR_TEMPERATURE: -            { -                const double a = priv->frequency == FPGA_48MHZ ? 0.3 : 0.25; -                const double b = priv->frequency == FPGA_48MHZ ? 1000 : 1200; -                guint32 temperature; - -                temperature = read_register_value (priv->handle, "sensor_temperature"); -                g_value_set_double (value, a * (temperature - b)); -            } -            break; -        case PROP_FPGA_TEMPERATURE: -            { -                const double a = 503.975 / 1024.0; -                const double b = 273.15; -                guint32 temperature; - -                temperature = read_register_value (priv->handle, "fpga_temperature"); -                g_value_set_double (value, a * temperature - b); -            } -            break; -        case PROP_EXPOSURE_TIME: -            { -                const gdouble frequency = priv->frequency == FPGA_40MHZ ? 40.0 : 48.0; -                g_value_set_double (value, read_register_value (priv->handle, "cmosis_exp_time") * 129 / frequency / 1000 / 1000 ); -            } -            break; -        case PROP_HAS_STREAMING: -            g_value_set_boolean(value, TRUE); -            break; -        case PROP_HAS_CAMRAM_RECORDING: -            g_value_set_boolean(value, FALSE); -            break; -        case PROP_ROI_X: -            g_value_set_uint(value, 0); -            break; -        case PROP_ROI_Y: -            g_value_set_uint(value, 0); -            break; -        case PROP_ROI_WIDTH: -            g_value_set_uint(value, SENSOR_WIDTH); -            break; -        case PROP_ROI_HEIGHT: -            g_value_set_uint(value, SENSOR_HEIGHT); -            break; -        case PROP_ROI_WIDTH_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_ROI_HEIGHT_MULTIPLIER: -            g_value_set_uint(value, 1); -            break; -        case PROP_NAME: -            g_value_set_string(value, "Ufo Camera w/ CMOSIS CMV2000"); -            break; -        case PROP_TRIGGER_MODE: -            break; -        default: -            { -                RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id)); - -                if (reg_info != NULL) -                    g_value_set_uint (value, reg_info->cached_value); -                else -                    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); -            } -            break; -    } -} - -static void uca_ufo_camera_finalize(GObject *object) -{ -    UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object); -    pcilib_close(priv->handle); -    G_OBJECT_CLASS(uca_ufo_camera_parent_class)->finalize(object); -} - -static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass) -{ -    GObjectClass *gobject_class = G_OBJECT_CLASS(klass); -    gobject_class->set_property = uca_ufo_camera_set_property; -    gobject_class->get_property = uca_ufo_camera_get_property; -    gobject_class->finalize = uca_ufo_camera_finalize; - -    UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); -    camera_class->start_recording = uca_ufo_camera_start_recording; -    camera_class->stop_recording = uca_ufo_camera_stop_recording; -    camera_class->start_readout = uca_ufo_camera_start_readout; -    camera_class->grab = uca_ufo_camera_grab; - -    for (guint i = 0; base_overrideables[i] != 0; i++) -        g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]); - -    ufo_properties[PROP_SENSOR_TEMPERATURE] = -        g_param_spec_double("sensor-temperature", -            "Temperature of the sensor", -            "Temperature of the sensor in degree Celsius", -            -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, -            G_PARAM_READABLE); - -    ufo_properties[PROP_FPGA_TEMPERATURE] = -        g_param_spec_double("fpga-temperature", -            "Temperature of the FPGA", -            "Temperature of the FPGA in degree Celsius", -            -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, -            G_PARAM_READABLE); - -    /* -     * This automatic property installation includes the properties created -     * dynamically in uca_ufo_camera_new(). -     */ -    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++) -        g_object_class_install_property(gobject_class, id, ufo_properties[id]); - -    g_type_class_add_private(klass, sizeof(UcaUfoCameraPrivate)); -} - -static void uca_ufo_camera_init(UcaUfoCamera *self) -{ -    self->priv = UCA_UFO_CAMERA_GET_PRIVATE(self); -} diff --git a/src/cameras/uca-ufo-camera.h b/src/cameras/uca-ufo-camera.h deleted file mode 100644 index 0b52ffb..0000000 --- a/src/cameras/uca-ufo-camera.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library 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 Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#ifndef __UCA_UFO_CAMERA_H -#define __UCA_UFO_CAMERA_H - -#include <glib-object.h> -#include "uca-camera.h" - -G_BEGIN_DECLS - -#define UCA_TYPE_UFO_CAMERA             (uca_ufo_camera_get_type()) -#define UCA_UFO_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCamera)) -#define UCA_IS_UFO_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_UFO_CAMERA)) -#define UCA_UFO_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_UFO_CAMERA, UcaUfoCameraClass)) -#define UCA_IS_UFO_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_UFO_CAMERA)) -#define UCA_UFO_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCameraClass)) - -#define UCA_UFO_CAMERA_ERROR uca_ufo_camera_error_quark() -typedef enum { -    UCA_UFO_CAMERA_ERROR_INIT, -    UCA_UFO_CAMERA_ERROR_START_RECORDING, -    UCA_UFO_CAMERA_ERROR_STOP_RECORDING, -    UCA_UFO_CAMERA_ERROR_TRIGGER, -    UCA_UFO_CAMERA_ERROR_NEXT_EVENT, -    UCA_UFO_CAMERA_ERROR_NO_DATA, -    UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED -} UcaUfoCameraError; - -typedef struct _UcaUfoCamera           UcaUfoCamera; -typedef struct _UcaUfoCameraClass      UcaUfoCameraClass; -typedef struct _UcaUfoCameraPrivate    UcaUfoCameraPrivate; - -/** - * UcaUfoCamera: - * - * Creates #UcaUfoCamera instances by loading corresponding shared objects. The - * contents of the #UcaUfoCamera structure are private and should only be - * accessed via the provided API. - */ -struct _UcaUfoCamera { -    /*< private >*/ -    UcaCamera parent; - -    UcaUfoCameraPrivate *priv; -}; - -/** - * UcaUfoCameraClass: - * - * #UcaUfoCamera class - */ -struct _UcaUfoCameraClass { -    /*< private >*/ -    UcaCameraClass parent; -}; - -UcaUfoCamera *uca_ufo_camera_new(GError **error); - -GType uca_ufo_camera_get_type(void); - -G_END_DECLS - -#endif diff --git a/src/uca-camera.c b/src/uca-camera.c index d9d2d6a..53b2d7a 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -15,35 +15,19 @@     with this library; if not, write to the Free Software Foundation, Inc., 51     Franklin St, Fifth Floor, Boston, MA 02110, USA */ +/** + * SECTION:uca-camera + * @Short_description: Base class representing a camera + * @Title: UcaCamera + * + * UcaCamera is the base camera from which a real hardware camera derives from. + */ +  #include <glib.h>  #include "config.h"  #include "uca-camera.h"  #include "uca-enums.h" -#ifdef HAVE_PCO_CL -#include "cameras/uca-pco-camera.h" -#endif - -#ifdef HAVE_PYLON_CAMERA -#include "cameras/uca-pylon-camera.h" -#endif - -#ifdef HAVE_MOCK_CAMERA -#include "cameras/uca-mock-camera.h" -#endif - -#ifdef HAVE_UFO_CAMERA -#include "cameras/uca-ufo-camera.h" -#endif - -#ifdef HAVE_PHOTON_FOCUS -#include "cameras/uca-pf-camera.h" -#endif - -#ifdef HAVE_DEXELA_CL -#include "cameras/uca-dexela-camera.h" -#endif -  #define UCA_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_CAMERA, UcaCameraPrivate))  G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT) @@ -52,7 +36,7 @@ G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT)   * UcaCameraTrigger:   * @UCA_CAMERA_TRIGGER_AUTO: Trigger automatically   * @UCA_CAMERA_TRIGGER_EXTERNAL: Trigger from an external source - * @UCA_CAMERA_TRIGGER_INTERNAL: Trigger internally from software using + * @UCA_CAMERA_TRIGGER_SOFTWARE: Trigger from software using   *      #uca_camera_trigger   */ @@ -63,33 +47,31 @@ G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT)   * @UCA_CAMERA_ERROR_NOT_RECORDING: Camera is not recording   * @UCA_CAMERA_ERROR_NO_GRAB_FUNC: No grab callback was set   * @UCA_CAMERA_ERROR_NOT_IMPLEMENTED: Virtual function is not implemented + * @UCA_CAMERA_ERROR_END_OF_STREAM: Data stream has ended.   */  GQuark uca_camera_error_quark()  { -    return g_quark_from_static_string("uca-camera-error-quark"); +    return g_quark_from_static_string ("uca-camera-error-quark");  } -static gchar *uca_camera_types[] = { -#ifdef HAVE_PCO_CL -        "pco", -#endif -#ifdef HAVE_PYLON_CAMERA -        "pylon", -#endif -#ifdef HAVE_MOCK_CAMERA -        "mock", -#endif -#ifdef HAVE_UFO_CAMERA -        "ufo", -#endif -#ifdef HAVE_PHOTON_FOCUS -        "pf", -#endif -#ifdef HAVE_DEXELA_CL -		"dexela", -#endif -        NULL -}; +/** + * UcaUnit: + * @UCA_UNIT_NA: Not applicable + * @UCA_UNIT_METER: Length in SI meter + * @UCA_UNIT_SECOND: Time in SI second + * @UCA_UNIT_PIXEL: Number of pixels in one dimension + * @UCA_UNIT_DEGREE_CELSIUS: Temperature in degree Celsius + * @UCA_UNIT_COUNT: Generic number + * + * Units should be registered by camera implementations using + * uca_camera_register_unit() and can be queried by client programs with + * uca_camera_get_unit(). + */ + +GQuark uca_unit_quark () +{ +    return g_quark_from_static_string ("uca-unit-quark"); +}  enum {      LAST_SIGNAL @@ -112,6 +94,7 @@ const gchar *uca_camera_props[N_BASE_PROPERTIES] = {      "sensor-max-frame-rate",      "trigger-mode",      "exposure-time", +    "frames-per-second",      "roi-x0",      "roi-y0",      "roi-width", @@ -120,6 +103,7 @@ const gchar *uca_camera_props[N_BASE_PROPERTIES] = {      "roi-height-multiplier",      "has-streaming",      "has-camram-recording", +    "recorded-frames",      "transfer-asynchronously",      "is-recording",      "is-readout" @@ -133,7 +117,14 @@ struct _UcaCameraPrivate {      gboolean transfer_async;  }; -static void uca_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +static void +uca_camera_set_property_unit (GParamSpec *pspec, UcaUnit unit) +{ +    g_param_spec_set_qdata (pspec, UCA_UNIT_QUARK, GINT_TO_POINTER (unit)); +} + +static void +uca_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)  {      UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); @@ -147,26 +138,53 @@ static void uca_camera_set_property(GObject *object, guint property_id, const GV              priv->transfer_async = g_value_get_boolean(value);              break; +        case PROP_FRAMES_PER_SECOND: +            { +                gdouble frames_per_second; + +                frames_per_second = g_value_get_double (value); +                g_object_set (object, "exposure-time", 1. / frames_per_second, NULL); +            } +            break; +          default:              G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);      }  } -static void uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +static void +uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)  { -    UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); +    UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE (object);      switch (property_id) {          case PROP_IS_RECORDING: -            g_value_set_boolean(value, priv->is_recording); +            g_value_set_boolean (value, priv->is_recording);              break;          case PROP_IS_READOUT: -            g_value_set_boolean(value, priv->is_readout); +            g_value_set_boolean (value, priv->is_readout);              break;          case PROP_TRANSFER_ASYNCHRONOUSLY: -            g_value_set_boolean(value, priv->transfer_async); +            g_value_set_boolean (value, priv->transfer_async); +            break; + +        case PROP_TRIGGER_MODE: +            g_value_set_enum (value, UCA_CAMERA_TRIGGER_AUTO); +            break; + +        case PROP_FRAMES_PER_SECOND: +            { +                gdouble exposure_time; + +                g_object_get (object, "exposure-time", &exposure_time, NULL); +                g_value_set_double (value, 1. / exposure_time); +            } +            break; + +        case PROP_RECORDED_FRAMES: +            g_value_set_uint (value, 0);              break;          default: @@ -174,11 +192,19 @@ static void uca_camera_get_property(GObject *object, guint property_id, GValue *      }  } -static void uca_camera_class_init(UcaCameraClass *klass) +static void +uca_camera_finalize (GObject *object) +{ +    G_OBJECT_CLASS (uca_camera_parent_class)->finalize (object); +} + +static void +uca_camera_class_init (UcaCameraClass *klass)  {      GObjectClass *gobject_class = G_OBJECT_CLASS(klass);      gobject_class->set_property = uca_camera_set_property;      gobject_class->get_property = uca_camera_get_property; +    gobject_class->finalize = uca_camera_finalize;      klass->start_recording = NULL;      klass->stop_recording = NULL; @@ -310,6 +336,13 @@ static void uca_camera_class_init(UcaCameraClass *klass)              0.0, G_MAXDOUBLE, 1.0,              G_PARAM_READWRITE); +    camera_properties[PROP_FRAMES_PER_SECOND] = +        g_param_spec_double(uca_camera_props[PROP_FRAMES_PER_SECOND], +            "Frames per second", +            "Frames per second", +            0.0, G_MAXDOUBLE, 1.0, +            G_PARAM_READWRITE); +      camera_properties[PROP_HAS_STREAMING] =          g_param_spec_boolean(uca_camera_props[PROP_HAS_STREAMING],              "Streaming capability", @@ -322,6 +355,20 @@ static void uca_camera_class_init(UcaCameraClass *klass)              "Is the camera able to record the data in-camera",              FALSE, G_PARAM_READABLE); +    /** +     * UcaCamera:recorded-frames +     * +     * Number of frames that are recorded into internal camera memory. +     * +     * Since: 1.1 +     */ +    camera_properties[PROP_RECORDED_FRAMES] = +        g_param_spec_uint(uca_camera_props[PROP_RECORDED_FRAMES], +            "Number of frames recorded into internal camera memory", +            "Number of frames recorded into internal camera memory", +            0, G_MAXUINT, 0, +            G_PARAM_READABLE); +      camera_properties[PROP_TRANSFER_ASYNCHRONOUSLY] =          g_param_spec_boolean(uca_camera_props[PROP_TRANSFER_ASYNCHRONOUSLY],              "Specify whether data should be transfered asynchronously", @@ -346,7 +393,8 @@ static void uca_camera_class_init(UcaCameraClass *klass)      g_type_class_add_private(klass, sizeof(UcaCameraPrivate));  } -static void uca_camera_init(UcaCamera *camera) +static void +uca_camera_init (UcaCamera *camera)  {      camera->grab_func = NULL; @@ -355,105 +403,21 @@ static void uca_camera_init(UcaCamera *camera)      camera->priv->is_readout = FALSE;      camera->priv->transfer_async = FALSE; -    /* -     * This here would be the best place to instantiate the tango server object, -     * along these lines: -     * -     * // I'd prefer if you expose a single C method, so we don't have to -     * // compile uca-camera.c with g++ -     * tango_handle = tango_server_new(camera); -     * -     * void tango_server_new(UcaCamera *camera) -     * { -     *     // Do whatever is necessary. In the end you will have some kind of -     *     // Tango object t which needs to somehow hook up to the properties. A -     *     // list of all available properties can be enumerated with -     *     // g_object_class_list_properties(G_OBJECT_CLASS(camera), -     *     //     &n_properties); -     * -     *     // For setting/getting properties, use g_object_get/set_property() or -     *     // g_object_get/set() whatever is more suitable. -     * } -     */ -} - -static UcaCamera *uca_camera_new_from_type(const gchar *type, GError **error) -{ -#ifdef HAVE_MOCK_CAMERA -    if (!g_strcmp0(type, "mock")) -        return UCA_CAMERA(uca_mock_camera_new(error)); -#endif - -#ifdef HAVE_PCO_CL -    if (!g_strcmp0(type, "pco")) -        return UCA_CAMERA(uca_pco_camera_new(error)); -#endif - -#ifdef HAVE_PYLON_CAMERA -    if (!g_strcmp0(type, "pylon")) -        return UCA_CAMERA(uca_pylon_camera_new(error)); -#endif - -#ifdef HAVE_UFO_CAMERA -    if (!g_strcmp0(type, "ufo")) -        return UCA_CAMERA(uca_ufo_camera_new(error)); -#endif - -#ifdef HAVE_PHOTON_FOCUS -    if (!g_strcmp0(type, "pf")) -        return UCA_CAMERA(uca_pf_camera_new(error)); -#endif - -#ifdef HAVE_DEXELA_CL -    if (!g_strcmp0(type, "dexela")) -        return UCA_CAMERA(uca_dexela_camera_new(error)); -#endif - -    return NULL; -} - -/** - * uca_camera_get_types: - * - * Enumerate all camera types that can be instantiated with uca_camera_new(). - * - * Returns: An array of strings with camera types. The list should be freed with - * g_strfreev(). - */ -gchar **uca_camera_get_types() -{ -    return g_strdupv(uca_camera_types); -} - -/** - * uca_camera_new: - * @type: Type name of the camera - * @error: Location to store an error or %NULL - * - * Factory method for instantiating cameras by names listed in - * uca_camera_get_types(). - * - * Returns: A new #UcaCamera of the correct type or %NULL if type was not found - */ -UcaCamera *uca_camera_new(const gchar *type, GError **error) -{ -    UcaCamera *camera = NULL; -    GError *tmp_error = NULL; - -    camera = uca_camera_new_from_type(type, &tmp_error); - -    if (tmp_error != NULL) { -        g_propagate_error(error, tmp_error); -        return NULL; -    } - -    if ((tmp_error == NULL) && (camera == NULL)) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_FOUND, -                "Camera type %s not found", type); -        return NULL; -    } - -    return camera; +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_WIDTH], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HEIGHT], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_BITDEPTH], UCA_UNIT_COUNT); +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HORIZONTAL_BINNING], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_VERTICAL_BINNING], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_SENSOR_MAX_FRAME_RATE], UCA_UNIT_COUNT); +    uca_camera_set_property_unit (camera_properties[PROP_EXPOSURE_TIME], UCA_UNIT_SECOND); +    uca_camera_set_property_unit (camera_properties[PROP_FRAMES_PER_SECOND], UCA_UNIT_COUNT); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_X], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_Y], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT], UCA_UNIT_PIXEL); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH_MULTIPLIER], UCA_UNIT_COUNT); +    uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT_MULTIPLIER], UCA_UNIT_COUNT); +    uca_camera_set_property_unit (camera_properties[PROP_RECORDED_FRAMES], UCA_UNIT_COUNT);  }  /** @@ -465,38 +429,47 @@ UcaCamera *uca_camera_new(const gchar *type, GError **error)   * #UcaCameraGrabFunc callback is set, frames are automatically transfered to   * the client program, otherwise you must use uca_camera_grab().   */ -void uca_camera_start_recording(UcaCamera *camera, GError **error) +void +uca_camera_start_recording (UcaCamera *camera, GError **error)  { -    g_return_if_fail(UCA_IS_CAMERA(camera)); +    UcaCameraClass *klass; +    GError *tmp_error = NULL; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + +    g_return_if_fail (UCA_IS_CAMERA (camera)); -    UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); +    klass = UCA_CAMERA_GET_CLASS (camera); -    g_return_if_fail(klass != NULL); -    g_return_if_fail(klass->start_recording != NULL); +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->start_recording != NULL); + +    g_static_mutex_lock (&mutex);      if (camera->priv->is_recording) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,                  "Camera is already recording"); -        return; +        goto start_recording_unlock;      }      if (camera->priv->transfer_async && (camera->grab_func == NULL)) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC, +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC,                  "No grab callback function set"); -        return; +        goto start_recording_unlock;      } -    GError *tmp_error = NULL;      (*klass->start_recording)(camera, &tmp_error);      if (tmp_error == NULL) {          camera->priv->is_readout = FALSE;          camera->priv->is_recording = TRUE;          /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ -        g_object_notify(G_OBJECT(camera), "is-recording"); +        g_object_notify (G_OBJECT (camera), "is-recording");      }      else -        g_propagate_error(error, tmp_error); +        g_propagate_error (error, tmp_error); + +start_recording_unlock: +    g_static_mutex_unlock (&mutex);  }  /** @@ -506,32 +479,41 @@ void uca_camera_start_recording(UcaCamera *camera, GError **error)   *   * Stop recording.   */ -void uca_camera_stop_recording(UcaCamera *camera, GError **error) +void +uca_camera_stop_recording (UcaCamera *camera, GError **error)  { -    g_return_if_fail(UCA_IS_CAMERA(camera)); +    UcaCameraClass *klass; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; -    UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); +    g_return_if_fail (UCA_IS_CAMERA (camera)); -    g_return_if_fail(klass != NULL); -    g_return_if_fail(klass->stop_recording != NULL); +    klass = UCA_CAMERA_GET_CLASS (camera); -    if (!camera->priv->is_recording) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, -                "Camera is not recording"); -        return; -    } +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->stop_recording != NULL); -    GError *tmp_error = NULL; -    (*klass->stop_recording)(camera, &tmp_error); +    g_static_mutex_lock (&mutex); -    if (tmp_error == NULL) { -        camera->priv->is_readout = FALSE; -        camera->priv->is_recording = FALSE; -        /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ -        g_object_notify(G_OBJECT(camera), "is-recording"); +    if (!camera->priv->is_recording) { +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, +                     "Camera is not recording");      } -    else -        g_propagate_error(error, tmp_error); +    else { +        GError *tmp_error = NULL; + +        (*klass->stop_recording)(camera, &tmp_error); + +        if (tmp_error == NULL) { +            camera->priv->is_readout = FALSE; +            camera->priv->is_recording = FALSE; +            /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ +            g_object_notify (G_OBJECT (camera), "is-recording"); +        } +        else +            g_propagate_error (error, tmp_error); +    } + +    g_static_mutex_unlock (&mutex);  }  /** @@ -544,31 +526,84 @@ void uca_camera_stop_recording(UcaCamera *camera, GError **error)   * uca_camera_stop_recording(). Frames have to be picked up with   * ufo_camera_grab().   */ -void uca_camera_start_readout(UcaCamera *camera, GError **error) +void +uca_camera_start_readout (UcaCamera *camera, GError **error)  { -    g_return_if_fail(UCA_IS_CAMERA(camera)); +    UcaCameraClass *klass; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + +    g_return_if_fail (UCA_IS_CAMERA(camera)); -    UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); +    klass = UCA_CAMERA_GET_CLASS(camera); -    g_return_if_fail(klass != NULL); -    g_return_if_fail(klass->start_readout != NULL); +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->start_readout != NULL); + +    g_static_mutex_lock (&mutex);      if (camera->priv->is_recording) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, -                "Camera is still recording"); -        return; +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, +                     "Camera is still recording"); +    } +    else { +        GError *tmp_error = NULL; + +        (*klass->start_readout) (camera, &tmp_error); + +        if (tmp_error == NULL) { +            camera->priv->is_readout = TRUE; +            /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ +            g_object_notify (G_OBJECT (camera), "is-readout"); +        } +        else +            g_propagate_error (error, tmp_error);      } -    GError *tmp_error = NULL; -    (*klass->start_readout)(camera, &tmp_error); +    g_static_mutex_unlock (&mutex); +} -    if (tmp_error == NULL) { -        camera->priv->is_readout = TRUE; -        /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ -        g_object_notify(G_OBJECT(camera), "is-readout"); +/** + * uca_camera_stop_readout: + * @camera: A #UcaCamera object + * @error: Location to store a #UcaCameraError error or %NULL + * + * Stop reading out frames. + * + * Since: 1.1 + */ +void +uca_camera_stop_readout (UcaCamera *camera, GError **error) +{ +    UcaCameraClass *klass; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + +    g_return_if_fail (UCA_IS_CAMERA(camera)); + +    klass = UCA_CAMERA_GET_CLASS(camera); + +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->start_readout != NULL); + +    g_static_mutex_lock (&mutex); + +    if (camera->priv->is_recording) { +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, +                     "Camera is still recording");      } -    else -        g_propagate_error(error, tmp_error); +    else { +        GError *tmp_error = NULL; + +        (*klass->stop_readout) (camera, &tmp_error); + +        if (tmp_error == NULL) { +            camera->priv->is_readout = FALSE; +            g_object_notify (G_OBJECT (camera), "is-readout"); +        } +        else +            g_propagate_error (error, tmp_error); +    } + +    g_static_mutex_unlock (&mutex);  }  /** @@ -579,7 +614,8 @@ void uca_camera_start_readout(UcaCamera *camera, GError **error)   *   * Set the grab function that is called whenever a frame is readily transfered.   */ -void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data) +void +uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data)  {      camera->grab_func = func;      camera->user_data = user_data; @@ -595,22 +631,27 @@ void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointe   * You must have called uca_camera_start_recording() before, otherwise you will   * get a #UCA_CAMERA_ERROR_NOT_RECORDING error.   */ -void uca_camera_trigger(UcaCamera *camera, GError **error) +void +uca_camera_trigger (UcaCamera *camera, GError **error)  { -    g_return_if_fail(UCA_IS_CAMERA(camera)); +    UcaCameraClass *klass; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; -    UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); +    g_return_if_fail (UCA_IS_CAMERA (camera)); -    g_return_if_fail(klass != NULL); -    g_return_if_fail(klass->trigger != NULL); +    klass = UCA_CAMERA_GET_CLASS (camera); -    if (!camera->priv->is_recording) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, -                "Camera is not recording"); -        return; -    } +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->trigger != NULL); + +    g_static_mutex_lock (&mutex); -    (*klass->trigger)(camera, error); +    if (!camera->priv->is_recording) +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is not recording"); +    else +        (*klass->trigger) (camera, error); + +    g_static_mutex_unlock (&mutex);  }  /** @@ -626,23 +667,96 @@ void uca_camera_trigger(UcaCamera *camera, GError **error)   *   * You must have called uca_camera_start_recording() before, otherwise you will   * get a #UCA_CAMERA_ERROR_NOT_RECORDING error. + * + * If *data is %NULL after returning from uca_camera_grab() and error is also + * %NULL, the data stream has ended. For example, with cameras that support + * in-camera memory, all frames have been transfered.   */ -void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error) +void +uca_camera_grab (UcaCamera *camera, gpointer *data, GError **error)  { -    g_return_if_fail(UCA_IS_CAMERA(camera)); +    UcaCameraClass *klass; +    static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + +    g_return_if_fail (UCA_IS_CAMERA(camera)); + +    klass = UCA_CAMERA_GET_CLASS (camera); + +    g_return_if_fail (klass != NULL); +    g_return_if_fail (klass->grab != NULL); +    g_return_if_fail (data != NULL); + +    g_static_mutex_lock (&mutex); + +    if (!camera->priv->is_recording && !camera->priv->is_readout) +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is neither recording nor in readout mode"); +    else +        (*klass->grab) (camera, data, error); -    UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); +    g_static_mutex_unlock (&mutex); +} -    g_return_if_fail(klass != NULL); -    g_return_if_fail(klass->grab != NULL); -    g_return_if_fail(data != NULL); +/** + * uca_camera_register_unit: + * @camera: A #UcaCamera object + * @prop_name: Name of a property + * @unit: #UcaUnit + * + * Associates @prop_name of @camera with a specific @unit. + * + * Since: 1.1 + */ +void +uca_camera_register_unit (UcaCamera *camera, +                          const gchar *prop_name, +                          UcaUnit unit) +{ +    UcaCameraClass *klass; +    GObjectClass *oclass; +    GParamSpec *pspec; -    if (!camera->priv->is_recording && !camera->priv->is_readout) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, -                "Camera is neither recording nor in readout mode"); +    klass  = UCA_CAMERA_GET_CLASS (camera); +    oclass = G_OBJECT_CLASS (klass); +    pspec  = g_object_class_find_property (oclass, prop_name); + +    if (pspec == NULL) { +        g_warning ("Camera does not have property `%s'", prop_name);          return;      } -    (*klass->grab)(camera, data, error); +    uca_camera_set_property_unit (pspec, unit); +} + +/** + * uca_camera_get_unit: + * @camera: A #UcaCamera object + * @prop_name: Name of a property + * + * Returns the unit associated with @prop_name of @camera. + * + * Returns: A #UcaUnit value associated with @prop_name. If there is none, the + * value will be #UCA_UNIT_NA. + * Since: 1.1 + */ +UcaUnit +uca_camera_get_unit (UcaCamera *camera, +                     const gchar *prop_name) +{ +    UcaCameraClass *klass; +    GObjectClass *oclass; +    GParamSpec *pspec; +    gpointer data; + +    klass  = UCA_CAMERA_GET_CLASS (camera); +    oclass = G_OBJECT_CLASS (klass); +    pspec  = g_object_class_find_property (oclass, prop_name); + +    if (pspec == NULL) { +        g_warning ("Camera does not have property `%s'", prop_name); +        return UCA_UNIT_NA; +    } + +    data = g_param_spec_get_qdata (pspec, UCA_UNIT_QUARK); +    return data == NULL ? UCA_UNIT_NA : GPOINTER_TO_INT (data);  } diff --git a/src/uca-camera.h b/src/uca-camera.h index 8924fa8..87996c6 100644 --- a/src/uca-camera.h +++ b/src/uca-camera.h @@ -29,23 +29,36 @@ G_BEGIN_DECLS  #define UCA_IS_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_CAMERA))  #define UCA_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_CAMERA, UcaCameraClass)) -#define UCA_CAMERA_ERROR uca_camera_error_quark() +#define UCA_CAMERA_ERROR    uca_camera_error_quark() +#define UCA_UNIT_QUARK      uca_unit_quark() +  GQuark uca_camera_error_quark(void); +GQuark uca_unit_quark(void);  typedef enum {      UCA_CAMERA_ERROR_NOT_FOUND,      UCA_CAMERA_ERROR_RECORDING,      UCA_CAMERA_ERROR_NOT_RECORDING,      UCA_CAMERA_ERROR_NO_GRAB_FUNC, -    UCA_CAMERA_ERROR_NOT_IMPLEMENTED +    UCA_CAMERA_ERROR_NOT_IMPLEMENTED, +    UCA_CAMERA_ERROR_END_OF_STREAM  } UcaCameraError;  typedef enum {      UCA_CAMERA_TRIGGER_AUTO, -    UCA_CAMERA_TRIGGER_INTERNAL, +    UCA_CAMERA_TRIGGER_SOFTWARE,      UCA_CAMERA_TRIGGER_EXTERNAL  } UcaCameraTrigger; +typedef enum { +    UCA_UNIT_NA, +    UCA_UNIT_METER, +    UCA_UNIT_SECOND, +    UCA_UNIT_PIXEL, +    UCA_UNIT_DEGREE_CELSIUS, +    UCA_UNIT_COUNT +} UcaUnit; +  typedef struct _UcaCamera           UcaCamera;  typedef struct _UcaCameraClass      UcaCameraClass;  typedef struct _UcaCameraPrivate    UcaCameraPrivate; @@ -63,6 +76,7 @@ enum {      PROP_SENSOR_MAX_FRAME_RATE,      PROP_TRIGGER_MODE,      PROP_EXPOSURE_TIME, +    PROP_FRAMES_PER_SECOND,      PROP_ROI_X,      PROP_ROI_Y,      PROP_ROI_WIDTH, @@ -71,6 +85,7 @@ enum {      PROP_ROI_HEIGHT_MULTIPLIER,      PROP_HAS_STREAMING,      PROP_HAS_CAMRAM_RECORDING, +    PROP_RECORDED_FRAMES,      /* These properties are handled internally */      PROP_TRANSFER_ASYNCHRONOUSLY, @@ -110,24 +125,39 @@ struct _UcaCameraClass {      GObjectClass parent;      void (*start_recording) (UcaCamera *camera, GError **error); -    void (*stop_recording) (UcaCamera *camera, GError **error); -    void (*start_readout) (UcaCamera *camera, GError **error); -    void (*trigger) (UcaCamera *camera, GError **error); -    void (*grab) (UcaCamera *camera, gpointer *data, GError **error); +    void (*stop_recording)  (UcaCamera *camera, GError **error); +    void (*start_readout)   (UcaCamera *camera, GError **error); +    void (*stop_readout)    (UcaCamera *camera, GError **error); +    void (*trigger)         (UcaCamera *camera, GError **error); +    void (*grab)            (UcaCamera *camera, gpointer *data, GError **error);      void (*recording_started) (UcaCamera *camera);      void (*recording_stopped) (UcaCamera *camera);  }; -gchar **uca_camera_get_types(); -UcaCamera *uca_camera_new(const gchar *type, GError **error); - -void uca_camera_start_recording(UcaCamera *camera, GError **error); -void uca_camera_stop_recording(UcaCamera *camera, GError **error); -void uca_camera_start_readout(UcaCamera *camera, GError **error); -void uca_camera_trigger(UcaCamera *camera, GError **error); -void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error); -void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data); +UcaCamera * uca_camera_new              (const gchar        *type, +                                         GError            **error); +void        uca_camera_start_recording  (UcaCamera          *camera, +                                         GError            **error); +void        uca_camera_stop_recording   (UcaCamera          *camera, +                                         GError            **error); +void        uca_camera_start_readout    (UcaCamera          *camera, +                                         GError            **error); +void        uca_camera_stop_readout     (UcaCamera          *camera, +                                         GError            **error); +void        uca_camera_trigger          (UcaCamera          *camera, +                                         GError            **error); +void        uca_camera_grab             (UcaCamera          *camera, +                                         gpointer           *data, +                                         GError            **error); +void        uca_camera_set_grab_func    (UcaCamera          *camera, +                                         UcaCameraGrabFunc   func, +                                         gpointer            user_data); +void        uca_camera_register_unit    (UcaCamera          *camera, +                                         const gchar        *prop_name, +                                         UcaUnit             unit); +UcaUnit     uca_camera_get_unit         (UcaCamera          *camera, +                                         const gchar        *prop_name);  GType uca_camera_get_type(void); diff --git a/src/uca-docs.xml.in b/src/uca-docs.xml.in index 43a830d..093fd36 100644 --- a/src/uca-docs.xml.in +++ b/src/uca-docs.xml.in @@ -16,8 +16,8 @@    <chapter>      <title>Unified Camera Access</title> -        <xi:include href="xml/uca-camera.xml"/> -        ${_xml_doc_input} +    <xi:include href="xml/uca-camera.xml"/> +    <xi:include href="xml/uca-plugin-manager.xml"/>    </chapter>    <index id="api-index-full"> diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c new file mode 100644 index 0000000..e99f478 --- /dev/null +++ b/src/uca-plugin-manager.c @@ -0,0 +1,345 @@ +/* Copyright (C) 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> +   (Karlsruhe Institute of Technology) + +   This library is free software; you can redistribute it and/or modify it +   under the terms of the GNU Lesser General Public License as published by the +   Free Software Foundation; either version 2.1 of the License, or (at your +   option) any later version. + +   This library 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 Lesser General Public License for more +   details. + +   You should have received a copy of the GNU Lesser General Public License along +   with this library; if not, write to the Free Software Foundation, Inc., 51 +   Franklin St, Fifth Floor, Boston, MA 02110, USA */ + +/** + * SECTION:uca-plugin-manager + * @Short_description: Load an #UcaFilter from a shared object + * @Title: UcaPluginManager + * + * The plugin manager opens shared object modules searched for in locations + * specified with uca_plugin_manager_add_path(). A #UcaCamera can be + * instantiated with uca_plugin_manager_new_camera() with a one-to-one mapping + * between filter name xyz and module name libucaxyz.so. Any errors are reported + * as one of #UcaPluginManagerError codes. To get a list of available camera + * names call uca_plugin_manager_get_available_cameras(). + * + * By default, any path listed in the %UCA_CAMERA_PATH environment variable is + * added to the search path. + * + * @Since: 1.1 + */ +#include <gmodule.h> +#include "uca-plugin-manager.h" + +G_DEFINE_TYPE (UcaPluginManager, uca_plugin_manager, G_TYPE_OBJECT) + +#define UCA_PLUGIN_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerPrivate)) + +struct _UcaPluginManagerPrivate { +    GList *search_paths; +}; + +static const gchar *MODULE_PATTERN = "libuca([A-Za-z]+)"; + +typedef UcaCamera * (*GetCameraFunc) (GError **error); + +/** + * UcaPluginManagerError: + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND: The module could not be found + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN: Module could not be opened + * @UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND: Necessary entry symbol was not + *      found + * + * Possible errors that uca_plugin_manager_get_filter() can return. + */ +GQuark +uca_plugin_manager_error_quark (void) +{ +    return g_quark_from_static_string ("uca-plugin-manager-error-quark"); +} + +/** + * uca_plugin_manager_new: + * + * Create a plugin manager object to instantiate camera objects. + * + * Return value: A new plugin manager object. + */ +UcaPluginManager * +uca_plugin_manager_new () +{ +    return UCA_PLUGIN_MANAGER (g_object_new (UCA_TYPE_PLUGIN_MANAGER, NULL)); +} + +/** + * uca_plugin_manager_add_path: + * @manager: A #UcaPluginManager + * @path: Path to look for camera modules + * + * Add a search path to the plugin manager. + */ +void +uca_plugin_manager_add_path (UcaPluginManager   *manager, +                             const gchar        *path) +{ +    g_return_if_fail (UCA_IS_PLUGIN_MANAGER (manager)); + +    if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { +        UcaPluginManagerPrivate *priv; + +        priv = manager->priv; +        priv->search_paths = g_list_append (priv->search_paths, +                                            g_strdup (path)); +    } +} + +static GList * +get_camera_module_paths (const gchar *path) +{ +    GRegex *pattern; +    GDir *dir; +    GList *result = NULL; + +    pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); +    dir = g_dir_open (path, 0, NULL); + +    if (dir != NULL) { +        GMatchInfo *match_info = NULL; +        const gchar *name = g_dir_read_name (dir); + +        while (name != NULL) { +            if (g_regex_match (pattern, name, 0, &match_info)) +                result = g_list_append (result, g_build_filename (path, name, NULL)); + +            g_match_info_free (match_info); +            name = g_dir_read_name (dir); +        } +    } + +    return result; +} + +static GList * +scan_search_paths (GList *search_paths) +{ +    GList *camera_paths = NULL; + +    for (GList *it = g_list_first (search_paths); it != NULL; it = g_list_next (it)) { +        camera_paths = g_list_concat (camera_paths, +                                      get_camera_module_paths ((const gchar*) it->data)); +    } + +    return camera_paths; +} + +static void +transform_camera_module_path_to_name (gchar *path, GList **result) +{ +    GRegex *pattern; +    GMatchInfo *match_info; + +    pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); +    g_regex_match (pattern, path, 0, &match_info); + +    *result = g_list_append (*result, g_match_info_fetch (match_info, 1)); +    g_match_info_free (match_info); +} + +static void +list_free_full (GList *list) +{ +    g_list_foreach (list, (GFunc) g_free, NULL); +    g_list_free (list); +} + +/** + * uca_plugin_manager_get_available_cameras: + * @manager: A #UcaPluginManager + * + * Return value: (element-type utf8) (transfer full): A list with strings of + * available camera names. You have to free the individual strings with + * g_list_foreach(list, (GFunc) g_free, NULL) and the list itself with + * g_list_free. + */ +GList * +uca_plugin_manager_get_available_cameras (UcaPluginManager *manager) +{ +    UcaPluginManagerPrivate *priv; +    GList *camera_paths; +    GList *camera_names = NULL; + +    g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager), NULL); + +    priv = manager->priv; +    camera_paths = scan_search_paths (priv->search_paths); + +    g_list_foreach (camera_paths, (GFunc) transform_camera_module_path_to_name, &camera_names); +    list_free_full (camera_paths); + +    return camera_names; +} + +static gchar * +find_camera_module_path (GList *search_paths, const gchar *name) +{ +    gchar *result = NULL; +    GList *paths; + +    paths = scan_search_paths (search_paths); + +    for (GList *it = g_list_first (paths); it != NULL; it = g_list_next (it)) { +        gchar *path = (gchar *) it->data; +        gchar *basename = g_path_get_basename ((gchar *) path); + +        if (g_strrstr (basename, name)) { +            result = g_strdup (path); +            g_free (basename); +            break; +        } + +        g_free (basename); +    } + +    list_free_full (paths); +    return result; +} + +/** + * uca_plugin_manager_get_camera: + * @manager: A #UcaPluginManager + * @name: Name of the camera module, that maps to libuca<name>.so + * @error: Location for a #GError + * + * Create a new camera instance with camera @name. + * + * Returns: (transfer full): A new #UcaCamera object. + */ +UcaCamera * +uca_plugin_manager_get_camera (UcaPluginManager   *manager, +                               const gchar        *name, +                               GError            **error) +{ +    UcaPluginManagerPrivate *priv; +    UcaCamera *camera; +    GModule *module; +    GetCameraFunc *func; +    gchar *module_path; +    GError *tmp_error = NULL; + +    const gchar *symbol_name = "uca_camera_impl_new"; + +    g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL); + +    priv = manager->priv; +    module_path = find_camera_module_path (priv->search_paths, name); + +    if (module_path == NULL) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, +                "Camera module `%s' not found", name); +        return NULL; +    } + +    module = g_module_open (module_path, G_MODULE_BIND_LAZY); +    g_free (module_path); + +    if (!module) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, +                     "Camera module `%s' could not be opened: %s", name, g_module_error ()); +        return NULL; +    } + +    func = g_malloc0 (sizeof (GetCameraFunc)); + +    if (!g_module_symbol (module, symbol_name, (gpointer *) func)) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND, +                     "%s", g_module_error ()); +        g_free (func); + +        if (!g_module_close (module)) +            g_warning ("%s", g_module_error ()); + +        return NULL; +    } + +    camera = (*func) (&tmp_error); + +    if (tmp_error != NULL) { +        g_propagate_error (error, tmp_error); +        return NULL; +    } + +    return camera; +} + +static void +uca_plugin_manager_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ +    switch (property_id) { +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +            break; +    } +} + +static void +uca_plugin_manager_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ +    switch (property_id) { +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +            break; +    } +} + +static void +uca_plugin_manager_dispose (GObject *object) +{ +    G_OBJECT_CLASS (uca_plugin_manager_parent_class)->dispose (object); +} + +static void +uca_plugin_manager_finalize (GObject *object) +{ +    UcaPluginManagerPrivate *priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (object); + +    g_list_foreach (priv->search_paths, (GFunc) g_free, NULL); +    g_list_free (priv->search_paths); + +    G_OBJECT_CLASS (uca_plugin_manager_parent_class)->finalize (object); +} + +static void +uca_plugin_manager_class_init (UcaPluginManagerClass *klass) +{ +    GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +    gobject_class->get_property = uca_plugin_manager_get_property; +    gobject_class->set_property = uca_plugin_manager_set_property; +    gobject_class->dispose      = uca_plugin_manager_dispose; +    gobject_class->finalize     = uca_plugin_manager_finalize; + +    g_type_class_add_private (klass, sizeof (UcaPluginManagerPrivate)); +} + +static void +uca_plugin_manager_init (UcaPluginManager *manager) +{ +    UcaPluginManagerPrivate *priv; +    const gchar *uca_camera_path; + +    manager->priv = priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (manager); +    priv->search_paths = NULL; + +    uca_camera_path = g_getenv ("UCA_CAMERA_PATH"); + +    if (uca_camera_path != NULL) +        uca_plugin_manager_add_path (manager, uca_camera_path); + +    uca_plugin_manager_add_path (manager, "/usr/lib/uca"); +    uca_plugin_manager_add_path (manager, "/usr/lib64/uca"); +    uca_plugin_manager_add_path (manager, "/usr/local/lib/uca"); +    uca_plugin_manager_add_path (manager, "/usr/local/lib64/uca"); +} diff --git a/src/uca-plugin-manager.h b/src/uca-plugin-manager.h new file mode 100644 index 0000000..6c3ab4e --- /dev/null +++ b/src/uca-plugin-manager.h @@ -0,0 +1,65 @@ +#ifndef __UCA_PLUGIN_MANAGER_H +#define __UCA_PLUGIN_MANAGER_H + +#include <glib-object.h> +#include "uca-camera.h" + +G_BEGIN_DECLS + +#define UCA_TYPE_PLUGIN_MANAGER             (uca_plugin_manager_get_type()) +#define UCA_PLUGIN_MANAGER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManager)) +#define UCA_IS_PLUGIN_MANAGER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) +#define UCA_IS_PLUGIN_MANAGER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) + +#define UCA_PLUGIN_MANAGER_ERROR uca_plugin_manager_error_quark() +GQuark uca_plugin_manager_error_quark(void); + +typedef enum { +    UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, +    UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, +    UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND +} UcaPluginManagerError; + +typedef struct _UcaPluginManager           UcaPluginManager; +typedef struct _UcaPluginManagerClass      UcaPluginManagerClass; +typedef struct _UcaPluginManagerPrivate    UcaPluginManagerPrivate; + +/** + * UcaPluginManager: + * + * Creates #UcaFilter instances by loading corresponding shared objects. The + * contents of the #UcaPluginManager structure are private and should only be + * accessed via the provided API. + */ +struct _UcaPluginManager { +    /*< private >*/ +    GObject parent_instance; + +    UcaPluginManagerPrivate *priv; +}; + +/** + * UcaPluginManagerClass: + * + * #UcaPluginManager class + */ +struct _UcaPluginManagerClass { +    /*< private >*/ +    GObjectClass parent_class; +}; + +UcaPluginManager    *uca_plugin_manager_new         (void); +void                 uca_plugin_manager_add_path    (UcaPluginManager   *manager, +                                                     const gchar        *path); +GList               *uca_plugin_manager_get_available_cameras +                                                    (UcaPluginManager   *manager); +UcaCamera           *uca_plugin_manager_get_camera  (UcaPluginManager   *manager, +                                                     const gchar        *name, +                                                     GError            **error); +GType                uca_plugin_manager_get_type    (void); + +G_END_DECLS + +#endif diff --git a/src/uca.types.in b/src/uca.types.in index a9ce408..7526948 100644 --- a/src/uca.types.in +++ b/src/uca.types.in @@ -1,2 +1,2 @@  uca_camera_get_type -${_types_input} +uca_plugin_manager_get_type  | 
