3 * Copyright (C) 2006 Theodore Kilgore <kilgota@auburn.edu>
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.
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.
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.
29 #include <gphoto2/gphoto2.h>
30 #include <gphoto2/gphoto2-port.h>
31 #include "gphoto2-endian.h"
35 #define GP_MODULE "jl2005a"
38 jl2005a_init (Camera *camera, GPPort *port, CameraPrivateLibrary *priv)
40 GP_DEBUG("Running jl2005a_init\n");
42 jl2005a_shortquery(port, 0x0d); /* Supposed to get 0x08 */
43 jl2005a_shortquery(port, 0x1c); /* Supposed to get 0x01 */
44 jl2005a_shortquery(port, 0x20); /* Supposed to get 0x04 */
45 gp_port_write (port, "\xab\x00", 2);
46 gp_port_write (port, "\xa1\x02", 2);
47 gp_port_write (port, "\xab\x00", 2);
48 gp_port_write (port, "\xa2\x02", 2);
49 jl2005a_shortquery(port, 0x1d); /* 1 if camera is full, else 0 */
50 gp_port_write (port, "\xab\x00", 2);
51 gp_port_write (port, "\xa1\x00", 2);
52 priv->nb_entries = jl2005a_shortquery(port, 0x0a)&0xff;
53 /* Number of pix returned here */
54 GP_DEBUG("%d entries in the camera\n", priv->nb_entries);
55 return jl2005a_shortquery(port, 0x1d); /* Should get 0, same as GP_OK */
59 jl2005a_get_pic_data_size (GPPort *port, int n)
61 unsigned int size = 0;
65 command[1] = (char)(n&0xff);
66 GP_DEBUG("Getting photo data size\n");
67 gp_port_write (port, "\xab\x00", 2);
68 gp_port_write (port, command, 2);
69 gp_port_write (port, "\xab\x00", 2);
70 gp_port_write (port, "\xa2\x0b", 2);
71 jl2005a_shortquery(port, 0x1d);
73 GP_DEBUG("size = 0x%x\n", size);
74 response = (jl2005a_read_info_byte(port, 1) )&0xff;
75 size = ((response&0xff) << 8)| size;
76 GP_DEBUG("size = 0x%x\n", size);
77 response = (jl2005a_read_info_byte(port, 2 ))&0xff;
78 size = ((response&0xff)<<16)|size;
81 GP_DEBUG("size = 0x%x\n", size);
86 jl2005a_get_pic_width (GPPort *port)
90 response = (jl2005a_read_info_byte(port, 3))&0xff;
91 width = (response&0xff);
92 response = (jl2005a_read_info_byte(port, 4) )&0xff;
93 width = ((response&0xff) << 8)|width;
98 jl2005a_get_pic_height (GPPort *port)
102 response = (jl2005a_read_info_byte(port, 5) )&0xff;
103 height = (response&0xff);
104 response = (jl2005a_read_info_byte(port, 6) )&0xff;
105 height = ((response&0xff)<< 8)|height;
110 set_usb_in_endpoint (Camera *camera, int inep)
112 GPPortSettings settings;
113 gp_port_get_settings ( camera ->port, &settings);
114 settings.usb.inep = inep;
115 GP_DEBUG("inep reset to %02X\n", inep);
116 return gp_port_set_settings ( camera ->port, settings);
120 jl2005a_read_picture_data (Camera *camera, GPPort *port,
121 unsigned char *data, unsigned int size)
124 unsigned char *to_read;
127 response = (jl2005a_read_info_byte(port, 7) )&0xff;
128 /* Always 0x80. Purpose unknown */
129 response = (jl2005a_read_info_byte(port, 0x0a) )&0xff;
130 /* Previous byte is 0x11 if what is to be downloaded is the first
131 * frame in a clip, is 0x01 if it is any clip frame after the initial
132 * one, and is zero if what is to be downloaded is a standalone photo.
133 * If clips will in the future be processed as AVI files, then there is
134 * not any information to know how many frames are present, prior to
135 * downloading them. There is only a starting point and an indicator
138 gp_port_write (port, "\xab\x00", 2);
139 gp_port_write (port, "\xa1\x04", 2);
140 gp_port_write (port, "\xab\x00", 2);
141 gp_port_write (port, "\xa2\x08", 2);
142 gp_port_write (port, "\xab\x00", 2);
143 gp_port_write (port, "\xa1\x05", 2);
144 gp_port_write (port, "\xab\x00", 2);
145 gp_port_write (port, "\xa2\x08", 2);
147 /* Switch the inep over to 0x81. */
148 set_usb_in_endpoint (camera, 0x81);
149 while (size > maxdl) {
150 gp_port_read(port, (char *)to_read, maxdl);
154 gp_port_read(port, (char *)to_read, size);
155 /* Switch the inep back to 0x84. */
156 set_usb_in_endpoint (camera, 0x84);
161 jl2005a_reset (Camera *camera, GPPort *port)
164 gp_port_write (port,"\xab\x00" , 2);
165 gp_port_write (port, "\xa1\x00", 2);
166 gp_port_write (port, "\xab\x00", 2);
167 gp_port_write (port, "\xa2\x02", 2);
168 for (i=0; i < 4; i++)
169 jl2005a_shortquery(port, 0x1d);
170 /* Supposed to get something like 0x01, 0x01, 0x01, 0x00 */
174 int jl2005a_read_info_byte(GPPort *port, int n)
179 command[1] = (char)(n&0xff);
180 gp_port_write (port, "\xab\x00", 2);
181 gp_port_write (port, command , 2);
182 gp_port_write (port, "\xab\x00", 2);
183 gp_port_write (port, "\xa2\x0c", 2);
184 gp_port_write (port, "\xab\x00", 2);
185 gp_port_write (port, "\xa3\xa1", 2);
186 gp_port_write (port, "\xab\x00", 2);
187 gp_port_write (port, "\xab\x00", 2);
188 gp_port_read (port,&response, 1);
189 return response&0xff;
193 int jl2005a_shortquery(GPPort *port, int n)
198 command[1] = (char)(n&0xff);
199 gp_port_write (port, "\xab\x00", 2);
200 gp_port_write (port, command, 2);
201 gp_port_write (port, "\xab\x00", 2);
202 gp_port_write (port, "\xa3\xa1", 2);
203 gp_port_write (port, "\xab\x00", 2);
204 gp_port_write (port, "\xab\x00", 2);
205 gp_port_read (port, &response, 1);
206 return response&0xff;
209 int jl2005a_decompress (unsigned char *inp, unsigned char *outp, int width,
213 for (i=0; i < height/2; i+=2) {
214 memcpy(outp+2*i*width,inp+i*width, 2*width);
216 memcpy(outp+(height-2)*width,outp+(height-4)*width, 2*width);
217 for (i=0; i < height/4-1; i++) {
218 for (j=0; j < width; j++) {
219 outp[(4*i+2)*width+j]=(inp[(2*i)*width+j]+
220 inp[(2*i+2)*width+j])/2;
221 outp[(4*i+3)*width+j]=(outp[(4*i+1)*width+j]+
222 outp[(4*i+5)*width+j])/2;
226 memmove(outp+6*width, outp, (height-6)*width);