show git hash (if available) when invoking -v key
[gpivtools.git] / src / dac / rec_image.c
blob08ac7957ced8ef307c40ef42ea7d3805d956ee0e
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
4 /**************************************************************************
5 ** Title: grab one gray image using libdc1394
6 ** $RCSfile: rec_image.c,v $
7 ** $Revision: 1.7 $$Name: $
8 ** $Date: 2007-11-23 16:18:55 $
9 ** Copyright (C) 2005, 2006, 2007, 2008
10 ** Gerber van der Graaf <gerber_graaf@users,sourceforge.net
12 ** Description:
14 ** Get one gray image using libdc1394 and store it as portable gray map
15 ** (pgm). Based on 'samplegrab' from Chris Urmson
17 **-------------------------------------------------------------------------
19 ** $Log: rec_image.c,v $
20 ** Revision 1.7 2007-11-23 16:18:55 gerber
21 ** release 0.5.0: Kafka
23 ** Revision 1.6 2007-01-29 14:26:54 gerber
24 ** Added image formats png, gif, tif, pgm, bpm. Added gpiv_aint
26 ** Revision 1.5 2006-09-18 07:36:16 gerber
27 ** split up of trigger and camera (image recording)
29 ** Revision 1.4 2006/01/31 14:18:03 gerber
30 ** version 0.3.2
32 ** Revision 1.3 2005/02/26 16:29:19 gerber
33 ** parameter flags (parameter_logic) defined as gboolean, added scale_type to struct __GpivPostPar for inverse scaling
35 ** Revision 1.2 2005/01/19 15:45:58 gerber
36 ** all executables start with gpiv_
38 ** Revision 1.1 2005/01/19 10:36:03 gerber
39 ** Initiation of Data Acquisition; triggering of lasers and camera, recording images
41 ** Revision 1.2 2001/09/14 08:10:41 ronneber
42 ** - some cosmetic changes
44 ** Revision 1.1 2001/07/24 13:50:59 ronneber
45 ** - simple test programs to demonstrate the use of libdc1394 (based
46 ** on 'samplegrab' of Chris Urmson
49 **************************************************************************/
51 #include <stdio.h>
52 #ifdef ENABLE_CAM
53 #include <libraw1394/raw1394.h>
54 #include <libdc1394/dc1394_control.h>
55 #endif /* ENABLE_CAM */
56 #include <stdlib.h>
57 #include <getopt.h>
58 #include <gpiv.h>
59 #include "system.h"
60 #ifdef ENABLE_CAM
61 #include "rec_image.h"
62 #endif /* ENABLE_CAM */
63 #include <unistd.h> /* unsigned int sleep(unsigned int seconds); */
65 #include "config.h"
66 #include "git-rev.h"
69 #define EXIT_FAILURE 1
71 #ifdef ENABLE_CAM
73 char *xmalloc ();
74 char *xrealloc ();
75 char *xstrdup ();
78 char *program_name;
80 /* Option flags and variables */
82 #define USAGE "\
83 Usage: gpiv_rec_image [-h | --help] -v | --version] -V | --verbose] [-x | --x_corr] \n\
84 [filename] > stdout \n\
85 \n\
86 keys: \n\
87 -h | --help this on-line help \n\
88 -v | --version: version number \n\
89 -V | --verbose: program prints more information \n\
90 -x | --x_corr record two succesive images for cross-correlation \n\
91 filename: image filename. Overrides stdout. \n\
92 Output will be a .png formatted image \n\
95 #define HELP "\
96 gpiv_recimg captures images from a IIDC-compliant camera with IEE1394 connection \n\
100 * Global parameters and variables
102 gboolean use_stdin_stdout = FALSE;
103 gboolean verbose = FALSE; /* --verbose */
104 gboolean print_par = FALSE;
107 static void
108 command_args (int argc,
109 char *argv[],
110 char fname[GPIV_MAX_CHARS],
111 GpivImagePar *image_par
113 /* ----------------------------------------------------------------------------
114 * Command line argument handling
117 char c = '\0';
118 gint argc_next;
120 while (--argc > 0 && (*++argv)[0] == '-') {
123 * argc_next is set to 1 if the next cmd line argument has to be searched for;
124 * in case that the command line argument concerns more than one char or cmd
125 * line argument needs a parameter
128 argc_next = 0;
129 while (argc_next == 0 && (c = *++argv[0]))
131 switch (c) {
132 case 'v':
133 #ifdef GIT_HASH
134 printf ("git hash: %s\n", GIT_REV);
135 #else
136 printf ("version: %s\n", GPIVTOOLS_VERSION);
137 #endif
138 exit(0);
139 break;
141 case 'h':
142 printf("%s\n",HELP);
143 printf("%s\n",USAGE);
144 exit(0);
145 break;
147 case 'V':
148 verbose = TRUE;
149 break;
151 case 'x':
152 image_par->x_corr = TRUE;
153 image_par->x_corr__set = TRUE;
154 break;
156 * long option keys
158 case '-':
159 if (strcmp("-help", *argv) == 0) {
160 printf("\n%s", HELP);
161 printf("\n%s", USAGE);
162 exit(0);
163 } else if (strcmp("-verbose", *argv) == 0) {
164 verbose = TRUE;
165 } else if (strcmp("-version", *argv) == 0) {
166 #ifdef GIT_HASH
167 printf ("git hash: %s\n", GIT_REV);
168 #else
169 printf ("version: %s\n", GPIVTOOLS_VERSION);
170 #endif
171 exit(0);
172 } else if (strcmp("-x_corr", *argv) == 0) {
173 image_par->x_corr = TRUE;
174 image_par->x_corr__set = TRUE;
175 } else {
176 #ifdef GIT_HASH
177 gpiv_error ("%s: unknown option: %s", GIT_REV, *argv);
178 #else
179 gpiv_error ("%s: unknown option: %s", GPIVTOOLS_VERSION, *argv);
180 #endif
182 argc_next = 1;
183 break;
185 default:
186 #ifdef GIT_HASH
187 gpiv_error ("%s: unknown option: %s", GIT_REV, *argv);
188 #else
189 gpiv_error ("%s: unknown option: %s", GPIVTOOLS_VERSION, *argv);
190 #endif
191 break;
196 * Check if filename or stdin /stdout is used
198 if (argc == 1) {
199 use_stdin_stdout = FALSE;
200 strcpy(fname, argv[argc - 1]);
201 } else if (argc == 0) {
202 use_stdin_stdout = TRUE;
203 print_par = FALSE;
204 } else {
205 #ifdef GIT_HASH
206 gpiv_error("\n%s: unknown argument: %s: %s", GIT_REV, *argv, USAGE);
207 #else
208 gpiv_error("\n%s: unknown argument: %s: %s", GPIVTOOLS_VERSION, *argv, USAGE);
209 #endif
217 int
218 main(int argc,
219 char *argv[]
221 /*-----------------------------------------------------------------------------
224 FILE* imagefile;
225 dc1394_cameracapture capture;
226 quadlet_t value;
227 GpivCamVar *cam_var = NULL;
228 gchar *err_msg = NULL;
229 gchar fname[GPIV_MAX_CHARS];
231 unsigned char **lframe1 = NULL, **lframe2 = NULL;
232 guint16 **img1 = NULL, **img2 = NULL;
233 GpivImagePar gpiv_image_par;
234 gint i, j;
236 * from coriander:
238 /* chain_t **image_pipes; */
239 /* Format7Info *format7_info; */
240 /* UIInfo *uiinfos; */
241 /* SelfIdPacket_t *selfids; */
244 program_name = "gpiv_recimg";
245 gpiv_img_parameters_set (&gpiv_image_par, FALSE);
246 gpiv_image_par.x_corr = FALSE;
247 command_args (argc, argv, fname, &gpiv_image_par);
248 if (verbose) printf ("starting %s\n", program_name);
250 if ((cam_var = gpiv_cam_get_camvar (verbose)) == NULL) {
251 g_error("from: rec_image->main\n from: gpiv_cam_get_camvar\n %s",
252 err_msg);
256 * coriander: IsoStartThread->on_button_receive
258 cam_var->misc_info[0].format = FORMAT_VGA_NONCOMPRESSED;
259 cam_var->misc_info[0].mode = MODE_640x480_MONO;
260 cam_var->misc_info[0].framerate = FRAMERATE_7_5;
261 if (dc1394_setup_capture (cam_var->camera[0].handle,
262 cam_var->camera[0].id,
263 cam_var->misc_info[0].iso_channel,
264 cam_var->misc_info[0].format,
265 cam_var->misc_info[0].mode,
266 /* maxspeed */ SPEED_400,
267 cam_var->misc_info[0].framerate,
268 &capture)
269 != DC1394_SUCCESS) {
270 /* info->receive_method=RECEIVE_METHOD_RAW1394; */
271 dc1394_release_camera (cam_var->handle, &capture);
272 raw1394_destroy_handle (cam_var->handle);
273 g_error ("unable to setup camera-\n"
274 "check line %d of %s to make sure\n"
275 "that the video mode, framerate and format are\n"
276 "supported by your camera\n",
277 __LINE__,__FILE__);
278 } else {
279 if (verbose) g_message("dc1394_setup_capture: succes");
282 /* int */
283 /* dc1394_set_exposure(raw1394handle_t handle, nodeid_t node, */
284 /* unsigned int exposure); */
286 dc1394_auto_on_off(cam_var->camera[0].handle, cam_var->camera[0].id,
287 FEATURE_EXPOSURE, 1);
288 /* 0=off, nonzero=on */
290 * set trigger mode
291 * BUGFIX: disabled temporarly
293 if( dc1394_set_trigger_mode(cam_var->handle,
294 /* capture.node */ cam_var->camera[0].id,
295 TRIGGER_MODE_0)
296 != DC1394_SUCCESS) {
297 if (verbose) g_message("unable to set camera trigger mode\n");
298 } else {
299 if (verbose) g_message("dc1394_set_trigger_mode: succes");
302 * report camera's feature set
304 if (verbose) dc1394_print_feature_set (&cam_var->feature_set[0]);
307 * test on single feature
309 if (verbose
310 && dc1394_query_basic_functionality (cam_var->handle,
311 capture.node,
312 &value)
313 != DC1394_SUCCESS) {
314 g_warning("dc1394_query_basic_functionality: failed\n");
315 } else {
316 if ((value>>(8*sizeof(quadlet_t)-19-1)) != 0) {
317 if (verbose) g_message("single shot supperted");
318 } else {
319 if (verbose) g_message("single shot _NOT_ supperted");
324 * have the camera start sending us data
325 * on_iso_start_clicked
327 if (dc1394_start_iso_transmission (cam_var->handle, capture.node)
328 != DC1394_SUCCESS) {
329 dc1394_release_camera(cam_var->handle, &capture);
330 raw1394_destroy_handle(cam_var->handle);
331 g_error("unable to start camera iso transmission");
332 } else {
333 if (verbose) g_message("dc1394_start_iso_transmission: succes");
336 sleep(1);
338 * capture one or two frames
339 * on_service_iso_toggled->IsoStartThread
341 if (dc1394_single_capture (cam_var->handle, &capture) != DC1394_SUCCESS) {
342 dc1394_release_camera(cam_var->handle, &capture);
343 raw1394_destroy_handle(cam_var->handle);
344 g_error("unable to capture a frame");
345 } else {
346 if (verbose) g_message("dc1394_single_capture: succes");
348 lframe1 = gpiv_ucmatrix (capture.frame_height, capture.frame_width);
349 memcpy( lframe1[0], (const char *) capture.capture_buffer,
350 sizeof(char) * capture.frame_width * capture.frame_height);
352 if (gpiv_image_par.x_corr) {
353 if (dc1394_single_capture (cam_var->handle, &capture) != DC1394_SUCCESS) {
354 dc1394_release_camera(cam_var->handle, &capture);
355 raw1394_destroy_handle(cam_var->handle);
356 g_error("unable to capture a frame");
357 } else {
358 if (verbose) g_message("dc1394_single_capture: succes");
361 lframe2 = gpiv_ucmatrix (capture.frame_height, capture.frame_width);
362 memcpy( lframe2[0], (const char *) capture.capture_buffer,
363 sizeof(char) * capture.frame_width * capture.frame_height);
365 * Stop data transmission
367 if (dc1394_stop_iso_transmission(cam_var->handle, capture.node)
368 != DC1394_SUCCESS) {
369 g_warning("couldn't stop the camera?\n");
370 } else {
371 if (verbose) g_message("dc1394_stop_iso_transmissio: succes");
375 * save image as 'Image.pgm'
377 if (use_stdin_stdout) {
378 imagefile = stdout;
379 } else {
380 if((imagefile = fopen(fname, "wb")) == NULL) {
381 dc1394_release_camera(cam_var->handle, &capture);
382 raw1394_destroy_handle(cam_var->handle);
383 g_error( "Can't create %s", fname);
387 if (verbose) g_message("width = %d height = %d",
388 capture.frame_width,
389 capture.frame_height);
392 * Printing to png image file
394 gpiv_image_par.nrows = capture.frame_height;
395 gpiv_image_par.nrows__set = TRUE;
396 gpiv_image_par.ncolumns = capture.frame_width;
397 gpiv_image_par.ncolumns__set = TRUE;
398 /* BUGFIX: dc1394_query_format7_data_depth does not work */
399 /* dc1394_query_format7_data_depth(cam_var->handle, capture.node, */
400 /* cam_var->misc_info[0].mode, */
401 /* &gpiv_image_par.depth); */
402 /* if (verbose) g_message ("%s:: depth from query = %d", program_name, gpiv_image_par.depth); */
403 gpiv_image_par.depth = 8;
404 gpiv_image_par.depth__set = TRUE;
405 g_snprintf (gpiv_image_par.software, GPIV_MAX_CHARS, "%s", program_name);
406 gpiv_image_par.software__set = TRUE;
407 g_snprintf (gpiv_image_par.source, GPIV_MAX_CHARS, "Vendor: %s Model: %s",
408 cam_var->camera[0].vendor, cam_var->camera[0].model);
409 gpiv_image_par.source__set = TRUE;
410 if (verbose) gpiv_img_print_header (gpiv_image_par);
412 img1 = gpiv_alloc_img(gpiv_image_par);
413 if (gpiv_image_par.x_corr) {
414 img2 = gpiv_alloc_img(gpiv_image_par);
415 } else {
416 img2 = img1;
420 * copying capture_buffer to a 2-dimensional array of unsigned char
421 * in order to get it in 2-dimensional array img1 of guint16, as used in the
422 * gpiv programs and libraries.
424 for (i = 0; i < gpiv_image_par.nrows; i++) {
425 for (j = 0; j < gpiv_image_par.ncolumns; j++) {
426 img1[i][j] = (guint16) lframe1[i][j];
429 gpiv_free_ucmatrix(lframe1);
430 if (gpiv_image_par.x_corr) {
431 for (i = 0; i < gpiv_image_par.nrows; i++) {
432 for (j = 0; j < gpiv_image_par.ncolumns; j++) {
433 img2[i][j] = (guint16) lframe2[i][j];
436 gpiv_free_ucmatrix(lframe2);
439 if ((err_msg =
440 gpiv_write_png_image (imagefile, &img1, &img2, &gpiv_image_par, TRUE))
441 != NULL) {
442 gpiv_error ("%s: %s\n", argv[0], err_msg);
444 if (use_stdin_stdout == FALSE) fclose (imagefile);
447 * Close camera
449 dc1394_release_camera(cam_var->handle, &capture);
451 free(cam_var->camera);
452 free(cam_var->feature_set);
453 free(cam_var->misc_info);
454 /* free(image_pipes); */
455 /* free(format7_info); */
456 /* free(uiinfos); */
457 /* free(selfids); */
459 raw1394_destroy_handle(cam_var->handle);
460 return 0;
465 void
466 GetFormat7Capabilities(raw1394handle_t handle,
467 nodeid_t node,
468 Format7Info *info
470 /*-----------------------------------------------------------------------------
473 int i, f, err;
474 quadlet_t value;
476 err = dc1394_query_supported_modes(handle, node,
477 FORMAT_SCALABLE_IMAGE_SIZE, &value);
478 if (!err) {
479 g_error("Could not query Format7 supported modes");
480 } else {
481 for (i = 0, f = MODE_FORMAT7_MIN; f < MODE_FORMAT7_MAX; f++, i++) {
482 info->mode[i].present = (value & (0x1<<(31-i)) );
484 * Check for mode presence before query
487 if (info->mode[i].present) {
488 err=1;
489 err *= dc1394_query_format7_max_image_size
490 (handle,node,f,
491 &info->mode[i].max_size_x,
492 &info->mode[i].max_size_y);
493 err *= dc1394_query_format7_unit_size
494 (handle,node,f,&info->mode[i].step_x,
495 &info->mode[i].step_y);
496 err *= dc1394_query_format7_image_position
497 (handle,node,f,&info->mode[i].pos_x,
498 &info->mode[i].pos_y);
499 err *= dc1394_query_format7_image_size
500 (handle,node,f,&info->mode[i].size_x,
501 &info->mode[i].size_y);
503 err *= dc1394_query_format7_pixel_number
504 (handle,node,f,&info->mode[i].pixnum);
505 err *= dc1394_query_format7_byte_per_packet
506 (handle,node,f,&info->mode[i].bpp);
507 err *= dc1394_query_format7_packet_para
508 (handle,node,f,&info->mode[i].min_bpp,
509 &info->mode[i].max_bpp);
510 err *= dc1394_query_format7_total_bytes
511 (handle, node, f,
512 &info->mode[i].total_bytes);
515 dc1394_query_format7_total_bytes(raw1394handle_t handle, nodeid_t node,
516 unsigned int mode, unsigned long long int *total_bytes);
519 * TODO: get color coding id
521 err *= dc1394_query_format7_color_coding
522 (handle,node,f,
523 &info->mode[i].
524 color_coding);
525 if (!err) g_error("Got a problem querying format7 capabilitie");
530 info->edit_mode = MODE_FORMAT7_MIN;
533 #else /* ENABLE_CAM */
535 int
536 main(int argc,
537 char *argv[]
539 /*-----------------------------------------------------------------------------
542 g_error("%s: this is dead code as ENABLE_CAM is not set",
543 argv[0]);
544 return -1;
547 #endif /* ENABLE_CAM */