1 /*
2 Copyright (C) 2008, Panasonic Russia Ltd.
3 Copyright (C) 2010-2011, m. allan noah
4 */
5 /* sane - Scanner Access Now Easy.
6 Panasonic KV-S1020C / KV-S1025C USB scanners.
7 */
8
9 #define DEBUG_NOT_STATIC
10
11 #include "../include/sane/config.h"
12
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <limits.h>
16 #include <signal.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <unistd.h>
23
24 #include "../include/sane/sane.h"
25 #include "../include/sane/saneopts.h"
26 #include "../include/sane/sanei.h"
27 #include "../include/sane/sanei_usb.h"
28 #include "../include/sane/sanei_backend.h"
29 #include "../include/sane/sanei_config.h"
30 #include "../include/lassert.h"
31
32 #include "kvs1025.h"
33 #include "kvs1025_low.h"
34
35 #include "../include/sane/sanei_debug.h"
36
37 /* SANE backend operations, see SANE Standard for details
38 https://sane-project.gitlab.io/standard/ */
39
40 /* Init the KV-S1025 SANE backend. This function must be called before any other
41 SANE function can be called. */
42 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)43 sane_init (SANE_Int * version_code,
44 SANE_Auth_Callback __sane_unused__ authorize)
45 {
46 SANE_Status status;
47
48 DBG_INIT ();
49
50 DBG (DBG_sane_init, "sane_init\n");
51
52 DBG (DBG_error,
53 "This is panasonic KV-S1020C / KV-S1025C version %d.%d build %d\n",
54 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, V_BUILD);
55
56 if (version_code)
57 {
58 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, V_BUILD);
59 }
60
61 /* Initialize USB */
62 sanei_usb_init ();
63
64 status = kv_enum_devices ();
65 if (status)
66 return status;
67
68 DBG (DBG_proc, "sane_init: leave\n");
69 return SANE_STATUS_GOOD;
70 }
71
72 /* Terminate the KV-S1025 SANE backend */
73 void
sane_exit(void)74 sane_exit (void)
75 {
76 DBG (DBG_proc, "sane_exit: enter\n");
77
78 kv_exit ();
79
80 DBG (DBG_proc, "sane_exit: exit\n");
81 }
82
83 /* Get device list */
84 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)85 sane_get_devices (const SANE_Device *** device_list,
86 SANE_Bool __sane_unused__ local_only)
87 {
88 DBG (DBG_proc, "sane_get_devices: enter\n");
89 kv_get_devices_list (device_list);
90 DBG (DBG_proc, "sane_get_devices: leave\n");
91 return SANE_STATUS_GOOD;
92 }
93
94 /* Open device, return the device handle */
95 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)96 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
97 {
98 return kv_open_by_name (devicename, handle);
99 }
100
101 /* Close device */
102 void
sane_close(SANE_Handle handle)103 sane_close (SANE_Handle handle)
104 {
105 DBG (DBG_proc, "sane_close: enter\n");
106 kv_close ((PKV_DEV) handle);
107 DBG (DBG_proc, "sane_close: leave\n");
108 }
109
110 /* Get option descriptor */
111 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)112 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
113 {
114 return kv_get_option_descriptor ((PKV_DEV) handle, option);
115 }
116
117 /* Control option */
118 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)119 sane_control_option (SANE_Handle handle, SANE_Int option,
120 SANE_Action action, void *val, SANE_Int * info)
121 {
122 return kv_control_option ((PKV_DEV) handle, option, action, val, info);
123 }
124
125 /* Get scan parameters */
126 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)127 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
128 {
129 PKV_DEV dev = (PKV_DEV) handle;
130
131 int side = dev->current_side == SIDE_FRONT ? 0 : 1;
132
133 DBG (DBG_proc, "sane_get_parameters: enter\n");
134
135 if (!(dev->scanning))
136 {
137 /* Setup the parameters for the scan. (guessed value) */
138 int resolution = dev->val[OPT_RESOLUTION].w;
139 int width, length, depth = kv_get_depth (kv_get_mode (dev));;
140
141 DBG (DBG_proc, "sane_get_parameters: initial settings\n");
142 kv_calc_paper_size (dev, &width, &length);
143
144 DBG (DBG_error, "Resolution = %d\n", resolution);
145 DBG (DBG_error, "Paper width = %d, height = %d\n", width, length);
146
147 /* Prepare the parameters for the caller. */
148 dev->params[0].format = kv_get_mode (dev) == SM_COLOR ?
149 SANE_FRAME_RGB : SANE_FRAME_GRAY;
150
151 dev->params[0].last_frame = SANE_TRUE;
152 dev->params[0].pixels_per_line = ((width * resolution) / 1200) & (~0xf);
153
154 dev->params[0].depth = depth > 8 ? 8 : depth;
155
156 dev->params[0].bytes_per_line =
157 (dev->params[0].pixels_per_line / 8) * depth;
158 dev->params[0].lines = (length * resolution) / 1200;
159
160 memcpy (&dev->params[1], &dev->params[0], sizeof (SANE_Parameters));
161 }
162
163 /* Return the current values. */
164 if (params)
165 *params = (dev->params[side]);
166
167 DBG (DBG_proc, "sane_get_parameters: exit\n");
168 return SANE_STATUS_GOOD;
169 }
170
171 /* Start scanning */
172 SANE_Status
sane_start(SANE_Handle handle)173 sane_start (SANE_Handle handle)
174 {
175 SANE_Status status;
176 PKV_DEV dev = (PKV_DEV) handle;
177 SANE_Bool dev_ready;
178 KV_CMD_RESPONSE rs;
179
180 DBG (DBG_proc, "sane_start: enter\n");
181 if (!dev->scanning)
182 {
183 /* open device */
184 if (!kv_already_open (dev))
185 {
186 DBG (DBG_proc, "sane_start: need to open device\n");
187 status = kv_open (dev);
188 if (status)
189 {
190 return status;
191 }
192 }
193 /* Begin scan */
194 DBG (DBG_proc, "sane_start: begin scan\n");
195
196 /* Get necessary parameters */
197 sane_get_parameters (dev, NULL);
198
199 dev->current_page = 0;
200 dev->current_side = SIDE_FRONT;
201
202 /* The scanner must be ready. */
203 status = CMD_test_unit_ready (dev, &dev_ready);
204 if (status || !dev_ready)
205 {
206 return SANE_STATUS_DEVICE_BUSY;
207 }
208
209 if (!strcmp (dev->val[OPT_MANUALFEED].s, "off"))
210 {
211 status = CMD_get_document_existanse (dev);
212 if (status)
213 {
214 DBG (DBG_proc, "sane_start: exit with no more docs\n");
215 return status;
216 }
217 }
218
219 /* Set window */
220 status = CMD_reset_window (dev);
221 if (status)
222 {
223 return status;
224 }
225
226 status = CMD_set_window (dev, SIDE_FRONT, &rs);
227 if (status)
228 {
229 DBG (DBG_proc, "sane_start: error setting window\n");
230 return status;
231 }
232
233 if (rs.status)
234 {
235 DBG (DBG_proc, "sane_start: error setting window\n");
236 DBG (DBG_proc,
237 "sane_start: sense_key=0x%x, ASC=0x%x, ASCQ=0x%x\n",
238 get_RS_sense_key (rs.sense),
239 get_RS_ASC (rs.sense), get_RS_ASCQ (rs.sense));
240 return SANE_STATUS_DEVICE_BUSY;
241 }
242
243 if (IS_DUPLEX (dev))
244 {
245 status = CMD_set_window (dev, SIDE_BACK, &rs);
246
247 if (status)
248 {
249 DBG (DBG_proc, "sane_start: error setting window\n");
250 return status;
251 }
252 if (rs.status)
253 {
254 DBG (DBG_proc, "sane_start: error setting window\n");
255 DBG (DBG_proc,
256 "sane_start: sense_key=0x%x, "
257 "ASC=0x%x, ASCQ=0x%x\n",
258 get_RS_sense_key (rs.sense),
259 get_RS_ASC (rs.sense), get_RS_ASCQ (rs.sense));
260 return SANE_STATUS_INVAL;
261 }
262 }
263
264 /* Scan */
265 status = CMD_scan (dev);
266 if (status)
267 {
268 return status;
269 }
270
271 status = AllocateImageBuffer (dev);
272 if (status)
273 {
274 return status;
275 }
276 dev->scanning = 1;
277 }
278 else
279 {
280 /* renew page */
281 if (IS_DUPLEX (dev))
282 {
283 if (dev->current_side == SIDE_FRONT)
284 {
285 /* back image data already read, so just return */
286 dev->current_side = SIDE_BACK;
287 DBG (DBG_proc, "sane_start: duplex back\n");
288 status = SANE_STATUS_GOOD;
289 goto cleanup;
290 }
291 else
292 {
293 dev->current_side = SIDE_FRONT;
294 dev->current_page++;
295 }
296 }
297 else
298 {
299 dev->current_page++;
300 }
301 }
302 DBG (DBG_proc, "sane_start: NOW SCANNING page\n");
303
304 /* Read image data */
305 status = ReadImageData (dev, dev->current_page);
306 if (status)
307 {
308 dev->scanning = 0;
309 return status;
310 }
311
312 /* Get picture element size */
313 {
314 int width, height;
315 status = CMD_read_pic_elements (dev, dev->current_page,
316 SIDE_FRONT, &width, &height);
317 if (status)
318 return status;
319 }
320
321 if (IS_DUPLEX (dev))
322 {
323 int width, height;
324 status = CMD_read_pic_elements (dev, dev->current_page,
325 SIDE_BACK, &width, &height);
326 if (status)
327 return status;
328 }
329
330 /* software based enhancement functions from sanei_magic */
331 /* these will modify the image, and adjust the params */
332 /* at this point, we are only looking at the front image */
333 /* of simplex or duplex data, back side has already exited */
334 /* so, we do both sides now, if required */
335 if (dev->val[OPT_SWDESKEW].w){
336 buffer_deskew(dev,SIDE_FRONT);
337 }
338 if (dev->val[OPT_SWCROP].w){
339 buffer_crop(dev,SIDE_FRONT);
340 }
341 if (dev->val[OPT_SWDESPECK].w){
342 buffer_despeck(dev,SIDE_FRONT);
343 }
344 if (dev->val[OPT_SWDEROTATE].w || dev->val[OPT_ROTATE].w){
345 buffer_rotate(dev,SIDE_FRONT);
346 }
347
348 if (IS_DUPLEX (dev)){
349 if (dev->val[OPT_SWDESKEW].w){
350 buffer_deskew(dev,SIDE_BACK);
351 }
352 if (dev->val[OPT_SWCROP].w){
353 buffer_crop(dev,SIDE_BACK);
354 }
355 if (dev->val[OPT_SWDESPECK].w){
356 buffer_despeck(dev,SIDE_BACK);
357 }
358 if (dev->val[OPT_SWDEROTATE].w || dev->val[OPT_ROTATE].w){
359 buffer_rotate(dev,SIDE_BACK);
360 }
361 }
362
363 cleanup:
364
365 /* check if we need to skip this page */
366 if (dev->val[OPT_SWSKIP].w && buffer_isblank(dev,dev->current_side)){
367 DBG (DBG_proc, "sane_start: blank page, recurse\n");
368 return sane_start(handle);
369 }
370
371 DBG (DBG_proc, "sane_start: exit\n");
372 return status;
373 }
374
375 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)376 sane_read (SANE_Handle handle, SANE_Byte * buf,
377 SANE_Int max_len, SANE_Int * len)
378 {
379 PKV_DEV dev = (PKV_DEV) handle;
380 int side = dev->current_side == SIDE_FRONT ? 0 : 1;
381
382 int size = max_len;
383 if (!dev->scanning)
384 return SANE_STATUS_EOF;
385
386 if (size > dev->img_size[side])
387 size = dev->img_size[side];
388
389 if (size == 0)
390 {
391 *len = size;
392 return SANE_STATUS_EOF;
393 }
394
395 if (dev->val[OPT_INVERSE].w &&
396 (kv_get_mode (dev) == SM_BINARY || kv_get_mode (dev) == SM_DITHER))
397 {
398 int i;
399 unsigned char *p = dev->img_pt[side];
400 for (i = 0; i < size; i++)
401 {
402 buf[i] = ~p[i];
403 }
404 }
405 else
406 {
407 memcpy (buf, dev->img_pt[side], size);
408 }
409
410 /*hexdump(DBG_error, "img data", buf, 128); */
411
412 dev->img_pt[side] += size;
413 dev->img_size[side] -= size;
414
415 DBG (DBG_proc, "sane_read: %d bytes to read, "
416 "%d bytes read, EOF=%s %d\n",
417 max_len, size, dev->img_size[side] == 0 ? "True" : "False", side);
418
419 if (len)
420 {
421 *len = size;
422 }
423 if (dev->img_size[side] == 0)
424 {
425 if (!strcmp (dev->val[OPT_FEEDER_MODE].s, "single"))
426 if ((IS_DUPLEX (dev) && side) || !IS_DUPLEX (dev))
427 dev->scanning = 0;
428 }
429 return SANE_STATUS_GOOD;
430 }
431
432 void
sane_cancel(SANE_Handle handle)433 sane_cancel (SANE_Handle handle)
434 {
435 PKV_DEV dev = (PKV_DEV) handle;
436 DBG (DBG_proc, "sane_cancel: scan canceled.\n");
437 dev->scanning = 0;
438
439 kv_close (dev);
440 }
441
442 SANE_Status
sane_set_io_mode(SANE_Handle h,SANE_Bool m)443 sane_set_io_mode (SANE_Handle h, SANE_Bool m)
444 {
445 (void) h;
446 (void) m;
447 return SANE_STATUS_UNSUPPORTED;
448 }
449
450 SANE_Status
sane_get_select_fd(SANE_Handle h,SANE_Int * fd)451 sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
452 {
453 (void) h;
454 (void) fd;
455 return SANE_STATUS_UNSUPPORTED;
456 }
457