1 /* compile with gcc -Wall -o canon-capture -lgphoto2 canon-capture.c
2  * This code released into the public domain 21 July 2008
3  *
4  * This program does the equivalent of:
5  * gphoto2 --shell
6  *   > set-config capture=1
7  *   > capture-image-and-download
8  * compile with gcc -Wall -o canon-capture -lgphoto2 canon-capture.c
9  *
10  * Taken from: http://credentiality2.blogspot.com/2008/07/linux-libgphoto2-image-capture-from.html
11  */
12 
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/time.h>
17 #include <fcntl.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <gphoto2/gphoto2.h>
22 
23 #include "samples.h"
24 
errordumper(GPLogLevel level,const char * domain,const char * str,void * data)25 static void errordumper(GPLogLevel level, const char *domain, const char *str,
26                  void *data) {
27   struct timeval tv;
28 
29   gettimeofday (&tv, NULL);
30   fprintf(stdout, "%d.%d: %s\n", (int)tv.tv_sec, (int)tv.tv_usec, str);
31 }
32 
33 /* This seems to have no effect on where images go
34 void set_capturetarget(Camera *canon, GPContext *canoncontext) {
35 	int retval;
36 	printf("Get root config.\n");
37 	CameraWidget *rootconfig; // okay, not really
38 	CameraWidget *actualrootconfig;
39 
40 	retval = gp_camera_get_config(canon, &rootconfig, canoncontext);
41 	actualrootconfig = rootconfig;
42 	printf("  Retval: %d\n", retval);
43 
44 	printf("Get main config.\n");
45 	CameraWidget *child;
46 	retval = gp_widget_get_child_by_name(rootconfig, "main", &child);
47 	printf("  Retval: %d\n", retval);
48 
49 	printf("Get settings config.\n");
50 	rootconfig = child;
51 	retval = gp_widget_get_child_by_name(rootconfig, "settings", &child);
52 	printf("  Retval: %d\n", retval);
53 
54 	printf("Get capturetarget.\n");
55 	rootconfig = child;
56 	retval = gp_widget_get_child_by_name(rootconfig, "capturetarget", &child);
57 	printf("  Retval: %d\n", retval);
58 
59 
60 	CameraWidget *capture = child;
61 
62 	const char *widgetinfo;
63 	gp_widget_get_name(capture, &widgetinfo);
64 	printf("config name: %s\n", widgetinfo );
65 
66 	const char *widgetlabel;
67 	gp_widget_get_label(capture, &widgetlabel);
68 	printf("config label: %s\n", widgetlabel);
69 
70 	int widgetid;
71 	gp_widget_get_id(capture, &widgetid);
72 	printf("config id: %d\n", widgetid);
73 
74 	CameraWidgetType widgettype;
75 	gp_widget_get_type(capture, &widgettype);
76 	printf("config type: %d == %d \n", widgettype, GP_WIDGET_RADIO);
77 
78 
79 	printf("Set value.\n");
80 
81 	// capture to ram should be 0, although I think the filename also plays into
82 	// it
83 	int one=1;
84 	retval = gp_widget_set_value(capture, &one);
85 	printf("  Retval: %d\n", retval);
86 
87 	printf("Enabling capture to CF.\n");
88 	retval = gp_camera_set_config(canon, actualrootconfig, canoncontext);
89 	printf("  Retval: %d\n", retval);
90 }
91 */
92 
93 static void
capture_to_file(Camera * canon,GPContext * canoncontext,char * fn)94 capture_to_file(Camera *canon, GPContext *canoncontext, char *fn) {
95 	int fd, retval;
96 	CameraFile *canonfile;
97 	CameraFilePath camera_file_path;
98 
99 	printf("Capturing.\n");
100 
101 	/* NOP: This gets overridden in the library to /capt0000.jpg */
102 	strcpy(camera_file_path.folder, "/");
103 	strcpy(camera_file_path.name, "foo.jpg");
104 
105 	retval = gp_camera_capture(canon, GP_CAPTURE_IMAGE, &camera_file_path, canoncontext);
106 	printf("  Retval: %d\n", retval);
107 
108 	printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);
109 
110 	fd = open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644);
111 	retval = gp_file_new_from_fd(&canonfile, fd);
112 	printf("  Retval: %d\n", retval);
113 	retval = gp_camera_file_get(canon, camera_file_path.folder, camera_file_path.name,
114 		     GP_FILE_TYPE_NORMAL, canonfile, canoncontext);
115 	printf("  Retval: %d\n", retval);
116 
117 	printf("Deleting.\n");
118 	retval = gp_camera_file_delete(canon, camera_file_path.folder, camera_file_path.name,
119 			canoncontext);
120 	printf("  Retval: %d\n", retval);
121 
122 	gp_file_free(canonfile);
123 }
124 
125 int
main(int argc,char ** argv)126 main(int argc, char **argv) {
127 	Camera	*canon;
128 	int	retval;
129 	GPContext *canoncontext = sample_create_context();
130 
131 	gp_log_add_func(GP_LOG_DEBUG, errordumper, NULL);
132 	gp_camera_new(&canon);
133 
134 	/* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the
135 	 * init function seems to traverse the entire filesystem on the camera.  This
136 	 * is partly why it takes so long.
137 	 * (Marcus: the ptp2 driver does this by default currently.)
138 	 */
139 	printf("Camera init.  Takes about 10 seconds.\n");
140 	retval = gp_camera_init(canon, canoncontext);
141 	if (retval != GP_OK) {
142 		printf("  Retval: %d\n", retval);
143 		exit (1);
144 	}
145 	canon_enable_capture(canon, TRUE, canoncontext);
146 	/*set_capturetarget(canon, canoncontext);*/
147 	capture_to_file(canon, canoncontext, "foo.jpg");
148 	capture_to_file(canon, canoncontext, "foo1.jpg");
149 	capture_to_file(canon, canoncontext, "foo2.jpg");
150 	capture_to_file(canon, canoncontext, "foo3.jpg");
151 	capture_to_file(canon, canoncontext, "foo4.jpg");
152 	capture_to_file(canon, canoncontext, "foo5.jpg");
153 	capture_to_file(canon, canoncontext, "foo6.jpg");
154 	gp_camera_exit(canon, canoncontext);
155 	return 0;
156 }
157