/* Copyright (C) 2012 Volker Kaiser (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 #include #include #include #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); }