bug repair: loading .png image, from Adrian Daerr
[gpiv.git] / src / dac_cam.c
blobff75839729d1cabe9efd31ae1b8df6144531b34b
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
3 /*----------------------------------------------------------------------
5 gpiv - Graphic program for Particle Image Velocimetry, based on gtk/gnome
6 libraries.
8 Copyright (C) 2005, 2006, 2007, 2008
9 Gerber van der Graaf <gerber_graaf@users.sourceforge.net>
11 This file is part of gpiv.
13 Gpiv is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2, or (at your option)
16 any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ----------------------------------------------------------------------*/
30 * functions for dac_cam
31 * $Log: dac_cam.c,v $
32 * Revision 1.7 2008-04-28 12:00:57 gerber
33 * hdf-formatted files are now with .hdf extension (previously: .gpi)
35 * Revision 1.6 2007-12-19 08:42:35 gerber
36 * debugged
38 * Revision 1.5 2007-11-23 16:24:07 gerber
39 * release 0.5.0: Kafka
41 * Revision 1.4 2007-06-06 17:00:48 gerber
42 * Retreives images/data from URI using Gnome Virtual File System.
44 * Revision 1.3 2007-03-22 16:00:32 gerber
45 * Added image processing tabulator
47 * Revision 1.2 2007-01-29 11:27:43 gerber
48 * added image formats png, gif, tif png, bmp, improved buffer display
50 * Revision 1.1 2006-09-18 07:29:49 gerber
51 * Split up of triggering and image recording (camera)
54 #ifdef ENABLE_CAM
56 #include <pthread.h>
57 #include "gpiv_gui.h"
58 #include "utils.h"
59 #include "console.h"
60 #include "dac_cam.h"
61 #include "display.h"
62 #include <libdc1394/dc1394_control.h>
64 static struct tm *dac_time;
65 static GDate *date;
67 pthread_mutex_t mutex_rec = PTHREAD_MUTEX_INITIALIZER;
70 typedef struct _ImgFrame ImgFrame;
71 struct _ImgFrame {
72 unsigned char **A;
73 unsigned char **B;
74 /* gint count; */
78 * Prototypes of local functions
80 static void
81 rec_frame(ImgFrame *img_frame
84 static void
85 thread_rec_frame(void *img_frame
88 static void
89 thread_rec_frame_serie(ImgFrame img_frame[GPIV_NIMG_MAX]
92 static void
93 add_buffer(GpivConsole *gpiv,
94 gchar *fname_base,
95 gint ibuf,
96 unsigned char **frameA,
97 unsigned char **frameB
100 static void
101 renew_buffer(GpivConsole *gpiv,
102 gchar *fname_base,
103 gint ibuf,
104 unsigned char **frameA,
105 unsigned char **frameB
108 static void
109 recreate_img(Display * disp,
110 unsigned char **frameA,
111 unsigned char **frameB
115 static int
116 open_dac_img(GpivCamVar *cam_var,
117 unsigned char **frameA,
118 unsigned char **frameB,
119 Image * img,
120 gboolean alloc_mem
123 static void
124 load_dac_buffer(GpivConsole *gpiv,
125 GpivCamVar *cam_var,
126 gboolean second_image,
127 char *fname,
128 int ibuf,
129 unsigned char **frameA,
130 unsigned char **frameB,
131 enum ClistPut clist_put
134 static void
135 rec_and_display(GpivConsole *gpiv
139 * Global functions
141 void
142 exec_cam_start(GpivConsole * gpiv
144 /*-----------------------------------------------------------------------------
148 * dc1394 stuff
150 /* quadlet_t value; */
152 cancel_process = FALSE;
155 * report camera's feature set
156 * in: on_menu_camera_select
158 /* dc1394_print_feature_set(&cam_var->feature_set[0]); */
160 /* g_message("exec_cam_start:: mode[%d] = %s", */
161 /* cam_var->misc_info[0].mode, */
162 /* format0_desc[cam_var->misc_info[0].mode - MODE_FORMAT0_MIN]); */
163 /* g_message("exec_cam_start:: format[%d] = %s", */
164 /* cam_var->misc_info[0].format, */
165 /* format_desc[cam_var->misc_info[0].format - FORMAT_MIN]); */
167 if (verbose) g_warning("exec_cam_start:: fps = %d", cam_var->misc_info[0].framerate/* - FRAMERATE_MIN */);
168 if (dc1394_setup_capture(cam_var->camera[0].handle,
169 cam_var->camera[0].id,
170 cam_var->misc_info[0].iso_channel,
171 cam_var->misc_info[0].format,
172 cam_var->misc_info[0].mode,
173 cam_var->maxspeed,
175 cam_var->misc_info[0].framerate,
177 /* FRAMERATE_7_5, */
179 /* FRAMERATE_3_75, */
181 &cam_var->capture[0])
182 != DC1394_SUCCESS) {
183 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
184 raw1394_destroy_handle(cam_var->handle);
185 warning_gpiv(_("Unable to setup camera-\n\
186 check line %d of %s to make sure\n\
187 that the video mode,framerate and format are\n\
188 supported by your camera"),
189 __LINE__,__FILE__);
190 return;
195 * have the camera start sending us data
197 if (dc1394_start_iso_transmission(cam_var->handle, cam_var->capture[0].node)
198 != DC1394_SUCCESS) {
199 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
200 raw1394_destroy_handle(cam_var->handle);
201 warning_gpiv(_("Unable to start camera iso transmission"));
202 return;
206 * let sending data for a while before grabbing and storing to stabilize
207 * data transfer
209 /* sleep(1); */
210 usleep(1000);
214 * set trigger mode and use triggering or just free run
217 if (gpiv_par->console__trigger_cam) {
218 if (verbose) g_warning("exec_cam_start:: trigger_cam");
219 /* if (dc1394_set_trigger_mode(cam_var->handle, */
220 /* cam_var->capture[0].node, */
221 /* TRIGGER_MODE_0) != DC1394_SUCCESS) */
222 /* { */
223 /* warning_gpiv(_("unable to set camera trigger mode")); */
224 /* } */
225 /* exec_trigger_start(); */
227 rec_and_display(gpiv);
229 /* exec_trigger_stop(); */
230 } else {
231 if (verbose) g_warning("exec_cam_start:: !trigger_cam");
232 rec_and_display(gpiv);
236 /* pthread_exit(NULL); */
239 * Stop data transmission
241 if (verbose) g_warning("exec_cam_start:: Stop data transmission and release camera");
242 if (dc1394_stop_iso_transmission(cam_var->handle, cam_var->capture[0].node)
243 != DC1394_SUCCESS
244 /* && dc1394_release_camera(cam_var->handle, &cam_var->capture[0]) */
245 /* != DC1394_SUCCESS */
247 warning_gpiv(_("couldn't stop the camera?"));
249 /* in: exec_stop_cam dc1394_release_camera(cam_var->handle, &cam_var->capture[0]); */
250 /*in: exec_stop_cam: raw1394_destroy_handle(cam_var->handle); */
255 void
256 exec_cam_stop (void
258 /*-----------------------------------------------------------------------------
261 gint i;
263 cancel_process = TRUE;
264 for (i = 0; i < cam_var->numCameras; i++) {
265 if (dc1394_stop_iso_transmission(cam_var->handle, cam_var->capture[i].node)
266 != DC1394_SUCCESS)
268 warning_gpiv(_("couldn't stop the camera?"));
271 pthread_exit(NULL);
272 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
274 if (cam_var->numCameras > 0) {
275 raw1394_destroy_handle(cam_var->handle);
282 * Callback functions
284 void
285 on_menu_camera_select (GtkWidget *widget,
286 gpointer data)
287 /* ----------------------------------------------------------------------------
294 void
295 on_menu_format (GtkWidget *widget,
296 gpointer data)
297 /* ----------------------------------------------------------------------------
300 GpivConsole * gpiv = gtk_object_get_data(GTK_OBJECT(widget), "gpiv");
301 gint mode = (int) data;
302 gint format = 0;
303 gint was_iso_on;
304 /* change_mode_and_format(format, FORMAT_VGA_NONCOMPRESSED); */
305 /* IsoFlowCheck(state); */
307 if (verbose) g_message("on_menu_format:: ");
308 if (!dc1394_get_iso_status(cam_var->camera[0].handle, cam_var->camera[0].id,
309 &cam_var->misc_info[0].is_iso_on)) {
310 g_warning("Cannot get ISO status");
311 } else {
312 if (cam_var->misc_info[0].is_iso_on > 0) {
313 cancel_process = TRUE;
316 was_iso_on = cam_var->misc_info[0].is_iso_on;
317 /* g_message("on_menu_format:: is_iso_on = %d", was_iso_on); */
320 if (mode >= MODE_FORMAT0_MIN && mode <= MODE_FORMAT0_MAX) {
321 format = FORMAT_VGA_NONCOMPRESSED;
323 /* g_message("on_menu_format:: mode[%d] = %s", */
324 /* mode, format0_desc[mode - MODE_FORMAT0_MIN]); */
326 /* g_message(":n_menu_format: format[%d] = %s", */
327 /* format, */
328 /* format_desc[format - FORMAT_MIN]); */
329 } else if (mode >= MODE_FORMAT1_MIN && mode <= MODE_FORMAT1_MAX) {
330 format = FORMAT_SVGA_NONCOMPRESSED_1;
331 } else if (mode >= MODE_FORMAT2_MIN && mode <= MODE_FORMAT2_MAX) {
332 format = FORMAT_SVGA_NONCOMPRESSED_2;
333 } else if (mode >= MODE_FORMAT6_MIN && mode <= MODE_FORMAT6_MAX) {
334 format = FORMAT_STILL_IMAGE;
335 } else if (mode >= MODE_FORMAT7_MIN && mode <= MODE_FORMAT7_MAX) {
336 format = FORMAT_SCALABLE_IMAGE_SIZE;
337 /* } else if (mode >= COLOR_FORMAT7_MIN && mode <= COLOR_FORMAT7_MAX) { */
338 /* format = FORMAT_SCALABLE_IMAGE_SIZE; */
339 } else {
340 warning_gpiv(_("on_menu_format: non valid format"));
343 if (!dc1394_set_video_format(cam_var->camera[0].handle,
344 cam_var->camera[0].id,
345 format)) {
346 if (verbose) g_warning("on_menu_format:: Could not set video format");
347 } else {
348 cam_var->misc_info[0].format = format;
351 if (!dc1394_set_video_mode(cam_var->camera[0].handle,
352 cam_var->camera[0].id,
353 mode)) {
354 if (verbose) g_warning("on_menu_format:: Could not set video format");
355 } else {
356 cam_var->misc_info[0].mode = mode;
361 if (was_iso_on > 0) {
362 exec_cam_start(gpiv);
365 /* BuildFpsMenu(); */
368 /* UpdateTriggerFrame(); */
370 /* IsoFlowResume(state); */
373 /* MODE_320x240_YUV422, */
374 /* MODE_640x480_YUV411, */
375 /* MODE_640x480_YUV422, */
376 /* MODE_640x480_RGB, */
377 /* MODE_640x480_MONO, */
378 /* MODE_640x480_MONO16 */
383 void
384 on_menu_fps (GtkWidget *widget,
385 gpointer data)
386 /* ----------------------------------------------------------------------------
389 cam_var->misc_info[0].framerate = (int) data/* - FRAMERATE_MIN */;
390 /* cam_var->misc_info[0].framerat */
391 if (verbose) g_warning("on_menu_fps:: fps = %d", cam_var->misc_info[0].framerate);
396 * BUGFIX: include in trigger callbacks?
398 void
399 on_trigger_polarity_toggled (GtkToggleButton *togglebutton,
400 gpointer user_data)
402 /* ----------------------------------------------------------------------------
404 if (!dc1394_set_trigger_polarity(cam_var->camera[0].handle,
405 cam_var->camera[0].id,
406 togglebutton->active)) {
407 message_gpiv(_("Cannot set trigger polarity"));
408 } else {
409 cam_var->feature_set[0].feature[FEATURE_TRIGGER-FEATURE_MIN].
410 trigger_polarity = (int) togglebutton->active;
416 void
417 on_trigger_external_toggled (GtkToggleButton *togglebutton,
418 gpointer user_data)
420 /* ----------------------------------------------------------------------------
422 if (!dc1394_feature_on_off(cam_var->camera[0].handle,
423 cam_var->camera[0].id,
424 FEATURE_TRIGGER,
425 togglebutton->active)) {
426 message_gpiv(_("Cannot set external trigger source"));
427 } else {
428 cam_var->feature_set[0].feature[FEATURE_TRIGGER - FEATURE_MIN].is_on =
429 togglebutton->active;
431 /* UpdateTriggerFrame(); */
436 void
437 on_trigger_mode_activate (GtkWidget *widget,
438 gpointer user_data)
439 /* ----------------------------------------------------------------------------
442 if (!dc1394_set_trigger_mode(cam_var->camera[0].handle, cam_var->camera[0].id,
443 (int) user_data)) {
444 message_gpiv(_("Cannot set trigger mode"));
445 } else {
446 cam_var->feature_set[0].feature[FEATURE_TRIGGER-FEATURE_MIN].
447 trigger_mode = (int) user_data;
450 /* UpdateTriggerFrame(); */
455 /* void */
456 /* on_trigger_value_changed (GtkAdjustment *adj, */
457 /* gpointer user_data) */
458 /* { */
459 /* if (!dc1394_set_feature_value(cam_var->camera[0].handle, cam_var->camera[0].id, */
460 /* FEATURE_TRIGGER, adj->value)) */
461 /* message_gpiv(_("Cannot set external trigger count")); */
462 /* else */
463 /* cam_var->feature_set[0].feature[FEATURE_TRIGGER-FEATURE_MIN].value = */
464 /* adj->value; */
465 /* } */
468 void
469 on_checkbutton_camera_trigger_enter (GtkWidget *widget,
470 gpointer data)
471 /* ----------------------------------------------------------------------------
474 GpivConsole * gpiv = gtk_object_get_data(GTK_OBJECT(widget), "gpiv");
475 gchar *msg = _("Enables triggering of the camera");
476 gnome_appbar_set_status(GNOME_APPBAR(gpiv->appbar), msg);
481 void
482 on_checkbutton_camera_trigger (GtkWidget *widget,
483 gpointer data)
484 /* ----------------------------------------------------------------------------
487 if (GTK_TOGGLE_BUTTON(widget)->active) {
488 gpiv_par->console__trigger_cam = TRUE;
489 } else {
490 gpiv_par->console__trigger_cam = FALSE;
496 void
497 on_man_auto_menu (GtkWidget *widget,
498 gpointer data)
499 /* ----------------------------------------------------------------------------
502 GtkWidget *scale = gtk_object_get_data(GTK_OBJECT(widget), "scale");
503 int feature = (int) data;
504 enum VariableType {
505 MAN,
506 AUTO
507 } var_type;
509 var_type = atoi(gtk_object_get_data(GTK_OBJECT(widget), "var_type"));
510 if (!dc1394_auto_on_off(cam_var->camera[0].handle,
511 cam_var->camera[0].id,
512 feature, var_type)) {
513 message_gpiv(_("on_man_auto_menu: Cannnot set auto / manual"));
516 if (var_type == MAN) {
517 gtk_widget_set_sensitive (GTK_WIDGET(scale), TRUE);
518 } else if (var_type == AUTO) {
519 gtk_widget_set_sensitive (GTK_WIDGET(scale), FALSE);
526 void
527 on_scale_changed (GtkAdjustment *adj,
528 gpointer user_data)
529 /* ----------------------------------------------------------------------------
532 switch((int)user_data) {
533 case FEATURE_TEMPERATURE:
534 if (!dc1394_set_temperature(cam_var->camera[0].handle,
535 cam_var->camera[0].id,
536 adj->value))
537 message_gpiv(_("on_scale_changed: Cannot set temperature"));
538 else
539 cam_var->feature_set[0].feature[FEATURE_TEMPERATURE-FEATURE_MIN].
540 value = adj->value;
541 break;
543 default:
544 /* g_message("on_scale_changed:: feature = %d value = %f", */
545 /* (gint) user_data, adj->value); */
546 if (!dc1394_set_feature_value(cam_var->camera[0].handle,
547 cam_var->camera[0].id,
548 (gint) user_data,
549 adj->value)) {
550 message_gpiv(_("on_scale_changed: Cannot set feature"));
551 } else {
552 cam_var->feature_set[0].feature[(gint) user_data - FEATURE_MIN].
553 value = adj->value;
555 break;
562 void
563 on_button_dac_camstart_enter (GtkWidget *widget,
564 gpointer data
566 /*-----------------------------------------------------------------------------
569 GpivConsole * gpiv = gtk_object_get_data(GTK_OBJECT(widget), "gpiv");
570 gchar *msg = _("Records PIV images");
571 gnome_appbar_set_status(GNOME_APPBAR(gpiv->appbar), msg);
576 void
577 on_button_dac_camstart (GtkWidget * widget,
578 gpointer data
580 /* ----------------------------------------------------------------------------
581 * The actual calculation of particle image displacements
584 GpivConsole * gpiv = gtk_object_get_data(GTK_OBJECT(widget), "gpiv");
586 cancel_process = FALSE;
587 /*in exec_cam_start: exec_trigger_start(); */
588 exec_cam_start(gpiv);
594 void
595 on_button_dac_camstop_enter (GtkWidget *widget,
596 gpointer data
598 /*-----------------------------------------------------------------------------
601 GpivConsole * gpiv = gtk_object_get_data(GTK_OBJECT(widget), "gpiv");
602 gchar *msg = _("Stops recording PIV images");
603 gnome_appbar_set_status(GNOME_APPBAR(gpiv->appbar), msg);
608 void
609 on_button_dac_camstop (GtkWidget * widget,
610 gpointer data
612 /* ----------------------------------------------------------------------------
613 * The actual calculation of particle image displacements
616 cancel_process = TRUE;
617 #ifdef ENABLE_TRIG
618 exec_trigger_stop();
619 #endif
620 exec_cam_stop();
625 * Local functions
628 static int
629 open_dac_img(GpivCamVar *cam_var,
630 unsigned char **frameA,
631 unsigned char **frameB,
632 Image * img,
633 gboolean alloc_mem
635 /*-----------------------------------------------------------------------------
636 * Opens an image obtained from the camera (Counterpart of open_img from file)
639 gint i, j;
640 gchar *month;
642 * parameter initializing of image
644 gpiv_img_parameters_set(img->image->header, FALSE);
646 img->image->header->ncolumns = cam_var->capture[0].frame_width;
647 img->image->header->nrows = cam_var->capture[0].frame_height;
648 img->image->header->x_corr = gpiv_par->x_corr;
649 img->image->header->ncolumns__set = TRUE;
650 img->image->header->nrows__set = TRUE;
651 img->image->header->x_corr__set = TRUE;
653 gl_image_par = gpiv_img_cp_parameters (img->image->header);
654 if (verbose) g_message("open_dac_img:: 1 creation_date = %s",
655 img->image->header->creation_date);
657 * Apply time and date to creation_date (buffer) parameter
659 month = month_name(g_date_month(date));
660 g_snprintf(img->image->header->creation_date,
661 GPIV_MAX_CHARS,
662 "%d %s %d %d:%d:%d",
663 g_date_day(date),
664 month,
665 g_date_year(date),
666 dac_time->tm_hour,
667 dac_time->tm_min,
668 dac_time->tm_sec);
669 g_free(month);
672 /* if(alloc_mem) { */
673 img->img1 = gpiv_alloc_img(img->image_par);
674 /* } */
676 for (i = 0; i < img->image->header->nrows ; i++) {
677 for (j = 0; j < img->image->header->ncolumns; j++) {
679 * format 640x480 = 1:1.3
681 img->img1[i][j/* + i/3 */] = (guint16) frameA[i][j];
687 if (gpiv_par->x_corr) {
688 /* if(alloc_mem) { */
689 img->img2 = gpiv_alloc_img(img->image_par);
690 /* } */
691 for (i = 0; i < img->image->header->nrows ; i++) {
692 for (j = 0; j < img->image->header->ncolumns; j++) {
694 * format 640x480 = 1:1.3
696 img->img2[i][j/* + i/3 */] = (guint16) frameB[i][j];
699 } else {
700 img->img2 = img->img1;
704 img->exist_img = TRUE;
705 img->saved_img = FALSE;
706 return 0;
710 static void
711 load_dac_buffer (GpivConsole *gpiv,
712 GpivCamVar *cam_var,
713 gboolean second_image,
714 char *fname,
715 int ibuf,
716 unsigned char **frameA,
717 unsigned char **frameB,
718 enum ClistPut clist_put
720 /*-----------------------------------------------------------------------------
721 * create display and its (popup) menu, load image, piv data and puts
722 * buffername into clist
725 gint return_val = 0;
726 gchar *clist_buf_txt[MAX_BUFS][2], cl_int[4];
729 display[ibuf] = create_display(fname, ibuf, gpiv);
730 display_act = display[ibuf];
731 gtk_widget_show(display_act->mwin);
733 /* zoom_display(display_act, display_act->zoom_index); */
737 g_snprintf (display_act->file_uri_name, GPIV_MAX_CHARS, "%s", fname);
738 if((return_val = open_dac_img (cam_var, frameA, frameB,
739 display_act->img, FALSE))
740 != 0) {
741 gtk_object_destroy (GTK_OBJECT(display[ibuf]->mwin));
742 if (ibuf > 0) {
743 ibuf = nbufs - 1;;
744 display_act = display[ibuf];
745 } else {
746 display_act = NULL;
748 nbufs--;
749 return;
753 * Pop-up menu after loading data
755 display_act->display_popupmenu = create_display_popupmenu (display_act);
756 gtk_widget_show (display_act->display_popupmenu);
757 gtk_signal_connect_object (GTK_OBJECT(display_act->mwin),
758 "button_press_event",
759 GTK_SIGNAL_FUNC (on_my_popup_handler),
760 GTK_OBJECT(display_act->display_popupmenu));
763 zoom_display (display_act, display_act->zoom_index);
766 * Displaying
768 create_background (display_act);
769 create_img (display_act);
770 if (display_act->img->exist_img ) {
771 show_img1 (display_act);
772 } else {
773 hide_img1 (display_act);
776 if (gl_image_par->x_corr) {
777 if (display_act->img->exist_img) {
778 show_img2 (display_act);
779 } else {
780 hide_img2 (display_act);
785 /* display_act->img.img_mean = image_mean(display_act->img.img1, */
786 /* gpiv_par->img_width, */
787 /* gpiv_par->img_height); */
790 if (gpiv_par->display__intregs == 1) {
791 if (verbose) g_message("load_dac_buffer:: create_all_intregs");
792 create_all_intregs(display_act);
796 * Add buffer to list
798 g_snprintf(cl_int, 4, "%d", ibuf);
799 clist_buf_txt[ibuf][0] = (gchar *) cl_int;
800 clist_buf_txt[ibuf][1] = fname;
801 if (clist_put == PREPEND) {
802 gtk_clist_prepend(GTK_CLIST(gpiv->clist_buf),
803 clist_buf_txt[ibuf]);
804 } else if (clist_put == INSERT) {
805 gtk_clist_insert(GTK_CLIST(gpiv->clist_buf), ibuf,
806 clist_buf_txt[ibuf]);
807 } else if (clist_put == APPEND) {
808 gtk_clist_append(GTK_CLIST(gpiv->clist_buf),
809 clist_buf_txt[ibuf]);
810 } else {
811 error_gpiv("non-existent CLIST enumerate");
814 gtk_clist_set_row_data(GTK_CLIST(gpiv->clist_buf), ibuf,
815 display_act);
819 * Copy general image parameters to the buffer parameters
820 * and display in imgh tabulator
822 /* gpiv_img_cp_parameters(gl_image_par, display_act->img.image_par); */
824 if (verbose) g_message ("load_dac_buffer:: ncolumns=%d nrows = %d",
825 display_act->img->image->header->ncolumns, display_act->img->image->header->nrows);
826 gtk_widget_set_size_request (display_act->canvas,
827 (gint) (display_act->zoom_factor *
828 display_act->img->image->header->ncolumns),
829 (gint) (display_act->zoom_factor *
830 display_act->img->image->header->nrows));
836 static void
837 rec_and_display (GpivConsole *gpiv
838 /* , ImgFrame *img_frame */
840 /*-----------------------------------------------------------------------------
843 gint ibuf = 0;
844 ImgFrame img_frame[GPIV_NIMG_MAX];
846 gint return_val = 0;
847 pthread_t thread_rec;
848 pthread_attr_t attr;
850 gint mode, cycles, DURATION;
851 pthread_attr_init(&attr);
852 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
856 * Select which parameters and constants to be used; from RTAI trigger
857 * system (if enabled, this may be used) or from camera. If trigger has not
858 * been enabled only from camera
860 #ifdef ENABLE_TRIG
861 if (gpiv_par->process_trig) {
862 mode = gl_trig_par.ttime.mode;
863 cycles = gl_trig_par.ttime.cycles;
864 DURATION = GPIV_TIMER_MODE__DURATION;
865 } else {
866 mode = gl_cam_par->mode;
867 cycles = gl_cam_par->cycles;
868 DURATION = GPIV_CAM_MODE__DURATION;
870 #else /* ENABLE_TRIG */
871 mode = gl_cam_par->mode;
872 cycles = gl_cam_par->cycles;
873 DURATION = GPIV_CAM_MODE__DURATION;
874 #endif /* ENABLE_TRIG */
877 * Closing existing buffer windows and cleaning up Clist
878 * BUGFIX: windows remain open
880 if (mode == DURATION) {
881 for (ibuf = 0; ibuf < nbufs; ibuf++) {
882 if (display[ibuf] != NULL) {
883 close_buffer(gpiv, display[ibuf]);
886 gtk_clist_clear(GTK_CLIST(gpiv->clist_buf));
887 nbufs = 0;
890 * allocating image mem
892 for (ibuf = 0; ibuf < cycles; ibuf++) {
893 img_frame[ibuf].A =
894 gpiv_ucmatrix(cam_var->capture[0].frame_height,
895 cam_var->capture[0].frame_width);
896 if (gpiv_par->x_corr) {
897 img_frame[ibuf].B = gpiv_ucmatrix(cam_var->capture[0].frame_height,
898 cam_var->capture[0].frame_width);
903 * recording
906 #define THREADING
908 * use threading
910 /* if (verbose) */
911 /* g_message("rec_and_display:: Creating thread_rec from %d", pthread_self ()); */
912 #ifdef THREADING
913 if ((return_val = pthread_create (&thread_rec,
914 &attr,
915 (void *) &thread_rec_frame_serie,
916 (void *) &img_frame)) == TRUE) {
917 pthread_exit(NULL);
918 g_error("return code from pthread_create() is %d\n", return_val);
920 pthread_join(thread_rec, NULL);
921 if (verbose) g_message ("rec_and_display:: waited on thread_rec. Done");
924 * no threading used
926 #else
927 for (ibuf = 0; ibuf < cycles; ibuf++) {
928 if (cancel_process) break;
929 rec_frame(&img_frame[ibuf]);
931 progress_value = (gfloat) (ibuf + 1.0) /
932 (gfloat) cycles;
933 g_snprintf(progress_string, GPIV_MAX_CHARS,
934 "recording image #%d", ibuf);
935 while (g_main_iteration(FALSE));
936 gtk_progress_set_value(gnome_appbar_get_progress
937 (GNOME_APPBAR(gpiv->appbar)),
938 progress_value * 100.0);
939 gnome_appbar_push(GNOME_APPBAR(gpiv->appbar),
940 progress_string);
943 #endif /* THREADING */
944 #undef THREADING
946 * displaying and freeing image mem
948 for (ibuf = 0; ibuf < cycles; ibuf++) {
949 add_buffer(gpiv, gpiv_var->fn_last[0], ibuf, img_frame[ibuf].A,
950 img_frame[ibuf].B);
951 gpiv_free_ucmatrix(img_frame[ibuf].A);
952 if (gpiv_par->x_corr) {
953 gpiv_free_ucmatrix(img_frame[ibuf].B);
958 * timing is indefinite periodic
959 * display only and continuously images in buffer 0
961 } else {
962 ibuf = 0;
963 gtk_clist_select_row(GTK_CLIST(gpiv->clist_buf), ibuf, 0);
964 if (verbose) g_message("rec_and_display:: INDEFINITE");
966 /* BUGFIX: for Gtk2 */
967 /* gtk_progress_bar_set_pulse_step (GNOME_APPBAR(gpiv->appbar), */
968 /* 0.1); */
970 img_frame[ibuf].A =
971 gpiv_ucmatrix(cam_var->capture[0].frame_height,
972 cam_var->capture[0].frame_width);
973 if (gpiv_par->x_corr) {
974 img_frame[ibuf].B = gpiv_ucmatrix(cam_var->capture[0].frame_height,
975 cam_var->capture[0].frame_width);
978 while (!cancel_process) {
979 rec_frame(&img_frame[ibuf]);
980 while (g_main_iteration(FALSE));
981 renew_buffer(gpiv, gpiv_var->fn_last[0], ibuf, img_frame[ibuf].A,
982 img_frame[ibuf].B);
983 /* BUGFIX: for Gtk2 */
984 /* gtk_progress_bar_pulse ((GNOME_APPBAR(gpiv->appbar)) */
989 gpiv_free_ucmatrix(img_frame[ibuf].A);
990 if (gpiv_par->x_corr) {
991 gpiv_free_ucmatrix(img_frame[ibuf].B);
996 pthread_attr_destroy(&attr);
1000 static void
1001 thread_rec_frame(void *img_frame)
1002 /*-----------------------------------------------------------------------------
1005 ImgFrame *my_frame = NULL;
1006 unsigned char **frameA = my_frame->A;
1007 unsigned char **frameB = my_frame->B;
1009 if (verbose) g_warning("thread_rec_frame:: 0");
1010 my_frame = (ImgFrame *) img_frame;
1013 /* unsigned char **frameA = gpiv_ucmatrix(cam_var->capture[0].frame_height, */
1014 /* cam_var->capture[0].frame_width); */
1017 if (verbose) g_message("thread_rec_frame:: 0.1");
1019 * capture one frame
1021 if (dc1394_single_capture(cam_var->handle, &cam_var->capture[0])
1022 != DC1394_SUCCESS) {
1023 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
1024 raw1394_destroy_handle(cam_var->handle);
1025 warning_gpiv(_("unable to capture a frame"));
1026 /* return(); */
1027 } else {
1028 if (verbose) g_message("thread_rec_frame:: 1");
1032 * Copy buffer content to tmp buffer array
1033 * block data for thread
1036 pthread_mutex_lock(&mutex_rec);
1037 memcpy( frameA[0], (const char *) cam_var->capture[0].capture_buffer,
1038 sizeof(char) * cam_var->capture[0].frame_width *
1039 cam_var->capture[0].frame_height);
1040 pthread_mutex_unlock(&mutex_rec);
1041 if (verbose) g_message("thread_rec_frame:: 2");
1045 * Repeat if cross correlation; x_corr = TRUE
1047 if (gpiv_par->x_corr) {
1048 if (dc1394_single_capture(cam_var->handle, &cam_var->capture[0])
1049 != DC1394_SUCCESS) {
1050 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
1051 raw1394_destroy_handle(cam_var->handle);
1052 warning_gpiv(_("unable to capture a frame"));
1053 /* return(); */
1054 } else {
1056 pthread_mutex_lock(&mutex_rec);
1057 memcpy( frameB[0], (const char *) cam_var->capture[0].capture_buffer,
1058 sizeof(char) * cam_var->capture[0].frame_width *
1059 cam_var->capture[0].frame_height);
1060 pthread_mutex_unlock(&mutex_rec);
1065 /* gpiv_free_ucmatrix(frameA); */
1067 if (verbose) g_warning("thread_rec_frame:: 3/3");
1068 pthread_exit(0);
1074 static void
1075 thread_rec_frame_serie(ImgFrame img_frame[GPIV_NIMG_MAX]
1077 /*-----------------------------------------------------------------------------
1078 * capture a series of images
1081 gint ibuf, cycles;
1083 #ifdef ENABLE_TRIG
1084 cycles = gl_trig_par.ttime.cycles;
1085 #else /* ENABLE_TRIG */
1086 cycles = gl_cam_par->cycles;
1087 #endif /* ENABLE_TRIG */
1089 /* g_message("thread_rec_frame_series:: 0 with id = %d", (int) pthread_self ()); */
1090 for (ibuf = 0; ibuf < cycles; ibuf++) {
1091 if (cancel_process) break;
1092 /* BUGFIX: thread_rec_frame_serie calls rec_frame, NOT thread_ rec_frame; correct?
1093 rec_frame(&img_frame[ibuf]);
1095 /* g_message("thread_rec_frame_series:: 1/1"); */
1096 pthread_exit(NULL);
1101 static void
1102 rec_frame(ImgFrame *img_frame
1104 /*-----------------------------------------------------------------------------
1106 * capture a single image frame or frame pair
1110 /* g_message("rec_frame:: 0"); */
1112 if (dc1394_single_capture(cam_var->handle, &cam_var->capture[0])
1113 != DC1394_SUCCESS) {
1114 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
1115 raw1394_destroy_handle(cam_var->handle);
1116 g_warning("unable to capture a frame");
1117 return;
1121 * Copy buffer content to tmp buffer array
1123 memcpy( img_frame->A[0],
1124 (const char *) cam_var->capture[0].capture_buffer,
1125 sizeof(char) * cam_var->capture[0].frame_width *
1126 cam_var->capture[0].frame_height);
1128 if (gpiv_par->x_corr) {
1130 * capture second frame
1132 if (dc1394_single_capture(cam_var->handle, &cam_var->capture[0])
1133 != DC1394_SUCCESS) {
1134 dc1394_release_camera(cam_var->handle, &cam_var->capture[0]);
1135 raw1394_destroy_handle(cam_var->handle);
1136 g_warning("unable to capture a frame");
1137 return;
1140 memcpy( img_frame->B[0],
1141 (const char *) cam_var->capture[0].capture_buffer,
1142 sizeof(char) * cam_var->capture[0].frame_width *
1143 cam_var->capture[0].frame_height);
1146 /* g_message("rec_frame:: 3/3"); */
1151 static void
1152 add_buffer(GpivConsole *gpiv,
1153 gchar *fname_base,
1154 gint ibuf,
1155 unsigned char **frameA,
1156 unsigned char **frameB
1158 /*-----------------------------------------------------------------------------
1161 gchar cbuf[4], cdate[GPIV_MAX_CHARS], ctime[GPIV_MAX_CHARS];
1162 /* GTimeVal *my_gtime = NULL; */
1163 time_t ltime_t;
1165 * Use numbers or timing to concanate after buffer names
1169 /* BUGFIX GTimeVal might be used for more accurate timing */
1170 /* my_gtime = g_malloc(sizeof(GTimeVal)); */
1171 /* g_get_current_time(my_gtime); */
1173 date = g_date_new ();
1174 g_date_set_time(date, time (NULL));
1175 ltime_t = time(&ltime_t);
1176 dac_time = localtime(&ltime_t);
1177 g_snprintf(ctime, sizeof(gint) * 3 + 2,
1178 "%d.%d.%d_",
1179 dac_time->tm_hour,
1180 dac_time->tm_min,
1181 dac_time->tm_sec);
1184 g_snprintf(cdate, sizeof(gint) * 3 + 2,
1185 "%d.%d.%d_",
1186 g_date_day(date),
1187 g_date_month(date),
1188 g_date_year(date));
1190 g_snprintf(cbuf, 4, "%d", ibuf);
1192 if (gpiv_var->fname_date
1193 && gpiv_var->fname_time) {
1194 fname_base = g_strdup(g_strconcat(gpiv_var->fn_last[0],
1195 (gchar *) cdate,
1196 (gchar *) ctime,
1197 (gchar *) cbuf,
1198 NULL));
1199 } else if (gpiv_var->fname_date) {
1200 fname_base = g_strdup(g_strconcat(gpiv_var->fn_last[0],
1201 (gchar *) cdate,
1202 (gchar *) cbuf,
1203 NULL));
1204 } else if (gpiv_var->fname_time) {
1205 fname_base = g_strdup(g_strconcat(gpiv_var->fn_last[0],
1206 (gchar *) ctime,
1207 (gchar *) cbuf,
1208 NULL));
1209 } else {
1210 fname_base = g_strdup(g_strconcat(gpiv_var->fn_last[0],
1211 (gchar *) cbuf,
1212 NULL));
1215 load_dac_buffer(gpiv, cam_var, FALSE, fname_base, ibuf, frameA, frameB,
1216 INSERT);
1217 nbufs++;
1219 /* g_free(my_gtime); */
1220 g_free(fname_base);
1221 g_date_free(date);
1222 return;
1227 static void
1228 renew_buffer(GpivConsole *gpiv,
1229 gchar *fname_base,
1230 gint ibuf,
1231 unsigned char **frameA,
1232 unsigned char **frameB
1234 /*-----------------------------------------------------------------------------
1235 * updates image of buffer
1239 * Open buffer 0 if not exist
1242 if (display[ibuf] == NULL) {
1243 add_buffer(gpiv, fname_base, ibuf, frameA, frameB);
1244 } else {
1245 display_act = display[ibuf];
1247 recreate_img(display_act, frameA, frameB);
1248 if (display_act->img->exist_img) {
1249 show_img1(display_act);
1250 } else {
1251 hide_img1(display_act);
1254 if (gl_image_par->x_corr) {
1255 if (display_act->img->exist_img) {
1256 show_img2(display_act);
1257 } else {
1258 hide_img2(display_act);
1269 static void
1270 recreate_img(Display * disp,
1271 unsigned char **frameA,
1272 unsigned char **frameB
1274 /* ----------------------------------------------------------------------------
1275 * Re-creates image in gnome canvas; without memallocating of rgbbuf_img1 and
1276 * rgbbuf_img2
1277 * row stride; each row is a 4-byte buffer array
1280 guchar *pos1 = NULL;
1281 /* guchar *pos2 = NULL; */
1282 gint i, j;
1283 GdkPixbuf *pixbuf1 = NULL;
1284 /* GdkPixbuf *pixbuf2 = NULL; */
1285 guint16 fact = 1;
1286 gint depth = 8;
1288 assert (disp != NULL);
1289 //assert (disp->img->img1 != NULL);
1290 assert (disp->img->rgbbuf_img1 != NULL);
1291 if (disp->img->image->header->x_corr) {
1292 // assert (disp->img->img2 != NULL);
1293 assert (disp->img->rgbbuf_img2 != NULL);
1295 assert (disp->img->exist_img);
1298 fact = fact << (disp->img->image->header->depth - depth);
1299 disp->img->rgb_img_width = disp->img->image->header->ncolumns * 3;
1300 while ((disp->img->rgb_img_width) % 4 != 0) {
1301 disp->img->rgb_img_width++;
1304 pixbuf1 = gdk_pixbuf_new_from_data(disp->img->rgbbuf_img1,
1305 GDK_COLORSPACE_RGB,
1306 FALSE, /* gboolean has_alpha */
1307 disp->img->image->header->depth,
1308 disp->img->image->header->ncolumns,
1309 disp->img->image->header->nrows,
1310 disp->img->rgb_img_width, /* rowstride */
1311 NULL,
1312 NULL);
1316 pos1 = disp->img->rgbbuf_img1;
1317 for (i = 0; i < disp->img->image->header->nrows; i++) {
1318 for (j = 0; j < disp->img->image->header->ncolumns; j++) {
1319 *pos1++ = (guchar) (frameA[i][j] / fact);
1320 *pos1++ = (guchar) (frameA[i][j] / fact);
1321 *pos1++ = (guchar) (frameA[i][j] / fact);
1326 gnome_canvas_item_set(GNOME_CANVAS_ITEM (disp->img->gci_img1),
1327 "pixbuf", pixbuf1,
1328 NULL);
1329 /* gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM (disp->img->gci_img1)); */
1330 /* gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (disp->img->gci_img1)); */
1332 /* gtk_widget_pop_visual(); */
1333 /* gtk_widget_pop_colormap(); */
1336 gdk_pixbuf_unref (pixbuf1);
1340 /* if(image->header->x_corr) { */
1341 /* pos2 = NULL; */
1343 /* disp->img->rgbbuf_img2 = g_malloc(disp->img->rgb_img_width * 3 * */
1344 /* gpiv_par->img_height); */
1346 /* pixbuf2 = gdk_pixbuf_new_from_data(disp->img->rgbbuf_img2, */
1347 /* GDK_COLORSPACE_RGB, */
1348 /* FALSE, */
1349 /* depth, */
1350 /* gpiv_par->img_width, */
1351 /* gpiv_par->img_height, */
1352 /* disp->img->rgb_img_width, */
1353 /* NULL, */
1354 /* NULL); */
1356 /* if (disp->img->gci_img2 != NULL) { */
1357 /* destroy_img(disp); */
1358 /* } */
1360 /* disp->img->gci_img2 = */
1361 /* gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS */
1362 /* (disp->canvas)), */
1363 /* gnome_canvas_pixbuf_get_type (), */
1364 /* "pixbuf", pixbuf2, */
1365 /* NULL); */
1368 /* pos2 = disp->img->rgbbuf_img2; */
1369 /* for (i = 0; i < gpiv_par->img_height; i++) { */
1370 /* for (j = 0; j < gpiv_par->img_width; j++) { */
1371 /* *pos2++ = (guchar) (frameB[i][j] / fact); */
1372 /* *pos2++ = (guchar) (frameB[i][j] / fact); */
1373 /* *pos2++ = (guchar) (frameB[i][j] / fact); */
1374 /* } */
1375 /* } */
1377 /* gdk_pixbuf_unref (pixbuf2); */
1379 /* } else { */
1380 disp->img->gci_img2 = disp->img->gci_img2;
1381 /* } */
1387 #endif /* ENABLE_CAM */