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
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
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 **************************************************************************/
53 #include <libraw1394/raw1394.h>
54 #include <libdc1394/dc1394_control.h>
55 #endif /* ENABLE_CAM */
61 #include "rec_image.h"
62 #endif /* ENABLE_CAM */
63 #include <unistd.h> /* unsigned int sleep(unsigned int seconds); */
69 #define EXIT_FAILURE 1
80 /* Option flags and variables */
83 Usage: gpiv_rec_image [-h | --help] -v | --version] -V | --verbose] [-x | --x_corr] \n\
84 [filename] > stdout \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\
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
;
108 command_args (int argc
,
110 char fname
[GPIV_MAX_CHARS
],
111 GpivImagePar
*image_par
113 /* ----------------------------------------------------------------------------
114 * Command line argument handling
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
129 while (argc_next
== 0 && (c
= *++argv
[0]))
134 printf ("git hash: %s\n", GIT_REV
);
136 printf ("version: %s\n", GPIVTOOLS_VERSION
);
143 printf("%s\n",USAGE
);
152 image_par
->x_corr
= TRUE
;
153 image_par
->x_corr__set
= TRUE
;
159 if (strcmp("-help", *argv
) == 0) {
160 printf("\n%s", HELP
);
161 printf("\n%s", USAGE
);
163 } else if (strcmp("-verbose", *argv
) == 0) {
165 } else if (strcmp("-version", *argv
) == 0) {
167 printf ("git hash: %s\n", GIT_REV
);
169 printf ("version: %s\n", GPIVTOOLS_VERSION
);
172 } else if (strcmp("-x_corr", *argv
) == 0) {
173 image_par
->x_corr
= TRUE
;
174 image_par
->x_corr__set
= TRUE
;
177 gpiv_error ("%s: unknown option: %s", GIT_REV
, *argv
);
179 gpiv_error ("%s: unknown option: %s", GPIVTOOLS_VERSION
, *argv
);
187 gpiv_error ("%s: unknown option: %s", GIT_REV
, *argv
);
189 gpiv_error ("%s: unknown option: %s", GPIVTOOLS_VERSION
, *argv
);
196 * Check if filename or stdin /stdout is used
199 use_stdin_stdout
= FALSE
;
200 strcpy(fname
, argv
[argc
- 1]);
201 } else if (argc
== 0) {
202 use_stdin_stdout
= TRUE
;
206 gpiv_error("\n%s: unknown argument: %s: %s", GIT_REV
, *argv
, USAGE
);
208 gpiv_error("\n%s: unknown argument: %s: %s", GPIVTOOLS_VERSION
, *argv
, USAGE
);
221 /*-----------------------------------------------------------------------------
225 dc1394_cameracapture capture
;
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
;
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",
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
,
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",
279 if (verbose
) g_message("dc1394_setup_capture: succes");
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 */
291 * BUGFIX: disabled temporarly
293 if( dc1394_set_trigger_mode(cam_var
->handle
,
294 /* capture.node */ cam_var
->camera
[0].id
,
297 if (verbose
) g_message("unable to set camera trigger mode\n");
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
310 && dc1394_query_basic_functionality (cam_var
->handle
,
314 g_warning("dc1394_query_basic_functionality: failed\n");
316 if ((value
>>(8*sizeof(quadlet_t
)-19-1)) != 0) {
317 if (verbose
) g_message("single shot supperted");
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
)
329 dc1394_release_camera(cam_var
->handle
, &capture
);
330 raw1394_destroy_handle(cam_var
->handle
);
331 g_error("unable to start camera iso transmission");
333 if (verbose
) g_message("dc1394_start_iso_transmission: succes");
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");
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");
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
)
369 g_warning("couldn't stop the camera?\n");
371 if (verbose
) g_message("dc1394_stop_iso_transmissio: succes");
375 * save image as 'Image.pgm'
377 if (use_stdin_stdout
) {
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",
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
);
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
);
440 gpiv_write_png_image (imagefile
, &img1
, &img2
, &gpiv_image_par
, TRUE
))
442 gpiv_error ("%s: %s\n", argv
[0], err_msg
);
444 if (use_stdin_stdout
== FALSE
) fclose (imagefile
);
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); */
459 raw1394_destroy_handle(cam_var
->handle
);
466 GetFormat7Capabilities(raw1394handle_t handle
,
470 /*-----------------------------------------------------------------------------
476 err
= dc1394_query_supported_modes(handle
, node
,
477 FORMAT_SCALABLE_IMAGE_SIZE
, &value
);
479 g_error("Could not query Format7 supported modes");
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
) {
489 err
*= dc1394_query_format7_max_image_size
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
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
525 if (!err
) g_error("Got a problem querying format7 capabilitie");
530 info
->edit_mode
= MODE_FORMAT7_MIN
;
533 #else /* ENABLE_CAM */
539 /*-----------------------------------------------------------------------------
542 g_error("%s: this is dead code as ENABLE_CAM is not set",
547 #endif /* ENABLE_CAM */