1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2001-2002 Matthew C. Duggan and Simon Krix
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 -----
40
41 This file is part of the canon_pp backend, supporting Canon CanoScan
42 Parallel scanners and also distributed as part of the stand-alone driver.
43
44 Misc constants for Canon CanoScan Parallel scanners and high-level scan
45 functions.
46
47 Simon Krix <kinsei@users.sourceforge.net>
48 */
49
50 #ifdef _AIX
51 #include <lalloca.h>
52 #endif
53
54 #ifndef NOSANE
55 #include "../include/sane/config.h"
56 #endif
57
58 #include <sys/time.h>
59 #include <unistd.h>
60 #include <errno.h>
61 #include <fcntl.h>
62 #include <string.h>
63 #include <stdlib.h>
64 #include <ieee1284.h>
65 #include "canon_pp-io.h"
66 #include "canon_pp-dev.h"
67
68 #ifdef NOSANE
69
70 /* No SANE, Things that only apply to stand-alone */
71 #include <stdio.h>
72 #include <stdarg.h>
73
DBG(int level, const char *format, ...)74 static void DBG(int level, const char *format, ...)
75 {
76 va_list args;
77 va_start(args, format);
78 if (level < 50) vfprintf(stderr, format, args);
79 va_end(args);
80 }
81 #else
82
83 #define DEBUG_DECLARE_ONLY
84 #include "canon_pp.h"
85 #include "../include/sane/sanei_config.h"
86 #include "../include/sane/sanei_backend.h"
87
88 #endif
89
90 struct scanner_hardware_desc {
91 char *name;
92 unsigned int natural_xresolution;
93 unsigned int natural_yresolution;
94 unsigned int scanbedlength;
95 unsigned int scanheadwidth; /* 0 means provided by scanner */
96 unsigned int type;
97 };
98
99 static const struct scanner_hardware_desc
100 /* The known scanner types */
101 hw_fb320p = { "FB320P", 2, 2, 3508, 2552, 0 },
102 hw_fb330p = { "FB330P", 2, 2, 3508, 0, 1 },
103 hw_fb620p = { "FB620P", 3, 3, 7016, 5104, 0 },
104 hw_fb630p = { "FB630P", 3, 3, 7016, 0, 1 },
105 hw_n640p = { "N640P", 3, 3, 7016, 0, 1 },
106 hw_n340p = { "N340P", 2, 2, 3508, 0, 1 },
107
108 /* A few generic scanner descriptions for aliens */
109 hw_alien600 = { "Unknown 600dpi", 3, 3, 7016, 0, 1 },
110 hw_alien300 = { "Unknown 300dpi", 2, 2, 3508, 0, 1 },
111 hw_alien = { "Unknown (600dpi?)", 3, 3, 7016, 0, 1 };
112
113 /* ID table linking ID strings with hardware descriptions */
114 struct scanner_id {
115 char *id;
116 const struct scanner_hardware_desc *hw;
117 };
118 static const struct scanner_id scanner_id_table[] = {
119 { "CANON IX-03055C", &hw_fb320p },
120 { "CANON IX-06025C", &hw_fb620p },
121 { "CANON IX-03075E", &hw_fb330p },
122 { "CANON IX-06075E", &hw_fb630p },
123 { "CANON IX-03095G", &hw_n340p },
124 { "CANON IX-06115G", &hw_n640p },
125 { NULL, NULL } };
126
127 /*const int scanline_count = 6;*/
128 static const char *header = "#CANONPP";
129 static const int fileversion = 3;
130
131 /* Internal functions */
132 static unsigned long column_sum(image_segment *image, int x);
133 static int adjust_output(image_segment *image, scan_parameters *scanp,
134 scanner_parameters *scannerp);
135 static int check8(unsigned char *p, int s);
136 /* Converts from weird scanner format -> sequential data */
137 static void convdata(unsigned char *srcbuffer, unsigned char *dstbuffer,
138 int width, int mode);
139 /* Sets up the scan command. This could use a better name
140 (and a rewrite). */
141 static int scanner_setup_params(unsigned char *buf, scanner_parameters *sp,
142 scan_parameters *scanp);
143
144 /* file reading and writing helpers */
145 static int safe_write(int fd, const char *p, unsigned long len);
146 static int safe_read(int fd, char *p, unsigned long len);
147
148 /* Command sending loop (waiting for ready status) */
149 static int send_command(struct parport *port, unsigned char *buf, int bufsize,
150 int delay, int timeout);
151
152 /* Commands ================================================ */
153
154 /* Command_1[] moved to canon_pp-io.c for neatness */
155
156
157 /* Read device ID command */
158 /* after this 0x26 (38) bytes are read */
159 static unsigned char cmd_readid[] = { 0xfe, 0x20, 0, 0, 0, 0, 0, 0, 0x26, 0 };
160
161 /* Reads 12 bytes of unknown information */
162 static unsigned char cmd_readinfo[] = { 0xf3, 0x20, 0, 0, 0, 0, 0, 0, 0x0c, 0 };
163
164 /* Scan init command: Always followed immediately by command cmd_scan */
165 static unsigned char cmd_initscan[] = { 0xde, 0x20, 0, 0, 0, 0, 0, 0, 0x2e, 0 };
166
167 /* Scan information block */
168 static unsigned char cmd_scan[45] =
169 { 0x11, 0x2c, 0x11, 0x2c, 0x10, 0x4b, 0x10, 0x4b, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0x08, 0x08, 0x01, 0x01, 0x80, 0x01,
172 0x80, 0x80, 0x02, 0, 0, 0xc1, 0, 0x08, 0x01, 0x01,
173 0, 0, 0, 0, 0
174 };
175
176 /* Read 6 byte buffer status block */
177 static unsigned char cmd_buf_status[] = { 0xf3, 0x21, 0, 0, 0, 0, 0, 0, 0x06, 0 };
178
179 /* Request a block of image data */
180 static unsigned char cmd_packet_req[] = {0xd4, 0x20, 0, 0, 0, 0, 0, 0x09, 0x64, 0};
181
182 /* "*SCANEND" command - returns the scanner to transparent mode */
183 static unsigned char cmd_scanend[] =
184 { 0x1b, 0x2a, 0x53, 0x43, 0x41, 0x4e, 0x45, 0x4e, 0x44, 0x0d };
185
186 /* Reads BLACK calibration image */
187 static unsigned char cmd_calblack[] ={0xf8, 0x20, 0, 0, 0, 0, 0, 0x4a, 0xc4, 0};
188
189 /* Clear the existing gamma table and create a new one */
190 static unsigned char cmd_cleargamma[] = {0xc5, 0x20, 0, 0, 0, 0, 0, 0, 0, 0};
191
192 /* Read back the gamma table values */
193 static unsigned char cmd_readgamma[] = {0xf6, 0x20, 0, 0, 0, 0, 0, 0, 0x20, 0};
194
195 /* Reads COLOUR (R,G or B) calibration image */
196 static unsigned char cmd_calcolour[]={0xf9, 0x20, 0, 0, 0, 0, 0, 0x4a, 0xc4, 0};
197
198 /* Abort scan */
199 static unsigned char cmd_abort[] = {0xef, 0x20, 0, 0, 0, 0, 0, 0, 0, 0};
200
201 /* Upload the gamma table (followed by 32 byte write) */
202 static unsigned char cmd_setgamma[] = {0xe6, 0x20, 0, 0, 0, 0, 0, 0, 0x20, 0};
203
204 #if 0
205 /* Something about RGB gamma/gain values? Not currently used by this code */
206 static unsigned char command_14[32] =
207 { 0x2, 0x0, 0x3, 0x7f,
208 0x2, 0x0, 0x3, 0x7f,
209 0x2, 0x0, 0x3, 0x7f,
210 0, 0, 0, 0,
211 0x12, 0xd1, 0x14, 0x82,
212 0, 0, 0, 0,
213 0x0f, 0xff,
214 0x0f, 0xff,
215 0x0f, 0xff, 0, 0 };
216 #endif
217
218
219 /* Misc functions =================================== */
220
221 /*
222 * safe_write(): a small wrapper which ensures all the data is written in calls
223 * to write(), since the POSIX call doesn't ensure it.
224 */
safe_write(int fd, const char *p, unsigned long len)225 static int safe_write(int fd, const char *p, unsigned long len) {
226 int diff;
227 unsigned long total = 0;
228
229 do {
230 diff = write(fd, p+total, len-total);
231 if (diff < 0)
232 {
233 if (errno == EINTR) continue;
234 return -1;
235 }
236 total += diff;
237 } while (len > total);
238
239 return 0;
240
241 }
242
243 /* same dealie for read, except in the case of read the return of 0 bytes with
244 * no INTR error indicates EOF */
safe_read(int fd, char *p, unsigned long len)245 static int safe_read(int fd, char *p, unsigned long len) {
246 int diff;
247 unsigned long total = 0;
248
249 do {
250 diff = read(fd, p+total, len-total);
251 if (diff <= 0)
252 {
253 if (errno == EINTR) continue;
254 if (diff == 0) return -2;
255 return -1;
256
257 }
258 total += diff;
259 } while (len > total);
260
261 return 0;
262
263 }
264
265
266 /* Scan-related functions =================================== */
267
sanei_canon_pp_init_scan(scanner_parameters *sp, scan_parameters *scanp)268 int sanei_canon_pp_init_scan(scanner_parameters *sp, scan_parameters *scanp)
269 {
270 /* Command for: Initialise and begin the scan procedure */
271 unsigned char command_b[56];
272
273 /* Buffer for buffer info block */
274 unsigned char buffer_info_block[6];
275
276 /* The image size the scanner says we asked for
277 (based on the scanner's replies) */
278 int true_scanline_size, true_scanline_count;
279
280 /* The image size we expect to get (based on *scanp) */
281 int expected_scanline_size, expected_scanline_count;
282
283 /* Set up the default scan command packet */
284 memcpy(command_b, cmd_initscan, 10);
285 memcpy(command_b+10, cmd_scan, 45);
286
287 /* Load the proper settings into it */
288 scanner_setup_params(command_b+10, sp, scanp);
289
290 /* Add checksum byte */
291 command_b[55] = check8(command_b+10, 45);
292
293 if (send_command(sp->port, command_b, 56, 50000, 1000000))
294 return -1;
295
296 /* Ask the scanner about the buffer */
297 if (send_command(sp->port, cmd_buf_status, 10, 50000, 1000000))
298 return -1;
299
300 /* Read buffer information block */
301 sanei_canon_pp_read(sp->port, 6, buffer_info_block);
302
303 if (check8(buffer_info_block, 6))
304 DBG(1, "init_scan: ** Warning: Checksum error reading buffer "
305 "info block.\n");
306
307 expected_scanline_count = scanp->height;
308
309 switch(scanp->mode)
310 {
311 case 0: /* greyscale; 10 bits per pixel */
312 expected_scanline_size = scanp->width * 1.25; break;
313 case 1: /* true-colour; 30 bits per pixel */
314 expected_scanline_size = scanp->width * 3.75; break;
315 default:
316 DBG(1, "init_scan: Illegal mode %i requested in "
317 "init_scan().\n", scanp->mode);
318 DBG(1, "This is a bug. Please report it.\n");
319 return -1;
320 }
321
322 /* The scanner's idea of the length of each scanline in bytes */
323 true_scanline_size = (buffer_info_block[0]<<8) | buffer_info_block[1];
324 /* The scanner's idea of the number of scanlines in total */
325 true_scanline_count = (buffer_info_block[2]<<8) | buffer_info_block[3];
326
327 if ((expected_scanline_size != true_scanline_size)
328 || (expected_scanline_count != true_scanline_count))
329 {
330 DBG(10, "init_scan: Warning: Scanner is producing an image "
331 "of unexpected size:\n");
332 DBG(10, "expected: %i bytes wide, %i scanlines tall.\n",
333 expected_scanline_size,
334 expected_scanline_count);
335 DBG(10, "true: %i bytes wide, %i scanlines tall.\n",
336 true_scanline_size, true_scanline_count);
337
338 if (scanp->mode == 0)
339 scanp->width = true_scanline_size / 1.25;
340 else
341 scanp->width = true_scanline_size / 3.75;
342
343 scanp->height = true_scanline_count;
344 }
345 return 0;
346 }
347
348
349 /* Wake the scanner, detect it, and fill sp with stuff */
sanei_canon_pp_initialise(scanner_parameters *sp, int mode)350 int sanei_canon_pp_initialise(scanner_parameters *sp, int mode)
351 {
352 unsigned char scanner_info[12];
353 const struct scanner_id *cur_id;
354 const struct scanner_hardware_desc *hw;
355
356 /* Hopefully take the scanner out of transparent mode */
357 if (sanei_canon_pp_wake_scanner(sp->port, mode))
358 {
359 DBG(10, "initialise: could not wake scanner\n");
360 return 1;
361 }
362
363 /* This block of code does something unknown but necessary */
364 DBG(50, "initialise: >> scanner_init\n");
365 if (sanei_canon_pp_scanner_init(sp->port))
366 {
367 /* If we're using an unsupported ieee1284 mode here, this is
368 * where it will fail, so fall back to nibble. */
369 sanei_canon_pp_set_ieee1284_mode(M1284_NIBBLE);
370 if (sanei_canon_pp_scanner_init(sp->port))
371 {
372 DBG(10, "initialise: Could not init scanner.\n");
373 return 1;
374 }
375 }
376 DBG(50, "initialise: << scanner_init\n");
377
378 /* Read Device ID */
379 memset(sp->id_string, 0, sizeof sp->id_string);
380 if (send_command(sp->port, cmd_readid, 10, 10000, 100000))
381 return -1;
382 sanei_canon_pp_read(sp->port, 38, (unsigned char *)(sp->id_string));
383
384 /* Read partially unknown data */
385 if (send_command(sp->port, cmd_readinfo, 10, 10000, 100000))
386 return -1;
387 sanei_canon_pp_read(sp->port, 12, scanner_info);
388
389 if (check8(scanner_info, 12))
390 {
391 DBG(10, "initialise: Checksum error reading Info Block.\n");
392 return 2;
393 }
394
395 sp->scanheadwidth = (scanner_info[2] << 8) | scanner_info[3];
396
397 /* Set up various known values */
398 cur_id = scanner_id_table;
399 while (cur_id->id)
400 {
401 if (!strncmp(sp->id_string+8, cur_id->id, strlen(cur_id->id)))
402 break;
403 cur_id++;
404 }
405
406 if (cur_id->id)
407 {
408 hw = cur_id->hw;
409 }
410 else if (sp->scanheadwidth == 5104)
411 {
412 /* Guess 600dpi scanner */
413 hw = &hw_alien600;
414 }
415 else if (sp->scanheadwidth == 2552)
416 {
417 /* Guess 300dpi scanner */
418 hw = &hw_alien300;
419 }
420 else
421 {
422 /* Guinea Pigs :) */
423 hw = &hw_alien;
424 }
425
426 strcpy(sp->name, hw->name);
427 sp->natural_xresolution = hw->natural_xresolution;
428 sp->natural_yresolution = hw->natural_yresolution;
429 sp->scanbedlength = hw->scanbedlength;
430 if (hw->scanheadwidth)
431 sp->scanheadwidth = hw->scanheadwidth;
432 sp->type = hw->type;
433
434 return 0;
435 }
436
437 /* Shut scanner down */
sanei_canon_pp_close_scanner(scanner_parameters *sp)438 int sanei_canon_pp_close_scanner(scanner_parameters *sp)
439 {
440 /* Put scanner in transparent mode */
441 sanei_canon_pp_sleep_scanner(sp->port);
442
443 /* Free memory (with purchase of memory of equal or greater value) */
444 if (sp->blackweight != NULL)
445 {
446 free(sp->blackweight);
447 sp->blackweight = NULL;
448 }
449 if (sp->redweight != NULL)
450 {
451 free(sp->redweight);
452 sp->redweight = NULL;
453 }
454 if (sp->greenweight != NULL)
455 {
456 free(sp->greenweight);
457 sp->greenweight = NULL;
458 }
459 if (sp->blueweight != NULL)
460 {
461 free(sp->blueweight);
462 sp->blueweight = NULL;
463 }
464
465 return 0;
466 }
467
468 /* Read the calibration information from file */
sanei_canon_pp_load_weights(const char *filename, scanner_parameters *sp)469 int sanei_canon_pp_load_weights(const char *filename, scanner_parameters *sp)
470 {
471 int fd;
472 int cal_data_size = sp->scanheadwidth * sizeof(unsigned long);
473 int cal_file_size;
474
475 char buffer[10];
476 int temp, ret;
477
478 /* Open file */
479 if ((fd = open(filename, O_RDONLY)) == -1)
480 return -1;
481
482 /* Read header and check it's right */
483 ret = safe_read(fd, buffer, strlen(header) + 1);
484 if ((ret < 0) || strcmp(buffer, header) != 0)
485 {
486 DBG(1,"Calibration file header is wrong, recalibrate please\n");
487 close(fd);
488 return -2;
489 }
490
491 /* Read and check file version (the calibrate file
492 format changes from time to time) */
493 ret = safe_read(fd, (char *)&temp, sizeof(int));
494
495 if ((ret < 0) || (temp != fileversion))
496 {
497 DBG(1,"Calibration file is wrong version, recalibrate please\n");
498 close(fd);
499 return -3;
500 }
501
502 /* Allocate memory for calibration values */
503 if (((sp->blueweight = malloc(cal_data_size)) == NULL)
504 || ((sp->redweight = malloc(cal_data_size)) == NULL)
505 || ((sp->greenweight = malloc(cal_data_size)) == NULL)
506 || ((sp->blackweight = malloc(cal_data_size)) == NULL))
507 return -4;
508
509 /* Read width of calibration data */
510 ret = safe_read(fd, (char *)&cal_file_size, sizeof(cal_file_size));
511
512 if ((ret < 0) || (cal_file_size != sp->scanheadwidth))
513 {
514 DBG(1, "Calibration doesn't match scanner, recalibrate?\n");
515 close(fd);
516 return -5;
517 }
518
519 /* Read calibration data */
520 if (safe_read(fd, (char *)(sp->blackweight), cal_data_size) < 0)
521 {
522 DBG(1, "Error reading black calibration data, recalibrate?\n");
523 close(fd);
524 return -6;
525 }
526
527 if (safe_read(fd, (char *)sp->redweight, cal_data_size) < 0)
528 {
529 DBG(1, "Error reading red calibration data, recalibrate?\n");
530 close(fd);
531 return -7;
532 }
533
534 if (safe_read(fd, (char *)sp->greenweight, cal_data_size) < 0)
535 {
536 DBG(1, "Error reading green calibration data, recalibrate?\n");
537 close(fd);
538 return -8;
539 }
540
541 if (safe_read(fd, (char *)sp->blueweight, cal_data_size) < 0)
542 {
543 DBG(1, "Error reading blue calibration data, recalibrate?\n");
544 close(fd);
545 return -9;
546 }
547
548 /* Read white-balance/gamma data */
549
550 if (safe_read(fd, (char *)&(sp->gamma), 32) < 0)
551 {
552 close(fd);
553 return -10;
554 }
555
556 close(fd);
557
558 return 0;
559 }
560
561 /* Mode is 0 for greyscale source data or 1 for RGB */
convert_to_rgb(image_segment *dest, unsigned char *src, int width, int scanlines, int mode)562 static void convert_to_rgb(image_segment *dest, unsigned char *src,
563 int width, int scanlines, int mode)
564 {
565 int curline;
566
567 const int colour_size = width * 1.25;
568 const int scanline_size = (mode == 0 ? colour_size : colour_size * 3);
569
570 for (curline = 0; curline < scanlines; curline++)
571 {
572
573 if (mode == 0) /* Grey */
574 {
575 convdata(src + (curline * scanline_size),
576 dest->image_data +
577 (curline * width * 2), width, 1);
578 }
579 else if (mode == 1) /* Truecolour */
580 {
581 /* Red */
582 convdata(src + (curline * scanline_size),
583 dest->image_data +
584 (curline * width *3*2) + 4, width, 2);
585 /* Green */
586 convdata(src + (curline * scanline_size) + colour_size,
587 dest->image_data +
588 (curline * width *3*2) + 2, width, 2);
589 /* Blue */
590 convdata(src + (curline * scanline_size) +
591 (2 * colour_size), dest->image_data +
592 (curline * width *3*2), width, 2);
593 }
594
595 } /* End of scanline loop */
596
597 }
598
sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp, scan_parameters *scanp, int scanline_number, int do_adjust, int scanlines_left)599 int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
600 scan_parameters *scanp, int scanline_number, int do_adjust,
601 int scanlines_left)
602 {
603 unsigned char *input_buffer = NULL;
604 image_segment *output_image = NULL;
605
606 unsigned char packet_header[4];
607 unsigned char packet_req_command[10];
608
609 int read_data_size;
610 int scanline_size;
611
612 if (scanp->mode == 1) /* RGB */
613 scanline_size = scanp->width * 3.75;
614 else /* Greyscale */
615 scanline_size = scanp->width * 1.25;
616
617 read_data_size = scanline_size * scanline_number;
618
619 /* Allocate output_image struct */
620 if ((output_image = malloc(sizeof(*output_image))) == NULL)
621 {
622 DBG(1, "read_segment: Error: Not enough memory for scanner "
623 "input buffer\n");
624 goto error_out;
625 }
626
627 /* Allocate memory for input buffer */
628 if ((input_buffer = malloc(scanline_size * scanline_number)) == NULL)
629 {
630 DBG(1, "read_segment: Error: Not enough memory for scanner "
631 "input buffer\n");
632 goto error_out;
633 }
634
635 output_image->width = scanp->width;
636 output_image->height = scanline_number;
637
638 /* Allocate memory for dest image segment */
639
640 output_image->image_data =
641 malloc(output_image->width * output_image->height *
642 (scanp->mode ? 3 : 1) * 2);
643
644 if (output_image->image_data == NULL)
645 {
646 DBG(1, "read_segment: Error: Not enough memory for "
647 "image data\n");
648 goto error_out;
649 }
650
651 /* Set up packet request command */
652 memcpy(packet_req_command, cmd_packet_req, 10);
653 packet_req_command[7] = ((read_data_size + 4) & 0xFF00) >> 8;
654 packet_req_command[8] = (read_data_size + 4) & 0xFF;
655
656 /* Send packet req. and wait for the scanner's READY signal */
657 if (send_command(sp->port, packet_req_command, 10, 9000, 2000000))
658 {
659 DBG(1, "read_segment: Error: didn't get response within 2s "
660 "of sending request");
661 goto error_out;
662 }
663
664 /* Read packet header */
665 if (sanei_canon_pp_read(sp->port, 4, packet_header))
666 {
667 DBG(1, "read_segment: Error reading packet header\n");
668 goto error_out;
669 }
670
671 if ((packet_header[2]<<8) + packet_header[3] != read_data_size)
672 {
673 DBG(1, "read_segment: Error: Expected data size: %i bytes.\n",
674 read_data_size);
675 DBG(1, "read_segment: Expecting %i bytes times %i "
676 "scanlines.\n", scanline_size, scanline_number);
677 DBG(1, "read_segment: Actual data size: %i bytes.\n",
678 (packet_header[2] << 8) + packet_header[3]);
679 goto error_out;
680 }
681
682 /* Read scanlines_this_packet scanlines into the input buf */
683
684 if (sanei_canon_pp_read(sp->port, read_data_size, input_buffer))
685 {
686 DBG(1, "read_segment: Segment read incorrectly, and we don't "
687 "know how to recover.\n");
688 goto error_out;
689 }
690
691 /* This is the only place we can abort safely -
692 * between reading one segment and requesting the next one. */
693 if (sp->abort_now) goto error_out;
694
695 if (scanlines_left >= (scanline_number * 2))
696 {
697 DBG(100, "read_segment: Speculatively starting more scanning "
698 "(%d left)\n", scanlines_left);
699 sanei_canon_pp_write(sp->port, 10, packet_req_command);
700 /* Don't read status, it's unlikely to be ready *just* yet */
701 }
702
703 DBG(100, "read_segment: Convert to RGB\n");
704 /* Convert data */
705 convert_to_rgb(output_image, input_buffer, scanp->width,
706 scanline_number, scanp->mode);
707
708 /* Adjust pixel readings according to calibration data */
709 if (do_adjust) {
710 DBG(100, "read_segment: Adjust output\n");
711 adjust_output(output_image, scanp, sp);
712 }
713
714 /* output */
715 *dest = output_image;
716 /* finished with this now */
717 free(input_buffer);
718 return 0;
719
720 error_out:
721 if (output_image && output_image->image_data)
722 free(output_image->image_data);
723 if (output_image) free(output_image);
724 if (input_buffer) free(input_buffer);
725 sp->abort_now = 0;
726 return -1;
727 }
728
729 /*
730 check8: Calculates the checksum-8 for s bytes pointed to by p.
731
732 For messages from the scanner, this should normally end up returning
733 0, since the last byte of most packets is the value that makes the
734 total up to 0 (or 256 if you're left-handed).
735 Hence, usage: if (check8(buffer, size)) {DBG(10, "checksum error!\n");}
736
737 Can also be used to generate valid checksums for sending to the scanner.
738 */
check8(unsigned char *p, int s)739 static int check8(unsigned char *p, int s) {
740 int total=0,i;
741 for(i=0;i<s;i++)
742 total-=(signed char)p[i];
743 total &=0xFF;
744 return total;
745 }
746
747 /* Converts from scanner format -> linear
748 width is in pixels, not bytes. */
749 /* This function could use a rewrite */
convdata(unsigned char *srcbuffer, unsigned char *dstbuffer, int width, int mode)750 static void convdata(unsigned char *srcbuffer, unsigned char *dstbuffer,
751 int width, int mode)
752 /* This is a tricky (read: crap) function (read: hack) which is why I probably
753 spent more time commenting it than programming it. The thing to remember
754 here is that the scanner uses interpolated scanlines, so it's
755 RRRRRRRGGGGGGBBBBBB not RGBRGBRGBRGBRGB. So, the calling function just
756 increments the destination pointer slightly to handle green, then a bit
757 more for blue. If you don't understand, tough. */
758 {
759 int count;
760 int i, j, k;
761
762 for (count = 0; count < width; count++)
763 {
764 /* The scanner stores data in a bizarre butchered 10-bit
765 format. I'll try to explain it in 100 words or less:
766
767 Scanlines are made up of groups of 4 pixels. Each group of
768 4 is stored inside 5 bytes. The first 4 bytes of the group
769 contain the lowest 8 bits of one pixel each (in the right
770 order). The 5th byte contains the most significant 2 bits
771 of each pixel in the same order. */
772
773 i = srcbuffer[count + (count >> 2)]; /* Low byte for pixel */
774 j = srcbuffer[(((count / 4) + 1) * 5) - 1]; /* "5th" byte */
775 j = j >> ((count % 4) * 2); /* Get upper 2 bits of intensity */
776 j = j & 0x03; /* Can't hurt */
777 /* And the final 10-bit pixel value is: */
778 k = (j << 8) | i;
779
780 /* now we return this as a 16 bit value */
781 k = k << 6;
782
783 if (mode == 1) /* Scanner -> Grey */
784 {
785 dstbuffer[count * 2] = HIGH_BYTE(k);
786 dstbuffer[(count * 2) + 1] = LOW_BYTE(k);
787 }
788 else if (mode == 2) /* Scanner -> RGB */
789 {
790 dstbuffer[count * 3 * 2] = HIGH_BYTE(k);
791 dstbuffer[(count * 3 * 2) + 1] = LOW_BYTE(k);
792 }
793
794 }
795 }
796
adjust_output(image_segment *image, scan_parameters *scanp, scanner_parameters *scannerp)797 static int adjust_output(image_segment *image, scan_parameters *scanp,
798 scanner_parameters *scannerp)
799 /* Needing a good cleanup */
800 {
801 /* light and dark points for the CCD sensor in question
802 * (stored in file as 0-1024, scaled to 0-65536) */
803 unsigned long hi, lo;
804 /* The result of our calculations */
805 unsigned long result;
806 unsigned long temp;
807 /* The CCD sensor which read the current pixel - this is a tricky value
808 to get right. */
809 int ccd, scaled_xoff;
810 /* Loop variables */
811 unsigned int scanline, pixelnum, colour;
812 unsigned long int pixel_address;
813 unsigned int cols = scanp->mode ? 3 : 1;
814
815 for (scanline = 0; scanline < image->height; scanline++)
816 {
817 for (pixelnum = 0; pixelnum < image->width; pixelnum++)
818 {
819 /* Figure out CCD sensor number */
820 /* MAGIC FORMULA ALERT! */
821 ccd = (pixelnum << (scannerp->natural_xresolution -
822 scanp->xresolution)) + (1 <<
823 (scannerp->natural_xresolution
824 - scanp->xresolution)) - 1;
825
826 scaled_xoff = scanp->xoffset <<
827 (scannerp->natural_xresolution -
828 scanp->xresolution);
829
830 ccd += scaled_xoff;
831
832 for (colour = 0; colour < cols; colour++)
833 {
834 /* Address of pixel under scrutiny */
835 pixel_address =
836 (scanline * image->width * cols * 2) +
837 (pixelnum * cols * 2) + (colour * 2);
838
839 /* Dark value is easy
840 * Range of lo is 0-18k */
841 lo = (scannerp->blackweight[ccd]) * 3;
842
843 /* Light value depends on the colour,
844 * and is an average in greyscale mode. */
845 if (scanp->mode == 1) /* RGB */
846 {
847 switch (colour)
848 {
849 case 0: hi = scannerp->redweight[ccd] * 3;
850 break;
851 case 1: hi = scannerp->greenweight[ccd] * 3;
852 break;
853 default: hi = scannerp->blueweight[ccd] * 3;
854 break;
855 }
856 }
857 else /* Grey - scanned using green */
858 {
859 hi = scannerp->greenweight[ccd] * 3;
860 }
861
862 /* Check for bad calibration data as it
863 can cause a divide-by-0 error */
864 if (hi <= lo)
865 {
866 DBG(1, "adjust_output: Bad cal data!"
867 " hi: %ld lo: %ld\n"
868 "Recalibrate, that "
869 "should fix it.\n",
870 hi, lo);
871 return -1;
872 }
873
874 /* Start with the pixel value in result */
875 result = MAKE_SHORT(*(image->image_data +
876 pixel_address),
877 *(image->image_data +
878 pixel_address + 1));
879
880 result = result >> 6; /* Range now = 0-1023 */
881 /*
882 if (scanline == 10)
883 DBG(200, "adjust_output: Initial pixel"
884 " value: %ld\n",
885 result);
886 */
887 result *= 54; /* Range now = 0-54k */
888
889 /* Clip to dark and light values */
890 if (result < lo) result = lo;
891 if (result > hi) result = hi;
892
893 /* result = (base-lo) * max_value / (hi-lo) */
894 temp = result - lo;
895 temp *= 65536;
896 temp /= (hi - lo);
897
898 /* Clip output result has been clipped to lo,
899 * and hi >= lo, so temp can't be < 0 */
900 if (temp > 65535)
901 temp = 65535;
902 /*
903 if (scanline == 10)
904 {
905 DBG(200, "adjust_output: %d: base = "
906 "%lu, result %lu (%lu "
907 "- %lu)\n", pixelnum,
908 result, temp, lo, hi);
909 }
910 */
911 result = temp;
912
913 /* Store the value back where it came
914 * from (always bigendian) */
915 *(image->image_data + pixel_address)
916 = HIGH_BYTE(result);
917 *(image->image_data + pixel_address+1)
918 = LOW_BYTE(result);
919 }
920 }
921 }
922 /*DBG(100, "Finished adjusting output\n");*/
923 return 0;
924 }
925
926 /* Calibration run. Aborting allowed at "safe" points where the scanner won't
927 * be left in a crap state. */
sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)928 int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
929 {
930 int count, readnum, colournum, scanlinenum;
931 int outfile;
932
933 int scanline_size;
934
935 int scanline_count = 6;
936 /* Don't change this unless you also want to change do_adjust */
937 const int calibration_reads = 3;
938
939 unsigned char command_buffer[10];
940
941 image_segment image;
942 unsigned char *databuf;
943
944 char colours[3][6] = {"Red", "Green", "Blue"};
945
946 /* Calibration data is monochromatic (greyscale format) */
947 scanline_size = sp->scanheadwidth * 1.25;
948
949 /* 620P has to be difficult here... */
950 if (!(sp->type) ) scanline_count = 8;
951
952 /* Probably shouldn't have to abort *just* yet, but may as well check */
953 if (sp->abort_now) return -1;
954
955 DBG(40, "Calibrating %ix%i pixels calibration image "
956 "(%i bytes each scan).\n",
957 sp->scanheadwidth, scanline_count,
958 scanline_size * scanline_count);
959
960 /* Allocate memory for calibration data */
961 sp->blackweight = (unsigned long *)
962 calloc(sizeof(unsigned long), sp->scanheadwidth);
963 sp->redweight = (unsigned long *)
964 calloc(sizeof(unsigned long), sp->scanheadwidth);
965 sp->greenweight = (unsigned long *)
966 calloc(sizeof(unsigned long), sp->scanheadwidth);
967 sp->blueweight = (unsigned long *)
968 calloc(sizeof(unsigned long), sp->scanheadwidth);
969
970 /* The data buffer needs to hold a number of images (calibration_reads)
971 * per colour, each sp->scanheadwidth x scanline_count */
972 databuf = malloc(scanline_size * scanline_count * calibration_reads*3);
973
974 /* And allocate space for converted image data in this image_segment */
975 image.image_data = malloc(scanline_count * sp->scanheadwidth * 2 *
976 calibration_reads);
977 image.width = sp->scanheadwidth;
978 image.height = scanline_count * calibration_reads;
979
980 /* Sending the "dark calibration" command */
981 memcpy(command_buffer, cmd_calblack, 10);
982
983 /* Which includes the size of data we expect the scanner to return */
984 command_buffer[7] = ((scanline_size * scanline_count) & 0xff00) >> 8;
985 command_buffer[8] = (scanline_size * scanline_count) & 0xff;
986
987 DBG(40, "Step 1/3: Calibrating black level...\n");
988 for (readnum = 0; readnum < calibration_reads; readnum++)
989 {
990 DBG(40, " * Black scan number %d/%d.\n", readnum + 1,
991 calibration_reads);
992
993 if (sp->abort_now) return -1;
994
995 if (send_command(sp->port, command_buffer, 10, 100000, 5000000))
996 {
997 DBG(1, "Error reading black level!\n");
998 free (image.image_data);
999 free(databuf);
1000 return -1;
1001
1002 }
1003
1004 /* Black reference data */
1005 sanei_canon_pp_read(sp->port, scanline_size * scanline_count,
1006 databuf +
1007 (readnum * scanline_size * scanline_count));
1008 }
1009
1010 /* Convert scanner format to a greyscale 16bpp image */
1011 for (scanlinenum = 0;
1012 scanlinenum < scanline_count * calibration_reads;
1013 scanlinenum++)
1014 {
1015 convdata(databuf + (scanlinenum * scanline_size),
1016 image.image_data +
1017 (scanlinenum * sp->scanheadwidth*2),
1018 sp->scanheadwidth, 1);
1019 }
1020
1021 /* Take column totals */
1022 for (count = 0; count < sp->scanheadwidth; count++)
1023 {
1024 /* Value is normalised as if we took 6 scanlines, even if we
1025 * didn't (620P I'm looking at you!) */
1026 sp->blackweight[count] = (column_sum(&image, count) * 6)
1027 / scanline_count >> 6;
1028 }
1029
1030 /* 620P has to be difficult here... */
1031 if (!(sp->type) )
1032 {
1033 scanline_count = 6;
1034 image.height = scanline_count * calibration_reads;
1035 }
1036
1037 DBG(40, "Step 2/3: Gamma tables...\n");
1038 DBG(40, " * Requesting creation of new of gamma tables...\n");
1039 if (sp->abort_now) return -1;
1040 if (send_command(sp->port, cmd_cleargamma, 10, 100000, 5000000))
1041 {
1042 DBG(1,"Error sending gamma command!\n");
1043 free (image.image_data);
1044 free(databuf);
1045 return -1;
1046 }
1047
1048 DBG(20, " * Snoozing for 15 seconds while the scanner calibrates...");
1049 usleep(15000000);
1050 DBG(40, "done.\n");
1051
1052 DBG(40, " * Requesting gamma table values...");
1053 if (send_command(sp->port, cmd_readgamma, 10, 100000, 10000000))
1054 {
1055 DBG(1,"Error sending gamma table request!\n");
1056 free (image.image_data);
1057 free(databuf);
1058 return -1;
1059 }
1060 DBG(40, "done.\n");
1061
1062 DBG(40, " * Reading white-balance/gamma data... ");
1063 sanei_canon_pp_read(sp->port, 32, sp->gamma);
1064 DBG(40, "done.\n");
1065
1066 if (sp->abort_now) return -1;
1067
1068 memcpy(command_buffer, cmd_calcolour, 10);
1069
1070 /* Set up returned data size */
1071 command_buffer[7] = ((scanline_size * scanline_count) & 0xff00) >> 8;
1072 command_buffer[8] = (scanline_size * scanline_count) & 0xff;
1073
1074 DBG(40, "Step 3/3: Calibrating sensors...\n");
1075 /* Now for the RGB high-points */
1076 for (colournum = 1; colournum < 4; colournum++)
1077 {
1078 /* Set the colour we want to read */
1079 command_buffer[3] = colournum;
1080 for (readnum = 0; readnum < 3; readnum++)
1081 {
1082 DBG(10, " * %s sensors, scan number %d/%d.\n",
1083 colours[colournum-1], readnum + 1,
1084 calibration_reads);
1085
1086 if (sp->abort_now) return -1;
1087 if (send_command(sp->port, command_buffer, 10,
1088 100000, 5000000))
1089 {
1090 DBG(1,"Error sending scan request!");
1091 free (image.image_data);
1092 free(databuf);
1093 return -1;
1094 }
1095
1096 sanei_canon_pp_read(sp->port, scanline_size *
1097 scanline_count, databuf +
1098 (readnum * scanline_size *
1099 scanline_count));
1100
1101 }
1102
1103 /* Convert colour data from scanner format to RGB data */
1104 for (scanlinenum = 0; scanlinenum < scanline_count *
1105 calibration_reads; scanlinenum++)
1106 {
1107 convdata(databuf + (scanlinenum * scanline_size),
1108 image.image_data +
1109 (scanlinenum * sp->scanheadwidth * 2),
1110 sp->scanheadwidth, 1);
1111 }
1112
1113 /* Sum each column of the image and store the results in sp */
1114 for (count = 0; count < sp->scanheadwidth; count++)
1115 {
1116 if (colournum == 1)
1117 sp->redweight[count] =
1118 column_sum(&image, count) >> 6;
1119 else if (colournum == 2)
1120 sp->greenweight[count] =
1121 column_sum(&image, count) >> 6;
1122 else
1123 sp->blueweight[count] =
1124 column_sum(&image, count) >> 6;
1125 }
1126
1127 }
1128
1129 if (sp->abort_now) return -1;
1130
1131 /* cal_file == NUL indicates we want an in-memory scan only */
1132 if (cal_file != NULL)
1133 {
1134 DBG(40, "Writing calibration to %s\n", cal_file);
1135 outfile = open(cal_file, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1136 if (outfile < 0)
1137 {
1138 DBG(10, "Error opening cal file for writing\n");
1139 }
1140
1141 /* Header */
1142 if (safe_write(outfile, header, strlen(header) + 1) < 0)
1143 DBG(10, "Write error on calibration file %s", cal_file);
1144 if (safe_write(outfile, (const char *)&fileversion, sizeof(int)) < 0)
1145 DBG(10, "Write error on calibration file %s", cal_file);
1146
1147 /* Data */
1148 if (safe_write(outfile, (char *)&(sp->scanheadwidth),
1149 sizeof(sp->scanheadwidth)) < 0)
1150 DBG(10, "Write error on calibration file %s", cal_file);
1151 if (safe_write(outfile, (char *)(sp->blackweight),
1152 sp->scanheadwidth * sizeof(long)) < 0)
1153 DBG(10, "Write error on calibration file %s", cal_file);
1154 if (safe_write(outfile, (char *)(sp->redweight),
1155 sp->scanheadwidth * sizeof(long)) < 0)
1156 DBG(10, "Write error on calibration file %s", cal_file);
1157 if (safe_write(outfile, (char *)(sp->greenweight),
1158 sp->scanheadwidth * sizeof(long)) < 0)
1159 DBG(10, "Write error on calibration file %s", cal_file);
1160 if (safe_write(outfile, (char *)(sp->blueweight),
1161 sp->scanheadwidth * sizeof(long)) < 0)
1162 DBG(10, "Write error on calibration file %s", cal_file);
1163 if (safe_write(outfile, (char *)(sp->gamma), 32) < 0)
1164 DBG(10, "Write error on calibration file %s", cal_file);
1165
1166 close(outfile);
1167 }
1168
1169 free(databuf);
1170 free(image.image_data);
1171
1172 return 0;
1173 }
1174
column_sum(image_segment *image, int x)1175 static unsigned long column_sum(image_segment *image, int x)
1176 /* This gives us a number from 0-n*65535 where n is the height of the image */
1177 {
1178 unsigned int row, p;
1179 unsigned long total = 0;
1180
1181 p = x;
1182 for (row = 0; row < image->height; row++)
1183 {
1184 total+= MAKE_SHORT(image->image_data[2*p],
1185 image->image_data[2*p+1]);
1186 p += image->width;
1187 }
1188 return total;
1189 }
1190
1191
scanner_setup_params(unsigned char *buf, scanner_parameters *sp, scan_parameters *scanp)1192 static int scanner_setup_params(unsigned char *buf, scanner_parameters *sp,
1193 scan_parameters *scanp)
1194 {
1195 int scaled_width, scaled_height;
1196 int scaled_xoff, scaled_yoff;
1197
1198 /* Natural resolution (I think) */
1199 if (sp->scanheadwidth == 2552)
1200 {
1201 buf[0] = 0x11; /* 300 | 0x1000 */
1202 buf[1] = 0x2c;
1203 buf[2] = 0x11;
1204 buf[3] = 0x2c;
1205 } else {
1206 buf[0] = 0x12; /* 600 | 0x1000*/
1207 buf[1] = 0x58;
1208 buf[2] = 0x12;
1209 buf[3] = 0x58;
1210 }
1211
1212 scaled_width = scanp->width <<
1213 (sp->natural_xresolution - scanp->xresolution);
1214 /* YO! This needs fixing if we ever use yresolution! */
1215 scaled_height = scanp->height <<
1216 (sp->natural_xresolution - scanp->xresolution);
1217 scaled_xoff = scanp->xoffset <<
1218 (sp->natural_xresolution - scanp->xresolution);
1219 scaled_yoff = scanp->yoffset <<
1220 (sp->natural_xresolution - scanp->xresolution);
1221
1222 /* Input resolution */
1223 buf[4] = (((75 << scanp->xresolution) & 0xff00) >> 8) | 0x10;
1224 buf[5] = (75 << scanp->xresolution) & 0xff;
1225 /* Interpolated resolution */
1226 buf[6] = (((75 << scanp->xresolution) & 0xff00) >> 8) | 0x10;;
1227 buf[7] = (75 << scanp->xresolution) & 0xff;
1228
1229 /* X offset */
1230 buf[8] = (scaled_xoff & 0xff000000) >> 24;
1231 buf[9] = (scaled_xoff & 0xff0000) >> 16;
1232 buf[10] = (scaled_xoff & 0xff00) >> 8;
1233 buf[11] = scaled_xoff & 0xff;
1234
1235 /* Y offset */
1236 buf[12] = (scaled_yoff & 0xff000000) >> 24;
1237 buf[13] = (scaled_yoff & 0xff0000) >> 16;
1238 buf[14] = (scaled_yoff & 0xff00) >> 8;
1239 buf[15] = scaled_yoff & 0xff;
1240
1241 /* Width of image to be scanned */
1242 buf[16] = (scaled_width & 0xff000000) >> 24;
1243 buf[17] = (scaled_width & 0xff0000) >> 16;
1244 buf[18] = (scaled_width & 0xff00) >> 8;
1245 buf[19] = scaled_width & 0xff;
1246
1247 /* Height of image to be scanned */
1248 buf[20] = (scaled_height & 0xff000000) >> 24;
1249 buf[21] = (scaled_height & 0xff0000) >> 16;
1250 buf[22] = (scaled_height & 0xff00) >> 8;
1251 buf[23] = scaled_height & 0xff;
1252
1253
1254 /* These appear to be the only two colour mode possibilities.
1255 Pure black-and-white mode probably just uses greyscale and
1256 then gets its contrast adjusted by the driver. I forget. */
1257 if (scanp->mode == 1) /* Truecolour */
1258 buf[24] = 0x08;
1259 else /* Greyscale */
1260 buf[24] = 0x04;
1261
1262 return 0;
1263 }
1264
sanei_canon_pp_abort_scan(scanner_parameters *sp)1265 int sanei_canon_pp_abort_scan(scanner_parameters *sp)
1266 {
1267 /* The abort command (hopefully) */
1268 sanei_canon_pp_write(sp->port, 10, cmd_abort);
1269 sanei_canon_pp_check_status(sp->port);
1270 return 0;
1271 }
1272
1273 /* adjust_gamma: Upload a gamma profile to the scanner */
sanei_canon_pp_adjust_gamma(scanner_parameters *sp)1274 int sanei_canon_pp_adjust_gamma(scanner_parameters *sp)
1275 {
1276 sp->gamma[31] = check8(sp->gamma, 31);
1277 if (sanei_canon_pp_write(sp->port, 10, cmd_setgamma))
1278 return -1;
1279 if (sanei_canon_pp_write(sp->port, 32, sp->gamma))
1280 return -1;
1281
1282 return 0;
1283 }
1284
sanei_canon_pp_sleep_scanner(struct parport *port)1285 int sanei_canon_pp_sleep_scanner(struct parport *port)
1286 {
1287 /* *SCANEND Command - puts scanner to sleep */
1288 sanei_canon_pp_write(port, 10, cmd_scanend);
1289 sanei_canon_pp_check_status(port);
1290
1291 ieee1284_terminate(port);
1292
1293 return 0;
1294 /* FIXME: I murdered Simon's code here */
1295 /* expect(port, "Enter Transparent Mode", 0x1f, 0x1f, 1000000); */
1296 }
1297
sanei_canon_pp_detect(struct parport *port, int mode)1298 int sanei_canon_pp_detect(struct parport *port, int mode)
1299 {
1300 /*int caps;*/
1301 /* This code needs to detect whether or not a scanner is present on
1302 * the port, quickly and reliably. Fast version of
1303 * sanei_canon_pp_initialise()
1304 *
1305 * If this detect returns true, a more comprehensive check will
1306 * be conducted
1307 * Return values:
1308 * 0 = scanner present
1309 * anything else = scanner not present
1310 * PRE: port is open/unclaimed
1311 * POST: port is closed/unclaimed
1312 */
1313
1314 /* port is already open, just need to claim it */
1315
1316 if (ieee1284_claim(port) != E1284_OK)
1317 {
1318 DBG(0,"detect: Unable to claim port\n");
1319 return 2;
1320 }
1321 if (sanei_canon_pp_wake_scanner(port, mode))
1322 {
1323 DBG(10, "detect: could not wake scanner\n");
1324 ieee1284_release(port);
1325 return 3;
1326 }
1327
1328 /* Goodo, sleep (snaps fingers) */
1329 sanei_canon_pp_sleep_scanner(port);
1330
1331 ieee1284_release(port);
1332 /* ieee1284_close(port); */
1333
1334 return 0;
1335 }
1336
send_command(struct parport *port, unsigned char *buf, int bufsize, int delay, int timeout)1337 static int send_command(struct parport *port, unsigned char *buf, int bufsize,
1338 int delay, int timeout)
1339 /* Sends a command until the scanner says it is ready.
1340 * sleeps for delay microsecs between reads
1341 * returns -1 on error, -2 on timeout */
1342 {
1343 int retries = 0;
1344
1345 do
1346 {
1347 /* Send command */
1348 if (sanei_canon_pp_write(port, bufsize, buf))
1349 return -1;
1350
1351 /* sleep a bit */
1352 usleep(delay);
1353 } while (sanei_canon_pp_check_status(port) &&
1354 retries++ < (timeout/delay));
1355
1356 if (retries >= (timeout/delay)) return -2;
1357 return 0;
1358
1359 }
1360