Remove generated files
[framework/connectivity/libgphoto2.git] / camlibs / jl2005a / library.c
1 /* library.c
2  *
3  * Copyright (C) 2006 Theodore Kilgore <kilgota@auburn.edu>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, 
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details. 
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include <bayer.h>
28 #include <gamma.h>
29
30 #include <gphoto2/gphoto2.h>
31
32
33
34 #ifdef ENABLE_NLS
35 #  include <libintl.h>
36 #  undef _
37 #  define _(String) dgettext (PACKAGE, String)
38 #  ifdef gettext_noop
39 #    define N_(String) gettext_noop (String)
40 #  else
41 #    define N_(String) (String)
42 #  endif
43 #else
44 #  define _(String) (String)
45 #  define N_(String) (String)
46 #endif
47
48 #include "jl2005a.h"
49 #include <gphoto2/gphoto2-port.h>
50
51 #define GP_MODULE "jl2005a"
52
53 struct {
54         char *name;
55         CameraDriverStatus status;
56         unsigned short idVendor;
57         unsigned short idProduct;
58 } models[] = {
59         {"American Idol Keychain Camera", GP_DRIVER_STATUS_TESTING, 
60                                                             0x0979, 0x0224},
61         {"NogaNet TDC-15", GP_DRIVER_STATUS_TESTING, 0x0979, 0x0224},
62         {"Cobra DC125", GP_DRIVER_STATUS_EXPERIMENTAL, 0x0979, 0x0224},
63         {NULL,0,0,0}
64 };
65
66 int
67 camera_id (CameraText *id)
68 {
69         strcpy (id->text, "JL2005A camera");
70         return GP_OK;
71 }
72
73 int
74 camera_abilities (CameraAbilitiesList *list)
75 {
76         int i;    
77         CameraAbilities a;
78
79         for (i = 0; models[i].name; i++) {
80                 memset (&a, 0, sizeof(a));
81                 strcpy (a.model, models[i].name);
82                 a.status = models[i].status;
83                 a.port   = GP_PORT_USB;
84                 a.speed[0] = 0;
85                 a.usb_vendor = models[i].idVendor;
86                 a.usb_product= models[i].idProduct;
87                 if (a.status == GP_DRIVER_STATUS_EXPERIMENTAL)
88                         a.operations = GP_OPERATION_NONE;
89                 else
90                         a.operations = GP_OPERATION_CAPTURE_IMAGE;
91                 a.folder_operations = GP_FOLDER_OPERATION_NONE;
92                 a.file_operations   = GP_FILE_OPERATION_PREVIEW 
93                                         + GP_FILE_OPERATION_RAW; 
94                 gp_abilities_list_append (list, a);
95         }
96         return GP_OK;
97 }
98
99 static int
100 camera_summary (Camera *camera, CameraText *summary, GPContext *context)
101 {
102         int num_pics;
103         num_pics = camera->pl->nb_entries;
104         GP_DEBUG("camera->pl->nb_entries = %i\n",camera->pl->nb_entries);
105         sprintf (summary->text,_("This camera contains a Jeilin JL2005A chipset.\n" 
106                         "The number of photos in it is %i. \n"), num_pics);  
107         return GP_OK;
108 }
109
110
111 static int camera_manual (Camera *camera, CameraText *manual, GPContext *context) 
112 {
113         strcpy(manual->text, 
114         _(
115         "This driver supports cameras with Jeilin jl2005a chip \n"
116         "These cameras do not support deletion of photos, nor uploading\n"
117         "of data. \n"
118         "Decoding of compressed photos may or may not work well\n" 
119         "and does not work equally well for all supported cameras.\n"
120         "If present on the camera, video clip frames are downloaded \n"
121         "as consecutive still photos.\n"
122         "For further details please consult libgphoto2/camlibs/README.jl2005a\n"
123         )); 
124
125         return (GP_OK);
126 }
127
128
129 static int
130 camera_about (Camera *camera, CameraText *about, GPContext *context)
131 {
132         strcpy (about->text, _("jl2005a camera library\n"
133                             "Theodore Kilgore <kilgota@auburn.edu>\n"));
134         return GP_OK;
135 }
136
137 /*************** File and Downloading Functions *******************/
138
139 static int
140 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
141                 void *data, GPContext *context)
142 {
143         Camera *camera = data; 
144         int n;
145         n = camera->pl->nb_entries;
146         gp_list_populate (list, "jl_%03i.ppm", n);
147         return GP_OK;
148 }
149
150 static int
151 get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
152                CameraFileInfo *info, void *data, GPContext *context)
153 {
154         info->file.fields = GP_FILE_INFO_TYPE;
155         strcpy (info->file.type, GP_MIME_PPM);
156
157         return (GP_OK);
158 }
159
160 static int
161 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
162                CameraFileType type, CameraFile *file, void *user_data,
163                GPContext *context)
164 {
165         Camera *camera = user_data; 
166         int status = GP_OK;
167         int w, h = 0, k;
168         int i,j;
169         int b = 0;
170         int compressed = 0;
171         unsigned char header[5] = "\xff\xff\xff\xff\x55";
172         unsigned int size;
173         unsigned char *data;
174         unsigned char *image_start;
175         unsigned char *p_data=NULL;
176         unsigned char *ppm=NULL, *ptr=NULL;
177         unsigned char gtable[256];
178         unsigned char temp;
179
180         GP_DEBUG ("Downloading pictures!\n");
181
182         /* These are cheap cameras. There ain't no EXIF data. So kill this. */
183         if (GP_FILE_TYPE_EXIF == type) return GP_ERROR_FILE_EXISTS;
184         /* Get the number of the photo on the camera */
185         k = gp_filesystem_number (camera->fs, "/", filename, context); 
186         GP_DEBUG ("Filesystem number is %i\n",k);
187         b = jl2005a_get_pic_data_size(camera->port, k);
188         GP_DEBUG("b = %i = 0x%x bytes\n", b,b);
189         w = jl2005a_get_pic_width(camera->port);
190         GP_DEBUG ("width is %i\n", w); 
191         h = jl2005a_get_pic_height(camera->port);
192         GP_DEBUG ("height is %i\n", h); 
193         /* Image data to be downloaded contains header and footer bytes */
194         data = malloc (b+14);
195         if (!data) return GP_ERROR_NO_MEMORY;
196
197         jl2005a_read_picture_data (camera, camera->port, data, b+14);
198         if (memcmp(header,data,5) != 0)
199                 /* Image data is corrupted! Repeat the operation. */    
200                 jl2005a_read_picture_data (camera, camera->port, data, b+14);
201
202         if (GP_FILE_TYPE_RAW == type) {
203                 gp_file_set_mime_type(file, GP_MIME_RAW);
204                 gp_file_set_name(file, filename);
205                 gp_file_set_data_and_size(file, (char *)data , b+14 );
206                 return GP_OK;
207         }
208
209         /* Now get ready to put the data into a PPM image file. */
210         p_data = malloc( w*h );
211         if (!p_data) {
212                 status =  GP_ERROR_NO_MEMORY;
213                 goto end;
214         } 
215         image_start=data+5;
216         if (w == 176) {
217                 for (i=1; i < h; i +=4){
218                         for (j=1; j< w; j ++){
219                                 temp=image_start[i*w+j];
220                                 image_start[i*w+j] = image_start[(i+1)*w+j];
221                                 image_start[(i+1)*w+j] = temp;
222                         }
223                 }
224                 if (h == 72) {
225                         compressed = 1;
226                         h = 144;
227                 }
228         } else 
229                 if (h == 144) {
230                         compressed = 1;
231                         h = 288;
232                 }
233         p_data = malloc( w*h );
234         if (!p_data) {
235                 status =  GP_ERROR_NO_MEMORY;
236                 goto end;
237         } 
238         if (compressed)
239                 jl2005a_decompress (image_start, p_data, w, h);
240         else 
241                 memcpy(p_data, image_start, w*h);
242         ppm = malloc (w * h * 3 + 256); /* room for data and header */
243         if (!ppm) { 
244                 status = GP_ERROR_NO_MEMORY; 
245                 goto end;
246         }
247         sprintf ((char *)ppm,
248                         "P6\n"
249                         "# CREATOR: gphoto2, JL2005A library\n"
250                         "%d %d\n"
251                         "255\n", w, h);
252         size = strlen ((char *)ppm);
253         ptr = ppm + size;
254         size = size + (w * h * 3);
255         GP_DEBUG ("size = %i\n", size);                         
256         gp_ahd_decode (p_data, w , h, ptr, BAYER_TILE_BGGR);
257
258         free(p_data);
259         gp_gamma_fill_table (gtable, .65); 
260         gp_gamma_correct_single (gtable, ptr, w * h); 
261         gp_file_set_mime_type (file, GP_MIME_PPM);
262         gp_file_set_name (file, filename); 
263         gp_file_set_data_and_size (file, (char *)ppm, size);
264         end:
265         free(data);
266         return status;  
267         
268
269         return GP_OK;
270 }
271
272
273
274
275
276
277 /*************** Exit and Initialization Functions ******************/
278
279 static int
280 camera_exit (Camera *camera, GPContext *context)
281 {
282         GP_DEBUG ("jl2005a camera_exit");
283         jl2005a_reset(camera, camera->port);
284         gp_port_close(camera->port);
285         if (camera->pl) {
286                 free (camera->pl);
287                 camera->pl = NULL;
288         }
289         return GP_OK;
290 }
291
292 static CameraFilesystemFuncs fsfuncs = {
293         .file_list_func = file_list_func,
294         .get_file_func = get_file_func,
295         .get_info_func = get_info_func
296 };
297
298 int
299 camera_init(Camera *camera, GPContext *context)
300 {
301         GPPortSettings settings;
302         int ret = 0;
303
304         /* First, set up all the function pointers */
305         camera->functions->manual       = camera_manual;
306         camera->functions->summary      = camera_summary;
307         camera->functions->about        = camera_about;
308         camera->functions->exit     = camera_exit;
309    
310         GP_DEBUG ("Initializing the camera\n");
311         ret = gp_port_get_settings(camera->port,&settings);
312         if (ret < 0) return ret; 
313
314         switch (camera->port->type) {
315                 case GP_PORT_SERIAL:
316                         return ( GP_ERROR );
317                 case GP_PORT_USB:
318                         settings.usb.config = 1;
319                         settings.usb.altsetting = 0;
320                         settings.usb.interface = 0;
321                         /* inep 0x84 used for commands, 0x81 for data. */
322                         settings.usb.inep = 0x84;
323                         settings.usb.outep = 0x03;
324                         break;
325                 default:
326                         return ( GP_ERROR );
327         }
328
329         ret = gp_port_set_settings(camera->port,settings);
330         if (ret < 0) return ret; 
331
332         GP_DEBUG("interface = %i\n", settings.usb.interface);
333         GP_DEBUG("inep = %x\n", settings.usb.inep);     
334         GP_DEBUG("outep = %x\n", settings.usb.outep);
335
336         /* Tell the CameraFilesystem where to get lists from */
337         gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
338
339         camera->pl = malloc (sizeof (CameraPrivateLibrary));
340         if (!camera->pl) return GP_ERROR_NO_MEMORY;
341         memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
342         /* Connect to the camera */
343         camera->pl->data_reg_accessed = 0;
344         camera->pl->data_to_read = 0;
345         camera->pl->data_used_from_block = 0;
346         camera->pl->data_cache = NULL;
347         jl2005a_init (camera,camera->port, camera->pl);
348
349         return GP_OK;
350 }