From 65a2016becbb165afa4fdf16742f3586f83d0f30 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Thu, 17 Mar 2011 13:55:53 +0100 Subject: Allow resize of image dimensions --- src/cameras/dummy.c | 30 ++++++++++++++++++++++++------ src/uca.h | 1 + test/control.c | 34 +++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/cameras/dummy.c b/src/cameras/dummy.c index d71940e..ba95a67 100644 --- a/src/cameras/dummy.c +++ b/src/cameras/dummy.c @@ -5,17 +5,33 @@ #include "uca-cam.h" #include "uca-grabber.h" -struct dummy_cam_t { +typedef struct dummy_cam { uint32_t bitdepth; uint32_t framerate; char* buffer; -}; +} dummy_cam_t; -#define GET_DUMMY(uca) ((struct dummy_cam_t *)(uca->user)) +#define GET_DUMMY(uca) ((struct dummy_cam *)(uca->user)) #define set_void(p, type, value) { *((type *) p) = value; } static uint32_t uca_dummy_set_property(struct uca_camera *cam, enum uca_property_ids property, void *data) { + if (cam->state == UCA_CAM_RECORDING) + return UCA_ERR_PROP_CAMERA_RECORDING; + + switch (property) { + case UCA_PROP_WIDTH: + cam->frame_width = *((uint32_t *) data); + break; + + case UCA_PROP_HEIGHT: + cam->frame_height = *((uint32_t *) data); + break; + + default: + return UCA_ERR_PROP_INVALID; + } + return UCA_NO_ERROR; } @@ -63,11 +79,13 @@ static uint32_t uca_dummy_get_property(struct uca_camera *cam, enum uca_property uint32_t uca_dummy_start_recording(struct uca_camera *cam) { cam->current_frame = 0; + cam->state = UCA_CAM_RECORDING; return UCA_NO_ERROR; } uint32_t uca_dummy_stop_recording(struct uca_camera *cam) { + cam->state = UCA_CAM_ARMED; return UCA_NO_ERROR; } @@ -134,7 +152,7 @@ static const char digits[10][20] = { 0xff, 0xff, 0xff, 0x00 } }; -static void uca_dummy_print_number(struct dummy_cam_t *dummy, int number, int x, int y, int width) +static void uca_dummy_print_number(struct dummy_cam *dummy, int number, int x, int y, int width) { const int digit_width = 4; const int digit_height = 5; @@ -148,7 +166,7 @@ static void uca_dummy_print_number(struct dummy_cam_t *dummy, int number, int x, uint32_t uca_dummy_grab(struct uca_camera *cam, char *buffer) { - struct dummy_cam_t *dummy = GET_DUMMY(cam); + struct dummy_cam *dummy = GET_DUMMY(cam); dummy->buffer = buffer; /* print current frame number */ @@ -185,7 +203,7 @@ uint32_t uca_dummy_init(struct uca_camera **cam, struct uca_grabber *grabber) uca->frame_height = 240; uca->current_frame = 0; - struct dummy_cam_t *dummy_cam = (struct dummy_cam_t *) malloc(sizeof(struct dummy_cam_t)); + struct dummy_cam *dummy_cam = (struct dummy_cam *) malloc(sizeof(struct dummy_cam)); dummy_cam->bitdepth = 8; dummy_cam->framerate = 100; dummy_cam->buffer = NULL; diff --git a/src/uca.h b/src/uca.h index bafcf50..64eb3a4 100644 --- a/src/uca.h +++ b/src/uca.h @@ -203,6 +203,7 @@ enum uca_errors { UCA_ERR_PROP_INVALID, /**< the requested property is not supported by the camera */ UCA_ERR_PROP_GENERAL, /**< error occured reading/writing the property */ UCA_ERR_PROP_VALUE_OUT_OF_RANGE, /**< error occured writing the property */ + UCA_ERR_PROP_CAMERA_RECORDING, /**< cannot set/get property because camera is recording */ UCA_ERR_CAM_ARM, /**< camera is not armed */ UCA_ERR_CAM_RECORD, /**< could not record */ diff --git a/test/control.c b/test/control.c index 449c4ea..c220e21 100644 --- a/test/control.c +++ b/test/control.c @@ -1,10 +1,12 @@ #include #include #include +#include #include "uca.h" #include "uca-cam.h" + typedef struct { guchar *buffer, *pixels; gboolean running; @@ -12,16 +14,18 @@ typedef struct { GdkPixbuf *pixbuf; int width; int height; - int bits; + int pixel_size; struct uca_camera *cam; struct uca *u; -} ThreadData ; +} ThreadData; + typedef struct { ThreadData *thread_data; GtkTreeStore *tree_store; } ValueCellData; + enum { COLUMN_NAME = 0, COLUMN_VALUE, @@ -30,6 +34,7 @@ enum { NUM_COLUMNS }; + void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int height) { for (int x = 0; x < width; x++) { @@ -56,6 +61,22 @@ void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int height) } } +void reallocate_buffers(ThreadData *td, int width, int height) +{ + const size_t num_bytes = width * height * td->pixel_size; + + g_object_unref(td->pixbuf); + g_free(td->buffer); + + td->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height); + td->buffer = (guchar *) g_malloc(num_bytes); + td->width = width; + td->height = height; + td->pixels = gdk_pixbuf_get_pixels(td->pixbuf); + gtk_image_set_from_pixbuf(GTK_IMAGE(td->image), td->pixbuf); + memset(td->buffer, 0, num_bytes); +} + static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { return FALSE; @@ -76,9 +97,9 @@ void *grab_thread(void *args) while (data->running) { cam->grab(cam, (char *) data->buffer); - if (data->bits == 8) + if (data->pixel_size == 1) convert_8bit_to_rgb(data->pixels, data->buffer, data->width, data->height); - else if (data->bits == 16) + else if (data->pixel_size == 2) convert_16bit_to_rgb(data->pixels, data->buffer, data->width, data->height); gdk_threads_enter(); @@ -129,6 +150,9 @@ static void on_valuecell_edited(GtkCellRendererText *renderer, gchar *path, gcha /* TODO: extensive value checking */ uint32_t val = (uint32_t) g_ascii_strtoull(new_text, NULL, 10); cam->set_property(cam, prop_id, &val); + if ((prop_id == UCA_PROP_WIDTH) || (prop_id == UCA_PROP_HEIGHT)) + reallocate_buffers(value_data->thread_data, cam->frame_width, cam->frame_height); + gtk_tree_store_set(value_data->tree_store, &iter, COLUMN_VALUE, new_text, -1); } } @@ -320,10 +344,10 @@ int main(int argc, char *argv[]) td.pixels = gdk_pixbuf_get_pixels(pixbuf); td.width = width; td.height = height; - td.bits = bits_per_sample; td.cam = cam; td.u = u; td.running = FALSE; + td.pixel_size = pixel_size; g_signal_connect(window, "delete-event", G_CALLBACK (delete_event), NULL); -- cgit v1.2.3