summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Dritschler <timo.dritschler@kit.edu>2015-05-13 17:06:33 +0200
committerTimo Dritschler <timo.dritschler@kit.edu>2015-05-19 11:37:03 +0200
commit5e24887e06c306552dfd5f48f7ad94cc170bca30 (patch)
tree55f6671b6285f6691e9bc7dc6c27a5a3c18379ba
parent86d398e2029299e5f7de22263f97d770d146cab2 (diff)
downloadlibuca-5e24887e06c306552dfd5f48f7ad94cc170bca30.tar.gz
libuca-5e24887e06c306552dfd5f48f7ad94cc170bca30.tar.bz2
libuca-5e24887e06c306552dfd5f48f7ad94cc170bca30.tar.xz
libuca-5e24887e06c306552dfd5f48f7ad94cc170bca30.zip
UcaCamera base class: Changed properties
Changed sensor-width, sensor-height and sensor-bitdepth to construct only Added uca_camera_pspec_set_writable mock: allow characterization at construction time Its now possible to set sensor-width, sensor-height and sensor-bitdepth at construction time Creation of random data is now controlled by a property and can be set while recording
-rw-r--r--plugins/mock/CMakeLists.txt2
-rw-r--r--plugins/mock/uca-mock-camera.c156
-rw-r--r--src/uca-camera.c29
-rw-r--r--src/uca-camera.h3
4 files changed, 139 insertions, 51 deletions
diff --git a/plugins/mock/CMakeLists.txt b/plugins/mock/CMakeLists.txt
index a22616a..eafd180 100644
--- a/plugins/mock/CMakeLists.txt
+++ b/plugins/mock/CMakeLists.txt
@@ -4,7 +4,7 @@ project(ucamock C)
set(UCA_CAMERA_NAME "mock")
set(PLUGIN_VERSION "1.0.2")
set(PLUGIN_REVISION "1")
-set(PLUGIN_REQUIRES "libuca >= 2.0.0")
+set(PLUGIN_REQUIRES "libuca >= 2.1.0")
set(PLUGIN_SUMMARY "Mock plugin for libuca")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../package-plugin.sh.in
diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c
index a406f93..b1693b3 100644
--- a/plugins/mock/uca-mock-camera.c
+++ b/plugins/mock/uca-mock-camera.c
@@ -22,7 +22,6 @@
#include "uca-mock-camera.h"
#define UCA_MOCK_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraPrivate))
-#define __CREATE_RANDOM_IMAGE_DATA__
static void uca_mock_initable_iface_init (GInitableIface *iface);
@@ -31,7 +30,8 @@ G_DEFINE_TYPE_WITH_CODE (UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA,
uca_mock_initable_iface_init))
enum {
- N_PROPERTIES = N_BASE_PROPERTIES,
+ PROP_CREATE_RANDOM = N_BASE_PROPERTIES,
+ N_PROPERTIES
};
static const gint mock_overrideables[] = {
@@ -54,13 +54,19 @@ static GParamSpec *mock_properties[N_PROPERTIES] = { NULL, };
struct _UcaMockCameraPrivate {
guint width;
guint height;
+ guint bits;
+ guint bytes;
+ guint max_val;
guint roi_x, roi_y, roi_width, roi_height;
gfloat max_frame_rate;
gdouble exposure_time;
guint8 *dummy_data;
guint current_frame;
+ gboolean create_random;
GRand *rand;
+ guint8 *default_line;
+
gboolean thread_running;
GThread *grab_thread;
@@ -133,17 +139,27 @@ static const char g_digits[10][20] = {
static const guint DIGIT_WIDTH = 4;
static const guint DIGIT_HEIGHT = 5;
+
+static inline void
+set_pixel (guint8 *buffer, guint x, guint y, guint value, guint n_bytes, guint mask, guint width)
+{
+ gulong offset = ((y * width) + x) * n_bytes;
+ guint val = (value & mask);
+
+ for (guint i = 0; i < n_bytes; i++) {
+ buffer[offset + i] = (val >> (i * 8)) & 0xFF;
+ }
+}
+
static void
-print_number (guint8 *buffer, guint number, guint x, guint y, guint width)
+print_number (guint8 *buffer, guint number, guint x, guint y, guint n_bytes, guint mask, guint width)
{
for (int i = 0; i < DIGIT_WIDTH; i++) {
for (int j = 0; j < DIGIT_HEIGHT; j++) {
- char val = (char) g_digits[number][j*DIGIT_WIDTH+i];
- if(val != 0x00) {
- //This should make the frame counter appear in a bright yellow
- val = 0xBE;
- }
- buffer[(y+j)*width + (x+i)] = (guint8) val;
+ guint val = g_digits[number][j*DIGIT_WIDTH+i];
+ if (val > 0)
+ val = mask;
+ set_pixel (buffer, x+i, y+j, val, n_bytes, mask, width);
}
}
}
@@ -152,45 +168,38 @@ static void
print_current_frame (UcaMockCameraPrivate *priv, guint8 *buffer)
{
guint number = priv->current_frame;
- char default_line[priv->width];
guint divisor = 10000000;
int x = 1;
- memset(buffer, 0, 15 * priv->roi_width);
+ memset(buffer, 0, 15 * priv->roi_width * priv->bytes);
while (divisor > 0) {
- print_number(buffer, number / divisor, x, 1, priv->roi_width);
+ /* max_val doubles as a bit mask */
+ print_number(buffer, number / divisor, x, 1, priv->bytes, priv->max_val, priv->roi_width);
number = number % divisor;
divisor = divisor / 10;
x += DIGIT_WIDTH + 1;
}
- for (int p = 0; p < priv->roi_width; p++) {
- default_line[p] = (char) ((p*256) / (priv->roi_width));
- }
-
for (guint y = 16; y < priv->roi_height; y++) {
- guint index = y * priv->roi_width;
- memcpy (&buffer[index], &default_line[0], priv->roi_width);
+ guint index = y * priv->roi_width * priv->bytes;
+ memcpy (&buffer[index], priv->default_line + (priv->roi_x * priv->width), priv->roi_width * priv->bytes);
}
-#ifdef __CREATE_RANDOM_IMAGE_DATA__
- //This block will fill a square at the center of the image with noraml
- //distributed random data
- const double mean = 128.0;
- const double std = 32.0;
-
- for (guint y = (priv->roi_height / 3); y < ((priv->roi_height * 2) / 3); y++) {
- guint row_start = y * priv->roi_width;
-
- for (guint i = (priv->roi_width / 3); i < ((priv->roi_width * 2) / 3); i++) {
- int index = row_start + i;
- double u1 = g_rand_double (priv->rand);
- double u2 = g_rand_double (priv->rand);
- double r = sqrt (-2 * log(u1)) * cos(2 * G_PI * u2);
- buffer[index] = (guint8) (r * std + mean);
+ if (priv->create_random) {
+ //This block will fill a square at the center of the ROI with noraml
+ //distributed random data
+ const double mean = (double) ceil (priv->max_val / 2.);
+ const double std = (double) ceil (priv->max_val / 8.);
+
+ for (guint y = (priv->roi_height / 3); y < ((priv->roi_height * 2) / 3); y++) {
+ for (guint x = (priv->roi_width / 3); x < ((priv->roi_width * 2) / 3); x++) {
+ double u1 = g_rand_double (priv->rand);
+ double u2 = g_rand_double (priv->rand);
+ double r = sqrt (-2 * log(u1)) * cos(2 * G_PI * u2);
+ set_pixel (buffer, x, y, round (r * std + mean), priv->bytes, priv->max_val, priv->roi_width);
+ }
}
}
-#endif
}
static gpointer
@@ -222,7 +231,7 @@ uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
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);
+ priv->dummy_data = (guint8 *) g_malloc0(priv->roi_width * priv->roi_height * priv->bytes);
g_object_get(G_OBJECT(camera),
"transfer-asynchronously", &transfer_async,
@@ -285,7 +294,7 @@ uca_mock_camera_grab (UcaCamera *camera, gpointer data, GError **error)
print_current_frame (priv, priv->dummy_data);
priv->current_frame++;
- g_memmove (data, priv->dummy_data, priv->roi_width * priv->roi_height);
+ g_memmove (data, priv->dummy_data, priv->roi_width * priv->roi_height * priv->bytes);
return TRUE;
}
@@ -302,6 +311,15 @@ uca_mock_camera_set_property (GObject *object, guint property_id, const GValue *
}
switch (property_id) {
+ case PROP_SENSOR_WIDTH:
+ priv->width = g_value_get_uint (value);
+ break;
+ case PROP_SENSOR_HEIGHT:
+ priv->height = g_value_get_uint (value);
+ break;
+ case PROP_SENSOR_BITDEPTH:
+ priv->bits = g_value_get_uint (value);
+ break;
case PROP_EXPOSURE_TIME:
priv->exposure_time = g_value_get_double (value);
break;
@@ -317,6 +335,9 @@ uca_mock_camera_set_property (GObject *object, guint property_id, const GValue *
case PROP_ROI_HEIGHT:
priv->roi_height = g_value_get_uint (value);
break;
+ case PROP_CREATE_RANDOM:
+ priv->create_random = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
return;
@@ -339,7 +360,7 @@ uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value,
g_value_set_uint(value, priv->height);
break;
case PROP_SENSOR_BITDEPTH:
- g_value_set_uint(value, 8);
+ g_value_set_uint(value, priv->bits);
break;
case PROP_EXPOSURE_TIME:
g_value_set_double(value, priv->exposure_time);
@@ -362,6 +383,9 @@ uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value,
case PROP_HAS_CAMRAM_RECORDING:
g_value_set_boolean(value, FALSE);
break;
+ case PROP_CREATE_RANDOM:
+ g_value_set_boolean(value, priv->create_random);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -377,13 +401,15 @@ uca_mock_camera_finalize(GObject *object)
if (priv->thread_running) {
priv->thread_running = FALSE;
- g_thread_join(priv->grab_thread);
+ g_thread_join (priv->grab_thread);
}
- g_free(priv->dummy_data);
- g_value_array_free(priv->binnings);
+ g_free (priv->dummy_data);
+ g_value_array_free (priv->binnings);
+
+ g_free (priv->default_line);
- G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object);
+ G_OBJECT_CLASS (uca_mock_camera_parent_class)->finalize(object);
}
static gboolean
@@ -392,6 +418,30 @@ ufo_mock_camera_initable_init (GInitable *initable,
GError **error)
{
g_return_val_if_fail (UCA_IS_MOCK_CAMERA (initable), FALSE);
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE (UCA_MOCK_CAMERA (initable));
+
+ g_object_get (G_OBJECT (initable),
+ "sensor-width", &priv->width,
+ "sensor-height", &priv->height,
+ "sensor-bitdepth", &priv->bits,
+ NULL);
+
+ priv->roi_width = priv->width;
+ priv->roi_height = priv->height;
+ priv->bytes = ceil (priv->bits / 8.);
+
+ priv->max_val = 0;
+ for (guint i = 0; i < priv->bits; i++) {
+ priv->max_val |= 1 << i;
+ }
+
+ priv->default_line = g_malloc0 (priv->width * priv->bytes);
+ gdouble step_size = ((gdouble) priv->max_val) / priv->width;
+ for (guint p = 0; p < priv->roi_width; p++) {
+ guint val = round (p * step_size);
+ set_pixel (priv->default_line, p, 0, val, priv->bytes, priv->max_val, priv->width);
+ }
+
return TRUE;
}
@@ -418,9 +468,19 @@ uca_mock_camera_class_init(UcaMockCameraClass *klass)
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_CREATE_RANDOM] =
+ g_param_spec_boolean("create-random",
+ "Add random data to picture",
+ "If TRUE, fills a rectangle in the center of the picture with random data",
+ TRUE,
+ G_PARAM_READWRITE);
+
for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
g_object_class_install_property(gobject_class, id, mock_properties[id]);
+ uca_camera_pspec_set_writable (g_object_class_find_property (gobject_class, uca_camera_props[PROP_EXPOSURE_TIME]), TRUE);
+ uca_camera_pspec_set_writable (mock_properties[PROP_CREATE_RANDOM], TRUE);
+
g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate));
}
@@ -430,13 +490,12 @@ 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 = 512;
- self->priv->height = self->priv->roi_height = 512;
self->priv->max_frame_rate = 100000.0f;
self->priv->grab_thread = NULL;
self->priv->current_frame = 0;
self->priv->exposure_time = 0.05;
-
+ self->priv->create_random = TRUE;
+
self->priv->binnings = g_value_array_new(1);
self->priv->rand = g_rand_new ();
@@ -444,6 +503,15 @@ uca_mock_camera_init(UcaMockCamera *self)
g_value_init(&val, G_TYPE_UINT);
g_value_set_uint(&val, 1);
g_value_array_append(self->priv->binnings, &val);
+
+
+ /* will be set in initable_init */
+ self->priv->width = self->priv->roi_width = 0;
+ self->priv->height = self->priv->roi_height = 0;
+ self->priv->bits = 0;
+ self->priv->bytes = 0;
+ self->priv->max_val = 0;
+ self->priv->default_line = NULL;
}
G_MODULE_EXPORT GType
diff --git a/src/uca-camera.c b/src/uca-camera.c
index a312a39..c36451c 100644
--- a/src/uca-camera.c
+++ b/src/uca-camera.c
@@ -372,15 +372,15 @@ uca_camera_class_init (UcaCameraClass *klass)
g_param_spec_uint(uca_camera_props[PROP_SENSOR_WIDTH],
"Width of sensor",
"Width of the sensor in pixels",
- 1, G_MAXUINT, 1,
- G_PARAM_READABLE);
+ 1, G_MAXUINT, 512,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
camera_properties[PROP_SENSOR_HEIGHT] =
g_param_spec_uint(uca_camera_props[PROP_SENSOR_HEIGHT],
"Height of sensor",
"Height of the sensor in pixels",
- 1, G_MAXUINT, 1,
- G_PARAM_READABLE);
+ 1, G_MAXUINT, 512,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
camera_properties[PROP_SENSOR_PIXEL_WIDTH] =
g_param_spec_double (uca_camera_props[PROP_SENSOR_PIXEL_WIDTH],
@@ -400,8 +400,8 @@ uca_camera_class_init (UcaCameraClass *klass)
g_param_spec_uint(uca_camera_props[PROP_SENSOR_BITDEPTH],
"Number of bits per pixel",
"Number of bits per pixel",
- 1, 32, 1,
- G_PARAM_READABLE);
+ 1, 32, 8,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
camera_properties[PROP_SENSOR_HORIZONTAL_BINNING] =
g_param_spec_uint(uca_camera_props[PROP_SENSOR_HORIZONTAL_BINNING],
@@ -1154,7 +1154,24 @@ uca_camera_set_writable (UcaCamera *camera,
GParamSpec *pspec;
pspec = get_param_spec_by_name (camera, prop_name);
+ uca_camera_pspec_set_writable (pspec, writable);
+}
+/**
+ * uca_camera_pspec_set_writable: (skip)
+ * @pspec: A #GParamSpec
+ * @writable: %TRUE if property can be written during acquisition
+ *
+ * Sets a flag that defines if the property defined by @pspec can be written
+ * during an acquisition. This can be used during UcaCamera class
+ * initialization.
+ *
+ * Since: 2.1
+ */
+void
+uca_camera_pspec_set_writable (GParamSpec *pspec,
+ gboolean writable)
+{
if (pspec != NULL) {
if (g_param_spec_get_qdata (pspec, UCA_WRITABLE_QUARK) != NULL)
g_warning ("::%s is already fixed", pspec->name);
diff --git a/src/uca-camera.h b/src/uca-camera.h
index 97d3e6e..af95123 100644
--- a/src/uca-camera.h
+++ b/src/uca-camera.h
@@ -179,6 +179,9 @@ UcaUnit uca_camera_get_unit (UcaCamera *camera,
void uca_camera_set_writable (UcaCamera *camera,
const gchar *prop_name,
gboolean writable);
+void uca_camera_pspec_set_writable
+ (GParamSpec *pspec,
+ gboolean writable);
gboolean uca_camera_is_writable_during_acquisition
(UcaCamera *camera,
const gchar *prop_name);