summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS17
-rw-r--r--docs/manual.md18
-rw-r--r--plugins/mock/uca-mock-camera.c18
-rw-r--r--plugins/pco/uca-pco-camera.c23
-rw-r--r--plugins/pf/uca-pf-camera.c24
-rw-r--r--plugins/ufo/uca-ufo-camera.c38
-rw-r--r--src/uca-camera.c30
-rw-r--r--src/uca-camera.h9
-rw-r--r--tools/benchmark.c2
-rw-r--r--tools/grab.c2
-rw-r--r--tools/gui/control.c6
11 files changed, 104 insertions, 83 deletions
diff --git a/NEWS b/NEWS
index 700ee4d..e26e520 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,20 @@
+Changes in libuca 1.2
+=====================
+
+API break
+---------
+
+The interface of uca_camera_grab() has changed. The buffer must be provided as a
+void pointer (or gpointer in GLib speak), _not_ the address of a void pointer.
+Furthermore, uca_camera_grab() returns TRUE if grabbing an image was successful
+and FALSE if not.
+
+The plugin manager does not call the plugins "constructor" function directly but
+instantiates it via the GInitable initialization function. Therefore, all
+plugins must implement initialization code in the objects init function and flag
+errors in the init method from the GInitable interface.
+
+
Changes in libuca 1.1
=====================
diff --git a/docs/manual.md b/docs/manual.md
index 0dd9c66..0b81bdb 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -185,22 +185,18 @@ To synchronously grab frames, first start the camera:
g_assert_no_error (error);
~~~
-Now you have two options with regard to memory buffers. If you already have a
-suitable sized buffer, just pass it to `uca_camera_grab`. Otherwise pass a
-pointer pointing to `NULL` (this is different from a `NULL` pointer!). In this
-case memory will be allocated for you:
+Now, you have to allocate a suitably sized buffer and pass it to
+`uca_camera_grab`.
~~~ {.c}
- gpointer buffer_1 = NULL; /* A pointer pointing to NULL */
- gpointer buffer_2 = g_malloc0 (640 * 480 * 2);
+ gpointer buffer = g_malloc0 (640 * 480 * 2);
- /* Memory will be allocated. Remember to free it! */
- uca_camera_grab (camera, &buffer_1, &error);
-
- /* Memory buffer will be used */
- uca_camera_grab (camera, &buffer_2, &error);
+ uca_camera_grab (camera, buffer, &error);
~~~
+You have to make sure that the buffer is large enough by querying the size of
+the region of interest and the number of bits that are transferred.
+
### Getting and setting camera parameters
diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c
index c7561ab..675d5ec 100644
--- a/plugins/mock/uca-mock-camera.c
+++ b/plugins/mock/uca-mock-camera.c
@@ -242,20 +242,18 @@ uca_mock_camera_trigger (UcaCamera *camera, GError **error)
{
}
-static void
-uca_mock_camera_grab (UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+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);
+ g_return_val_if_fail (UCA_IS_MOCK_CAMERA(camera), FALSE);
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE (camera);
- if (*data == NULL)
- *data = g_malloc0(priv->roi_width * priv->roi_height);
-
- g_memmove(*data, priv->dummy_data, priv->roi_width * priv->roi_height);
- print_current_frame(priv, *data);
+ g_memmove (data, priv->dummy_data, priv->roi_width * priv->roi_height);
+ print_current_frame (priv, data);
priv->current_frame++;
+
+ return TRUE;
}
static void
diff --git a/plugins/pco/uca-pco-camera.c b/plugins/pco/uca-pco-camera.c
index de68001..4a0cce6 100644
--- a/plugins/pco/uca-pco-camera.c
+++ b/plugins/pco/uca-pco-camera.c
@@ -565,12 +565,12 @@ uca_pco_camera_trigger(UcaCamera *camera, GError **error)
"Could not trigger frame acquisition");
}
-static void
-uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+uca_pco_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
static const gint MAX_TIMEOUT = 5;
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_PCO_CAMERA(camera), FALSE);
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
gboolean is_readout = FALSE;
@@ -580,7 +580,7 @@ uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
if (priv->current_image == priv->num_recorded_images) {
g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM,
"End of data stream");
- return;
+ return FALSE;
}
/*
@@ -595,19 +595,20 @@ uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
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);
+ g_set_error (error, UCA_PCO_CAMERA_ERROR,
+ UCA_PCO_CAMERA_ERROR_FG_GENERAL,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
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->description->type == CAMERATYPE_PCO_EDGE)
- pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height);
+ 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);
+ memcpy((gchar *) data, (gchar *) frame, priv->frame_width * priv->frame_height * priv->num_bytes);
+
+ return TRUE;
}
static void
diff --git a/plugins/pf/uca-pf-camera.c b/plugins/pf/uca-pf-camera.c
index 085fde5..b7967be 100644
--- a/plugins/pf/uca-pf-camera.c
+++ b/plugins/pf/uca-pf-camera.c
@@ -184,25 +184,27 @@ uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
"This photon focus camera does not support recording to internal memory");
}
-static void
-uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+uca_pf_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_PF_CAMERA (camera), FALSE);
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);
+ 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);
+ g_set_error (error, UCA_PF_CAMERA_ERROR,
+ UCA_PF_CAMERA_ERROR_FG_ACQUISITION,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
- 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);
+ guint16 *frame = Fg_getImagePtrEx (priv->fg, priv->last_frame,
+ priv->fg_port, priv->fg_mem);
- memcpy((gchar *) *data, (gchar *) frame, priv->roi_width * priv->roi_height);
+ memcpy((gchar *) data, (gchar *) frame, priv->roi_width * priv->roi_height);
+ return TRUE;
}
static void
diff --git a/plugins/ufo/uca-ufo-camera.c b/plugins/ufo/uca-ufo-camera.c
index f68614e..93c13a8 100644
--- a/plugins/ufo/uca-ufo-camera.c
+++ b/plugins/ufo/uca-ufo-camera.c
@@ -34,6 +34,15 @@
return; \
}
+#define PCILIB_SET_ERROR_RETURN_FALSE(err, err_type) \
+ if (err != 0) { \
+ g_set_error(error, UCA_UFO_CAMERA_ERROR, \
+ err_type, \
+ "%s:%i pcilib: %s (errcode = %d)", \
+ __FILE__, __LINE__, strerror(err), err);\
+ return FALSE; \
+ }
+
#define UCA_UFO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCameraPrivate))
static void uca_ufo_camera_initable_iface_init (GInitableIface *iface);
@@ -301,10 +310,10 @@ uca_ufo_camera_stop_readout(UcaCamera *camera, GError **error)
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
}
-static void
-uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+uca_ufo_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_UFO_CAMERA(camera), FALSE);
UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
pcilib_event_id_t event_id;
pcilib_event_info_t event_info;
@@ -313,20 +322,17 @@ uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
const gsize size = SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16);
if (priv->trigger != UCA_CAMERA_TRIGGER_EXTERNAL) {
- err = pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_TRIGGER);
+ err = pcilib_trigger (priv->handle, PCILIB_EVENT0, 0, NULL);
+ PCILIB_SET_ERROR_RETURN_FALSE (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);
+ err = pcilib_get_next_event (priv->handle, priv->timeout, &event_id, sizeof(pcilib_event_info_t), &event_info);
+ PCILIB_SET_ERROR_RETURN_FALSE (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, (size_t *) &err);
+ gpointer src = pcilib_get_data (priv->handle, event_id, PCILIB_EVENT_DATA, (size_t *) &err);
if (src == NULL)
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NO_DATA);
+ PCILIB_SET_ERROR_RETURN_FALSE (err, UCA_UFO_CAMERA_ERROR_NO_DATA);
/*
* Apparently, we checked that err equals total size in previous version.
@@ -336,15 +342,17 @@ uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
*/
/* assert(err == size); */
- memcpy(*data, src, 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);
+ err = pcilib_return_data (priv->handle, event_id, PCILIB_EVENT_DATA, data);
+ PCILIB_SET_ERROR_RETURN_FALSE (err, UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED);
+
+ return TRUE;
}
static void
diff --git a/src/uca-camera.c b/src/uca-camera.c
index 8905a95..ec4b418 100644
--- a/src/uca-camera.c
+++ b/src/uca-camera.c
@@ -669,34 +669,31 @@ uca_camera_trigger (UcaCamera *camera, GError **error)
/**
* uca_camera_grab:
* @camera: A #UcaCamera object
- * @data: Pointer to pointer to the data. Must not be %NULL.
+ * @data: (type gulong): Pointer to suitably sized data buffer. Must not be
+ * %NULL.
* @error: Location to store a #UcaCameraError error or %NULL
*
- * Grab a frame a single frame and store the result in @data. If the pointer
- * pointing to the data is %NULL, memory will be allocated otherwise it will be
- * used to store the frame. If memory is allocated by uca_camera_grab() it must
- * be freed by the caller.
+ * Grab a frame a single frame and store the result in @data.
*
* 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)
+gboolean
+uca_camera_grab (UcaCamera *camera, gpointer data, GError **error)
{
UcaCameraClass *klass;
+ gboolean result;
+
+ /* FIXME: this prevents accessing two independent cameras simultanously. */
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- g_return_if_fail (UCA_IS_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_CAMERA(camera), FALSE);
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_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->grab != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
g_static_mutex_lock (&mutex);
@@ -704,11 +701,12 @@ uca_camera_grab (UcaCamera *camera, gpointer *data, GError **error)
g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is neither recording nor in readout mode");
else {
g_static_mutex_lock (&access_lock);
- (*klass->grab) (camera, data, error);
+ result = (*klass->grab) (camera, data, error);
g_static_mutex_unlock (&access_lock);
}
g_static_mutex_unlock (&mutex);
+ return result;
}
/**
diff --git a/src/uca-camera.h b/src/uca-camera.h
index 87996c6..f6fdace 100644
--- a/src/uca-camera.h
+++ b/src/uca-camera.h
@@ -129,7 +129,7 @@ struct _UcaCameraClass {
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);
+ gboolean (*grab) (UcaCamera *camera, gpointer data, GError **error);
void (*recording_started) (UcaCamera *camera);
void (*recording_stopped) (UcaCamera *camera);
@@ -147,9 +147,10 @@ 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);
+gboolean uca_camera_grab (UcaCamera *camera,
+ gpointer data,
+ GError **error)
+ __attribute__((nonnull (2)));
void uca_camera_set_grab_func (UcaCamera *camera,
UcaCameraGrabFunc func,
gpointer user_data);
diff --git a/tools/benchmark.c b/tools/benchmark.c
index 170a96c..f262a06 100644
--- a/tools/benchmark.c
+++ b/tools/benchmark.c
@@ -100,7 +100,7 @@ grab_frames_sync (UcaCamera *camera, gpointer buffer, guint n_frames)
uca_camera_start_recording (camera, &error);
for (guint i = 0; i < n_frames; i++) {
- uca_camera_grab(camera, &buffer, &error);
+ uca_camera_grab(camera, buffer, &error);
if (error != NULL) {
g_warning ("Error grabbing frame %02i/%i: `%s'", i, n_frames, error->message);
diff --git a/tools/grab.c b/tools/grab.c
index b020279..e8e91be 100644
--- a/tools/grab.c
+++ b/tools/grab.c
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
while (counter < 5) {
g_print(" grab frame ... ");
g_timer_start(timer);
- uca_camera_grab(camera, &buffer, &error);
+ uca_camera_grab(camera, buffer, &error);
if (error != NULL) {
g_print("\nError: %s\n", error->message);
diff --git a/tools/gui/control.c b/tools/gui/control.c
index 192859c..b17040f 100644
--- a/tools/gui/control.c
+++ b/tools/gui/control.c
@@ -161,7 +161,7 @@ preview_frames (void *args)
gpointer buffer;
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, &error);
+ uca_camera_grab (data->camera, buffer, &error);
if (error == NULL) {
convert_grayscale_to_rgb (data, buffer);
@@ -191,7 +191,7 @@ record_frames (gpointer args)
while (data->state == RECORDING) {
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, NULL);
+ uca_camera_grab (data->camera, buffer, NULL);
if (error == NULL) {
ring_buffer_proceed (data->buffer);
@@ -345,7 +345,7 @@ download_frames (ThreadData *data)
while (error == NULL) {
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, &error);
+ uca_camera_grab (data->camera, buffer, &error);
ring_buffer_proceed (data->buffer);
gdk_threads_enter ();
gtk_adjustment_set_value (data->download_adjustment, current_frame++);