1 /* SANE - Scanner Access Now Easy.
2
3 Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4 Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
5
6 This file is part of the SANE package.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 As a special exception, the authors of SANE give permission for
22 additional uses of the libraries contained in this release of SANE.
23
24 The exception is that, if you link a SANE library with other files
25 to produce an executable, this does not by itself cause the
26 resulting executable to be covered by the GNU General Public
27 License. Your use of that executable is in no way restricted on
28 account of linking the SANE library code into it.
29
30 This exception does not, however, invalidate any other reasons why
31 the executable file might be covered by the GNU General Public
32 License.
33
34 If you submit changes to SANE to the maintainers to be included in
35 a subsequent release, you agree by submitting the changes that
36 those changes may be distributed with this exception intact.
37
38 If you write modifications of your own for SANE, it is your choice
39 whether to permit this exception to apply to your modifications.
40 If you do not wish that, delete this exception notice.
41 */
42
43 /****************************************************************************
44 * Credits should go to Martin Schewe (http://pixma.schewe.com) who analysed
45 * the protocol of MP750.
46 ****************************************************************************/
47
48 #include "../include/sane/config.h"
49
50 #include <stdlib.h>
51 #include <string.h>
52
53 #include "pixma_rename.h"
54 #include "pixma_common.h"
55 #include "pixma_io.h"
56
57 /* TODO: remove lines marked with SIM. They are inserted so that I can test
58 the subdriver with the simulator. WY */
59
60 #ifdef __GNUC__
61 # define UNUSED(v) (void) v
62 #else
63 # define UNUSED(v)
64 #endif
65
66 #define IMAGE_BLOCK_SIZE 0xc000
67 #define CMDBUF_SIZE 512
68 #define HAS_PAPER(s) (s[1] == 0)
69 #define IS_WARMING_UP(s) (s[7] != 3)
70 #define IS_CALIBRATED(s) (s[8] == 0xf)
71
72 #define MP750_PID 0x1706
73 #define MP760_PID 0x1708
74 #define MP780_PID 0x1707
75
76
77 enum mp750_state_t
78 {
79 state_idle,
80 state_warmup,
81 state_scanning,
82 state_transfering,
83 state_finished
84 };
85
86 enum mp750_cmd_t
87 {
88 cmd_start_session = 0xdb20,
89 cmd_select_source = 0xdd20,
90 cmd_scan_param = 0xde20,
91 cmd_status = 0xf320,
92 cmd_abort_session = 0xef20,
93 cmd_time = 0xeb80,
94 cmd_read_image = 0xd420,
95
96 cmd_activate = 0xcf60,
97 cmd_calibrate = 0xe920,
98 cmd_error_info = 0xff20
99 };
100
101 typedef struct mp750_t
102 {
103 enum mp750_state_t state;
104 pixma_cmdbuf_t cb;
105 unsigned raw_width, raw_height;
106 uint8_t current_status[12];
107
108 uint8_t *buf, *rawimg, *img;
109 /* make new buffer for rgb_to_gray to act on */
110 uint8_t *imgcol;
111 unsigned line_size; /* need in 2 functions */
112
113 unsigned rawimg_left, imgbuf_len, last_block_size, imgbuf_ofs;
114 int shifted_bytes;
115 int stripe_shift; /* for 2400dpi */
116 unsigned last_block;
117
118 unsigned monochrome:1;
119 unsigned needs_abort:1;
120 } mp750_t;
121
122
123
124 static void mp750_finish_scan (pixma_t * s);
125 static void check_status (pixma_t * s);
126
127 static int
has_paper(pixma_t * s)128 has_paper (pixma_t * s)
129 {
130 mp750_t *mp = (mp750_t *) s->subdriver;
131 return HAS_PAPER (mp->current_status);
132 }
133
134 static int
is_warming_up(pixma_t * s)135 is_warming_up (pixma_t * s)
136 {
137 mp750_t *mp = (mp750_t *) s->subdriver;
138 return IS_WARMING_UP (mp->current_status);
139 }
140
141 static int
is_calibrated(pixma_t * s)142 is_calibrated (pixma_t * s)
143 {
144 mp750_t *mp = (mp750_t *) s->subdriver;
145 return IS_CALIBRATED (mp->current_status);
146 }
147
148 static void
drain_bulk_in(pixma_t * s)149 drain_bulk_in (pixma_t * s)
150 {
151 mp750_t *mp = (mp750_t *) s->subdriver;
152 while (pixma_read (s->io, mp->buf, IMAGE_BLOCK_SIZE) >= 0);
153 }
154
155 static int
abort_session(pixma_t * s)156 abort_session (pixma_t * s)
157 {
158 mp750_t *mp = (mp750_t *) s->subdriver;
159 return pixma_exec_short_cmd (s, &mp->cb, cmd_abort_session);
160 }
161
162 static int
query_status(pixma_t * s)163 query_status (pixma_t * s)
164 {
165 mp750_t *mp = (mp750_t *) s->subdriver;
166 uint8_t *data;
167 int error;
168
169 data = pixma_newcmd (&mp->cb, cmd_status, 0, 12);
170 error = pixma_exec (s, &mp->cb);
171 if (error >= 0)
172 {
173 memcpy (mp->current_status, data, 12);
174 PDBG (pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u\n",
175 data[1], data[8], data[7]));
176 }
177 return error;
178 }
179
180 static int
activate(pixma_t * s, uint8_t x)181 activate (pixma_t * s, uint8_t x)
182 {
183 mp750_t *mp = (mp750_t *) s->subdriver;
184 uint8_t *data = pixma_newcmd (&mp->cb, cmd_activate, 10, 0);
185 data[0] = 1;
186 data[3] = x;
187 return pixma_exec (s, &mp->cb);
188 }
189
190 static int
activate_cs(pixma_t * s, uint8_t x)191 activate_cs (pixma_t * s, uint8_t x)
192 {
193 /*SIM*/ check_status (s);
194 return activate (s, x);
195 }
196
197 static int
start_session(pixma_t * s)198 start_session (pixma_t * s)
199 {
200 mp750_t *mp = (mp750_t *) s->subdriver;
201 return pixma_exec_short_cmd (s, &mp->cb, cmd_start_session);
202 }
203
204 static int
select_source(pixma_t * s)205 select_source (pixma_t * s)
206 {
207 mp750_t *mp = (mp750_t *) s->subdriver;
208 uint8_t *data = pixma_newcmd (&mp->cb, cmd_select_source, 10, 0);
209 data[0] = (s->param->source == PIXMA_SOURCE_ADF) ? 2 : 1;
210 data[1] = 1;
211 return pixma_exec (s, &mp->cb);
212 }
213
214 static int
has_ccd_sensor(pixma_t * s)215 has_ccd_sensor (pixma_t * s)
216 {
217 return ((s->cfg->cap & PIXMA_CAP_CCD) != 0);
218 }
219
220 static int
is_ccd_grayscale(pixma_t * s)221 is_ccd_grayscale (pixma_t * s)
222 {
223 return (has_ccd_sensor (s) && (s->param->channels == 1));
224 }
225
226 /* CCD sensors don't have a Grayscale mode, but use color mode instead */
227 static unsigned
get_cis_ccd_line_size(pixma_t * s)228 get_cis_ccd_line_size (pixma_t * s)
229 {
230 return (s->param->wx ? s->param->line_size / s->param->w * s->param->wx
231 : s->param->line_size) * ((is_ccd_grayscale (s)) ? 3 : 1);
232 }
233
234 static int
send_scan_param(pixma_t * s)235 send_scan_param (pixma_t * s)
236 {
237 mp750_t *mp = (mp750_t *) s->subdriver;
238 uint8_t *data;
239
240 data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x2e, 0);
241 pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04);
242 pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x06);
243 pixma_set_be32 (s->param->x, data + 0x08);
244 pixma_set_be32 (s->param->y, data + 0x0c);
245 pixma_set_be32 (mp->raw_width, data + 0x10);
246 pixma_set_be32 (mp->raw_height, data + 0x14);
247 data[0x18] = 8; /* 8 = color, 4 = grayscale(?) */
248 /* GH: No, there is no grayscale for CCD devices, Windows shows same */
249 data[0x19] = s->param->depth * ((is_ccd_grayscale (s)) ? 3 : s->param->channels); /* bits per pixel */
250 data[0x20] = 0xff;
251 data[0x23] = 0x81;
252 data[0x26] = 0x02;
253 data[0x27] = 0x01;
254 data[0x29] = mp->monochrome ? 0 : 1;
255
256 return pixma_exec (s, &mp->cb);
257 }
258
259 static int
calibrate(pixma_t * s)260 calibrate (pixma_t * s)
261 {
262 mp750_t *mp = (mp750_t *) s->subdriver;
263 return pixma_exec_short_cmd (s, &mp->cb, cmd_calibrate);
264 }
265
266 static int
calibrate_cs(pixma_t * s)267 calibrate_cs (pixma_t * s)
268 {
269 /*SIM*/ check_status (s);
270 return calibrate (s);
271 }
272
273 static int
request_image_block_ex(pixma_t * s, unsigned *size, uint8_t * info, unsigned flag)274 request_image_block_ex (pixma_t * s, unsigned *size, uint8_t * info,
275 unsigned flag)
276 {
277 mp750_t *mp = (mp750_t *) s->subdriver;
278 int error;
279
280 memset (mp->cb.buf, 0, 10);
281 pixma_set_be16 (cmd_read_image, mp->cb.buf);
282 mp->cb.buf[7] = *size >> 8;
283 mp->cb.buf[8] = 4 | flag;
284 mp->cb.reslen = pixma_cmd_transaction (s, mp->cb.buf, 10, mp->cb.buf, 6);
285 mp->cb.expected_reslen = 0;
286 error = pixma_check_result (&mp->cb);
287 if (error >= 0)
288 {
289 if (mp->cb.reslen == 6)
290 {
291 *info = mp->cb.buf[2];
292 *size = pixma_get_be16 (mp->cb.buf + 4);
293 }
294 else
295 {
296 error = PIXMA_EPROTO;
297 }
298 }
299 return error;
300 }
301
302 static int
request_image_block(pixma_t * s, unsigned *size, uint8_t * info)303 request_image_block (pixma_t * s, unsigned *size, uint8_t * info)
304 {
305 return request_image_block_ex (s, size, info, 0);
306 }
307
308 static int
request_image_block2(pixma_t * s, uint8_t * info)309 request_image_block2 (pixma_t * s, uint8_t * info)
310 {
311 unsigned temp = 0;
312 return request_image_block_ex (s, &temp, info, 0x20);
313 }
314
315 static int
read_image_block(pixma_t * s, uint8_t * data)316 read_image_block (pixma_t * s, uint8_t * data)
317 {
318 int count, temp;
319
320 count = pixma_read (s->io, data, IMAGE_BLOCK_SIZE);
321 if (count < 0)
322 return count;
323 if (count == IMAGE_BLOCK_SIZE)
324 {
325 int error = pixma_read (s->io, &temp, 0);
326 if (error < 0)
327 {
328 PDBG (pixma_dbg
329 (1, "WARNING: reading zero-length packet failed %d\n", error));
330 }
331 }
332 return count;
333 }
334
335 static int
read_error_info(pixma_t * s, void *buf, unsigned size)336 read_error_info (pixma_t * s, void *buf, unsigned size)
337 {
338 unsigned len = 16;
339 mp750_t *mp = (mp750_t *) s->subdriver;
340 uint8_t *data;
341 int error;
342
343 data = pixma_newcmd (&mp->cb, cmd_error_info, 0, len);
344 error = pixma_exec (s, &mp->cb);
345 if (error >= 0 && buf)
346 {
347 if (len < size)
348 size = len;
349 /* NOTE: I've absolutely no idea what the returned data mean. */
350 memcpy (buf, data, size);
351 error = len;
352 }
353 return error;
354 }
355
356 static int
send_time(pixma_t * s)357 send_time (pixma_t * s)
358 {
359 /* TODO: implement send_time() */
360 UNUSED (s);
361 PDBG (pixma_dbg (3, "send_time() is not yet implemented.\n"));
362 return 0;
363 }
364
365 static int
handle_interrupt(pixma_t * s, int timeout)366 handle_interrupt (pixma_t * s, int timeout)
367 {
368 int error;
369 uint8_t intr[16];
370
371 error = pixma_wait_interrupt (s->io, intr, sizeof (intr), timeout);
372 if (error == PIXMA_ETIMEDOUT)
373 return 0;
374 if (error < 0)
375 return error;
376 if (error != 16)
377 {
378 PDBG (pixma_dbg (1, "WARNING: unexpected interrupt packet length %d\n",
379 error));
380 return PIXMA_EPROTO;
381 }
382
383 if (intr[10] & 0x40)
384 send_time (s);
385 if (intr[12] & 0x40)
386 query_status (s);
387 if (intr[15] & 1)
388 s->events = PIXMA_EV_BUTTON2; /* b/w scan */
389 if (intr[15] & 2)
390 s->events = PIXMA_EV_BUTTON1; /* color scan */
391 return 1;
392 }
393
394 static void
check_status(pixma_t * s)395 check_status (pixma_t * s)
396 {
397 while (handle_interrupt (s, 0) > 0);
398 }
399
400 static int
step1(pixma_t * s)401 step1 (pixma_t * s)
402 {
403 int error, tmo;
404
405 error = activate (s, 0);
406 if (error < 0)
407 return error;
408 error = query_status (s);
409 if (error < 0)
410 return error;
411 if (s->param->source == PIXMA_SOURCE_ADF && !has_paper (s))
412 return PIXMA_ENO_PAPER;
413 error = activate_cs (s, 0);
414 /*SIM*/ if (error < 0)
415 return error;
416 error = activate_cs (s, 0x20);
417 if (error < 0)
418 return error;
419
420 tmo = 60;
421 error = calibrate_cs (s);
422 while (error == PIXMA_EBUSY && --tmo >= 0)
423 {
424 if (s->cancel)
425 return PIXMA_ECANCELED;
426 PDBG (pixma_dbg
427 (2, "Scanner is busy. Timed out in %d sec.\n", tmo + 1));
428 pixma_sleep (1000000);
429 error = calibrate_cs (s);
430 }
431 return error;
432 }
433
434 static void
shift_rgb(const uint8_t * src, unsigned pixels, int sr, int sg, int sb, int stripe_shift, int line_size, uint8_t * dst)435 shift_rgb (const uint8_t * src, unsigned pixels,
436 int sr, int sg, int sb, int stripe_shift,
437 int line_size, uint8_t * dst)
438 {
439 unsigned st;
440
441 for (; pixels != 0; pixels--)
442 {
443 st = (pixels % 2 == 0) ? -2 * stripe_shift * line_size : 0;
444 *(dst++ + sr + st) = *src++;
445 *(dst++ + sg + st) = *src++;
446 *(dst++ + sb + st) = *src++;
447 }
448 }
449
450 static uint8_t *
rgb_to_gray(uint8_t * gptr, const uint8_t * cptr, unsigned pixels, unsigned c)451 rgb_to_gray (uint8_t * gptr, const uint8_t * cptr, unsigned pixels, unsigned c)
452 {
453 unsigned i, j, g;
454
455 /* gptr: destination gray scale buffer */
456 /* cptr: source color scale buffer */
457 /* c: 3 for 3-channel single-byte data, 6 for double-byte data */
458
459 for (i=0; i < pixels; i++)
460 {
461 for (j = 0, g = 0; j < 3; j++)
462 {
463 g += *cptr++;
464 if (c == 6) g += (*cptr++ << 8);
465 }
466 g /= 3;
467 *gptr++ = g;
468 if (c == 6) *gptr++ = (g >> 8);
469 }
470 return gptr;
471 }
472
473 static int
calc_component_shifting(pixma_t * s)474 calc_component_shifting (pixma_t * s)
475 {
476 switch (s->cfg->pid)
477 {
478 case MP760_PID:
479 switch (s->param->ydpi)
480 {
481 case 300:
482 return 3;
483 case 600:
484 return 6;
485 default:
486 return s->param->ydpi / 75;
487 }
488 /* never reached */
489 break;
490
491 case MP750_PID:
492 case MP780_PID:
493 default:
494 return 2 * s->param->ydpi / 75;
495 }
496 }
497
498 static void
workaround_first_command(pixma_t * s)499 workaround_first_command (pixma_t * s)
500 {
501 /* FIXME: Send a dummy command because the device doesn't response to the
502 first command that is sent directly after the USB interface has been
503 set up. Why? USB isn't set up properly? */
504 uint8_t cmd[10];
505 int error;
506
507 if (s->cfg->pid == MP750_PID)
508 return; /* MP750 doesn't have this problem(?) */
509
510 PDBG (pixma_dbg
511 (1,
512 "Work-around for the problem: device doesn't response to the first command.\n"));
513 memset (cmd, 0, sizeof (cmd));
514 pixma_set_be16 (cmd_calibrate, cmd);
515 error = pixma_write (s->io, cmd, 10);
516 if (error != 10)
517 {
518 if (error < 0)
519 {
520 PDBG (pixma_dbg
521 (1, " Sending a dummy command failed: %s\n",
522 pixma_strerror (error)));
523 }
524 else
525 {
526 PDBG (pixma_dbg
527 (1, " Sending a dummy command failed: count = %d\n", error));
528 }
529 return;
530 }
531 error = pixma_read (s->io, cmd, sizeof (cmd));
532 if (error >= 0)
533 {
534 PDBG (pixma_dbg
535 (1, " Got %d bytes response from a dummy command.\n", error));
536 }
537 else
538 {
539 PDBG (pixma_dbg
540 (1, " Reading response of a dummy command failed: %s\n",
541 pixma_strerror (error)));
542 }
543 }
544
545 static int
mp750_open(pixma_t * s)546 mp750_open (pixma_t * s)
547 {
548 mp750_t *mp;
549 uint8_t *buf;
550
551 mp = (mp750_t *) calloc (1, sizeof (*mp));
552 if (!mp)
553 return PIXMA_ENOMEM;
554
555 buf = (uint8_t *) malloc (CMDBUF_SIZE);
556 if (!buf)
557 {
558 free (mp);
559 return PIXMA_ENOMEM;
560 }
561
562 s->subdriver = mp;
563 mp->state = state_idle;
564
565 /* ofs: 0 1 2 3 4 5 6 7 8 9
566 cmd: cmd1 cmd2 00 00 00 00 00 00 00 00
567 data length-^^^^^ => cmd_len_field_ofs
568 |--------- cmd_header_len --------|
569
570 res: res1 res2
571 |---------| res_header_len
572 */
573 mp->cb.buf = buf;
574 mp->cb.size = CMDBUF_SIZE;
575 mp->cb.res_header_len = 2;
576 mp->cb.cmd_header_len = 10;
577 mp->cb.cmd_len_field_ofs = 7;
578
579 handle_interrupt (s, 200);
580 workaround_first_command (s);
581 return 0;
582 }
583
584 static void
mp750_close(pixma_t * s)585 mp750_close (pixma_t * s)
586 {
587 mp750_t *mp = (mp750_t *) s->subdriver;
588
589 mp750_finish_scan (s);
590 free (mp->cb.buf);
591 free (mp);
592 s->subdriver = NULL;
593 }
594
595 static int
mp750_check_param(pixma_t * s, pixma_scan_param_t * sp)596 mp750_check_param (pixma_t * s, pixma_scan_param_t * sp)
597 {
598 unsigned raw_width;
599
600 UNUSED (s);
601
602 sp->depth = 8; /* FIXME: Does MP750 supports other depth? */
603
604 /* GH: my implementation */
605 /* if ((sp->channels == 3) || (is_ccd_grayscale (s)))
606 raw_width = ALIGN_SUP (sp->w, 4);
607 else
608 raw_width = ALIGN_SUP (sp->w, 12);*/
609
610 /* the above code gives segmentation fault?!? why... it seems to work in the mp750_scan function */
611 raw_width = ALIGN_SUP (sp->w, 4);
612
613 /*sp->line_size = raw_width * sp->channels;*/
614 sp->line_size = raw_width * sp->channels * (sp->depth / 8); /* no cropping? */
615 return 0;
616 }
617
618 static int
mp750_scan(pixma_t * s)619 mp750_scan (pixma_t * s)
620 {
621 mp750_t *mp = (mp750_t *) s->subdriver;
622 int error;
623 uint8_t *buf;
624 unsigned size, dpi, spare;
625
626 dpi = s->param->ydpi;
627 /* add a stripe shift for 2400dpi */
628 mp->stripe_shift = (dpi == 2400) ? 4 : 0;
629
630 if (mp->state != state_idle)
631 return PIXMA_EBUSY;
632
633 /* clear interrupt packets buffer */
634 while (handle_interrupt (s, 0) > 0)
635 {
636 }
637
638 /* if (s->param->channels == 1)
639 mp->raw_width = ALIGN_SUP (s->param->w, 12);
640 else
641 mp->raw_width = ALIGN_SUP (s->param->w, 4);*/
642
643 /* change to use CCD grayscale mode --- why does this give segmentation error at runtime in mp750_check_param? */
644 if ((s->param->channels == 3) || (is_ccd_grayscale (s)))
645 mp->raw_width = ALIGN_SUP (s->param->w, 4);
646 else
647 mp->raw_width = ALIGN_SUP (s->param->w, 12);
648 /* not sure about MP750, but there is no need for aligning at 12 for the MP760/770, MP780/790 since always use CCD color mode */
649
650 /* modify for stripe shift */
651 spare = 2 * calc_component_shifting (s) + 2 * mp->stripe_shift; /* FIXME: or maybe (2*... + 1)? */
652 mp->raw_height = s->param->h + spare;
653 PDBG (pixma_dbg (3, "raw_width=%u raw_height=%u dpi=%u\n",
654 mp->raw_width, mp->raw_height, dpi));
655
656 /* PDBG (pixma_dbg (4, "line_size=%"PRIu64"\n",s->param->line_size)); */
657
658 mp->line_size = get_cis_ccd_line_size (s); /* scanner hardware line_size multiplied by 3 for CCD grayscale */
659
660 size = 8 + 2 * IMAGE_BLOCK_SIZE + spare * mp->line_size;
661 buf = (uint8_t *) malloc (size);
662 if (!buf)
663 return PIXMA_ENOMEM;
664 mp->buf = buf;
665 mp->rawimg = buf;
666 mp->imgbuf_ofs = spare * mp->line_size;
667 mp->imgcol = mp->rawimg + IMAGE_BLOCK_SIZE + 8; /* added to make rgb->gray */
668 mp->img = mp->rawimg + IMAGE_BLOCK_SIZE + 8;
669 mp->imgbuf_len = IMAGE_BLOCK_SIZE + mp->imgbuf_ofs;
670 mp->rawimg_left = 0;
671 mp->last_block_size = 0;
672 mp->shifted_bytes = -(int) mp->imgbuf_ofs;
673
674 error = step1 (s);
675 if (error >= 0)
676 error = start_session (s);
677 if (error >= 0)
678 mp->state = state_warmup;
679 if (error >= 0)
680 error = select_source (s);
681 if (error >= 0)
682 error = send_scan_param (s);
683 if (error < 0)
684 {
685 mp750_finish_scan (s);
686 return error;
687 }
688 return 0;
689 }
690
691
692 static int
mp750_fill_buffer(pixma_t * s, pixma_imagebuf_t * ib)693 mp750_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
694 {
695 mp750_t *mp = (mp750_t *) s->subdriver;
696 int error;
697 uint8_t info;
698 unsigned block_size, bytes_received, n;
699 int shift[3], base_shift;
700 int c;
701
702 c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8; /* single-byte or double-byte data */
703
704 if (mp->state == state_warmup)
705 {
706 int tmo = 60;
707
708 query_status (s);
709 check_status (s);
710 /*SIM*/ while (!is_calibrated (s) && --tmo >= 0)
711 {
712 if (s->cancel)
713 return PIXMA_ECANCELED;
714 if (handle_interrupt (s, 1000) > 0)
715 {
716 block_size = 0;
717 error = request_image_block (s, &block_size, &info);
718 /*SIM*/ if (error < 0)
719 return error;
720 }
721 }
722 if (tmo < 0)
723 {
724 PDBG (pixma_dbg (1, "WARNING: Timed out waiting for calibration\n"));
725 return PIXMA_ETIMEDOUT;
726 }
727 pixma_sleep (100000);
728 query_status (s);
729 if (is_warming_up (s) || !is_calibrated (s))
730 {
731 PDBG (pixma_dbg (1, "WARNING: Wrong status: wup=%d cal=%d\n",
732 is_warming_up (s), is_calibrated (s)));
733 return PIXMA_EPROTO;
734 }
735 block_size = 0;
736 request_image_block (s, &block_size, &info);
737 /*SIM*/ mp->state = state_scanning;
738 mp->last_block = 0;
739 }
740
741 /* TODO: Move to other place, values are constant. */
742 base_shift = calc_component_shifting (s) * mp->line_size;
743 if (s->param->source == PIXMA_SOURCE_ADF)
744 {
745 shift[0] = 0;
746 shift[1] = -base_shift;
747 shift[2] = -2 * base_shift;
748 }
749 else
750 {
751 shift[0] = -2 * base_shift;
752 shift[1] = -base_shift;
753 shift[2] = 0;
754 }
755
756 do
757 {
758 if (mp->last_block_size > 0)
759 {
760 block_size = mp->imgbuf_len - mp->last_block_size;
761 memcpy (mp->img, mp->img + mp->last_block_size, block_size);
762 }
763
764 do
765 {
766 if (s->cancel)
767 return PIXMA_ECANCELED;
768 if (mp->last_block)
769 {
770 /* end of image */
771 info = mp->last_block;
772 if (info != 0x38)
773 {
774 query_status (s);
775 /*SIM*/ while ((info & 0x28) != 0x28)
776 {
777 pixma_sleep (10000);
778 error = request_image_block2 (s, &info);
779 if (s->cancel)
780 return PIXMA_ECANCELED; /* FIXME: Is it safe to cancel here? */
781 if (error < 0)
782 return error;
783 }
784 }
785 mp->needs_abort = (info != 0x38);
786 mp->last_block = info;
787 mp->state = state_finished;
788 return 0;
789 }
790
791 check_status (s);
792 /*SIM*/ while (handle_interrupt (s, 1) > 0);
793 /*SIM*/ block_size = IMAGE_BLOCK_SIZE;
794 error = request_image_block (s, &block_size, &info);
795 if (error < 0)
796 {
797 if (error == PIXMA_ECANCELED)
798 read_error_info (s, NULL, 0);
799 return error;
800 }
801 mp->last_block = info;
802 if ((info & ~0x38) != 0)
803 {
804 PDBG (pixma_dbg (1, "WARNING: Unknown info byte %x\n", info));
805 }
806 if (block_size == 0)
807 {
808 /* no image data at this moment. */
809 pixma_sleep (10000);
810 }
811 }
812 while (block_size == 0);
813
814 error = read_image_block (s, mp->rawimg + mp->rawimg_left);
815 if (error < 0)
816 {
817 mp->state = state_transfering;
818 return error;
819 }
820 bytes_received = error;
821 PASSERT (bytes_received == block_size);
822
823 /* TODO: simplify! */
824 mp->rawimg_left += bytes_received;
825 n = mp->rawimg_left / 3;
826 /* n = number of pixels in the buffer? */
827
828 /* Color to Grayscale conversion for CCD sensor */
829 if (is_ccd_grayscale (s)) {
830 shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size,
831 mp->imgcol + mp->imgbuf_ofs);
832 /* dst: img, src: imgcol */
833 rgb_to_gray (mp->img, mp->imgcol, n, c); /* cropping occurs later? */
834 PDBG (pixma_dbg (4, "*fill_buffer: did grayscale conversion \n"));
835 }
836 /* Color image processing */
837 else {
838 shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size,
839 mp->img + mp->imgbuf_ofs);
840 PDBG (pixma_dbg (4, "*fill_buffer: no grayscale conversion---keep color \n"));
841 }
842
843 /* entering remaining unprocessed bytes after last complete pixel into mp->rawimg buffer -- no influence on mp->img */
844 n *= 3;
845 mp->shifted_bytes += n;
846 mp->rawimg_left -= n; /* rawimg_left = 0, 1 or 2 bytes left in the buffer. */
847 mp->last_block_size = n;
848 memcpy (mp->rawimg, mp->rawimg + n, mp->rawimg_left);
849
850 }
851 while (mp->shifted_bytes <= 0);
852
853 if ((unsigned) mp->shifted_bytes < mp->last_block_size)
854 {
855 if (is_ccd_grayscale (s))
856 ib->rptr = mp->img + mp->last_block_size/3 - mp->shifted_bytes/3; /* testing---works OK */
857 else
858 ib->rptr = mp->img + mp->last_block_size - mp->shifted_bytes;
859 }
860 else
861 ib->rptr = mp->img;
862 if (is_ccd_grayscale (s))
863 ib->rend = mp->img + mp->last_block_size/3; /* testing---works OK */
864 else
865 ib->rend = mp->img + mp->last_block_size;
866 return ib->rend - ib->rptr;
867 }
868
869 static void
mp750_finish_scan(pixma_t * s)870 mp750_finish_scan (pixma_t * s)
871 {
872 int error;
873 mp750_t *mp = (mp750_t *) s->subdriver;
874
875 switch (mp->state)
876 {
877 case state_transfering:
878 drain_bulk_in (s);
879 /* fall through */
880 case state_scanning:
881 case state_warmup:
882 error = abort_session (s);
883 if (error == PIXMA_ECANCELED)
884 read_error_info (s, NULL, 0);
885 /* fall through */
886 case state_finished:
887 if (s->param->source == PIXMA_SOURCE_FLATBED)
888 {
889 /*SIM*/ query_status (s);
890 if (abort_session (s) == PIXMA_ECANCELED)
891 {
892 read_error_info (s, NULL, 0);
893 query_status (s);
894 }
895 }
896 query_status (s);
897 /*SIM*/ activate (s, 0);
898 if (mp->needs_abort)
899 {
900 mp->needs_abort = 0;
901 abort_session (s);
902 }
903 free (mp->buf);
904 mp->buf = mp->rawimg = NULL;
905 mp->state = state_idle;
906 /* fall through */
907 case state_idle:
908 break;
909 }
910 }
911
912 static void
mp750_wait_event(pixma_t * s, int timeout)913 mp750_wait_event (pixma_t * s, int timeout)
914 {
915 /* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
916 * instance. */
917 while (s->events == 0 && handle_interrupt (s, timeout) > 0)
918 {
919 }
920 }
921
922 static int
mp750_get_status(pixma_t * s, pixma_device_status_t * status)923 mp750_get_status (pixma_t * s, pixma_device_status_t * status)
924 {
925 int error;
926
927 error = query_status (s);
928 if (error < 0)
929 return error;
930 status->hardware = PIXMA_HARDWARE_OK;
931 status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
932 status->cal =
933 (is_calibrated (s)) ? PIXMA_CALIBRATION_OK : PIXMA_CALIBRATION_OFF;
934 status->lamp = (is_warming_up (s)) ? PIXMA_LAMP_WARMING_UP : PIXMA_LAMP_OK;
935 return 0;
936 }
937
938
939 static const pixma_scan_ops_t pixma_mp750_ops = {
940 mp750_open,
941 mp750_close,
942 mp750_scan,
943 mp750_fill_buffer,
944 mp750_finish_scan,
945 mp750_wait_event,
946 mp750_check_param,
947 mp750_get_status
948 };
949
950 #define DEVICE(name, model, pid, dpi, cap) { \
951 name, /* name */ \
952 model, /* model */ \
953 0x04a9, pid, /* vid pid */ \
954 0, /* iface */ \
955 &pixma_mp750_ops, /* ops */ \
956 0, 0, /* min_xdpi & min_xdpi_16 not used in this subdriver */ \
957 dpi, 2*(dpi), /* xdpi, ydpi */ \
958 0, 0, /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \
959 0, 0, /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */ \
960 637, 877, /* width, height */ \
961 PIXMA_CAP_CCD| /* all scanners with CCD */ \
962 PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap \
963 }
964
965 const pixma_config_t pixma_mp750_devices[] = {
966 DEVICE ("Canon PIXMA MP750", "MP750", MP750_PID, 2400, PIXMA_CAP_ADF),
967 DEVICE ("Canon PIXMA MP760/770", "MP760/770", MP760_PID, 2400, PIXMA_CAP_TPU),
968 DEVICE ("Canon PIXMA MP780/790", "MP780/790", MP780_PID, 2400, PIXMA_CAP_ADF),
969 DEVICE (NULL, NULL, 0, 0, 0)
970 };
971