1 /* SANE - Scanner Access Now Easy.
2
3 Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4 Copyright (C) 2007-2009 Nicolas Martin, <nicols-guest at alioth dot debian dot org>
5 Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice.
42 */
43 /* test cases
44 1. short USB packet (must be no -ETIMEDOUT)
45 2. cancel using button on the printer (look for abort command)
46 3. start scan while busy (status 0x1414)
47 4. cancel using ctrl-c (must send abort command)
48 */
49
50 #define TPU_48 /* uncomment to activate TPU scan at 48 bits */
51 /*#define DEBUG_TPU_48*//* uncomment to debug 48 bits TPU on a non TPU device */
52 /*#define DEBUG_TPU_24*//* uncomment to debug 24 bits TPU on a non TPU device */
53
54 /*#define TPUIR_USE_RGB*/ /* uncomment to use RGB channels and convert them to gray; otherwise use R channel only */
55
56 #include "../include/sane/config.h"
57
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <time.h> /* localtime(C90) */
62
63 #include "pixma_rename.h"
64 #include "pixma_common.h"
65 #include "pixma_io.h"
66
67 /* Some macro code to enhance readability */
68 #define RET_IF_ERR(x) do { \
69 if ((error = (x)) < 0) \
70 return error; \
71 } while(0)
72
73 #define WAIT_INTERRUPT(x) do { \
74 error = handle_interrupt (s, x); \
75 if (s->cancel) \
76 return PIXMA_ECANCELED; \
77 if (error != PIXMA_ECANCELED && error < 0) \
78 return error; \
79 } while(0)
80
81 #ifdef __GNUC__
82 # define UNUSED(v) (void) v
83 #else
84 # define UNUSED(v)
85 #endif
86
87 /* Size of the command buffer should be multiple of wMaxPacketLength and
88 greater than 4096+24.
89 4096 = size of gamma table. 24 = header + checksum */
90 #define IMAGE_BLOCK_SIZE (512*1024)
91 #define CMDBUF_SIZE (4096 + 24)
92 #define UNKNOWN_PID 0xffff
93
94 #define CANON_VID 0x04a9
95
96 /* Generation 1 */
97 #define MP800_PID 0x170d
98 #define MP800R_PID 0x170e
99 #define MP830_PID 0x1713
100
101 /* Generation 2 */
102 #define MP810_PID 0x171a
103 #define MP960_PID 0x171b
104
105 /* Generation 3 */
106 /* PIXMA 2007 vintage */
107 #define MP970_PID 0x1726
108
109 /* Flatbed scanner CCD (2007) */
110 #define CS8800F_PID 0x1901
111
112 /* PIXMA 2008 vintage */
113 #define MP980_PID 0x172d
114
115 /* Generation 4 */
116 #define MP990_PID 0x1740
117
118 /* Flatbed scanner CCD (2010) */
119 #define CS9000F_PID 0x1908
120
121 /* 2010 new device (untested) */
122 #define MG8100_PID 0x174b /* CCD */
123
124 /* 2011 new device (untested) */
125 #define MG8200_PID 0x1756 /* CCD */
126
127 /* 2013 new device */
128 #define CS9000F_MII_PID 0x190d
129
130 /* Generation 4 XML messages that encapsulates the Pixma protocol messages */
131 #define XML_START_1 \
132 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
133 <cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\">\
134 <ivec:contents><ivec:operation>StartJob</ivec:operation>\
135 <ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
136 <ivec:bidi>1</ivec:bidi></ivec:param_set></ivec:contents></cmd>"
137
138 #define XML_START_2 \
139 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
140 <cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\" xmlns:vcn=\"http://www.canon.com/ns/cmd/2008/07/canon/\">\
141 <ivec:contents><ivec:operation>VendorCmd</ivec:operation>\
142 <ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
143 <vcn:ijoperation>ModeShift</vcn:ijoperation><vcn:ijmode>1</vcn:ijmode>\
144 </ivec:param_set></ivec:contents></cmd>"
145
146 #define XML_END \
147 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
148 <cmd xmlns:ivec=\"http://www.canon.com/ns/cmd/2008/07/common/\">\
149 <ivec:contents><ivec:operation>EndJob</ivec:operation>\
150 <ivec:param_set servicetype=\"scan\"><ivec:jobID>00000001</ivec:jobID>\
151 </ivec:param_set></ivec:contents></cmd>"
152
153 #if !defined(HAVE_LIBXML2)
154 #define XML_OK "<ivec:response>OK</ivec:response>"
155 #endif
156
157 enum mp810_state_t
158 {
159 state_idle,
160 state_warmup,
161 state_scanning,
162 state_transfering,
163 state_finished
164 };
165
166 enum mp810_cmd_t
167 {
168 cmd_start_session = 0xdb20,
169 cmd_select_source = 0xdd20,
170 cmd_gamma = 0xee20,
171 cmd_scan_param = 0xde20,
172 cmd_status = 0xf320,
173 cmd_abort_session = 0xef20,
174 cmd_time = 0xeb80,
175 cmd_read_image = 0xd420,
176 cmd_error_info = 0xff20,
177
178 cmd_start_calibrate_ccd_3 = 0xd520,
179 cmd_end_calibrate_ccd_3 = 0xd720,
180 cmd_scan_param_3 = 0xd820,
181 cmd_scan_start_3 = 0xd920,
182 cmd_status_3 = 0xda20,
183 cmd_get_tpu_info_3 = 0xf520,
184 cmd_set_tpu_info_3 = 0xea20,
185
186 cmd_e920 = 0xe920 /* seen in MP800 */
187 };
188
189 typedef struct mp810_t
190 {
191 enum mp810_state_t state;
192 pixma_cmdbuf_t cb;
193 uint8_t *imgbuf;
194 uint8_t current_status[16];
195 unsigned last_block;
196 uint8_t generation;
197 /* for Generation 3 and CCD shift */
198 uint8_t *linebuf;
199 uint8_t *data_left_ofs;
200 unsigned data_left_len;
201 int shift[3];
202 unsigned color_shift;
203 unsigned stripe_shift;
204 unsigned stripe_shift2; /* added for MP810, MP960 at 4800dpi & 9000F at 9600dpi */
205 unsigned jumplines; /* added for MP810, MP960 at 4800dpi & 9000F at 9600dpi */
206 uint8_t tpu_datalen;
207 uint8_t tpu_data[0x40];
208 } mp810_t;
209
210 /*
211 STAT: 0x0606 = ok,
212 0x1515 = failed (PIXMA_ECANCELED),
213 0x1414 = busy (PIXMA_EBUSY)
214
215 Transaction scheme
216 1. command_header/data | result_header
217 2. command_header | result_header/data
218 3. command_header | result_header/image_data
219
220 - data has checksum in the last byte.
221 - image_data has no checksum.
222 - data and image_data begins in the same USB packet as
223 command_header or result_header.
224
225 command format #1:
226 u16be cmd
227 u8[6] 0
228 u8[4] 0
229 u32be PLEN parameter length
230 u8[PLEN-1] parameter
231 u8 parameter check sum
232 result:
233 u16be STAT
234 u8 0
235 u8 0 or 0x21 if STAT == 0x1414
236 u8[4] 0
237
238 command format #2:
239 u16be cmd
240 u8[6] 0
241 u8[4] 0
242 u32be RLEN result length
243 result:
244 u16be STAT
245 u8[6] 0
246 u8[RLEN-1] result
247 u8 result check sum
248
249 command format #3: (only used by read_image_block)
250 u16be 0xd420
251 u8[6] 0
252 u8[4] 0
253 u32be max. block size + 8
254 result:
255 u16be STAT
256 u8[6] 0
257 u8 block info bitfield: 0x8 = end of scan, 0x10 = no more paper, 0x20 = no more data
258 u8[3] 0
259 u32be ILEN image data size
260 u8[ILEN] image data
261 */
262
263 static void mp810_finish_scan (pixma_t * s);
264
is_scanning_from_adf(pixma_t * s)265 static int is_scanning_from_adf (pixma_t * s)
266 {
267 return (s->param->source == PIXMA_SOURCE_ADF
268 || s->param->source == PIXMA_SOURCE_ADFDUP);
269 }
270
is_scanning_from_adfdup(pixma_t * s)271 static int is_scanning_from_adfdup (pixma_t * s)
272 {
273 return (s->param->source == PIXMA_SOURCE_ADFDUP);
274 }
275
is_scanning_from_tpu(pixma_t * s)276 static int is_scanning_from_tpu (pixma_t * s)
277 {
278 return (s->param->source == PIXMA_SOURCE_TPU);
279 }
280
send_xml_dialog(pixma_t * s, const char * xml_message)281 static int send_xml_dialog (pixma_t * s, const char * xml_message)
282 {
283 mp810_t *mp = (mp810_t *) s->subdriver;
284 int datalen;
285
286 datalen = pixma_cmd_transaction (s, xml_message, strlen (xml_message),
287 mp->cb.buf, 1024);
288 if (datalen < 0)
289 return datalen;
290
291 mp->cb.buf[datalen] = 0;
292
293 PDBG(pixma_dbg (10, "XML message sent to scanner:\n%s\n", xml_message));
294 PDBG(pixma_dbg (10, "XML response back from scanner:\n%s\n", mp->cb.buf));
295
296 #if defined(HAVE_LIBXML2)
297 return pixma_parse_xml_response((const char*)mp->cb.buf) == PIXMA_STATUS_OK;
298 #else
299 return (strcasestr ((const char *) mp->cb.buf, XML_OK) != NULL);
300 #endif
301 }
302
new_cmd_tpu_msg(pixma_t *s, pixma_cmdbuf_t * cb, uint16_t cmd)303 static void new_cmd_tpu_msg (pixma_t *s, pixma_cmdbuf_t * cb, uint16_t cmd)
304 {
305 pixma_newcmd (cb, cmd, 0, 0);
306 cb->buf[3] = (is_scanning_from_tpu (s)) ? 0x01 : 0x00;
307 }
308
start_session(pixma_t * s)309 static int start_session (pixma_t * s)
310 {
311 mp810_t *mp = (mp810_t *) s->subdriver;
312
313 new_cmd_tpu_msg (s, &mp->cb, cmd_start_session);
314 return pixma_exec (s, &mp->cb);
315 }
316
start_scan_3(pixma_t * s)317 static int start_scan_3 (pixma_t * s)
318 {
319 mp810_t *mp = (mp810_t *) s->subdriver;
320
321 new_cmd_tpu_msg (s, &mp->cb, cmd_scan_start_3);
322 return pixma_exec (s, &mp->cb);
323 }
324
send_cmd_start_calibrate_ccd_3(pixma_t * s)325 static int send_cmd_start_calibrate_ccd_3 (pixma_t * s)
326 {
327 mp810_t *mp = (mp810_t *) s->subdriver;
328
329 pixma_newcmd (&mp->cb, cmd_start_calibrate_ccd_3, 0, 0);
330 mp->cb.buf[3] = 0x01;
331 return pixma_exec (s, &mp->cb);
332 }
333
is_calibrated(pixma_t * s)334 static int is_calibrated (pixma_t * s)
335 {
336 mp810_t *mp = (mp810_t *) s->subdriver;
337 if (mp->generation >= 3)
338 {
339 return ((mp->current_status[0] & 0x01) == 1);
340 }
341 if (mp->generation == 1)
342 {
343 return (mp->current_status[8] == 1);
344 }
345 else
346 {
347 return (mp->current_status[9] == 1);
348 }
349 }
350
has_paper(pixma_t * s)351 static int has_paper (pixma_t * s)
352 {
353 mp810_t *mp = (mp810_t *) s->subdriver;
354
355 if (is_scanning_from_adfdup (s))
356 return (mp->current_status[1] == 0 || mp->current_status[2] == 0);
357 else
358 return (mp->current_status[1] == 0);
359 }
360
drain_bulk_in(pixma_t * s)361 static void drain_bulk_in (pixma_t * s)
362 {
363 mp810_t *mp = (mp810_t *) s->subdriver;
364 while (pixma_read (s->io, mp->imgbuf, IMAGE_BLOCK_SIZE) >= 0)
365 ;
366 }
367
abort_session(pixma_t * s)368 static int abort_session (pixma_t * s)
369 {
370 mp810_t *mp = (mp810_t *) s->subdriver;
371 return pixma_exec_short_cmd (s, &mp->cb, cmd_abort_session);
372 }
373
send_cmd_e920(pixma_t * s)374 static int send_cmd_e920 (pixma_t * s)
375 {
376 mp810_t *mp = (mp810_t *) s->subdriver;
377 return pixma_exec_short_cmd (s, &mp->cb, cmd_e920);
378 }
379
select_source(pixma_t * s)380 static int select_source (pixma_t * s)
381 {
382 mp810_t *mp = (mp810_t *) s->subdriver;
383 uint8_t *data;
384
385 data = pixma_newcmd (&mp->cb, cmd_select_source, 12, 0);
386 data[5] = ((mp->generation == 2) ? 1 : 0);
387 switch (s->param->source)
388 {
389 case PIXMA_SOURCE_FLATBED:
390 data[0] = 1;
391 data[1] = 1;
392 break;
393
394 case PIXMA_SOURCE_ADF:
395 data[0] = 2;
396 data[5] = 1;
397 data[6] = 1;
398 break;
399
400 case PIXMA_SOURCE_ADFDUP:
401 data[0] = 2;
402 data[5] = 3;
403 data[6] = 3;
404 break;
405
406 case PIXMA_SOURCE_TPU:
407 data[0] = 4;
408 data[1] = 2;
409 break;
410
411 case PIXMA_SOURCE_NONE:
412 /* this source can not be selected */
413 break;
414 }
415 return pixma_exec (s, &mp->cb);
416 }
417
send_get_tpu_info_3(pixma_t * s)418 static int send_get_tpu_info_3 (pixma_t * s)
419 {
420 mp810_t *mp = (mp810_t *) s->subdriver;
421 uint8_t *data;
422 int error;
423
424 data = pixma_newcmd (&mp->cb, cmd_get_tpu_info_3, 0, 0x34);
425 RET_IF_ERR(pixma_exec (s, &mp->cb));
426 memcpy (mp->tpu_data, data, 0x34);
427 return error;
428 }
429
send_set_tpu_info(pixma_t * s)430 static int send_set_tpu_info (pixma_t * s)
431 {
432 mp810_t *mp = (mp810_t *) s->subdriver;
433 uint8_t *data;
434
435 if (mp->tpu_datalen == 0)
436 return 0;
437 data = pixma_newcmd (&mp->cb, cmd_set_tpu_info_3, 0x34, 0);
438 memcpy (data, mp->tpu_data, 0x34);
439 return pixma_exec (s, &mp->cb);
440 }
441
send_gamma_table(pixma_t * s)442 static int send_gamma_table (pixma_t * s)
443 {
444 mp810_t *mp = (mp810_t *) s->subdriver;
445 const uint8_t *lut = s->param->gamma_table;
446 uint8_t *data;
447
448 if (s->cfg->cap & PIXMA_CAP_GT_4096)
449 {
450 data = pixma_newcmd (&mp->cb, cmd_gamma, 4096 + 8, 0);
451 data[0] = (s->param->channels == 3) ? 0x10 : 0x01;
452 pixma_set_be16 (0x1004, data + 2);
453 if (lut)
454 {
455 /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 4096 bytes from LUT ***** \n")); */
456 /* PDBG (pixma_hexdump (4, lut, 4096)); */
457 memcpy (data + 4, lut, 4096);
458 }
459 else
460 {
461 /* fallback: we should never see this */
462 PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 4096 bytes Table with %f ***** \n",
463 s->param->gamma));
464 pixma_fill_gamma_table (s->param->gamma, data + 4, 4096);
465 /* PDBG (pixma_hexdump (4, data + 4, 4096)); */
466 }
467 }
468 else
469 {
470 /* Gamma table for 2nd+ generation: 1024 * uint16_le */
471 data = pixma_newcmd (&mp->cb, cmd_gamma, 1024 * 2 + 8, 0);
472 data[0] = 0x10;
473 pixma_set_be16 (0x0804, data + 2);
474 if (lut)
475 {
476 /* PDBG (pixma_dbg (4, "*send_gamma_table***** Use 1024 * 2 bytes from LUT ***** \n")); */
477 /* PDBG (pixma_hexdump (4, lut, 1024 * 2)); */
478 memcpy (data + 4, lut, 1024 * 2);
479 }
480 else
481 {
482 /* fallback: we should never see this */
483 PDBG (pixma_dbg (4, "*send_gamma_table***** Generate 1024 * 2 bytes Table with %f ***** \n",
484 s->param->gamma));
485 pixma_fill_gamma_table (s->param->gamma, data + 4, 1024);
486 /* PDBG (pixma_hexdump (4, data + 4, 1024 * 2)); */
487 }
488 }
489 return pixma_exec (s, &mp->cb);
490 }
491
calc_raw_width(const mp810_t * mp, const pixma_scan_param_t * param)492 static unsigned calc_raw_width (const mp810_t * mp,
493 const pixma_scan_param_t * param)
494 {
495 unsigned raw_width;
496 /* NOTE: Actually, we can send arbitrary width to MP810. Lines returned
497 are always padded to multiple of 4 or 12 pixels. Is this valid for
498 other models, too? */
499 if (mp->generation >= 2)
500 {
501 raw_width = ALIGN_SUP (param->w + param->xs, 32);
502 /* PDBG (pixma_dbg (4, "*calc_raw_width***** width %u extended by %u and rounded to %u *****\n", param->w, param->xs, raw_width)); */
503 }
504 else if (param->channels == 1)
505 {
506 raw_width = ALIGN_SUP (param->w + param->xs, 12);
507 }
508 else
509 {
510 raw_width = ALIGN_SUP (param->w + param->xs, 4);
511 }
512 return raw_width;
513 }
514
has_ccd_sensor(pixma_t * s)515 static int has_ccd_sensor (pixma_t * s)
516 {
517 return ((s->cfg->cap & PIXMA_CAP_CCD) != 0);
518 }
519
520 #if 0
521 static int is_color (pixma_t * s)
522 {
523 return (s->param->mode == PIXMA_SCAN_MODE_COLOR);
524 }
525
526 static int is_color_48 (pixma_t * s)
527 {
528 return (s->param->mode == PIXMA_SCAN_MODE_COLOR_48);
529 }
530
531 static int is_color_negative (pixma_t * s)
532 {
533 return (s->param->mode == PIXMA_SCAN_MODE_NEGATIVE_COLOR);
534 }
535
536 static int is_color_all (pixma_t * s)
537 {
538 return (is_color (s) || is_color_48 (s) || is_color_negative (s));
539 }
540 #endif
541
is_gray(pixma_t * s)542 static int is_gray (pixma_t * s)
543 {
544 return (s->param->mode == PIXMA_SCAN_MODE_GRAY);
545 }
546
is_gray_16(pixma_t * s)547 static int is_gray_16 (pixma_t * s)
548 {
549 return (s->param->mode == PIXMA_SCAN_MODE_GRAY_16);
550 }
551
is_gray_negative(pixma_t * s)552 static int is_gray_negative (pixma_t * s)
553 {
554 return (s->param->mode == PIXMA_SCAN_MODE_NEGATIVE_GRAY);
555 }
556
is_gray_all(pixma_t * s)557 static int is_gray_all (pixma_t * s)
558 {
559 return (is_gray (s) || is_gray_16 (s) || is_gray_negative (s));
560 }
561
is_lineart(pixma_t * s)562 static int is_lineart (pixma_t * s)
563 {
564 return (s->param->mode == PIXMA_SCAN_MODE_LINEART);
565 }
566
is_tpuir(pixma_t * s)567 static int is_tpuir (pixma_t * s)
568 {
569 return (s->param->mode == PIXMA_SCAN_MODE_TPUIR);
570 }
571
572 /* CCD sensors don't have neither a Grayscale mode nor a Lineart mode,
573 * but use color mode instead */
get_cis_ccd_line_size(pixma_t * s)574 static unsigned get_cis_ccd_line_size (pixma_t * s)
575 {
576 return ((
577 s->param->wx ? s->param->line_size / s->param->w * s->param->wx
578 : s->param->line_size)
579 * ((is_tpuir (s) || is_gray_all (s) || is_lineart (s)) ? 3 : 1));
580 }
581
calc_shifting(pixma_t * s)582 static unsigned calc_shifting (pixma_t * s)
583 {
584 mp810_t *mp = (mp810_t *) s->subdriver;
585
586 /* If stripes shift needed (CCD devices), how many pixels shift */
587 mp->stripe_shift = 0;
588 mp->stripe_shift2 = 0;
589 mp->jumplines = 0;
590
591 switch (s->cfg->pid)
592 {
593 case MP800_PID:
594 case MP800R_PID:
595 case MP830_PID:
596 if (s->param->xdpi == 2400)
597 {
598 if (is_scanning_from_tpu(s))
599 mp->stripe_shift = 6;
600 else
601 mp->stripe_shift = 3;
602 }
603 if (s->param->ydpi > 75)
604 {
605 mp->color_shift = s->param->ydpi / ((s->param->ydpi < 1200) ? 150 : 75);
606
607 if (is_scanning_from_tpu (s))
608 mp->color_shift = s->param->ydpi / 75;
609
610 /* If you're trying to decipher this color-shifting code,
611 the following line is where the magic is revealed. */
612 mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s);
613 if (is_scanning_from_adf (s))
614 { /* ADF */
615 mp->shift[0] = 0;
616 mp->shift[2] = 2 * mp->shift[1];
617 }
618 else
619 { /* Flatbed or TPU */
620 mp->shift[0] = 2 * mp->shift[1];
621 mp->shift[2] = 0;
622 }
623 }
624 break;
625
626 case MP970_PID: /* MP970 at 4800 dpi */
627 case CS8800F_PID: /* CanoScan 8800F at 4800 dpi */
628 if (s->param->xdpi == 4800)
629 {
630 if (is_scanning_from_tpu (s))
631 mp->stripe_shift = 6;
632 else
633 mp->stripe_shift = 3;
634 }
635 break;
636
637 case CS9000F_PID: /* CanoScan 9000F at 4800 dpi */
638 case CS9000F_MII_PID:
639 if (s->param->xdpi == 4800)
640 {
641 if (is_scanning_from_tpu (s))
642 mp->stripe_shift = 6; /* should work for CS9000F same as manual */
643 else
644 mp->stripe_shift = 3;
645 }
646 if (s->param->xdpi == 9600)
647 {
648 if (is_scanning_from_tpu (s))
649 {
650 /* need to double up for TPU */
651 mp->stripe_shift = 6; /* for 1st set of 4 images */
652 /* unfortunately there are 2 stripe shifts */
653 mp->stripe_shift2 = 6; /* for 2nd set of 4 images */
654 mp->jumplines = 32; /* try 33 or 34 */
655 }
656 /* there is no 9600dpi support in flatbed mode */
657 }
658 break;
659
660 case MP960_PID:
661 if (s->param->xdpi == 2400)
662 {
663 if (is_scanning_from_tpu (s))
664 mp->stripe_shift = 6;
665 else
666 mp->stripe_shift = 3;
667 }
668 if (s->param->xdpi == 4800)
669 {
670 if (is_scanning_from_tpu (s))
671 {
672 mp->stripe_shift = 6;
673 mp->stripe_shift2 = 6;
674 }
675 else
676 {
677 mp->stripe_shift = 3;
678 mp->stripe_shift2 = 3;
679 }
680 mp->jumplines = 33; /* better than 32 or 34 : applies to flatbed & TPU */
681 }
682 break;
683
684 case MP810_PID:
685 if (s->param->xdpi == 2400)
686 {
687 if (is_scanning_from_tpu (s))
688 mp->stripe_shift = 6;
689 else
690 mp->stripe_shift = 3;
691 }
692 if (s->param->xdpi == 4800)
693 {
694 if (is_scanning_from_tpu (s))
695 {
696 mp->stripe_shift = 6;
697 mp->stripe_shift2 = 6;
698 }
699 else
700 {
701 mp->stripe_shift = 3;
702 mp->stripe_shift2 = 3;
703 }
704 mp->jumplines = 33; /* better than 32 or 34 : applies to flatbed & TPU */
705 }
706 break;
707
708 case MP990_PID:
709 if (s->param->xdpi == 4800)
710 {
711 if (is_scanning_from_tpu (s))
712 {
713 mp->stripe_shift = 6;
714 mp->stripe_shift2 = 6;
715 }
716 else
717 {
718 mp->stripe_shift = 3;
719 mp->stripe_shift2 = 3;
720 }
721 mp->jumplines = 34; /* better than 32 or 34 : applies to flatbed & TPU */
722 }
723 break;
724
725 default: /* Default, and all CIS devices */
726 break;
727 }
728 /* If color plane shift (CCD devices), how many pixels shift */
729 mp->color_shift = mp->shift[0] = mp->shift[1] = mp->shift[2] = 0;
730 if (s->param->ydpi > 75)
731 {
732 switch (s->cfg->pid)
733 {
734 case MP970_PID:
735 case CS8800F_PID: /* CanoScan 8800F */
736 mp->color_shift = s->param->ydpi / 50;
737 mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s);
738 mp->shift[0] = 0;
739 mp->shift[2] = 2 * mp->shift[1];
740 break;
741
742 case CS9000F_PID: /* CanoScan 9000F */
743 case CS9000F_MII_PID:
744 mp->color_shift = s->param->ydpi / 30;
745 mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s);
746 mp->shift[0] = 0;
747 mp->shift[2] = 2 * mp->shift[1];
748 break;
749
750 case MP980_PID:
751 case MP990_PID:
752 case MG8200_PID:
753 if (s->param->ydpi > 150)
754 {
755 mp->color_shift = s->param->ydpi / 75;
756 mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s);
757 mp->shift[0] = 0;
758 mp->shift[2] = 2 * mp->shift[1];
759 }
760 break;
761
762 case MP810_PID:
763 case MP960_PID:
764 mp->color_shift = s->param->ydpi / 50;
765 if (is_scanning_from_tpu (s))
766 mp->color_shift = s->param->ydpi / 50;
767 mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s);
768 mp->shift[0] = 2 * mp->shift[1];
769 mp->shift[2] = 0;
770 break;
771
772 default:
773 break;
774 }
775 }
776 /* special settings for 16 bit flatbed mode @ 75 dpi
777 * minimum of 150 dpi is used yet */
778 /* else if (!is_scanning_from_tpu (s))
779 {
780 switch (s->cfg->pid)
781 {
782 case CS9000F_PID:
783 case CS9000F_MII_PID:
784 if (is_color_48 (s) || is_gray_16 (s))
785 {
786 mp->color_shift = 5;
787 mp->shift[1] = 0;
788 mp->shift[0] = 0;
789 mp->shift[2] = 0;
790 }
791 break;
792 }
793 } */
794 /* PDBG (pixma_dbg (4, "*calc_shifing***** color_shift = %u, stripe_shift = %u, jumplines = %u *****\n",
795 mp->color_shift, mp->stripe_shift, mp->jumplines)); */
796 return (2 * mp->color_shift + mp->stripe_shift + mp->jumplines); /* note impact of stripe shift2 later if needed! */
797 }
798
send_scan_param(pixma_t * s)799 static int send_scan_param (pixma_t * s)
800 {
801 mp810_t *mp = (mp810_t *) s->subdriver;
802 uint8_t *data;
803 unsigned raw_width = calc_raw_width (mp, s->param);
804 unsigned h, h1, h2, shifting;
805
806 /* TPU scan does not support lineart */
807 if (is_scanning_from_tpu (s) && is_lineart (s))
808 {
809 return PIXMA_ENOTSUP;
810 }
811
812 shifting = calc_shifting (s);
813 h1 = s->param->h + shifting; /* add lines for color shifting */
814 /* PDBG (pixma_dbg (4, "* send_scan_param: height calc (choose lesser) 1 %u \n", h1 )); */
815 if (mp->generation >= 4) /* use most global condition */
816 {
817 /* tested for MP960, 9000F */
818 /* add lines for color shifting */
819 /* otherwise you cannot scan all lines defined for flatbed mode */
820 /* this shouldn't affect TPU mode */
821 h2 = s->cfg->height * s->param->ydpi / 75 + shifting;
822 /* PDBG (pixma_dbg (4, "* send_scan_param: height calc (choose lesser) 2 %u = %u max. lines for scanner + %u lines for color shifting \n", h2, s->cfg->height * s->param->ydpi / 75, shifting )); */
823 }
824 else
825 {
826 /* TODO: Check for other scanners. */
827 h2 = s->cfg->height * s->param->ydpi / 75; /* this might be causing problems for generation 1 devices */
828 /* PDBG (pixma_dbg (4, "* send_scan_param: height calc (choose lesser) 2 %u \n", h2 )); */
829 }
830 h = MIN (h1, h2);
831
832 if (mp->generation <= 2)
833 {
834 data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
835 pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04);
836 pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x06);
837 pixma_set_be32 (s->param->x, data + 0x08);
838 if (mp->generation == 2)
839 pixma_set_be32 (s->param->x - s->param->xs, data + 0x08);
840 pixma_set_be32 (s->param->y, data + 0x0c);
841 pixma_set_be32 (raw_width, data + 0x10);
842 pixma_set_be32 (h, data + 0x14);
843 data[0x18] =
844 ((s->param->channels != 1) || is_gray_all (s) || is_lineart (s)) ?
845 0x08 : 0x04;
846 data[0x19] = ((s->param->software_lineart) ? 8 : s->param->depth)
847 * ((is_gray_all (s) || is_lineart (s)) ? 3 : s->param->channels); /* bits per pixel */
848 data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0);
849 data[0x20] = 0xff;
850 data[0x23] = 0x81;
851 data[0x26] = 0x02;
852 data[0x27] = 0x01;
853 }
854 else
855 {
856 /* scan parameters:
857 * ================
858 *
859 * byte | # of | mode | value / description
860 * | bytes | |
861 * -----+-------+---------+---------------------------
862 * 0x00 | 1 | default | 0x01
863 * | | adf | 0x02
864 * | | tpu | 0x04
865 * | | tpuir | cs9000f: 0x03
866 * -----+-------+---------+---------------------------
867 * 0x01 | 1 | default | 0x00
868 * | | tpu | 0x02
869 * -----+-------+---------+---------------------------
870 * 0x02 | 1 | default | 0x01
871 * | | adfdup | 0x03
872 * -----+-------+---------+---------------------------
873 * 0x03 | 1 | default | 0x00
874 * | | adfdup | 0x03
875 * -----+-------+---------+---------------------------
876 * 0x04 | 1 | all | 0x00
877 * -----+-------+---------+---------------------------
878 * 0x05 | 1 | all | 0x01: This one also seen at 0. Don't know yet what's used for.
879 * -----+-------+---------+---------------------------
880 * ... | 1 | all | 0x00
881 * -----+-------+---------+---------------------------
882 * 0x08 | 2 | all | xdpi | 0x8000
883 * -----+-------+---------+---------------------------
884 * 0x0a | 2 | all | ydpi | 0x8000: Must be the same as xdpi.
885 * -----+-------+---------+---------------------------
886 * 0x0c | 4 | all | x position of start pixel
887 * -----+-------+---------+---------------------------
888 * 0x10 | 4 | all | y position of start pixel
889 * -----+-------+---------+---------------------------
890 * 0x14 | 4 | all | # of pixels in 1 line
891 * -----+-------+---------+---------------------------
892 * 0x18 | 4 | all | # of scan lines
893 * -----+-------+---------+---------------------------
894 * 0x1c | 1 | all | 0x08
895 * | | | 0x04 = relict from cis scanners?
896 * -----+-------+---------+---------------------------
897 * 0x1d | 1 | all | # of bits per pixel
898 * -----+-------+---------+---------------------------
899 * 0x1e | 1 | default | 0x00: paper
900 * | | tpu | 0x01: positives
901 * | | tpu | 0x02: negatives
902 * | | tpuir | 0x01: positives
903 * -----+-------+---------+---------------------------
904 * 0x1f | 1 | all | 0x01
905 * | | | cs9000f: 0x00: Not sure if that is because of positives.
906 * -----+-------+---------+---------------------------
907 * 0x20 | 1 | all | 0xff
908 * -----+-------+---------+---------------------------
909 * 0x21 | 1 | all | 0x81
910 * -----+-------+---------+---------------------------
911 * 0x22 | 1 | all | 0x00
912 * -----+-------+---------+---------------------------
913 * 0x23 | 1 | all | 0x02
914 * -----+-------+---------+---------------------------
915 * 0x24 | 1 | all | 0x01
916 * -----+-------+---------+---------------------------
917 * 0x25 | 1 | default | 0x00; cs8800f: 0x01
918 * | | tpu | 0x00; cs9000f, mg8200, mp990: 0x01
919 * | | tpuir | cs9000f: 0x00
920 * -----+-------+---------+---------------------------
921 * ... | 1 | all | 0x00
922 * -----+-------+---------+---------------------------
923 * 0x30 | 1 | all | 0x01
924 *
925 */
926
927 data = pixma_newcmd (&mp->cb, cmd_scan_param_3, 0x38, 0);
928 data[0x00] = is_scanning_from_adf (s) ? 0x02 : 0x01;
929 data[0x01] = 0x01;
930 if (is_scanning_from_tpu (s))
931 {
932 data[0x00] = is_tpuir (s) ? 0x03 : 0x04;
933 data[0x01] = 0x02;
934 data[0x1e] = 0x02; /* NB: CanoScan 8800F: 0x02->negatives, 0x01->positives, paper->0x00 */
935 }
936 data[0x02] = 0x01;
937 if (is_scanning_from_adfdup (s))
938 {
939 data[0x02] = 0x03;
940 data[0x03] = 0x03;
941 }
942 data[0x05] = pixma_calc_calibrate (s);
943 /* the scanner controls the scan */
944 /* no software control needed */
945 pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x08);
946 pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x0a);
947 /*PDBG (pixma_dbg (4, "*send_scan_param***** Setting: xdpi=%hi ydpi=%hi x=%u y=%u w=%u h=%u ***** \n",
948 s->param->xdpi,s->param->ydpi,(s->param->x)-(s->param->xs),s->param->y,raw_width,h));*/
949 pixma_set_be32 (s->param->x - s->param->xs, data + 0x0c);
950 pixma_set_be32 (s->param->y, data + 0x10);
951 pixma_set_be32 (raw_width, data + 0x14);
952 pixma_set_be32 (h, data + 0x18);
953 data[0x1c] = ((s->param->channels != 1) || is_tpuir (s) || is_gray_all (s) || is_lineart (s)) ? 0x08 : 0x04;
954
955 #ifdef DEBUG_TPU_48
956 data[0x1d] = 24;
957 #else
958 data[0x1d] = (is_scanning_from_tpu (s)) ? 48
959 : (((s->param->software_lineart) ? 8 : s->param->depth)
960 * ((is_tpuir (s) || is_gray_all (s) || is_lineart (s)) ? 3 : s->param->channels)); /* bits per pixel */
961 #endif
962
963 data[0x1f] = 0x01; /* for 9000F this appears to be 0x00, not sure if that is because of positives */
964
965 if (s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID || s->cfg->pid == MG8200_PID)
966 {
967 data[0x1f] = 0x00;
968 }
969
970 data[0x20] = 0xff;
971 data[0x21] = 0x81;
972 data[0x23] = 0x02;
973 data[0x24] = 0x01;
974
975 /* MG8200 & MP990 addition */
976 if (s->cfg->pid == MG8200_PID || s->cfg->pid == MP990_PID)
977 {
978 if (is_scanning_from_tpu (s))
979 {
980 data[0x25] = 0x01;
981 }
982 }
983
984 /* CS8800F & CS9000F addition */
985 if (s->cfg->pid == CS8800F_PID || s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID)
986 {
987 if (is_scanning_from_tpu (s))
988 { /* TPU */
989 /* 0x02->negatives, 0x01->positives, paper->0x00
990 * no paper in TPU mode */
991 if (s->param->mode == PIXMA_SCAN_MODE_NEGATIVE_COLOR
992 || s->param->mode == PIXMA_SCAN_MODE_NEGATIVE_GRAY)
993 {
994 PDBG(
995 pixma_dbg (4, "*send_scan_param***** TPU scan negatives *****\n"));
996 data[0x1e] = 0x02;
997 }
998 else
999 {
1000 PDBG(
1001 pixma_dbg (4, "*send_scan_param***** TPU scan positives *****\n"));
1002 data[0x1e] = 0x01;
1003 }
1004 /* CS8800F: 0x00 for TPU color management */
1005 if (s->cfg->pid == CS8800F_PID)
1006 data[0x25] = 0x00;
1007 /* CS9000F: 0x01 for TPU */
1008 if (s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID)
1009 data[0x25] = 0x01;
1010 if (s->param->mode == PIXMA_SCAN_MODE_TPUIR)
1011 data[0x25] = 0x00;
1012 }
1013 else
1014 { /* flatbed and ADF */
1015 /* paper->0x00 */
1016 data[0x1e] = 0x00;
1017 /* CS8800F: 0x01 normally */
1018 if (s->cfg->pid == CS8800F_PID)
1019 data[0x25] = 0x01;
1020 /* CS9000F: 0x00 normally */
1021 if (s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID)
1022 data[0x25] = 0x00;
1023 }
1024 }
1025
1026 data[0x30] = 0x01;
1027 }
1028 return pixma_exec (s, &mp->cb);
1029 }
1030
query_status_3(pixma_t * s)1031 static int query_status_3 (pixma_t * s)
1032 {
1033 mp810_t *mp = (mp810_t *) s->subdriver;
1034 uint8_t *data;
1035 int error, status_len;
1036
1037 status_len = 8;
1038 data = pixma_newcmd (&mp->cb, cmd_status_3, 0, status_len);
1039 RET_IF_ERR(pixma_exec (s, &mp->cb));
1040 memcpy (mp->current_status, data, status_len);
1041 return error;
1042 }
1043
query_status(pixma_t * s)1044 static int query_status (pixma_t * s)
1045 {
1046 mp810_t *mp = (mp810_t *) s->subdriver;
1047 uint8_t *data;
1048 int error, status_len;
1049
1050 status_len = (mp->generation == 1) ? 12 : 16;
1051 data = pixma_newcmd (&mp->cb, cmd_status, 0, status_len);
1052 RET_IF_ERR(pixma_exec (s, &mp->cb));
1053 memcpy (mp->current_status, data, status_len);
1054 PDBG(
1055 pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u busy=%u\n", data[1], data[8], data[7], data[9]));
1056 return error;
1057 }
1058
1059 #if 0
1060 static int send_time (pixma_t * s)
1061 {
1062 /* Why does a scanner need a time? */
1063 time_t now;
1064 struct tm *t;
1065 uint8_t *data;
1066 mp810_t *mp = (mp810_t *) s->subdriver;
1067
1068 data = pixma_newcmd (&mp->cb, cmd_time, 20, 0);
1069 pixma_get_time (&now, NULL);
1070 t = localtime (&now);
1071 strftime ((char *) data, 16, "%y/%m/%d %H:%M", t);
1072 PDBG(pixma_dbg (3, "Sending time: '%s'\n", (char *) data));
1073 return pixma_exec (s, &mp->cb);
1074 }
1075 #endif
1076
1077 /* TODO: Simplify this function. Read the whole data packet in one shot. */
read_image_block(pixma_t * s, uint8_t * header, uint8_t * data)1078 static int read_image_block (pixma_t * s, uint8_t * header, uint8_t * data)
1079 {
1080 uint8_t cmd[16];
1081 mp810_t *mp = (mp810_t *) s->subdriver;
1082 const int hlen = 8 + 8;
1083 int error, datalen;
1084
1085 memset (cmd, 0, sizeof(cmd));
1086 /* PDBG (pixma_dbg (4, "* read_image_block: last_block\n", mp->last_block)); */
1087 pixma_set_be16 (cmd_read_image, cmd);
1088 if ((mp->last_block & 0x20) == 0)
1089 pixma_set_be32 ((IMAGE_BLOCK_SIZE / 65536) * 65536 + 8, cmd + 0xc);
1090 else
1091 pixma_set_be32 (32 + 8, cmd + 0xc);
1092
1093 mp->state = state_transfering;
1094 mp->cb.reslen = pixma_cmd_transaction (s, cmd, sizeof(cmd), mp->cb.buf, 512); /* read 1st 512 bytes of image block */
1095 datalen = mp->cb.reslen;
1096 if (datalen < 0)
1097 return datalen;
1098
1099 memcpy (header, mp->cb.buf, hlen);
1100 /* PDBG (pixma_dbg (4, "* read_image_block: datalen %i\n", datalen)); */
1101 /* PDBG (pixma_dbg (4, "* read_image_block: hlen %i\n", hlen)); */
1102 if (datalen >= hlen)
1103 {
1104 datalen -= hlen;
1105 memcpy (data, mp->cb.buf + hlen, datalen);
1106 data += datalen;
1107 if (mp->cb.reslen == 512)
1108 { /* read the rest of the image block */
1109 error = pixma_read (s->io, data, IMAGE_BLOCK_SIZE - 512 + hlen);
1110 RET_IF_ERR(error);
1111 datalen += error;
1112 }
1113 }
1114
1115 mp->state = state_scanning;
1116 mp->cb.expected_reslen = 0;
1117 RET_IF_ERR(pixma_check_result (&mp->cb));
1118 if (mp->cb.reslen < hlen)
1119 return PIXMA_EPROTO;
1120 return datalen;
1121 }
1122
read_error_info(pixma_t * s, void *buf, unsigned size)1123 static int read_error_info (pixma_t * s, void *buf, unsigned size)
1124 {
1125 unsigned len = 16;
1126 mp810_t *mp = (mp810_t *) s->subdriver;
1127 uint8_t *data;
1128 int error;
1129
1130 data = pixma_newcmd (&mp->cb, cmd_error_info, 0, len);
1131 RET_IF_ERR(pixma_exec (s, &mp->cb));
1132 if (buf && len < size)
1133 {
1134 size = len;
1135 /* NOTE: I've absolutely no idea what the returned data mean. */
1136 memcpy (buf, data, size);
1137 error = len;
1138 }
1139 return error;
1140 }
1141
1142 /*
1143 handle_interrupt() waits until it receives an interrupt packet or times out.
1144 It calls send_time() and query_status() if necessary. Therefore, make sure
1145 that handle_interrupt() is only called from a safe context for send_time()
1146 and query_status().
1147
1148 Returns:
1149 0 timed out
1150 1 an interrupt packet received
1151 PIXMA_ECANCELED interrupted by signal
1152 <0 error
1153 */
handle_interrupt(pixma_t * s, int timeout)1154 static int handle_interrupt (pixma_t * s, int timeout)
1155 {
1156 uint8_t buf[64]; /* check max. packet size with 'lsusb -v' for "EP 9 IN" */
1157 int len;
1158
1159 len = pixma_wait_interrupt (s->io, buf, sizeof(buf), timeout);
1160 if (len == PIXMA_ETIMEDOUT)
1161 return 0;
1162 if (len < 0)
1163 return len;
1164 if (len%16) /* len must be a multiple of 16 bytes */
1165 {
1166 PDBG(pixma_dbg (1, "WARNING:unexpected interrupt packet length %d\n", len));
1167 return PIXMA_EPROTO;
1168 }
1169
1170 /* s->event = 0x0brroott
1171 * b: button
1172 * oo: original
1173 * tt: target
1174 * rr: scan resolution
1175 * poll event with 'scanimage -A' */
1176 if (s->cfg->pid == MG8200_PID)
1177 /* button no. in buf[7]
1178 * size in buf[10] 01=A4; 02=Letter; 08=10x15; 09=13x18; 0b=auto
1179 * format in buf[11] 01=JPEG; 02=TIFF; 03=PDF; 04=Kompakt-PDF
1180 * dpi in buf[12] 01=75; 02=150; 03=300; 04=600
1181 * target = format; original = size; scan-resolution = dpi */
1182 {
1183 if (buf[7] & 1)
1184 {
1185 /* color scan */
1186 s->events = PIXMA_EV_BUTTON1 | (buf[11] & 0x0f) | (buf[10] & 0x0f) << 8
1187 | (buf[12] & 0x0f) << 16;
1188 }
1189 if (buf[7] & 2)
1190 {
1191 /* b/w scan */
1192 s->events = PIXMA_EV_BUTTON2 | (buf[11] & 0x0f) | (buf[10] & 0x0f) << 8
1193 | (buf[12] & 0x0f) << 16;
1194 }
1195 }
1196 else if (s->cfg->pid == CS8800F_PID
1197 || s->cfg->pid == CS9000F_PID
1198 || s->cfg->pid == CS9000F_MII_PID)
1199 /* button no. in buf[1]
1200 * target = button no.
1201 * "Finish PDF" is Button-2, all others are Button-1 */
1202 {
1203 if ((s->cfg->pid == CS8800F_PID && buf[1] == 0x70)
1204 || (s->cfg->pid != CS8800F_PID && buf[1] == 0x50))
1205 {
1206 /* button 2 = cancel / end scan */
1207 s->events = PIXMA_EV_BUTTON2 | buf[1] >> 4;
1208 }
1209 else
1210 {
1211 /* button 1 = start scan */
1212 s->events = PIXMA_EV_BUTTON1 | buf[1] >> 4;
1213 }
1214 }
1215 else
1216 /* button no. in buf[0]
1217 * original in buf[0]
1218 * target in buf[1] */
1219 {
1220 /* More than one event can be reported at the same time. */
1221 if (buf[3] & 1)
1222 /* FIXME: This function makes trouble with a lot of scanners
1223 send_time (s);
1224 */
1225 PDBG (pixma_dbg (1, "WARNING:send_time() disabled!\n"));
1226 if (buf[9] & 2)
1227 query_status (s);
1228
1229 if (buf[0] & 2)
1230 {
1231 /* b/w scan */
1232 s->events = PIXMA_EV_BUTTON2 | (buf[1] & 0x0f) | (buf[0] & 0xf0) << 4;
1233 }
1234 if (buf[0] & 1)
1235 {
1236 /* color scan */
1237 s->events = PIXMA_EV_BUTTON1 | (buf[1] & 0x0f) | (buf[0] & 0xf0) << 4;
1238 }
1239 }
1240 return 1;
1241 }
1242
init_ccd_lamp_3(pixma_t * s)1243 static int init_ccd_lamp_3 (pixma_t * s)
1244 {
1245 mp810_t *mp = (mp810_t *) s->subdriver;
1246 uint8_t *data;
1247 int error, status_len, tmo;
1248
1249 status_len = 8;
1250 RET_IF_ERR(query_status (s));
1251 RET_IF_ERR(query_status (s));
1252 RET_IF_ERR(send_cmd_start_calibrate_ccd_3 (s));
1253 RET_IF_ERR(query_status (s));
1254 tmo = 20; /* like Windows driver, CCD lamp adjustment */
1255 while (--tmo >= 0)
1256 {
1257 data = pixma_newcmd (&mp->cb, cmd_end_calibrate_ccd_3, 0, status_len);
1258 RET_IF_ERR(pixma_exec (s, &mp->cb));
1259 memcpy (mp->current_status, data, status_len);
1260 PDBG(pixma_dbg (3, "Lamp status: %u , timeout in: %u\n", data[0], tmo));
1261 if (mp->current_status[0] == 3 || !is_scanning_from_tpu (s))
1262 break;
1263 WAIT_INTERRUPT(1000);
1264 }
1265 return error;
1266 }
1267
wait_until_ready(pixma_t * s)1268 static int wait_until_ready (pixma_t * s)
1269 {
1270 mp810_t *mp = (mp810_t *) s->subdriver;
1271 int error, tmo = 60;
1272
1273 RET_IF_ERR((mp->generation >= 3) ? query_status_3 (s) : query_status (s));
1274 while (!is_calibrated (s))
1275 {
1276 WAIT_INTERRUPT(1000);
1277 if (mp->generation >= 3)
1278 RET_IF_ERR(query_status_3 (s));
1279 else if (s->cfg->pid == MP800R_PID)
1280 RET_IF_ERR (query_status (s));
1281 if (--tmo == 0)
1282 {
1283 PDBG(pixma_dbg (1, "WARNING: Timed out in wait_until_ready()\n"));
1284 PDBG(query_status (s));
1285 return PIXMA_ETIMEDOUT;
1286 }
1287 }
1288 return 0;
1289 }
1290
1291 /* the RGB images are shifted by # of lines */
1292 /* the R image is shifted by colshift[0] */
1293 /* the G image is shifted by colshift[1] */
1294 /* the B image is shifted by colshift[2] */
1295 /* usually one of the RGB images must not be shifted */
1296 /* which one depends on the scanner */
1297 /* some scanners have an additional stripe shift */
1298 /* e.g. colshift[0]=0, colshift[1]=1, colshift[2]=2 */
1299 /* R image is OK: RGBRGBRGB... */
1300 /* ^^ ^^ ^^ */
1301 /* || || || */
1302 /* shift G image: RG|RG|RG|... */
1303 /* | | | */
1304 /* shift B image: RGBRGBRGB... */
1305 /* this doesn't affect the G and B images */
1306 /* G image will become the R image in the next run */
1307 /* B image will become the G image in the next run */
1308 /* the next line will become the B image in the next run */
1309 static uint8_t *
shift_colors(uint8_t * dptr, uint8_t * sptr, unsigned w, unsigned dpi, unsigned pid, unsigned c, int * colshft, unsigned strshft)1310 shift_colors (uint8_t * dptr, uint8_t * sptr, unsigned w, unsigned dpi,
1311 unsigned pid, unsigned c, int * colshft, unsigned strshft)
1312 {
1313 unsigned i, sr, sg, sb, st;
1314 UNUSED(dpi);
1315 UNUSED(pid);
1316 sr = colshft[0];
1317 sg = colshft[1];
1318 sb = colshft[2];
1319
1320 /* PDBG (pixma_dbg (4, "*shift_colors***** c=%u, w=%i, sr=%u, sg=%u, sb=%u, strshft=%u ***** \n",
1321 c, w, sr, sg, sb, strshft)); */
1322
1323 for (i = 0; i < w; i++)
1324 {
1325 /* stripes shift for MP970 at 4800 dpi, MP810 at 2400 dpi */
1326 st = (i % 2 == 0) ? strshft : 0;
1327
1328 *sptr++ = *(dptr++ + sr + st);
1329 if (c == 6)
1330 *sptr++ = *(dptr++ + sr + st);
1331 *sptr++ = *(dptr++ + sg + st);
1332 if (c == 6)
1333 *sptr++ = *(dptr++ + sg + st);
1334 *sptr++ = *(dptr++ + sb + st);
1335 if (c == 6)
1336 *sptr++ = *(dptr++ + sb + st);
1337 }
1338
1339 return dptr;
1340 }
1341
1342 static uint8_t *
shift_colorsCS9000(uint8_t * dptr, uint8_t * sptr, unsigned w, unsigned dpi, unsigned pid, unsigned c, int * colshft, unsigned strshft, unsigned strshft2, unsigned jump)1343 shift_colorsCS9000 (uint8_t * dptr, uint8_t * sptr, unsigned w, unsigned dpi,
1344 unsigned pid, unsigned c, int * colshft, unsigned strshft,
1345 unsigned strshft2, unsigned jump)
1346
1347 {
1348 unsigned i, sr, sg, sb, st, st2;
1349 UNUSED(dpi);
1350 UNUSED(pid);
1351 sr = colshft[0];
1352 sg = colshft[1];
1353 sb = colshft[2];
1354
1355 for (i = 0; i < w; i++)
1356 {
1357 if (i < (w / 2))
1358 {
1359 /* stripes shift for 1st 4 images for Canoscan 9000F at 9600dpi */
1360 st = (i % 2 == 0) ? strshft : 0;
1361 *sptr++ = *(dptr++ + sr + st);
1362 if (c == 6)
1363 *sptr++ = *(dptr++ + sr + st);
1364 *sptr++ = *(dptr++ + sg + st);
1365 if (c == 6)
1366 *sptr++ = *(dptr++ + sg + st);
1367 *sptr++ = *(dptr++ + sb + st);
1368 if (c == 6)
1369 *sptr++ = *(dptr++ + sb + st);
1370 }
1371 if (i >= (w / 2))
1372 {
1373 /* stripes shift for 2nd 4 images for Canoscan 9000F at 9600dpi */
1374 st2 = (i % 2 == 0) ? strshft2 : 0;
1375 *sptr++ = *(dptr++ + sr + jump + st2);
1376 if (c == 6)
1377 *sptr++ = *(dptr++ + sr + jump + st2);
1378 *sptr++ = *(dptr++ + sg + jump + st2);
1379 if (c == 6)
1380 *sptr++ = *(dptr++ + sg + jump + st2);
1381 *sptr++ = *(dptr++ + sb + jump + st2);
1382 if (c == 6)
1383 *sptr++ = *(dptr++ + sb + jump + st2);
1384 }
1385 }
1386 return dptr;
1387 }
1388
1389 static uint8_t *
shift_colorsCS9000_4800(uint8_t * dptr, uint8_t * sptr, unsigned w, unsigned dpi, unsigned pid, unsigned c, int * colshft, unsigned strshft, unsigned strshft2, unsigned jump)1390 shift_colorsCS9000_4800 (uint8_t * dptr, uint8_t * sptr, unsigned w,
1391 unsigned dpi, unsigned pid, unsigned c, int * colshft,
1392 unsigned strshft, unsigned strshft2, unsigned jump)
1393
1394 {
1395 unsigned i, sr, sg, sb, st2;
1396 UNUSED(dpi);
1397 UNUSED(pid);
1398 UNUSED(strshft);
1399 sr = colshft[0];
1400 sg = colshft[1];
1401 sb = colshft[2];
1402
1403 for (i = 0; i < w; i++)
1404 {
1405 /* stripes shift for 2nd 4 images
1406 * for Canoscan 9000F with 16 bit flatbed scans at 4800dpi */
1407 st2 = (i % 2 == 0) ? strshft2 : 0;
1408 *sptr++ = *(dptr++ + sr + jump + st2);
1409 if (c == 6)
1410 *sptr++ = *(dptr++ + sr + jump + st2);
1411 *sptr++ = *(dptr++ + sg + jump + st2);
1412 if (c == 6)
1413 *sptr++ = *(dptr++ + sg + jump + st2);
1414 *sptr++ = *(dptr++ + sb + jump + st2);
1415 if (c == 6)
1416 *sptr++ = *(dptr++ + sb + jump + st2);
1417 }
1418 return dptr;
1419 }
1420
1421 /* under some conditions some scanners have sub images in one line */
1422 /* e.g. doubled image, line size = 8 */
1423 /* line before reordering: px1 px3 px5 px7 px2 px4 px6 px8 */
1424 /* line after reordering: px1 px2 px3 px4 px5 px6 px7 px8 */
reorder_pixels(uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n, unsigned m, unsigned w, unsigned line_size)1425 static void reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c,
1426 unsigned n, unsigned m, unsigned w,
1427 unsigned line_size)
1428 {
1429 unsigned i;
1430
1431 for (i = 0; i < w; i++)
1432 { /* process complete line */
1433 memcpy (linebuf + c * (n * (i % m) + i / m), sptr + c * i, c);
1434 }
1435 memcpy (sptr, linebuf, line_size);
1436 }
1437
1438 /* special reorder matrix for mp960 */
mp960_reorder_pixels(uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n, unsigned m, unsigned w, unsigned line_size)1439 static void mp960_reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c,
1440 unsigned n, unsigned m, unsigned w,
1441 unsigned line_size)
1442 {
1443 unsigned i, i2;
1444
1445 /* try and copy 2 px at once */
1446 for (i = 0; i < w; i++)
1447 { /* process complete line */
1448 i2 = i % 2;
1449 if (i < w / 2)
1450 {
1451 if (i2 == 0)
1452 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m)), sptr + c * i, c);
1453 else
1454 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m)), sptr + c * i, c);
1455 }
1456 else
1457 {
1458 if (i2 == 0)
1459 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 1), sptr + c * i, c);
1460 else
1461 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 1), sptr + c * i, c);
1462 }
1463 }
1464
1465 memcpy (sptr, linebuf, line_size);
1466 }
1467
1468 /* special reorder matrix for mp970 */
mp970_reorder_pixels(uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned w, unsigned line_size)1469 static void mp970_reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c,
1470 unsigned w, unsigned line_size)
1471 {
1472 unsigned i, i8;
1473
1474 for (i = 0; i < w; i++)
1475 { /* process complete line */
1476 i8 = i % 8;
1477 memcpy (linebuf + c * (i + i8 - ((i8 > 3) ? 7 : 0)), sptr + c * i, c);
1478 }
1479 memcpy (sptr, linebuf, line_size);
1480 }
1481
1482 /* special reorder matrix for CS9000F */
cs9000f_initial_reorder_pixels(uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n, unsigned m, unsigned w, unsigned line_size)1483 static void cs9000f_initial_reorder_pixels (uint8_t * linebuf, uint8_t * sptr,
1484 unsigned c, unsigned n, unsigned m,
1485 unsigned w, unsigned line_size)
1486 {
1487 unsigned i, i2;
1488
1489 /* try and copy 2 px at once */
1490 for (i = 0; i < w; i++)
1491 { /* process complete line */
1492 i2 = i % 2;
1493 if (i < w / 8)
1494 {
1495 if (i2 == 0)
1496 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m)), sptr + c * i, c);
1497 else
1498 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m)), sptr + c * i, c);
1499 }
1500 else if (i >= w / 8 && i < w / 4)
1501 {
1502 if (i2 == 0)
1503 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 1), sptr + c * i, c);
1504 else
1505 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 1), sptr + c * i, c);
1506 }
1507 else if (i >= w / 4 && i < 3 * w / 8)
1508 {
1509 if (i2 == 0)
1510 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 2), sptr + c * i, c);
1511 else
1512 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 2), sptr + c * i, c);
1513 }
1514 else if (i >= 3 * w / 8 && i < w / 2)
1515 {
1516 if (i2 == 0)
1517 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 3), sptr + c * i, c);
1518 else
1519 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 3), sptr + c * i, c);
1520 }
1521 else if (i >= w / 2 && i < 5 * w / 8)
1522 {
1523 if (i2 == 0)
1524 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 4), sptr + c * i, c);
1525 else
1526 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 4), sptr + c * i, c);
1527 }
1528 else if (i >= 5 * w / 8 && i < 3 * w / 4)
1529 {
1530 if (i2 == 0)
1531 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 5), sptr + c * i, c);
1532 else
1533 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 5), sptr + c * i, c);
1534 }
1535 else if (i >= 3 * w / 4 && i < 7 * w / 8)
1536 {
1537 if (i2 == 0)
1538 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 6), sptr + c * i, c);
1539 else
1540 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 6), sptr + c * i, c);
1541 }
1542 else
1543 {
1544 if (i2 == 0)
1545 memcpy (linebuf + c * (n * ((i) % m) + ((i) / m) + 7), sptr + c * i, c);
1546 else
1547 memcpy (linebuf + c * (n * ((i - 1) % m) + 1 + ((i) / m) + 7), sptr + c * i, c);
1548 }
1549 }
1550
1551 memcpy (sptr, linebuf, line_size);
1552 }
1553
1554 /* CS9000F 9600dpi reorder: actually 4800dpi since each pixel is doubled */
1555 /* need to rearrange each sequence of 16 pairs of pixels as follows: */
1556 /* start px : 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 */
1557 /* before : p1a p1b p1c p1d p2a p2b p2c p2d p3a p3b p3c p3d p4a p4b p4c p4d */
1558 /* after : p1a p3a p1b p3b p1c p3c p1d p3d p2a p4a p2b p4b p2c p4c p2d p4d */
1559 /* start px : 0 16 2 18 4 20 6 22 8 24 10 26 12 28 14 30 */
1560 /* change : * * * * * * * * * * * * * * */
1561 /* no change: * * */
1562 /* so the 1st and the 3rd set are interleaved, followed by the 2nd and 4th sets interleaved */
cs9000f_second_reorder_pixels(uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned w, unsigned line_size)1563 static void cs9000f_second_reorder_pixels (uint8_t * linebuf, uint8_t * sptr,
1564 unsigned c, unsigned w,
1565 unsigned line_size)
1566 {
1567 unsigned i, i8;
1568 static const int shifts[8] =
1569 { 2, 4, 6, 8, -8, -6, -4, -2 };
1570
1571 for (i = 0; i < w; i += 2)
1572 { /* process complete line */
1573 i8 = (i >> 1) & 0x7;
1574 /* Copy 2 pixels at once */
1575 memcpy (linebuf + c * (i + shifts[i8]), sptr + c * i, c * 2);
1576 }
1577
1578 memcpy (sptr, linebuf, line_size);
1579 }
1580
1581 #ifndef TPU_48
1582 static unsigned
pack_48_24_bpc(uint8_t * sptr, unsigned n)1583 pack_48_24_bpc (uint8_t * sptr, unsigned n)
1584 {
1585 unsigned i;
1586 uint8_t *cptr, lsb;
1587 static uint8_t offset = 0;
1588
1589 cptr = sptr;
1590 if (n % 2 != 0)
1591 PDBG (pixma_dbg (3, "WARNING: misaligned image.\n"));
1592 for (i = 0; i < n; i += 2)
1593 {
1594 /* offset = 1 + (offset % 3); */
1595 lsb = *sptr++;
1596 *cptr++ = ((*sptr++) << offset) | lsb >> (8 - offset);
1597 }
1598 return (n / 2);
1599 }
1600 #endif
1601
1602 /* This function deals both with PIXMA CCD sensors producing shifted color
1603 * planes images, Grayscale CCD scan and Generation >= 3 high dpi images.
1604 * Each complete line in mp->imgbuf is processed for shifting CCD sensor
1605 * color planes, reordering pixels above 600 dpi for Generation >= 3, and
1606 * converting to Grayscale for CCD sensors. */
post_process_image_data(pixma_t * s, pixma_imagebuf_t * ib)1607 static unsigned post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib)
1608 {
1609 mp810_t *mp = (mp810_t *) s->subdriver;
1610 unsigned c, lines, line_size, n, m, cw, cx, reducelines;
1611 uint8_t *sptr, *dptr, *gptr, *cptr;
1612 unsigned /*color_shift, stripe_shift, stripe_shift2,*/ jumplines /*, height*/;
1613 int test;
1614
1615 /* For testers: */
1616 /* set this to 1 in order to get unprocessed images next to one another at 9600dpi */
1617 /* other resolutions should not be affected */
1618 /* set this to 2 if you want to see the same with jumplines=0 */
1619 test = 0;
1620 jumplines = 0;
1621
1622 c = ((is_tpuir (s) || is_gray_all (s) || is_lineart (s)) ? 3 : s->param->channels)
1623 * ((s->param->software_lineart) ? 8 : s->param->depth) / 8;
1624 cw = c * s->param->w;
1625 cx = c * s->param->xs;
1626
1627 /* PDBG (pixma_dbg (4, "*post_process_image_data***** c = %u, cw = %u, cx = %u *****\n", c, cw, cx)); */
1628
1629 if (mp->generation >= 3)
1630 n = s->param->xdpi / 600;
1631 else
1632 /* FIXME: maybe need different values for CIS and CCD sensors */
1633 n = s->param->xdpi / 2400;
1634
1635 /* Some exceptions to global rules here */
1636 if (s->cfg->pid == MP970_PID || s->cfg->pid == MP990_PID || s->cfg->pid == MG8200_PID
1637 || s->cfg->pid == CS8800F_PID || s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID)
1638 n = MIN (n, 4);
1639
1640 /* exception for 9600dpi on Canoscan 9000F */
1641 if ((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) && (s->param->xdpi == 9600))
1642 {
1643 n = 8;
1644 if (test > 0)
1645 n = 1; /* test if 8 images are next to one another */
1646 }
1647
1648 /* test if 2 images are next to one another */
1649 if ((s->cfg->pid == MP960_PID) && (s->param->xdpi == 4800) && (test > 0))
1650 {
1651 n = 1;
1652 }
1653
1654 m = (n > 0) ? s->param->wx / n : 1;
1655
1656 sptr = dptr = gptr = cptr = mp->imgbuf;
1657 line_size = get_cis_ccd_line_size (s);
1658 /* PDBG (pixma_dbg (4, "*post_process_image_data***** ----- Set n=%u, m=%u, line_size=%u ----- ***** \n", n, m, line_size)); */
1659 /* PDBG (pixma_dbg (4, "*post_process_image_data***** ----- spr=dpr=%u, linebuf=%u ----- ***** \n", sptr, mp->linebuf)); */
1660
1661 lines = (mp->data_left_ofs - mp->imgbuf) / line_size;
1662 /* PDBG (pixma_dbg (4, "*post_process_image_data***** lines = %i > 2 * mp->color_shift + mp->stripe_shift = %i ***** \n",
1663 lines, 2 * mp->color_shift + mp->stripe_shift)); */
1664 /* PDBG (pixma_dbg (4, "*post_process_image_data***** mp->color_shift = %u, mp->stripe_shift = %u, , mp->stripe_shift2 = %u ***** \n",
1665 mp->color_shift, mp->stripe_shift, mp->stripe_shift2)); */
1666
1667 /*color_shift = mp->color_shift;*/
1668 /*stripe_shift = mp->stripe_shift;*/
1669 /*stripe_shift2 = mp->stripe_shift2;*/
1670 jumplines = mp->jumplines;
1671
1672 /* height not needed here! */
1673 /* removed to avoid confusion */
1674 /* height = MIN (s->param->h + calc_shifting (s),
1675 s->cfg->height * s->param->ydpi / 75); */
1676
1677 /* have to test if rounding down is OK or not -- currently 0.5 lines is rounded down */
1678 /* note stripe shifts doubled already in definitions */
1679 if ((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) && (s->param->xdpi == 9600) && (test > 0))
1680 {
1681 /* using test==2 you can check in GIMP the required offset, and
1682 use the below line (uncommented) and replace XXX with that
1683 number, and then compile again with test set to 1. */
1684
1685 jumplines = 32;
1686 if (test == 2)
1687 jumplines = 0;
1688 }
1689
1690 /* mp960 test */
1691 if ((s->cfg->pid == MP960_PID) && (s->param->xdpi == 4800) && (test > 0))
1692 {
1693 jumplines = 32;
1694 if (test == 2)
1695 jumplines = 0;
1696 }
1697
1698 reducelines = ((2 * mp->color_shift + mp->stripe_shift) + jumplines);
1699 /* PDBG (pixma_dbg (4, "*post_process_image_data: lines %u, reducelines %u \n", lines, reducelines)); */
1700 if (lines > reducelines)
1701 { /* (line - reducelines) of image lines can be converted */
1702 unsigned i;
1703
1704 lines -= reducelines;
1705
1706 for (i = 0; i < lines; i++, sptr += line_size)
1707 { /* convert only full image lines */
1708 /* Color plane and stripes shift needed by e.g. CCD */
1709 /* PDBG (pixma_dbg (4, "*post_process_image_data***** Processing with c=%u, n=%u, m=%u, w=%i, line_size=%u ***** \n",
1710 c, n, m, s->param->wx, line_size)); */
1711 if (c >= 3)
1712 {
1713 if (((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) && (s->param->xdpi == 9600))
1714 || ((s->cfg->pid == MP960_PID) && (s->param->xdpi == 4800))
1715 || ((s->cfg->pid == MP810_PID) && (s->param->xdpi == 4800)))
1716 {
1717 dptr = shift_colorsCS9000 (dptr, sptr, s->param->wx, s->param->xdpi,
1718 s->cfg->pid, c, mp->shift,
1719 mp->stripe_shift, mp->stripe_shift2,
1720 jumplines * line_size);
1721 }
1722
1723 else if ((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) /* 9000F: 16 bit flatbed scan at 4800dpi */
1724 && ((s->param->mode == PIXMA_SCAN_MODE_COLOR_48)
1725 || (s->param->mode == PIXMA_SCAN_MODE_GRAY_16))
1726 && (s->param->xdpi == 4800)
1727 && (s->param->source == PIXMA_SOURCE_FLATBED))
1728 dptr = shift_colorsCS9000_4800 (dptr, sptr, s->param->wx,
1729 s->param->xdpi, s->cfg->pid, c,
1730 mp->shift, mp->stripe_shift,
1731 mp->stripe_shift2,
1732 jumplines * line_size);
1733
1734 else
1735 /* all except 9000F at 9600dpi */
1736 dptr = shift_colors (dptr, sptr, s->param->wx, s->param->xdpi,
1737 s->cfg->pid, c, mp->shift, mp->stripe_shift);
1738 }
1739
1740 /*PDBG (pixma_dbg (4, "*post_process_image_data***** test = %i *****\n", test)); */
1741
1742 /*--comment out all between this line and the one below for 9000F tests at 9600dpi or MP960 at 4800dpi ------*/
1743 /* if ( 0 ) */
1744 if ((((s->cfg->pid != CS9000F_PID && s->cfg->pid != CS9000F_MII_PID) || (s->param->xdpi < 9600))
1745 && ((s->cfg->pid != MP960_PID) || (s->param->xdpi < 4800))
1746 && ((s->cfg->pid != MP810_PID) || (s->param->xdpi < 4800)))
1747 || (test == 0))
1748 {
1749 /* PDBG (pixma_dbg (4, "*post_process_image_data***** MUST GET HERE WHEN TEST == 0 *****\n")); */
1750
1751 if (!((s->cfg->pid == MP810_PID) && (s->param->xdpi == 4800))
1752 && !((s->cfg->pid == MP960_PID) && (s->param->xdpi == 4800))
1753 && !((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) && (s->param->xdpi == 9600)))
1754 { /* for both flatbed & TPU */
1755 /* PDBG (pixma_dbg (4, "*post_process_image_data***** reordering pixels normal n = %i *****\n", n)); */
1756 reorder_pixels (mp->linebuf, sptr, c, n, m, s->param->wx, line_size);
1757 }
1758
1759 if ((s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID) && (s->param->xdpi == 9600))
1760 {
1761 /* PDBG (pixma_dbg (4, "*post_process_image_data***** cs900f_initial_reorder_pixels n = %i *****\n", n)); */
1762 /* this combines pixels from 8 images 2px at a time from left to right: 1122334455667788... */
1763 cs9000f_initial_reorder_pixels (mp->linebuf, sptr, c, n, m,
1764 s->param->wx, line_size);
1765 /* final interleaving */
1766 cs9000f_second_reorder_pixels (mp->linebuf, sptr, c, s->param->wx,
1767 line_size);
1768 }
1769
1770 /* comment: special image format for MP960 in flatbed mode
1771 at 4800dpi. It is actually 2400dpi, with each pixel
1772 doubled. The TPU mode has proper pixel ordering */
1773 if ((((s->cfg->pid == MP960_PID) || (s->cfg->pid == MP810_PID)) && (s->param->xdpi == 4800))
1774 && (n > 0))
1775 {
1776 /* for both flatbed & TPU */
1777 /* PDBG (pixma_dbg (4, "*post_process_image_data***** flatbed mp960_reordering pixels n = %i *****\n", n)); */
1778 mp960_reorder_pixels (mp->linebuf, sptr, c, n, m, s->param->wx,
1779 line_size);
1780 }
1781
1782 /* comment: MP970, CS8800F, CS9000F specific reordering for 4800 dpi */
1783 if ((s->cfg->pid == MP970_PID || s->cfg->pid == CS8800F_PID
1784 || s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID
1785 || s->cfg->pid == MP990_PID) && (s->param->xdpi == 4800))
1786 {
1787 /*PDBG (pixma_dbg (4, "*post_process_image_data***** mp970_reordering pixels n = %i *****\n", n)); */
1788 mp970_reorder_pixels (mp->linebuf, sptr, c, s->param->wx, line_size);
1789 }
1790
1791 }
1792 /*-------------------------------------------------------*/
1793
1794 /* PDBG (pixma_dbg (4, "*post_process_image_data: sptr=%u, dptr=%u \n", sptr, dptr)); */
1795
1796 /* Crop line to selected borders */
1797 memmove (cptr, sptr + cx, cw);
1798 /* PDBG (pixma_dbg (4, "*post_process_image_data***** crop line: cx=%u, cw=%u ***** \n", cx, cw)); */
1799
1800 /* Color to Lineart convert for CCD sensor */
1801 if (is_lineart (s))
1802 cptr = gptr = pixma_binarize_line (s->param, gptr, cptr, s->param->w, c);
1803 #ifndef TPUIR_USE_RGB
1804 /* save IR only for CCD sensor */
1805 else if (is_tpuir (s))
1806 cptr = gptr = pixma_r_to_ir (gptr, cptr, s->param->w, c);
1807 /* Color to Grayscale convert for CCD sensor */
1808 else if (is_gray_all (s))
1809 #else
1810 /* IR *and* Color to Grayscale convert for CCD sensor */
1811 else if (is_tpuir (s) || is_gray_all (s))
1812 #endif
1813 cptr = gptr = pixma_rgb_to_gray (gptr, cptr, s->param->w, c);
1814 else
1815 cptr += cw;
1816 }
1817 /* PDBG (pixma_dbg (4, "*post_process_image_data: sptr=%u, dptr=%u \n", sptr, dptr)); */
1818 }
1819 ib->rptr = mp->imgbuf;
1820 ib->rend = cptr;
1821 return mp->data_left_ofs - sptr; /* # of non processed bytes */
1822 /* contains shift color data for new lines */
1823 /* and already received data for the next line */
1824 }
1825
mp810_open(pixma_t * s)1826 static int mp810_open (pixma_t * s)
1827 {
1828 mp810_t *mp;
1829 uint8_t *buf;
1830
1831 mp = (mp810_t *) calloc (1, sizeof(*mp));
1832 if (!mp)
1833 return PIXMA_ENOMEM;
1834
1835 buf = (uint8_t *) malloc (CMDBUF_SIZE + IMAGE_BLOCK_SIZE);
1836 if (!buf)
1837 {
1838 free (mp);
1839 return PIXMA_ENOMEM;
1840 }
1841
1842 s->subdriver = mp;
1843 mp->state = state_idle;
1844
1845 mp->cb.buf = buf;
1846 mp->cb.size = CMDBUF_SIZE;
1847 mp->cb.res_header_len = 8;
1848 mp->cb.cmd_header_len = 16;
1849 mp->cb.cmd_len_field_ofs = 14;
1850
1851 mp->imgbuf = buf + CMDBUF_SIZE;
1852
1853 /* General rules for setting Pixma protocol generation # */
1854 mp->generation = (s->cfg->pid >= MP810_PID) ? 2 : 1;
1855
1856 if (s->cfg->pid >= MP970_PID)
1857 mp->generation = 3;
1858
1859 if (s->cfg->pid >= MP990_PID)
1860 mp->generation = 4;
1861
1862 /* And exceptions to be added here */
1863 if (s->cfg->pid == CS8800F_PID)
1864 mp->generation = 3;
1865
1866 if (s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID)
1867 mp->generation = 4;
1868
1869 /* TPU info data setup */
1870 mp->tpu_datalen = 0;
1871
1872 if (mp->generation < 4)
1873 {
1874 /* Canoscan 8800F ignores commands if not initialized */
1875 if (s->cfg->pid == CS8800F_PID)
1876 abort_session (s);
1877 else
1878 {
1879 query_status (s);
1880 handle_interrupt (s, 200);
1881 if (mp->generation == 3 && has_ccd_sensor (s))
1882 send_cmd_start_calibrate_ccd_3 (s);
1883 }
1884 }
1885 return 0;
1886 }
1887
mp810_close(pixma_t * s)1888 static void mp810_close (pixma_t * s)
1889 {
1890 mp810_t *mp = (mp810_t *) s->subdriver;
1891
1892 mp810_finish_scan (s);
1893 free (mp->cb.buf);
1894 free (mp);
1895 s->subdriver = NULL;
1896 }
1897
mp810_check_param(pixma_t * s, pixma_scan_param_t * sp)1898 static int mp810_check_param (pixma_t * s, pixma_scan_param_t * sp)
1899 {
1900 mp810_t *mp = (mp810_t *) s->subdriver;
1901 unsigned w_max;
1902
1903 /* PDBG (pixma_dbg (4, "*mp810_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u, gamma=%f *****\n",
1904 sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx, sp->gamma)); */
1905
1906 sp->channels = 3;
1907 sp->software_lineart = 0;
1908 switch (sp->mode)
1909 {
1910 /* standard scan modes
1911 * 8 bit per channel in color and grayscale mode
1912 * 16 bit per channel with TPU */
1913 case PIXMA_SCAN_MODE_GRAY:
1914 case PIXMA_SCAN_MODE_NEGATIVE_GRAY:
1915 case PIXMA_SCAN_MODE_TPUIR:
1916 sp->channels = 1;
1917 /* fall through */
1918 case PIXMA_SCAN_MODE_COLOR:
1919 case PIXMA_SCAN_MODE_NEGATIVE_COLOR:
1920 sp->depth = 8;
1921 #ifdef TPU_48
1922 #ifndef DEBUG_TPU_48
1923 if (sp->source == PIXMA_SOURCE_TPU)
1924 #endif
1925 sp->depth = 16; /* TPU in 16 bits mode */
1926 #endif
1927 break;
1928 /* extended scan modes for 48 bit flatbed scanners
1929 * 16 bit per channel in color and grayscale mode */
1930 case PIXMA_SCAN_MODE_GRAY_16:
1931 sp->channels = 1;
1932 sp->depth = 16;
1933 break;
1934 case PIXMA_SCAN_MODE_COLOR_48:
1935 sp->channels = 3;
1936 sp->depth = 16;
1937 break;
1938 /* software lineart
1939 * 1 bit per channel */
1940 case PIXMA_SCAN_MODE_LINEART:
1941 sp->software_lineart = 1;
1942 sp->channels = 1;
1943 sp->depth = 1;
1944 break;
1945 }
1946
1947 /* for software lineart w must be a multiple of 8
1948 * I don't know why is_lineart(s) doesn't work here */
1949 if (sp->software_lineart == 1 && sp->w % 8)
1950 {
1951 sp->w += 8 - (sp->w % 8);
1952
1953 /* do not exceed the scanner capability */
1954 w_max = s->cfg->width * s->cfg->xdpi / 75;
1955 w_max -= w_max % 8;
1956 if (sp->w > w_max)
1957 sp->w = w_max;
1958 }
1959
1960 if (sp->source == PIXMA_SOURCE_TPU && !sp->tpu_offset_added)
1961 {
1962 unsigned fixed_offset_y; /* TPU offsets for CanoScan 8800F, or other CCD at 300dpi. */
1963 unsigned max_y; /* max TPU height for CS9000F at 75 dpi */
1964
1965 /* CanoScan 8800F and others adding an offset depending on resolution */
1966 /* CS9000F and others maximum TPU height */
1967 switch (s->cfg->pid)
1968 {
1969 case CS8800F_PID:
1970 fixed_offset_y = 140;
1971 max_y = MIN (740, s->cfg->height);
1972 break;
1973 case CS9000F_PID:
1974 case CS9000F_MII_PID:
1975 fixed_offset_y = 146;
1976 max_y = MIN (740, s->cfg->height);
1977 break;
1978 default:
1979 fixed_offset_y = 0;
1980 max_y = s->cfg->height;
1981 break;
1982 }
1983
1984 /* cropping y and h to scanable area */
1985 max_y *= (sp->ydpi) / 75;
1986 sp->y = MIN(sp->y, max_y);
1987 sp->h = MIN(sp->h, max_y - sp->y);
1988 /* PDBG (pixma_dbg (4, "*mp810_check_param***** Cropping: y=%u, h=%u *****\n",
1989 sp->y, sp->h)); */
1990 if (!sp->h)
1991 return SANE_STATUS_INVAL; /* no lines */
1992
1993 /* Convert the offsets from 300dpi to actual resolution */
1994 fixed_offset_y = fixed_offset_y * (sp->xdpi) / 300;
1995
1996 /* In TPU mode, the CS9000F appears to always subtract 146 from the
1997 vertical starting position, but clamps its at 0. Therefore vertical
1998 offsets 0 through 146 (@300 dpi) get all mapped onto the same
1999 physical starting position: line 0. Then, starting from 147, the
2000 offsets get mapped onto successive physical lines:
2001 y line
2002 0 -> 0
2003 1 -> 0
2004 2 -> 0
2005 ...
2006 146 -> 0
2007 147 -> 1
2008 148 -> 2
2009 ...
2010 Since a preview scan is typically made starting from y = 0, but
2011 partial image scans usually start at y >> 147, this results in a
2012 discontinuity in the y to line mapping, resulting in wrong offsets.
2013 To prevent this, we must always add (at least) 146 to the y
2014 offset before it is sent to the scanner. The scanner will then
2015 map y = 0 (146) to the first line, y = 1 (147) to the second line,
2016 and so on. Any distance that is then measured on the preview scan,
2017 can be translated without any discontinuity.
2018
2019 However, there is one complication: during a preview scan, which
2020 normally covers the whole scan area of the scanner, we should _not_
2021 add the offset because it will result in a reduced number of lines
2022 being returned (the scan height is clamped in
2023 pixma_check_scan_param()). Since the frontend has no way of telling
2024 that the scan area has been reduced, it would derive an incorrect
2025 effective scan resolution, and any position calculations based on
2026 this would therefore be inaccurate.
2027
2028 To prevent this, we don't add the offset in case y = 0, which is
2029 typically the case during a preview scan (the scanner effectively
2030 adds the offset for us, see above). In that way we keep the
2031 linearity and we don't affect the scan area during previews.
2032 */
2033
2034 if (sp->y > 0)
2035 sp->y += fixed_offset_y;
2036
2037 /* Prevent repeated corrections as check_param may be called multiple times */
2038 sp->tpu_offset_added = 1;
2039 }
2040
2041 if (mp->generation >= 2)
2042 {
2043 /* mod 32 and expansion of the X scan limits */
2044 /* PDBG (pixma_dbg (4, "*mp810_check_param***** (gen>=2) xs=mod32 ----- Initially: x=%u, y=%u, w=%u, h=%u *****\n", sp->x, sp->y, sp->w, sp->h)); */
2045 sp->xs = (sp->x) % 32;
2046 }
2047 else
2048 {
2049 sp->xs = 0;
2050 /* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) xs=0 Selected origin, origin shift: %u, %u *****\n", sp->x, sp->xs)); */
2051 }
2052 sp->wx = calc_raw_width (mp, sp);
2053 sp->line_size = sp->w * sp->channels * (((sp->software_lineart) ? 8 : sp->depth) / 8); /* bytes per line per color after cropping */
2054 /* PDBG (pixma_dbg (4, "*mp810_check_param***** (else) Final scan width and line-size: %u, %"PRIu64" *****\n", sp->wx, sp->line_size)); */
2055
2056 /* highest res is 600, 2400, 4800 or 9600 dpi */
2057 {
2058 uint8_t k;
2059
2060 if ((sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP)
2061 && mp->generation >= 4)
2062 /* ADF/ADF duplex mode: max scan res is 600 dpi, at least for generation 4 */
2063 k = sp->xdpi / MIN (sp->xdpi, 600);
2064 else if (sp->source == PIXMA_SOURCE_TPU && sp->mode == PIXMA_SCAN_MODE_TPUIR)
2065 /* TPUIR mode: max scan res is 2400 dpi */
2066 k = sp->xdpi / MIN (sp->xdpi, 2400);
2067 else if (sp->source == PIXMA_SOURCE_TPU && (s->cfg->pid == CS9000F_PID || s->cfg->pid == CS9000F_MII_PID))
2068 /* CS9000F in TPU mode */
2069 k = sp->xdpi / MIN (sp->xdpi, 9600);
2070 else
2071 /* default */
2072 k = sp->xdpi / MIN (sp->xdpi, 4800);
2073
2074 sp->x /= k;
2075 sp->xs /= k;
2076 sp->y /= k;
2077 sp->w /= k;
2078 sp->wx /= k;
2079 sp->h /= k;
2080 sp->xdpi /= k;
2081 sp->ydpi = sp->xdpi;
2082 }
2083
2084 /* lowest res is 75, 150, 300 or 600 dpi */
2085 {
2086 uint8_t k;
2087
2088 if (sp->source == PIXMA_SOURCE_TPU && sp->mode == PIXMA_SCAN_MODE_TPUIR)
2089 /* TPUIR mode */
2090 k = MAX (sp->xdpi, 600) / sp->xdpi;
2091 else if (sp->source == PIXMA_SOURCE_TPU
2092 && ((mp->generation >= 3) || (s->cfg->pid == MP810_PID) || (s->cfg->pid == MP960_PID)))
2093 /* TPU mode for generation 3+ scanners
2094 * MP810, MP960 appear to have a 200dpi mode for low-res scans, not 150 dpi */
2095 k = MAX (sp->xdpi, 300) / sp->xdpi;
2096 else if (sp->source == PIXMA_SOURCE_TPU
2097 || sp->mode == PIXMA_SCAN_MODE_COLOR_48 || sp->mode == PIXMA_SCAN_MODE_GRAY_16)
2098 /* TPU mode and 16 bit flatbed scans */
2099 k = MAX (sp->xdpi, 150) / sp->xdpi;
2100 else
2101 /* default */
2102 k = MAX (sp->xdpi, 75) / sp->xdpi;
2103
2104 sp->x *= k;
2105 sp->xs *= k;
2106 sp->y *= k;
2107 sp->w *= k;
2108 sp->wx *= k;
2109 sp->h *= k;
2110 sp->xdpi *= k;
2111 sp->ydpi = sp->xdpi;
2112 }
2113
2114 /* PDBG (pixma_dbg (4, "*mp810_check_param***** Finally: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n",
2115 sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx)); */
2116
2117 return 0;
2118 }
2119
mp810_scan(pixma_t * s)2120 static int mp810_scan (pixma_t * s)
2121 {
2122 int error = 0, tmo;
2123 mp810_t *mp = (mp810_t *) s->subdriver;
2124
2125 if (mp->state != state_idle)
2126 return PIXMA_EBUSY;
2127
2128 /* Generation 4: send XML dialog */
2129 if (mp->generation == 4 && s->param->adf_pageid == 0)
2130 {
2131 if (!send_xml_dialog (s, XML_START_1))
2132 return PIXMA_EPROTO;
2133 if (!send_xml_dialog (s, XML_START_2))
2134 return PIXMA_EPROTO;
2135 }
2136
2137 /* clear interrupt packets buffer */
2138 while (handle_interrupt (s, 0) > 0)
2139 {
2140 }
2141
2142 /* FIXME: Duplex ADF: check paper status only before odd pages (1,3,5,...). */
2143 if (is_scanning_from_adf (s))
2144 {
2145 if ((error = query_status (s)) < 0)
2146 return error;
2147 tmo = 10;
2148 while (!has_paper (s) && --tmo >= 0)
2149 {
2150 WAIT_INTERRUPT(1000);
2151 PDBG(pixma_dbg (2, "No paper in ADF. Timed out in %d sec.\n", tmo));
2152 }
2153 if (!has_paper (s))
2154 return PIXMA_ENO_PAPER;
2155 }
2156
2157 if (has_ccd_sensor (s) && (mp->generation <= 2))
2158 {
2159 error = send_cmd_e920 (s);
2160 switch (error)
2161 {
2162 case PIXMA_ECANCELED:
2163 case PIXMA_EBUSY:
2164 PDBG(pixma_dbg (2, "cmd e920 or d520 returned %s\n", pixma_strerror (error)));
2165 /* fall through */
2166 case 0:
2167 query_status (s);
2168 break;
2169 default:
2170 PDBG(pixma_dbg (1, "WARNING: cmd e920 or d520 failed %s\n", pixma_strerror (error)));
2171 return error;
2172 }
2173 tmo = 3; /* like Windows driver, CCD calibration ? */
2174 while (--tmo >= 0)
2175 {
2176 WAIT_INTERRUPT(1000);
2177 PDBG(pixma_dbg (2, "CCD Calibration ends in %d sec.\n", tmo));
2178 }
2179 /* pixma_sleep(2000000); */
2180 }
2181
2182 tmo = 10;
2183 if (s->param->adf_pageid == 0 || mp->generation <= 2)
2184 {
2185 error = start_session (s);
2186 while (error == PIXMA_EBUSY && --tmo >= 0)
2187 {
2188 if (s->cancel)
2189 {
2190 error = PIXMA_ECANCELED;
2191 break;
2192 }
2193 PDBG(pixma_dbg (2, "Scanner is busy. Timed out in %d sec.\n", tmo + 1));
2194 pixma_sleep (1000000);
2195 error = start_session (s);
2196 }
2197 if (error == PIXMA_EBUSY || error == PIXMA_ETIMEDOUT)
2198 {
2199 /* The scanner maybe hangs. We try to empty output buffer of the
2200 * scanner and issue the cancel command. */
2201 PDBG(pixma_dbg (2, "Scanner hangs? Sending abort_session command.\n"));
2202 drain_bulk_in (s);
2203 abort_session (s);
2204 pixma_sleep (500000);
2205 error = start_session (s);
2206 }
2207 if ((error >= 0) || (mp->generation >= 3))
2208 mp->state = state_warmup;
2209 if ((error >= 0) && (mp->generation <= 2))
2210 error = select_source (s);
2211 if ((error >= 0) && (mp->generation >= 3) && has_ccd_sensor (s))
2212 error = init_ccd_lamp_3 (s);
2213 if ((error >= 0) && !is_scanning_from_tpu (s))
2214 {
2215 int i;
2216 /* FIXME: 48 bit flatbed scans don't need gamma tables
2217 * the code below doesn't run */
2218 /*if (is_color_48 (s) || is_gray_16 (s))
2219 error = 0;
2220 else*/
2221 for (i = (mp->generation >= 3) ? 3 : 1; i > 0 && error >= 0; i--)
2222 error = send_gamma_table (s);
2223 }
2224 else if (error >= 0) /* in TPU mode, for gen 1, 2, and 3 */
2225 error = send_set_tpu_info (s);
2226 }
2227 else
2228 /* ADF pageid != 0 and gen3 or above */
2229 pixma_sleep (1000000);
2230
2231 if ((error >= 0) || (mp->generation >= 3))
2232 mp->state = state_warmup;
2233 if (error >= 0)
2234 error = send_scan_param (s);
2235 if ((error >= 0) && (mp->generation >= 3))
2236 error = start_scan_3 (s);
2237 if (error < 0)
2238 {
2239 mp->last_block = 0x38; /* Force abort session if ADF scan */
2240 mp810_finish_scan (s);
2241 return error;
2242 }
2243 return 0;
2244 }
2245
mp810_fill_buffer(pixma_t * s, pixma_imagebuf_t * ib)2246 static int mp810_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
2247 {
2248 int error;
2249 mp810_t *mp = (mp810_t *) s->subdriver;
2250 unsigned block_size, bytes_received, proc_buf_size, line_size;
2251 uint8_t header[16];
2252
2253 if (mp->state == state_warmup)
2254 { /* prepare read image data */
2255 /* PDBG (pixma_dbg (4, "**mp810_fill_buffer***** warmup *****\n")); */
2256
2257 RET_IF_ERR(wait_until_ready (s));
2258 pixma_sleep (1000000); /* No need to sleep, actually, but Window's driver
2259 * sleep 1.5 sec. */
2260 mp->state = state_scanning;
2261 mp->last_block = 0;
2262
2263 line_size = get_cis_ccd_line_size (s);
2264 proc_buf_size = (2 * calc_shifting (s) + 2) * line_size;
2265 mp->cb.buf = realloc (mp->cb.buf, CMDBUF_SIZE + IMAGE_BLOCK_SIZE + proc_buf_size);
2266 if (!mp->cb.buf)
2267 return PIXMA_ENOMEM;
2268 mp->linebuf = mp->cb.buf + CMDBUF_SIZE;
2269 mp->imgbuf = mp->data_left_ofs = mp->linebuf + line_size;
2270 mp->data_left_len = 0;
2271 }
2272
2273 do
2274 { /* read complete image data from the scanner */
2275 if (s->cancel)
2276 return PIXMA_ECANCELED;
2277 if ((mp->last_block & 0x28) == 0x28)
2278 { /* end of image */
2279 mp->state = state_finished;
2280 /* PDBG (pixma_dbg (4, "**mp810_fill_buffer***** end of image *****\n")); */
2281 return 0;
2282 }
2283 /* PDBG (pixma_dbg (4, "*mp810_fill_buffer***** moving %u bytes into buffer *****\n", mp->data_left_len)); */
2284 memmove (mp->imgbuf, mp->data_left_ofs, mp->data_left_len);
2285 error = read_image_block (s, header, mp->imgbuf + mp->data_left_len);
2286 if (error < 0)
2287 {
2288 if (error == PIXMA_ECANCELED)
2289 {
2290 /* NOTE: I see this in traffic logs but I don't know its meaning. */
2291 read_error_info (s, NULL, 0);
2292 }
2293 return error;
2294 }
2295
2296 bytes_received = error;
2297 /*PDBG (pixma_dbg (4, "*mp810_fill_buffer***** %u bytes received by read_image_block *****\n", bytes_received));*/
2298 block_size = pixma_get_be32 (header + 12);
2299 mp->last_block = header[8] & 0x38;
2300 if ((header[8] & ~0x38) != 0)
2301 {
2302 PDBG(pixma_dbg (1, "WARNING: Unexpected result header\n"));
2303 PDBG(pixma_hexdump (1, header, 16));
2304 }
2305 PASSERT(bytes_received == block_size);
2306
2307 if (block_size == 0)
2308 { /* no image data at this moment. */
2309 pixma_sleep (10000);
2310 }
2311 /* For TPU at 48 bits/pixel to output at 24 bits/pixel */
2312 #ifndef DEBUG_TPU_48
2313 #ifndef TPU_48
2314 PDBG (pixma_dbg (1, "WARNING: 9000F using 24 instead of 48 bit processing \n"));
2315 #ifndef DEBUG_TPU_24
2316 if (is_scanning_from_tpu (s))
2317 #endif
2318 bytes_received = pack_48_24_bpc (mp->imgbuf + mp->data_left_len, bytes_received);
2319 #endif
2320 #endif
2321 /* Post-process the image data */
2322 mp->data_left_ofs = mp->imgbuf + mp->data_left_len + bytes_received;
2323 mp->data_left_len = post_process_image_data (s, ib);
2324 mp->data_left_ofs -= mp->data_left_len;
2325 /* PDBG (pixma_dbg (4, "* mp810_fill_buffer: data_left_len %u \n", mp->data_left_len)); */
2326 /* PDBG (pixma_dbg (4, "* mp810_fill_buffer: data_left_ofs %u \n", mp->data_left_ofs)); */
2327 }
2328 while (ib->rend == ib->rptr);
2329
2330 return ib->rend - ib->rptr;
2331 }
2332
mp810_finish_scan(pixma_t * s)2333 static void mp810_finish_scan (pixma_t * s)
2334 {
2335 int error;
2336 mp810_t *mp = (mp810_t *) s->subdriver;
2337
2338 switch (mp->state)
2339 {
2340 case state_transfering:
2341 drain_bulk_in (s);
2342 /* fall through */
2343 case state_scanning:
2344 case state_warmup:
2345 case state_finished:
2346 /* Send the get TPU info message */
2347 if (is_scanning_from_tpu (s) && mp->tpu_datalen == 0)
2348 send_get_tpu_info_3 (s);
2349 /* FIXME: to process several pages ADF scan, must not send
2350 * abort_session and start_session between pages (last_block=0x28) */
2351 if (mp->generation <= 2 || !is_scanning_from_adf (s)
2352 || mp->last_block == 0x38)
2353 {
2354 error = abort_session (s); /* FIXME: it probably doesn't work in duplex mode! */
2355 if (error < 0)
2356 PDBG(pixma_dbg (1, "WARNING:abort_session() failed %d\n", error));
2357
2358 /* Generation 4: send XML end of scan dialog */
2359 if (mp->generation == 4)
2360 {
2361 if (!send_xml_dialog (s, XML_END))
2362 PDBG(pixma_dbg (1, "WARNING:XML_END dialog failed \n"));
2363 }
2364 }
2365 mp->state = state_idle;
2366 /* fall through */
2367 case state_idle:
2368 break;
2369 }
2370 }
2371
mp810_wait_event(pixma_t * s, int timeout)2372 static void mp810_wait_event (pixma_t * s, int timeout)
2373 {
2374 /* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
2375 * instance. */
2376 while (s->events == 0 && handle_interrupt (s, timeout) > 0)
2377 {
2378 }
2379 }
2380
mp810_get_status(pixma_t * s, pixma_device_status_t * status)2381 static int mp810_get_status (pixma_t * s, pixma_device_status_t * status)
2382 {
2383 int error;
2384
2385 RET_IF_ERR(query_status (s));
2386 status->hardware = PIXMA_HARDWARE_OK;
2387 status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
2388 status->cal =
2389 (is_calibrated (s)) ? PIXMA_CALIBRATION_OK : PIXMA_CALIBRATION_OFF;
2390 return 0;
2391 }
2392
2393 static const pixma_scan_ops_t pixma_mp800_ops =
2394 {
2395 mp810_open,
2396 mp810_close,
2397 mp810_scan,
2398 mp810_fill_buffer,
2399 mp810_finish_scan,
2400 mp810_wait_event,
2401 mp810_check_param,
2402 mp810_get_status
2403 };
2404
2405 #define DEVICE(name, model, pid, min_dpi_16, dpi, adftpu_min_dpi, adftpu_max_dpi, tpuir_min_dpi, tpuir_max_dpi, w, h, cap) { \
2406 name, /* name */ \
2407 model, /* model */ \
2408 CANON_VID, pid, /* vid pid */ \
2409 0, /* iface */ \
2410 &pixma_mp800_ops, /* ops */ \
2411 0, /* min_xdpi not used in this subdriver */ \
2412 min_dpi_16, /* min_xdpi_16 */ \
2413 dpi, 2*(dpi), /* xdpi, ydpi */ \
2414 adftpu_min_dpi, adftpu_max_dpi, /* adftpu_min_dpi, adftpu_max_dpi */ \
2415 tpuir_min_dpi, tpuir_max_dpi, /* tpuir_min_dpi, tpuir_max_dpi */ \
2416 w, h, /* width, height */ \
2417 PIXMA_CAP_CCD| /* all scanners with CCD*/ \
2418 PIXMA_CAP_EASY_RGB| \
2419 PIXMA_CAP_GRAY| /* all scanners with software grayscale */ \
2420 PIXMA_CAP_LINEART| /* all scanners with software lineart */ \
2421 PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
2422 }
2423
2424 #define END_OF_DEVICE_LIST DEVICE(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2425
2426 const pixma_config_t pixma_mp800_devices[] =
2427 {
2428 /* Generation 1: CCD */
2429 DEVICE ("Canon PIXMA MP800", "MP800", MP800_PID, 0, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU | PIXMA_CAP_GT_4096),
2430 DEVICE ("Canon PIXMA MP800R", "MP800R", MP800R_PID, 0, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU | PIXMA_CAP_GT_4096),
2431 DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 0, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP | PIXMA_CAP_GT_4096),
2432
2433 /* Generation 2: CCD */
2434 DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2435 DEVICE ("Canon PIXMA MP960", "MP960", MP960_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2436
2437 /* Generation 3 CCD not managed as Generation 2 */
2438 DEVICE ("Canon Pixma MP970", "MP970", MP970_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2439
2440 /* Flatbed scanner CCD (2007) */
2441 DEVICE ("Canoscan 8800F", "8800F", CS8800F_PID, 150, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT),
2442
2443 /* PIXMA 2008 vintage CCD */
2444 DEVICE ("Canon MP980 series", "MP980", MP980_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2445
2446 /* Generation 4 CCD */
2447 DEVICE ("Canon MP990 series", "MP990", MP990_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2448
2449 /* Flatbed scanner (2010) */
2450 DEVICE ("Canoscan 9000F", "9000F", CS9000F_PID, 150, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_TPUIR /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT),
2451
2452 /* Latest devices (2010) Generation 4 CCD untested */
2453 DEVICE ("Canon PIXMA MG8100", "MG8100", MG8100_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2454
2455 /* Latest devices (2011) Generation 4 CCD untested */
2456 DEVICE ("Canon PIXMA MG8200", "MG8200", MG8200_PID, 0, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU),
2457
2458 /* Flatbed scanner (2013) */
2459 DEVICE ("Canoscan 9000F Mark II", "9000FMarkII", CS9000F_MII_PID, 150, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_TPUIR | PIXMA_CAP_48BIT),
2460
2461 END_OF_DEVICE_LIST
2462 };
2463