diff options
author | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-09-28 18:16:56 +0200 |
---|---|---|
committer | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-09-28 18:16:56 +0200 |
commit | 99b737ae9f3f1d35a4696594821fa3bc39e8aa87 (patch) | |
tree | 73ed9e59018d3a8181397d5ff4afa70d5029da9a /src/cameras/uca-pco-camera.c | |
parent | 0bc642a31600bbfaac15779b8d932a409283ae3f (diff) | |
download | libuca-99b737ae9f3f1d35a4696594821fa3bc39e8aa87.tar.gz libuca-99b737ae9f3f1d35a4696594821fa3bc39e8aa87.tar.bz2 libuca-99b737ae9f3f1d35a4696594821fa3bc39e8aa87.tar.xz libuca-99b737ae9f3f1d35a4696594821fa3bc39e8aa87.zip |
Fix #146: Make a new top-level directory for cams
... and build a package for each camera. Moreover, for some reason we can live
without the CMake generated spec file for RPM generation. AFAICS, the RPMs are
prefixed correctly.
Diffstat (limited to 'src/cameras/uca-pco-camera.c')
-rw-r--r-- | src/cameras/uca-pco-camera.c | 1398 |
1 files changed, 0 insertions, 1398 deletions
diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c deleted file mode 100644 index 8bf2936..0000000 --- a/src/cameras/uca-pco-camera.c +++ /dev/null @@ -1,1398 +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 <gmodule.h> -#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; -} - -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; -} - -G_MODULE_EXPORT UcaCamera * -uca_camera_impl_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 UCA_CAMERA (camera); -} |