diff options
| -rw-r--r-- | plugins/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | plugins/file/CMakeLists.txt | 26 | ||||
| -rw-r--r-- | plugins/file/uca-file-camera.c | 350 | ||||
| -rw-r--r-- | plugins/file/uca-file-camera.h | 63 | 
4 files changed, 441 insertions, 1 deletions
| diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b630171..dbfb1b7 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,6 +1,7 @@  set(UCA_CONFIGDIR "${CMAKE_CURRENT_BINARY_DIR}/../src")  add_subdirectory(mock) +add_subdirectory(file)  add_subdirectory(pf)  add_subdirectory(pco)  add_subdirectory(pylon) @@ -9,7 +10,7 @@ add_subdirectory(dexela)  add_subdirectory(xkit)  message("-- Building the following plugins:") -set(_plugins "mock;pf;pco;pylon;ufo;dexela;xkit") +set(_plugins "mock;file;pf;pco;pylon;ufo;dexela;xkit")  foreach(_target ${_plugins})      if (TARGET "uca${_target}") diff --git a/plugins/file/CMakeLists.txt b/plugins/file/CMakeLists.txt new file mode 100644 index 0000000..3955366 --- /dev/null +++ b/plugins/file/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.6) +project(ucafile C) + +find_package(TIFF) + +if (TIFF_FOUND) +    set(UCA_CAMERA_NAME "file") +    set(PLUGIN_VERSION "0.0.1") +    set(PLUGIN_REVISION "0") +    set(PLUGIN_REQUIRES "libuca >= 1.2.0") +    set(PLUGIN_SUMMARY "File plugin for libuca") + +    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../package-plugin.sh.in +                   ${CMAKE_CURRENT_BINARY_DIR}/../../package-plugin-${UCA_CAMERA_NAME}.sh) + +    include_directories(${TIFF_INCLUDE_DIRS}) + +    add_library(ucafile SHARED +                uca-file-camera.c) + +    target_link_libraries(ucafile uca ${UCA_DEPS} ${TIFF_LIBRARIES}) + +    install(TARGETS ucafile +            LIBRARY DESTINATION ${UCA_PLUGINDIR} +            COMPONENT ${UCA_CAMERA_NAME}) +endif () diff --git a/plugins/file/uca-file-camera.c b/plugins/file/uca-file-camera.c new file mode 100644 index 0000000..5f7414c --- /dev/null +++ b/plugins/file/uca-file-camera.c @@ -0,0 +1,350 @@ +/* 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 <gmodule.h> +#include <gio/gio.h> +#include <string.h> +#include <tiffio.h> +#include "uca-file-camera.h" + +#define UCA_FILE_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_FILE_CAMERA, UcaFileCameraPrivate)) + +static void uca_file_initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (UcaFileCamera, uca_file_camera, UCA_TYPE_CAMERA, +                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, +                                                uca_file_initable_iface_init)) + +enum { +    PROP_PATH = N_BASE_PROPERTIES, +    N_PROPERTIES +}; + +static const gint file_overrideables[] = { +    PROP_NAME, +    PROP_SENSOR_WIDTH, +    PROP_SENSOR_HEIGHT, +    PROP_SENSOR_BITDEPTH, +    PROP_SENSOR_MAX_FRAME_RATE, +    PROP_EXPOSURE_TIME, +    PROP_ROI_X, +    PROP_ROI_Y, +    PROP_ROI_WIDTH, +    PROP_ROI_HEIGHT, +    PROP_HAS_STREAMING, +    PROP_HAS_CAMRAM_RECORDING, +    0, +}; + +static GParamSpec *file_properties[N_PROPERTIES] = { NULL, }; + +struct _UcaFileCameraPrivate { +    gchar *path; +    guint width; +    guint height; +    guint bitdepth; +    GList *fnames; +    GList *current; +}; + +static void +read_tiff_meta_data (UcaFileCameraPrivate *priv, const gchar *fname) +{ +    TIFF *file; + +    file = TIFFOpen (fname, "r"); + +    TIFFGetField (file, TIFFTAG_BITSPERSAMPLE, &priv->bitdepth); +    TIFFGetField (file, TIFFTAG_IMAGEWIDTH, &priv->width); +    TIFFGetField (file, TIFFTAG_IMAGELENGTH, &priv->height); + +    TIFFClose (file); +} + + +static gboolean +read_tiff_data (UcaFileCameraPrivate *priv, const gchar *fname, gpointer buffer) +{ +    TIFF *file; +    guint bitdepth; +    guint width; +    guint height; +    tsize_t result; +    int offset = 0; +    int step = priv->width; + +    file = TIFFOpen (fname, "r"); + +    TIFFGetField (file, TIFFTAG_BITSPERSAMPLE, &bitdepth); +    TIFFGetField (file, TIFFTAG_IMAGEWIDTH, &width); +    TIFFGetField (file, TIFFTAG_IMAGELENGTH, &height); + +    if (priv->bitdepth != bitdepth || priv->width != width || priv->height != height) { +        g_warning ("Data format not compatible: %ux%u@%u [expected %ux%u@%u]", +                   width, height, bitdepth, priv->width, priv->height, priv->bitdepth); +        TIFFClose (file); +        return FALSE; +    } + +    if (priv->bitdepth > 8) { +        step *= priv->bitdepth <= 16 ? 2 : 4; +    } + +    for (guint32 i = 0; i < priv->height; i++) { +        result = TIFFReadScanline (file, ((gchar *) buffer) + offset, i, 0); + +        if (result == -1) +            return FALSE; + +        offset += step; +    } + +    TIFFClose (file); +    return TRUE; +} + +static gboolean +update_fnames (UcaFileCameraPrivate *priv, GError **error) +{ +    GDir *dir; +    const gchar *fname; + +    g_list_free_full (priv->fnames, g_free); +    priv->fnames = NULL; + +    dir = g_dir_open (priv->path, 0, error); + +    if (dir == NULL) +        return FALSE; + +    while (1) { +        fname = g_dir_read_name (dir); + +        if (fname == NULL) +            break; + +        if (g_str_has_suffix (fname, ".tiff") || g_str_has_suffix (fname, ".tif")) +            priv->fnames = g_list_append (priv->fnames, g_strdup (fname)); +    } + +    priv->fnames = g_list_sort (priv->fnames, (GCompareFunc) g_strcmp0); +    priv->current = priv->fnames; + +    if (priv->current != NULL) +        read_tiff_meta_data (priv, (const gchar *) priv->current->data); + +    g_dir_close (dir); +    return TRUE; +} + +static void +uca_file_camera_start_recording(UcaCamera *camera, GError **error) +{ +    UcaFileCameraPrivate *priv; +    g_return_if_fail (UCA_IS_FILE_CAMERA (camera)); + +    priv = UCA_FILE_CAMERA_GET_PRIVATE (camera); + +    if (priv->fnames == NULL) { +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM, +                     "No files found"); +    } + +    priv->current = priv->fnames; +} + +static void +uca_file_camera_stop_recording(UcaCamera *camera, GError **error) +{ +} + +static void +uca_file_camera_trigger (UcaCamera *camera, GError **error) +{ +} + +static gboolean +uca_file_camera_grab (UcaCamera *camera, gpointer data, GError **error) +{ +    UcaFileCameraPrivate *priv; +    g_return_val_if_fail (UCA_IS_FILE_CAMERA (camera), FALSE); + +    priv = UCA_FILE_CAMERA_GET_PRIVATE (camera); + +    if (priv->current == NULL) { +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM, +                     "End of stream"); +        return FALSE; +    } + +    if (!read_tiff_data (priv, (const gchar *) priv->current->data, data)) { +        g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM, +                     "Error reading file"); +        return FALSE; +    } + +    priv->current = g_list_next (priv->current); +    return TRUE; +} + +static void +uca_file_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ +    g_return_if_fail(UCA_IS_FILE_CAMERA(object)); +    UcaFileCameraPrivate *priv = UCA_FILE_CAMERA_GET_PRIVATE(object); + +    switch (property_id) { +        case PROP_PATH: +            g_free (priv->path); +            priv->path = g_strdup (g_value_get_string (value)); +            update_fnames (priv, NULL); +            break; +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); +            return; +    } +} + +static void +uca_file_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ +    UcaFileCameraPrivate *priv = UCA_FILE_CAMERA_GET_PRIVATE(object); + +    switch (property_id) { +        case PROP_NAME: +            g_value_set_string (value, "file 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, priv->bitdepth); +            break; +        case PROP_SENSOR_MAX_FRAME_RATE: +            g_value_set_float (value, 100.0f); +            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, priv->width); +            break; +        case PROP_ROI_HEIGHT: +            g_value_set_uint (value, priv->height); +            break; +        case PROP_EXPOSURE_TIME: +            g_value_set_double (value, 0.1); +            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_PATH: +            g_value_set_string (value, priv->path); +            break; +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); +            break; +    } +} + +static void +uca_file_camera_finalize(GObject *object) +{ +    UcaFileCameraPrivate *priv; + +    priv = UCA_FILE_CAMERA_GET_PRIVATE(object); + +    g_list_free_full (priv->fnames, g_free); +    priv->fnames = NULL; + +    G_OBJECT_CLASS(uca_file_camera_parent_class)->finalize(object); +} + +static gboolean +ufo_file_camera_initable_init (GInitable *initable, +                               GCancellable *cancellable, +                               GError **error) +{ +    g_return_val_if_fail (UCA_IS_FILE_CAMERA (initable), FALSE); +    return TRUE; +} + +static void +uca_file_initable_iface_init (GInitableIface *iface) +{ +    iface->init = ufo_file_camera_initable_init; +} + +static void +uca_file_camera_class_init(UcaFileCameraClass *klass) +{ +    GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +    gobject_class->set_property = uca_file_camera_set_property; +    gobject_class->get_property = uca_file_camera_get_property; +    gobject_class->finalize = uca_file_camera_finalize; + +    UcaCameraClass *camera_class = UCA_CAMERA_CLASS (klass); +    camera_class->start_recording = uca_file_camera_start_recording; +    camera_class->stop_recording = uca_file_camera_stop_recording; +    camera_class->grab = uca_file_camera_grab; +    camera_class->trigger = uca_file_camera_trigger; + +    for (guint i = 0; file_overrideables[i] != 0; i++) +        g_object_class_override_property (gobject_class, file_overrideables[i], uca_camera_props[file_overrideables[i]]); + +    file_properties[PROP_PATH] = +        g_param_spec_string ("path", +                "Path to directory containing TIFF files", +                "Path to directory containing TIFF files", +                ".", +                G_PARAM_READWRITE); + +    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++) +        g_object_class_install_property (gobject_class, id, file_properties[id]); + +    g_type_class_add_private (klass, sizeof(UcaFileCameraPrivate)); +} + +static void +uca_file_camera_init(UcaFileCamera *self) +{ +    UcaFileCameraPrivate *priv; + +    self->priv = priv = UCA_FILE_CAMERA_GET_PRIVATE(self); +    priv->path = g_strdup ("."); +    priv->width = 512; +    priv->height = 512; +    priv->bitdepth = 8; + +    priv->fnames = NULL; +    update_fnames (priv, NULL); +} + +G_MODULE_EXPORT GType +uca_camera_get_type (void) +{ +    return UCA_TYPE_FILE_CAMERA; +} diff --git a/plugins/file/uca-file-camera.h b/plugins/file/uca-file-camera.h new file mode 100644 index 0000000..b7ce2c3 --- /dev/null +++ b/plugins/file/uca-file-camera.h @@ -0,0 +1,63 @@ +/* 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_FILE_CAMERA_H +#define __UCA_FILE_CAMERA_H + +#include <glib-object.h> +#include "uca-camera.h" + +G_BEGIN_DECLS + +#define UCA_TYPE_FILE_CAMERA             (uca_file_camera_get_type()) +#define UCA_FILE_CAMERA(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_FILE_CAMERA, UcaFileCamera)) +#define UCA_IS_FILE_CAMERA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_FILE_CAMERA)) +#define UCA_FILE_CAMERA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_FILE_CAMERA, UcaFileCameraClass)) +#define UCA_IS_FILE_CAMERA_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_FILE_CAMERA)) +#define UCA_FILE_CAMERA_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_FILE_CAMERA, UcaFileCameraClass)) + +typedef struct _UcaFileCamera           UcaFileCamera; +typedef struct _UcaFileCameraClass      UcaFileCameraClass; +typedef struct _UcaFileCameraPrivate    UcaFileCameraPrivate; + +/** + * UcaFileCamera: + * + * Creates #UcaFileCamera instances by loading corresponding shared objects. The + * contents of the #UcaFileCamera structure are private and should only be + * accessed via the provided API. + */ +struct _UcaFileCamera { +    /*< private >*/ +    UcaCamera parent; + +    UcaFileCameraPrivate *priv; +}; + +/** + * UcaFileCameraClass: + * + * #UcaFileCamera class + */ +struct _UcaFileCameraClass { +    /*< private >*/ +    UcaCameraClass parent; +}; + +G_END_DECLS + +#endif | 
