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