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