1 /****************************************************************/
2 /* jamcam.c - Gphoto2 library for the KBGear JamCam v2 and v3 */
4 /* Copyright © 2001 Chris Pinkham */
6 /* Author: Chris Pinkham <cpinkham@infi.net> */
8 /* This library is free software; you can redistribute it */
9 /* and/or modify it under the terms of the GNU Library General */
10 /* Public License as published by the Free Software Foundation; */
11 /* either version 2 of the License, or (at your option) any */
14 /* This library is distributed in the hope that it will be */
15 /* useful, but WITHOUT ANY WARRANTY; without even the implied */
16 /* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Library General Public License for */
20 /* You should have received a copy of the GNU Library General */
21 /* Public License along with this library; if not, write to the */
22 /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
23 /* Boston, MA 02111-1307, USA. */
24 /****************************************************************/
32 #include <gphoto2/gphoto2.h>
39 # define _(String) dgettext (GETTEXT_PACKAGE, String)
41 # define N_(String) gettext_noop (String)
43 # define N_(String) (String)
46 # define _(String) (String)
47 # define N_(String) (String)
52 #define GP_MODULE "jamcam"
55 #define JAMCAM_VERSION "0.6"
56 #define JAMCAM_LAST_MOD "11/28/2001 14:51 EST"
58 /* define what cameras we support */
64 { "KBGear:JamCam", 0x084E, 0x0001 },
69 int camera_id (CameraText *id)
71 /* GP_DEBUG ("* camera_id"); */
73 strcpy (id->text, "jamcam");
78 int camera_abilities (CameraAbilitiesList *list)
84 /* GP_DEBUG ("* camera_abilities"); */
86 ptr = models[x].model;
88 memset(&a, 0, sizeof(a));
89 strcpy (a.model, ptr );
90 a.status = GP_DRIVER_STATUS_PRODUCTION;
91 a.port = GP_PORT_SERIAL | GP_PORT_USB;
95 /* fixme, need to set these operations lists to correct values */
96 a.operations = GP_OPERATION_NONE;
97 a.file_operations = GP_FILE_OPERATION_PREVIEW;
99 a.folder_operations = GP_FOLDER_OPERATION_NONE;
101 a.usb_vendor = models[x].usb_vendor;
102 a.usb_product = models[x].usb_product;
104 gp_abilities_list_append (list, a);
106 ptr = models[++x].model;
112 static int file_list_func (CameraFilesystem *fs, const char *folder,
113 CameraList *list, void *data, GPContext *context)
115 Camera *camera = data;
118 GP_DEBUG ("* file_list_func");
119 GP_DEBUG ("*** folder: %s", folder);
121 CHECK (count = jamcam_file_count (camera));
122 CHECK (gp_list_populate (list, "pic_%04i.ppm", count));
127 static int get_info_func (CameraFilesystem *fs, const char *folder,
128 const char *filename, CameraFileInfo *info, void *data,
131 Camera *camera = data;
133 struct jamcam_file *jc_file;
135 GP_DEBUG ("* get_info_func");
136 GP_DEBUG ("*** folder: %s", folder);
137 GP_DEBUG ("*** filename: %s",filename);
139 /* Get the file number from the CameraFileSystem */
140 CHECK (n = gp_filesystem_number (camera->fs, folder,
143 jc_file = jamcam_file_info( camera, n );
145 /* fixme, get file size also */
146 info->file.fields = GP_FILE_INFO_TYPE;
147 strcpy (info->file.type, GP_MIME_PPM);
148 info->file.width = jc_file->width;
149 info->file.height = jc_file->height;
151 info->preview.fields = GP_FILE_INFO_TYPE;
152 strcpy (info->preview.type, GP_MIME_PPM);
153 info->preview.width = 80;
154 info->preview.height = 60;
159 static int camera_exit (Camera *camera, GPContext *context)
161 GP_DEBUG ("* camera_exit");
163 jamcam_file_count (camera);
167 #define CHECK_free(result) { \
171 free(raw); free(ppm); \
176 static int get_file_func (CameraFilesystem *fs, const char *folder,
177 const char *filename, CameraFileType type,
178 CameraFile *file, void *user_data, GPContext *context)
180 Camera *camera = user_data;
182 char tmp_filename[128];
183 unsigned char gtable[256];
187 struct jamcam_file *jc_file;
189 GP_DEBUG ("* camera_file_get");
190 GP_DEBUG ("*** folder: %s", folder);
191 GP_DEBUG ("*** filename: %s",filename);
192 GP_DEBUG ("*** type: %d", type);
194 CHECK (n = gp_filesystem_number (camera->fs, folder,
197 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
198 return (GP_ERROR_CANCEL);
200 raw = malloc(640*480 * 3);
201 ppm = malloc(640*480 * 3 + 200);
204 case GP_FILE_TYPE_PREVIEW:
206 CHECK_free (jamcam_request_thumbnail (camera, file, raw, &size, n, context));
214 "# CREATOR: gphoto2, jamcam library\n"
216 "255\n", width, height );
218 ptr = ppm + strlen( ppm );
220 size = strlen( ppm ) + ( height * width * 3 );
222 gp_bayer_decode(raw, width, height, ptr, BAYER_TILE_GBRG );
223 gp_gamma_fill_table( gtable, 0.5 );
224 gp_gamma_correct_single( gtable, ptr, height * width );
226 CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
227 CHECK_free (gp_file_set_name (file, filename));
228 CHECK_free (gp_file_append (file, ppm, size));
231 case GP_FILE_TYPE_NORMAL:
232 CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));
234 jc_file = jamcam_file_info (camera, n);
238 "# CREATOR: gphoto2, jamcam library\n"
240 "255\n", jc_file->width, jc_file->height );
242 ptr = ppm + strlen( ppm );
244 size = strlen( ppm ) + ( jc_file->width * jc_file->height * 3 );
246 gp_bayer_decode( raw, jc_file->width, jc_file->height, ptr,
248 gp_gamma_fill_table( gtable, 0.5 );
249 gp_gamma_correct_single( gtable, ptr, jc_file->width * jc_file->height );
251 CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
252 CHECK_free (gp_file_set_name (file, filename));
253 CHECK_free (gp_file_append (file, ppm, size));
256 case GP_FILE_TYPE_RAW:
257 CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));
258 CHECK_free (gp_file_set_mime_type (file, GP_MIME_RAW));
259 strcpy( tmp_filename, filename );
260 tmp_filename[strlen(tmp_filename)-3] = 'r';
261 tmp_filename[strlen(tmp_filename)-2] = 'a';
262 tmp_filename[strlen(tmp_filename)-1] = 'w';
263 CHECK_free (gp_file_set_name (file, tmp_filename));
264 CHECK_free (gp_file_append (file, raw, size));
267 free(raw); free(ppm);
268 return (GP_ERROR_NOT_SUPPORTED);
270 free(raw); free(ppm);
274 static int camera_summary (Camera *camera, CameraText *summary, GPContext *context)
279 GP_DEBUG ("* camera_summary");
281 /* possibly get # pics, mem free, etc. */
282 count = jamcam_file_count (camera);
284 sprintf (tmp, _("Frames Taken : %4d\n"), count);
285 strcat (summary->text, tmp );
290 static int camera_about (Camera *camera, CameraText *about, GPContext *context)
292 GP_DEBUG ("* camera_about");
295 _("jamcam library v" JAMCAM_VERSION
296 " " JAMCAM_LAST_MOD "\n"
297 "Chris Pinkham <cpinkham@infi.net>\n"
298 "Support for KBGear JamCam v2.0 & v3.0 digital cameras\n"
299 "based on reverse engineering serial protocol.\n"
305 static CameraFilesystemFuncs fsfuncs = {
306 .file_list_func = file_list_func,
307 .get_file_func = get_file_func,
308 .get_info_func = get_info_func,
311 int camera_init (Camera *camera, GPContext *context)
314 GPPortSettings settings;
316 GP_DEBUG ("* camera_init");
317 GP_DEBUG (" * jamcam library for Gphoto2 by Chris Pinkham <cpinkham@infi.net>");
318 GP_DEBUG (" * jamcam library v%s, %s", JAMCAM_VERSION, JAMCAM_LAST_MOD );
320 /* First, set up all the function pointers */
321 camera->functions->exit = camera_exit;
322 camera->functions->summary = camera_summary;
323 camera->functions->about = camera_about;
325 CHECK (gp_port_get_settings (camera->port, &settings));
326 switch( camera->port->type ) {
328 settings.serial.speed = 57600;
329 settings.serial.bits = 8;
330 settings.serial.parity = 0;
331 settings.serial.stopbits = 1;
334 /* Use the defaults the core parsed */
337 fprintf( stderr, "Unknown port type: %d\n", camera->port->type );
341 CHECK (gp_port_set_settings (camera->port, settings));
342 CHECK (gp_port_set_timeout (camera->port, TIMEOUT));
344 /* check to see if camera is really there */
345 CHECK (jamcam_enq (camera));
347 /* get number of images */
348 CHECK (count = jamcam_file_count (camera));
350 /* Set up the CameraFilesystem */
351 return gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);