1 /*
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  * and condensed into simple capture sample
13  */
14 
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <gphoto2/gphoto2.h>
23 
24 #include "samples.h"
25 
errordumper(GPLogLevel level,const char * domain,const char * str,void * data)26 static void errordumper(GPLogLevel level, const char *domain, const char *str,
27                  void *data) {
28   fprintf(stdout, "%s\n", str);
29 }
30 
31 static void
capture_to_memory(Camera * camera,GPContext * context,const char ** ptr,unsigned long int * size)32 capture_to_memory(Camera *camera, GPContext *context, const char **ptr, unsigned long int *size) {
33 	int retval;
34 	CameraFile *file;
35 	CameraFilePath camera_file_path;
36 
37 	printf("Capturing.\n");
38 
39 	/* NOP: This gets overridden in the library to /capt0000.jpg */
40 	strcpy(camera_file_path.folder, "/");
41 	strcpy(camera_file_path.name, "foo.jpg");
42 
43 	retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);
44 	printf("  Retval: %d\n", retval);
45 
46 	printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);
47 
48 	retval = gp_file_new(&file);
49 	printf("  Retval: %d\n", retval);
50 	retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name,
51 		     GP_FILE_TYPE_NORMAL, file, context);
52 	printf("  Retval: %d\n", retval);
53 
54 	gp_file_get_data_and_size (file, ptr, size);
55 
56 	printf("Deleting.\n");
57 	retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name,
58 			context);
59 	printf("  Retval: %d\n", retval);
60 	/*gp_file_free(file); */
61 }
62 
63 static void
capture_to_file(Camera * camera,GPContext * context,char * fn)64 capture_to_file(Camera *camera, GPContext *context, char *fn) {
65 	int fd, retval;
66 	CameraFile *file;
67 	CameraFilePath camera_file_path;
68 
69 	printf("Capturing.\n");
70 
71 	/* NOP: This gets overridden in the library to /capt0000.jpg */
72 	strcpy(camera_file_path.folder, "/");
73 	strcpy(camera_file_path.name, "foo.jpg");
74 
75 	retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);
76 	printf("  Retval: %d\n", retval);
77 
78 	printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);
79 
80 	fd = open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644);
81 	retval = gp_file_new_from_fd(&file, fd);
82 	printf("  Retval: %d\n", retval);
83 	retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name,
84 		     GP_FILE_TYPE_NORMAL, file, context);
85 	printf("  Retval: %d\n", retval);
86 
87 	gp_file_free(file);
88 
89 	printf("Deleting.\n");
90 	retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name,
91 			context);
92 	printf("  Retval: %d\n", retval);
93 }
94 
95 int
main(int argc,char ** argv)96 main(int argc, char **argv) {
97 	Camera	*camera;
98 	int	retval;
99 	GPContext *context = sample_create_context();
100 	FILE 	*f;
101 	char	*data;
102 	unsigned long size;
103 
104 	gp_log_add_func(GP_LOG_ERROR, errordumper, NULL);
105 	gp_camera_new(&camera);
106 
107 	/* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the
108 	 * init function seems to traverse the entire filesystem on the camera.  This
109 	 * is partly why it takes so long.
110 	 * (Marcus: the ptp2 driver does this by default currently.)
111 	 */
112 	printf("Camera init.  Takes about 10 seconds.\n");
113 	retval = gp_camera_init(camera, context);
114 	if (retval != GP_OK) {
115 		printf("  Retval of capture_to_file: %d\n", retval);
116 		exit (1);
117 	}
118 	capture_to_file(camera, context, "foo.jpg");
119 
120 	capture_to_memory(camera, context, (const char**)&data, &size);
121 
122 	f = fopen("foo2.jpg", "wb");
123 	if (f) {
124 		retval = fwrite (data, size, 1, f);
125 		if (retval != (int)size) {
126 			printf("  fwrite size %ld, written %d\n", size, retval);
127 		}
128 		fclose(f);
129 	} else
130 		printf("  fopen foo2.jpg failed.\n");
131 	gp_camera_exit(camera, context);
132 	return 0;
133 }
134