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-2008 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#include "../include/sane/config.h" 44 45#include <stdio.h> 46#include <stdlib.h> 47#include <string.h> 48#include <stdarg.h> 49#include <ctype.h> 50#include <math.h> /* pow(C90) */ 51 52#include <sys/time.h> /* gettimeofday(4.3BSD) */ 53#include <unistd.h> /* usleep */ 54 55#if defined(HAVE_LIBXML2) 56# include <libxml/parser.h> 57#endif 58 59#include "pixma_rename.h" 60#include "pixma_common.h" 61#include "pixma_io.h" 62 63#include "../include/sane/sanei_usb.h" 64#include "../include/sane/sane.h" 65 66#ifdef __GNUC__ 67# define UNUSED(v) (void) v 68#else 69# define UNUSED(v) 70#endif 71 72extern const pixma_config_t pixma_mp150_devices[]; 73extern const pixma_config_t pixma_mp750_devices[]; 74extern const pixma_config_t pixma_mp730_devices[]; 75extern const pixma_config_t pixma_mp800_devices[]; 76extern const pixma_config_t pixma_iclass_devices[]; 77 78static const pixma_config_t *const pixma_devices[] = { 79 pixma_mp150_devices, 80 pixma_mp750_devices, 81 pixma_mp730_devices, 82 pixma_mp800_devices, 83 pixma_iclass_devices, 84 NULL 85}; 86 87static pixma_t *first_pixma = NULL; 88static time_t tstart_sec = 0; 89static uint32_t tstart_usec = 0; 90static int debug_level = 1; 91 92 93#ifndef NDEBUG 94 95static void 96u8tohex (uint8_t x, char *str) 97{ 98 static const char hdigit[16] = 99 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 100 'e', 'f' 101 }; 102 str[0] = hdigit[(x >> 4) & 0xf]; 103 str[1] = hdigit[x & 0xf]; 104 str[2] = '\0'; 105} 106 107static void 108u32tohex (uint32_t x, char *str) 109{ 110 u8tohex (x >> 24, str); 111 u8tohex (x >> 16, str + 2); 112 u8tohex (x >> 8, str + 4); 113 u8tohex (x, str + 6); 114} 115 116void 117pixma_hexdump (int level, const void *d_, unsigned len) 118{ 119 const uint8_t *d = (const uint8_t *) (d_); 120 unsigned ofs, c, plen; 121 char line[100]; /* actually only 1+8+1+8*3+1+8*3+1 = 61 bytes needed */ 122 123 if (level > debug_level) 124 return; 125 if (level == debug_level) 126 /* if debuglevel == exact match and buffer contains more than 3 lines, print 2 lines + .... */ 127 plen = (len > 64) ? 32: len; 128 else 129 plen = len; 130 ofs = 0; 131 while (ofs < plen) 132 { 133 char *p; 134 line[0] = ' '; 135 u32tohex (ofs, line + 1); 136 line[9] = ':'; 137 p = line + 10; 138 for (c = 0; c != 16 && (ofs + c) < plen; c++) 139 { 140 u8tohex (d[ofs + c], p); 141 p[2] = ' '; 142 p += 3; 143 if (c == 7) 144 { 145 p[0] = ' '; 146 p++; 147 } 148 } 149 for (c = 0; c < 4; c++) 150 { 151 p[0] = ' '; 152 p++; 153 } 154 for (c = 0; c != 16 && (ofs + c) < plen; c++) 155 { 156 if (isprint(d[ofs + c])) 157 p[0] = d[ofs + c]; 158 else 159 p[0] = '.'; 160 p++; 161 if (c == 7) 162 { 163 p[0] = ' '; 164 p++; 165 } 166 } 167 p[0] = '\0'; 168 pixma_dbg (level, "%s\n", line); 169 ofs += c; 170 } 171 if (len > plen) 172 pixma_dbg(level, "......\n"); 173} 174 175static void 176time2str (char *buf, unsigned size) 177{ 178 time_t sec; 179 uint32_t usec; 180 181 pixma_get_time (&sec, &usec); 182 sec -= tstart_sec; 183 if (usec >= tstart_usec) 184 { 185 usec -= tstart_usec; 186 } 187 else 188 { 189 usec = 1000000 + usec - tstart_usec; 190 sec--; 191 } 192 snprintf (buf, size, "%lu.%03u", (unsigned long) sec, 193 (unsigned) (usec / 1000)); 194} 195 196void 197pixma_dump (int level, const char *type, const void *data, int len, 198 int size, int max) 199{ 200 int actual_len, print_len; 201 char buf[20]; 202 203 if (level > debug_level) 204 return; 205 if (debug_level >= 20) 206 max = -1; /* dump every bytes */ 207 208 time2str (buf, sizeof (buf)); 209 pixma_dbg (level, "%s T=%s len=%d\n", type, buf, len); 210 211 actual_len = (size >= 0) ? size : len; 212 print_len = (max >= 0 && max < actual_len) ? max : actual_len; 213 if (print_len >= 0) 214 { 215 pixma_hexdump (level, data, print_len); 216 if (print_len < actual_len) 217 pixma_dbg (level, " ...\n"); 218 } 219 if (len < 0) 220 pixma_dbg (level, " ERROR: %s\n", pixma_strerror (len)); 221 pixma_dbg (level, "\n"); 222} 223 224 225#endif /* NDEBUG */ 226 227/* NOTE: non-reentrant */ 228const char * 229pixma_strerror (int error) 230{ 231 static char buf[50]; 232 233 /* TODO: more human friendly messages */ 234 switch (error) 235 { 236 case PIXMA_EIO: 237 return "EIO"; 238 case PIXMA_ENODEV: 239 return "ENODEV"; 240 case PIXMA_EACCES: 241 return "EACCES"; 242 case PIXMA_ENOMEM: 243 return "ENOMEM"; 244 case PIXMA_EINVAL: 245 return "EINVAL"; 246 case PIXMA_EBUSY: 247 return "EBUSY"; 248 case PIXMA_ECANCELED: 249 return "ECANCELED"; 250 case PIXMA_ENOTSUP: 251 return "ENOTSUP"; 252 case PIXMA_ETIMEDOUT: 253 return "ETIMEDOUT"; 254 case PIXMA_EPROTO: 255 return "EPROTO"; 256 case PIXMA_EPAPER_JAMMED: 257 return "EPAPER_JAMMED"; 258 case PIXMA_ECOVER_OPEN: 259 return "ECOVER_OPEN"; 260 case PIXMA_ENO_PAPER: 261 return "ENO_PAPER"; 262 case PIXMA_EOF: 263 return "EEOF"; 264 } 265 snprintf (buf, sizeof (buf), "EUNKNOWN:%d", error); 266 return buf; 267} 268 269void 270pixma_set_debug_level (int level) 271{ 272 debug_level = level; 273} 274 275void 276pixma_set_be16 (uint16_t x, uint8_t * buf) 277{ 278 buf[0] = x >> 8; 279 buf[1] = x; 280} 281 282void 283pixma_set_be32 (uint32_t x, uint8_t * buf) 284{ 285 buf[0] = x >> 24; 286 buf[1] = x >> 16; 287 buf[2] = x >> 8; 288 buf[3] = x; 289} 290 291uint16_t 292pixma_get_be16 (const uint8_t * buf) 293{ 294 return ((uint16_t) buf[0] << 8) | buf[1]; 295} 296 297uint32_t 298pixma_get_be32 (const uint8_t * buf) 299{ 300 return ((uint32_t) buf[0] << 24) + ((uint32_t) buf[1] << 16) + 301 ((uint32_t) buf[2] << 8) + buf[3]; 302} 303 304uint8_t 305pixma_sum_bytes (const void *data, unsigned len) 306{ 307 const uint8_t *d = (const uint8_t *) data; 308 unsigned i, sum = 0; 309 for (i = 0; i != len; i++) 310 sum += d[i]; 311 return sum; 312} 313 314void 315pixma_sleep (unsigned long usec) 316{ 317 usleep (usec); 318} 319 320void 321pixma_get_time (time_t * sec, uint32_t * usec) 322{ 323 struct timeval tv; 324 gettimeofday (&tv, NULL); 325 if (sec) 326 *sec = tv.tv_sec; 327 if (usec) 328 *usec = tv.tv_usec; 329} 330 331/* convert 24/48 bit RGB to 8/16 bit ir 332 * 333 * Formular: g = R 334 * drop G + B 335 * 336 * sptr: source color scale buffer 337 * gptr: destination gray scale buffer 338 * c == 3: 24 bit RGB -> 8 bit ir 339 * c == 6: 48 bit RGB -> 16 bit ir 340 */ 341uint8_t * 342pixma_r_to_ir (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c) 343{ 344 unsigned i; 345 346 /* PDBG (pixma_dbg (4, "*pixma_rgb_to_ir*****\n")); */ 347 348 for (i = 0; i < w; i++) 349 { 350 *gptr++ = *sptr++; 351 if (c == 6) *gptr++ = *sptr++; /* 48 bit RGB: high byte */ 352 sptr += (c == 6) ? 4 : 2; /* drop G + B */ 353 } 354 return gptr; 355} 356 357/* convert 24/48 bit RGB to 8/16 bit grayscale 358 * 359 * Formular: Y' = 0,2126 R' + 0,7152 G' + 0,0722 B' 360 * 361 * sptr: source color scale buffer 362 * gptr: destination gray scale buffer 363 * c == 3: 24 bit RGB -> 8 bit gray 364 * c == 6: 48 bit RGB -> 16 bit gray 365 */ 366uint8_t * 367pixma_rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c) 368{ 369 unsigned i, g; 370 371 /* PDBG (pixma_dbg (4, "*pixma_rgb_to_gray*****\n")); */ 372 373 for (i = 0; i < w; i++) 374 { 375 if (c == 6) 376 { /* 48 bit RGB */ 377 unsigned r = sptr[0] + (sptr[1] << 8); 378 unsigned y = sptr[2] + (sptr[3] << 8); 379 unsigned b = sptr[4] + (sptr[5] << 8); 380 381 g = (r * 2126) + (y * 7152) + (b * 722); 382 sptr += 6; 383 } 384 else 385 { /* 24 bit RGB */ 386 g = (sptr[0] * 2126) + (sptr[1] * 7152) + (sptr[2] * 722); 387 sptr += 3; 388 } 389 g /= 10000; /* 8 and 16 bit gray */ 390 391 *gptr++ = g; 392 if (c == 6) *gptr++ = (g >> 8); /* 16 bit gray: high byte */ 393 } 394 return gptr; 395} 396 397/** 398 * This code was taken from the genesys backend 399 * uses threshold and threshold_curve to control software binarization 400 * @param sp device set up for the scan 401 * @param dst pointer where to store result 402 * @param src pointer to raw data 403 * @param width width of the processed line 404 * @param c 1 for 1-channel single-byte data, 405 * 3 for 3-channel single-byte data, 406 * 6 for double-byte data 407 * */ 408uint8_t * 409pixma_binarize_line(pixma_scan_param_t * sp, uint8_t * dst, uint8_t * src, unsigned width, unsigned c) 410{ 411 unsigned j, x, windowX, sum = 0; 412 unsigned threshold; 413 unsigned offset, addCol; 414 int dropCol, offsetX; 415 unsigned char mask; 416 uint8_t min, max; 417 418 /* PDBG (pixma_dbg (4, "*pixma_binarize_line***** src = %u, dst = %u, width = %u, c = %u, threshold = %u, threshold_curve = %u *****\n", 419 src, dst, width, c, sp->threshold, sp->threshold_curve)); */ 420 421 /* 16 bit grayscale not supported */ 422 if (c == 6) 423 { 424 PDBG (pixma_dbg (1, "*pixma_binarize_line***** Error: 16 bit grayscale not supported\n")); 425 return dst; 426 } 427 428 /* first, color convert to grayscale */ 429 if (c != 1) 430 pixma_rgb_to_gray(dst, src, width, c); 431 432 /* second, normalize line */ 433 min = 255; 434 max = 0; 435 for (x = 0; x < width; x++) 436 { 437 if (src[x] > max) 438 { 439 max = src[x]; 440 } 441 if (src[x] < min) 442 { 443 min = src[x]; 444 } 445 } 446 447 /* safeguard against dark or white areas */ 448 if(min>80) 449 min=0; 450 if(max<80) 451 max=255; 452 for (x = 0; x < width; x++) 453 { 454 src[x] = ((src[x] - min) * 255) / (max - min); 455 } 456 457 /* third, create sliding window, prefill the sliding sum */ 458 /* ~1mm works best, but the window needs to have odd # of pixels */ 459 windowX = (6 * sp->xdpi) / 150; 460 if (!(windowX % 2)) 461 windowX++; 462 463 /* to avoid conflicts with *dst start with offset */ 464 offsetX = 1 + (windowX / 2) / 8; 465 for (j = offsetX; j <= windowX; j++) 466 sum += src[j]; 467 /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** windowX = %u, startX = %u, sum = %u\n", 468 windowX, startX, sum)); */ 469 470 /* fourth, walk the input buffer, output bits */ 471 for (j = 0; j < width; j++) 472 { 473 /* output image location */ 474 offset = j % 8; 475 mask = 0x80 >> offset; 476 threshold = sp->threshold; 477 478 /* move sum/update threshold only if there is a curve */ 479 if (sp->threshold_curve) 480 { 481 addCol = j + windowX / 2; 482 dropCol = addCol - windowX; 483 484 if (dropCol >= offsetX && addCol < width) 485 { 486 sum += src[addCol]; 487 sum -= (sum < src[dropCol] ? sum : src[dropCol]); /* no negative sum */ 488 } 489 threshold = sp->lineart_lut[sum / windowX]; 490 /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** addCol = %u, dropCol = %d, sum = %u, windowX = %u, lut-element = %d, threshold = %u\n", 491 addCol, dropCol, sum, windowX, sum/windowX, threshold)); */ 492 } 493 494 /* lookup threshold */ 495 if (src[j] > threshold) 496 *dst &= ~mask; /* white */ 497 else 498 *dst |= mask; /* black */ 499 500 if (offset == 7) 501 dst++; 502 } 503 504 /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** ready: src = %u, dst = %u *****\n", src, dst)); */ 505 506 return dst; 507} 508 509/** 510 This code was taken from the genesys backend 511 Function to build a lookup table (LUT), often 512 used by scanners to implement brightness/contrast/gamma 513 or by backends to speed binarization/thresholding 514 515 offset and slope inputs are -127 to +127 516 517 slope rotates line around central input/output val, 518 0 makes horizontal line 519 520 pos zero neg 521 . x . . x 522 . x . . x 523 out . x .xxxxxxxxxxx . x 524 . x . . x 525 ....x....... ............ .......x.... 526 in in in 527 528 offset moves line vertically, and clamps to output range 529 0 keeps the line crossing the center of the table 530 531 high low 532 . xxxxxxxx . 533 . x . 534 out x . x 535 . . x 536 ............ xxxxxxxx.... 537 in in 538 539 out_min/max provide bounds on output values, 540 useful when building thresholding lut. 541 0 and 255 are good defaults otherwise. 542 * */ 543static SANE_Status 544load_lut (unsigned char * lut, 545 int in_bits, int out_bits, 546 int out_min, int out_max, 547 int slope, int offset) 548{ 549 int i, j; 550 double shift, rise; 551 int max_in_val = (1 << in_bits) - 1; 552 int max_out_val = (1 << out_bits) - 1; 553 unsigned char * lut_p = lut; 554 555 /* PDBG (pixma_dbg (4, "*load_lut***** start %d %d *****\n", slope, offset)); */ 556 557 /* slope is converted to rise per unit run: 558 * first [-127,127] to [-1,1] 559 * then multiply by PI/2 to convert to radians 560 * then take the tangent (T.O.A) 561 * then multiply by the normal linear slope 562 * because the table may not be square, i.e. 1024x256*/ 563 rise = tan((double)slope/127 * M_PI/2) * max_out_val / max_in_val; 564 565 /* line must stay vertically centered, so figure 566 * out vertical offset at central input value */ 567 shift = (double)max_out_val/2 - (rise*max_in_val/2); 568 569 /* convert the user offset setting to scale of output 570 * first [-127,127] to [-1,1] 571 * then to [-max_out_val/2,max_out_val/2]*/ 572 shift += (double)offset / 127 * max_out_val / 2; 573 574 for(i=0;i<=max_in_val;i++){ 575 j = rise*i + shift; 576 577 if(j<out_min){ 578 j=out_min; 579 } 580 else if(j>out_max){ 581 j=out_max; 582 } 583 584 *lut_p=j; 585 lut_p++; 586 } 587 588 /* PDBG (pixma_dbg (4, "*load_lut***** finish *****\n")); */ 589 /* PDBG (pixma_hexdump (4, lut, max_in_val+1)); */ 590 591 return SANE_STATUS_GOOD; 592} 593 594int 595pixma_map_status_errno (unsigned status) 596{ 597 switch (status) 598 { 599 case PIXMA_STATUS_OK: 600 return 0; 601 case PIXMA_STATUS_FAILED: 602 return PIXMA_ECANCELED; 603 case PIXMA_STATUS_BUSY: 604 return PIXMA_EBUSY; 605 default: 606 return PIXMA_EPROTO; 607 } 608} 609 610int 611pixma_check_result (pixma_cmdbuf_t * cb) 612{ 613 const uint8_t *r = cb->buf; 614 unsigned header_len = cb->res_header_len; 615 unsigned expected_reslen = cb->expected_reslen; 616 int error; 617 unsigned len; 618 619 if (cb->reslen < 0) 620 return cb->reslen; 621 622 len = (unsigned) cb->reslen; 623 if (len >= header_len) 624 { 625 error = pixma_map_status_errno (pixma_get_be16 (r)); 626 if (expected_reslen != 0) 627 { 628 if (len == expected_reslen) 629 { 630 if (pixma_sum_bytes (r + header_len, len - header_len) != 0) 631 error = PIXMA_EPROTO; 632 } 633 else 634 { 635 /* This case will happen when a command cannot be completely 636 executed, e.g. because you press the cancel button. The 637 device will return only a header with PIXMA_STATUS_FAILED. */ 638 if (len != header_len) 639 error = PIXMA_EPROTO; 640 } 641 } 642 } 643 else 644 error = PIXMA_EPROTO; 645 646#ifndef NDEBUG 647 if (error == PIXMA_EPROTO) 648 { 649 pixma_dbg (1, "WARNING: result len=%d expected %d\n", 650 len, cb->expected_reslen); 651 pixma_hexdump (1, r, MIN (len, 64)); 652 } 653#endif 654 return error; 655} 656 657int 658pixma_cmd_transaction (pixma_t * s, const void *cmd, unsigned cmdlen, 659 void *data, unsigned expected_len) 660{ 661 int error, tmo; 662 663 error = pixma_write (s->io, cmd, cmdlen); 664 if (error != (int) cmdlen) 665 { 666 if (error >= 0) 667 { 668 /* Write timeout is too low? */ 669 PDBG (pixma_dbg 670 (1, "ERROR: incomplete write, %u out of %u written\n", 671 (unsigned) error, cmdlen)); 672 error = PIXMA_ETIMEDOUT; 673 } 674 return error; 675 } 676 677 /* When you send the start_session command while the scanner optic is 678 going back to the home position after the last scan session has been 679 cancelled, you won't get the response before it arrives home. This takes 680 about 5 seconds. If the last session was succeeded, the scanner will 681 immediately answer with PIXMA_STATUS_BUSY. 682 683 Is 8 seconds timeout enough? This affects ALL commands that use 684 pixma_cmd_transaction(). Default value set in pixma_open(). */ 685 tmo = s->rec_tmo; 686 do 687 { 688 error = pixma_read (s->io, data, expected_len); 689 if (error == PIXMA_ETIMEDOUT) 690 { 691 PDBG (pixma_dbg (2, "No response yet. Timed out in %d sec.\n", tmo)); 692 693#ifndef HAVE_SANEI_USB_SET_TIMEOUT 694 /* 1s timeout 695 Only needed, if sanei_usb_set_timeout() isn't available. 696 pixma_read() has an internal timeout of 1 sec. */ 697 pixma_sleep (1000000); 698#endif 699 } 700 } 701 while (error == PIXMA_ETIMEDOUT && --tmo != 0); 702 if (error < 0) 703 { 704 PDBG (pixma_dbg (1, "WARNING: Error in response phase. cmd:%02x%02x\n", 705 ((const uint8_t *) cmd)[0], 706 ((const uint8_t *) cmd)[1])); 707 PDBG (pixma_dbg (1," If the scanner hangs, reset it and/or unplug the " 708 "USB cable.\n")); 709 } 710 return error; /* length of the result packet or error */ 711} 712 713uint8_t * 714pixma_newcmd (pixma_cmdbuf_t * cb, unsigned cmd, 715 unsigned dataout, unsigned datain) 716{ 717 unsigned cmdlen = cb->cmd_header_len + dataout; 718 unsigned reslen = cb->res_header_len + datain; 719 720 if (cmdlen > cb->size || reslen > cb->size) 721 return NULL; 722 memset (cb->buf, 0, cmdlen); 723 cb->cmdlen = cmdlen; 724 cb->expected_reslen = reslen; 725 pixma_set_be16 (cmd, cb->buf); 726 pixma_set_be16 (dataout + datain, cb->buf + cb->cmd_len_field_ofs); 727 if (dataout != 0) 728 return cb->buf + cb->cmd_header_len; 729 else 730 return cb->buf + cb->res_header_len; 731} 732 733int 734pixma_exec (pixma_t * s, pixma_cmdbuf_t * cb) 735{ 736 if (cb->cmdlen > cb->cmd_header_len) 737 pixma_fill_checksum (cb->buf + cb->cmd_header_len, 738 cb->buf + cb->cmdlen - 1); 739 cb->reslen = 740 pixma_cmd_transaction (s, cb->buf, cb->cmdlen, cb->buf, 741 cb->expected_reslen); 742 return pixma_check_result (cb); 743} 744 745int 746pixma_exec_short_cmd (pixma_t * s, pixma_cmdbuf_t * cb, unsigned cmd) 747{ 748 pixma_newcmd (cb, cmd, 0, 0); 749 return pixma_exec (s, cb); 750} 751 752int 753pixma_check_dpi (unsigned dpi, unsigned max) 754{ 755 /* valid dpi = 75 * 2^n */ 756 unsigned temp = dpi / 75; 757 if (dpi > max || dpi < 75 || 75 * temp != dpi || (temp & (temp - 1)) != 0) 758 return PIXMA_EINVAL; 759 return 0; 760} 761 762 763int 764pixma_init (void) 765{ 766 PDBG (pixma_dbg (2, "pixma version %d.%d.%d\n", PIXMA_VERSION_MAJOR, 767 PIXMA_VERSION_MINOR, PIXMA_VERSION_BUILD)); 768 PASSERT (first_pixma == NULL); 769 if (tstart_sec == 0) 770 pixma_get_time (&tstart_sec, &tstart_usec); 771 return pixma_io_init (); 772} 773 774void 775pixma_cleanup (void) 776{ 777 while (first_pixma) 778 pixma_close (first_pixma); 779 pixma_io_cleanup (); 780} 781 782int 783pixma_open (unsigned devnr, pixma_t ** handle) 784{ 785 int error; 786 pixma_t *s; 787 const pixma_config_t *cfg; 788 789 *handle = NULL; 790 cfg = pixma_get_device_config (devnr); 791 if (!cfg) 792 return PIXMA_EINVAL; /* invalid devnr */ 793 PDBG (pixma_dbg (2, "pixma_open(): %s\n", cfg->name)); 794 795 s = (pixma_t *) calloc (1, sizeof (s[0])); 796 if (!s) 797 return PIXMA_ENOMEM; 798 s->next = first_pixma; 799 first_pixma = s; 800 801 s->cfg = cfg; 802 s->rec_tmo = 8; /* set receive timeout to 8 seconds */ 803 error = pixma_connect (devnr, &s->io); 804 if (error < 0) 805 { 806 PDBG (pixma_dbg 807 (2, "pixma_connect() failed %s\n", pixma_strerror (error))); 808 goto rollback; 809 } 810 strncpy (s->id, pixma_get_device_id (devnr), sizeof (s->id) - 1); 811 s->ops = s->cfg->ops; 812 s->scanning = 0; 813 s->last_source = PIXMA_SOURCE_NONE; 814 error = s->ops->open (s); 815 if (error < 0) 816 goto rollback; 817 error = pixma_deactivate (s->io); 818 if (error < 0) 819 goto rollback; 820 *handle = s; 821 return 0; 822 823rollback: 824 PDBG (pixma_dbg (2, "pixma_open() failed %s\n", pixma_strerror (error))); 825 pixma_close (s); 826 return error; 827} 828 829void 830pixma_close (pixma_t * s) 831{ 832 pixma_t **p; 833 834 if (!s) 835 return; 836 for (p = &first_pixma; *p && *p != s; p = &((*p)->next)) 837 { 838 } 839 PASSERT (*p); 840 if (!(*p)) 841 return; 842 PDBG (pixma_dbg (2, "pixma_close(): %s\n", s->cfg->name)); 843 if (s->io) 844 { 845 if (s->scanning) 846 { 847 PDBG (pixma_dbg (3, "pixma_close(): scanning in progress, call" 848 " finish_scan()\n")); 849 s->ops->finish_scan (s); 850 } 851 s->ops->close (s); 852 pixma_disconnect (s->io); 853 } 854 *p = s->next; 855 free (s); 856} 857 858int 859pixma_scan (pixma_t * s, pixma_scan_param_t * sp) 860{ 861 int error; 862 863 error = pixma_check_scan_param (s, sp); 864 if (error < 0) 865 return error; 866 867 if (sp->mode == PIXMA_SCAN_MODE_LINEART) 868 { 869 load_lut(sp->lineart_lut, 8, 8, 50, 205, 870 sp->threshold_curve, sp->threshold-127); 871 } 872 873#ifndef NDEBUG 874 pixma_dbg (3, "\n"); 875 pixma_dbg (3, "pixma_scan(): start\n"); 876 pixma_dbg (3, " line_size=%"PRIu64" image_size=%"PRIu64" channels=%u depth=%u\n", 877 sp->line_size, sp->image_size, sp->channels, sp->depth); 878 pixma_dbg (3, " dpi=%ux%u offset=(%u,%u) dimension=%ux%u\n", 879 sp->xdpi, sp->ydpi, sp->x, sp->y, sp->w, sp->h); 880 pixma_dbg (3, " gamma=%f gamma_table=%p source=%d\n", sp->gamma, (void *) sp->gamma_table, sp->source); 881 pixma_dbg (3, " threshold=%d threshold_curve=%d\n", sp->threshold, sp->threshold_curve); 882 pixma_dbg (3, " adf-wait=%d\n", sp->adf_wait); 883 pixma_dbg (3, " ADF page count: %d\n", sp->adf_pageid); 884#endif 885 886 s->param = sp; 887 s->cancel = 0; 888 s->cur_image_size = 0; 889 s->imagebuf.wptr = NULL; 890 s->imagebuf.wend = NULL; 891 s->imagebuf.rptr = NULL; 892 s->imagebuf.rend = NULL; 893 s->underrun = 0; 894 error = s->ops->scan (s); 895 if (error >= 0) 896 { 897 s->scanning = 1; 898 } 899 else 900 { 901 PDBG (pixma_dbg 902 (3, "pixma_scan() failed %s\n", pixma_strerror (error))); 903 } 904 905 return error; 906} 907 908static uint8_t * 909fill_pixels (pixma_t * s, uint8_t * ptr, uint8_t * end, uint8_t value) 910{ 911 if (s->cur_image_size < s->param->image_size) 912 { 913 long n = s->param->image_size - s->cur_image_size; 914 if (n > (end - ptr)) 915 n = end - ptr; 916 memset (ptr, value, n); 917 s->cur_image_size += n; 918 ptr += n; 919 } 920 return ptr; 921} 922 923int 924pixma_read_image (pixma_t * s, void *buf, unsigned len) 925{ 926 int result; 927 pixma_imagebuf_t ib; 928 929 if (!s->scanning) 930 return 0; 931 if (s->cancel) 932 { 933 result = PIXMA_ECANCELED; 934 goto cancel; 935 } 936 937 ib = s->imagebuf; /* get rptr and rend */ 938 ib.wptr = (uint8_t *) buf; 939 ib.wend = ib.wptr + len; 940 941 if (s->underrun) 942 { 943 if (s->cur_image_size < s->param->image_size) 944 { 945 ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff); 946 } 947 else 948 { 949 PDBG (pixma_dbg 950 (3, "pixma_read_image(): completed (underrun detected)\n")); 951 s->scanning = 0; 952 } 953 return ib.wptr - (uint8_t *) buf; 954 } 955 956 while (ib.wptr != ib.wend) 957 { 958 if (ib.rptr == ib.rend) 959 { 960 ib.rptr = ib.rend = NULL; 961 result = s->ops->fill_buffer (s, &ib); 962 if (result < 0) 963 goto cancel; 964 if (result == 0) 965 { /* end of image? */ 966 s->ops->finish_scan (s); 967 /* set last source after successful scan */ 968 s->last_source = s->param->source; 969 if ((s->cur_image_size != s->param->image_size) && !s->param->mode_jpeg) 970 { 971 PDBG (pixma_dbg (1, "WARNING:image size mismatches\n")); 972 PDBG (pixma_dbg (1, 973 " %"PRIu64" expected (%d lines) but %"PRIu64" received (%"PRIu64" lines)\n", 974 s->param->image_size, s->param->h, 975 s->cur_image_size, 976 s->cur_image_size / s->param->line_size)); 977 if ((s->cur_image_size % s->param->line_size) != 0) 978 { 979 PDBG (pixma_dbg (1, 980 "BUG:received data not multiple of line_size\n")); 981 } 982 } 983 if ((s->cur_image_size < s->param->image_size) && !s->param->mode_jpeg) 984 { 985 s->underrun = 1; 986 ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff); 987 } 988 else 989 { 990 PDBG (pixma_dbg (3, "pixma_read_image():completed\n")); 991 s->scanning = 0; 992 } 993 break; 994 } 995 s->cur_image_size += result; 996 997 PASSERT (s->cur_image_size <= s->param->image_size); 998 } 999 if (ib.rptr) 1000 { 1001 unsigned count = MIN (ib.rend - ib.rptr, ib.wend - ib.wptr); 1002 memcpy (ib.wptr, ib.rptr, count); 1003 ib.rptr += count; 1004 ib.wptr += count; 1005 } 1006 } 1007 s->imagebuf = ib; /* store rptr and rend */ 1008 return ib.wptr - (uint8_t *) buf; 1009 1010cancel: 1011 s->ops->finish_scan (s); 1012 s->scanning = 0; 1013 if (result == PIXMA_ECANCELED) 1014 { 1015 PDBG (pixma_dbg (3, "pixma_read_image(): cancelled by %sware\n", 1016 (s->cancel) ? "soft" : "hard")); 1017 } 1018 else 1019 { 1020 PDBG (pixma_dbg (3, "pixma_read_image() failed %s\n", 1021 pixma_strerror (result))); 1022 } 1023 return result; 1024} 1025 1026void 1027pixma_cancel (pixma_t * s) 1028{ 1029 s->cancel = 1; 1030} 1031 1032int 1033pixma_enable_background (pixma_t * s, int enabled) 1034{ 1035 return pixma_set_interrupt_mode (s->io, enabled); 1036} 1037 1038int 1039pixma_activate_connection(pixma_t * s) 1040{ 1041 return pixma_activate (s->io); 1042} 1043 1044int 1045pixma_deactivate_connection(pixma_t * s) 1046{ 1047 return pixma_deactivate (s->io); 1048} 1049 1050uint32_t 1051pixma_wait_event (pixma_t * s, int timeout /*ms */ ) 1052{ 1053 unsigned events; 1054 1055 if (s->events == PIXMA_EV_NONE && s->ops->wait_event) 1056 s->ops->wait_event (s, timeout); 1057 events = s->events; 1058 s->events = PIXMA_EV_NONE; 1059 return events; 1060} 1061 1062#define CLAMP2(x,w,min,max,dpi) do { \ 1063 unsigned m = (max) * (dpi) / 75; \ 1064 x = MIN(x, m - min); \ 1065 w = MIN(w, m - x); \ 1066 if (w < min) w = min; \ 1067} while(0) 1068 1069int 1070pixma_check_scan_param (pixma_t * s, pixma_scan_param_t * sp) 1071{ 1072 unsigned cfg_xdpi; 1073 1074 if (!(sp->channels == 3 || 1075 (sp->channels == 1 && (s->cfg->cap & PIXMA_CAP_GRAY) != 0))) 1076 return PIXMA_EINVAL; 1077 1078 /* flatbed: use s->cfg->xdpi 1079 * TPU/ADF: use s->cfg->adftpu_max_dpi, if configured with dpi value */ 1080 cfg_xdpi = ((sp->source == PIXMA_SOURCE_FLATBED 1081 || s->cfg->adftpu_max_dpi == 0) ? s->cfg->xdpi 1082 : s->cfg->adftpu_max_dpi); 1083 1084 if (pixma_check_dpi (sp->xdpi, cfg_xdpi) < 0 || 1085 pixma_check_dpi (sp->ydpi, s->cfg->ydpi) < 0) 1086 return PIXMA_EINVAL; 1087 1088 /* xdpi must be equal to ydpi except that 1089 xdpi = max_xdpi and ydpi = max_ydpi. */ 1090 if (!(sp->xdpi == sp->ydpi || 1091 (sp->xdpi == cfg_xdpi && sp->ydpi == s->cfg->ydpi))) 1092 return PIXMA_EINVAL; 1093 1094 if (s->ops->check_param (s, sp) < 0) 1095 return PIXMA_EINVAL; 1096 1097 /* FIXME: I assume the same minimum width and height for every model. 1098 * new scanners need minimum 16 px height 1099 * minimum image size: 16 px x 16 px */ 1100 CLAMP2 (sp->x, sp->w, 16, s->cfg->width, sp->xdpi); 1101 CLAMP2 (sp->y, sp->h, 16, s->cfg->height, sp->ydpi); 1102 1103 switch (sp->source) 1104 { 1105 case PIXMA_SOURCE_FLATBED: 1106 break; 1107 1108 case PIXMA_SOURCE_TPU: 1109 if ((s->cfg->cap & PIXMA_CAP_TPU) != PIXMA_CAP_TPU) 1110 { 1111 sp->source = PIXMA_SOURCE_FLATBED; 1112 PDBG (pixma_dbg 1113 (1, "WARNING: TPU unsupported, fallback to flatbed.\n")); 1114 } 1115 break; 1116 1117 case PIXMA_SOURCE_ADF: 1118 if ((s->cfg->cap & PIXMA_CAP_ADF) != PIXMA_CAP_ADF) 1119 { 1120 sp->source = PIXMA_SOURCE_FLATBED; 1121 PDBG (pixma_dbg 1122 (1, "WARNING: ADF unsupported, fallback to flatbed.\n")); 1123 } 1124 break; 1125 1126 case PIXMA_SOURCE_ADFDUP: 1127 if ((s->cfg->cap & PIXMA_CAP_ADFDUP) != PIXMA_CAP_ADFDUP) 1128 { 1129 if (s->cfg->cap & PIXMA_CAP_ADF) 1130 { 1131 sp->source = PIXMA_SOURCE_ADF; 1132 } 1133 else 1134 { 1135 sp->source = PIXMA_SOURCE_FLATBED; 1136 } 1137 PDBG (pixma_dbg 1138 (1, "WARNING: ADF duplex unsupported, fallback to %d.\n", 1139 sp->source)); 1140 } 1141 break; 1142 case PIXMA_SOURCE_NONE: 1143 /* this source can not be selected */ 1144 break; 1145 } 1146 1147 if (sp->depth == 0) 1148 sp->depth = 8; 1149 if ((sp->depth % 8) != 0 && sp->depth != 1) 1150 return PIXMA_EINVAL; 1151 1152 sp->line_size = 0; 1153 1154 if (s->ops->check_param (s, sp) < 0) 1155 return PIXMA_EINVAL; 1156 1157 if (sp->line_size == 0) 1158 sp->line_size = sp->depth / 8 * sp->channels * sp->w; 1159 sp->image_size = sp->line_size * sp->h; 1160 1161 /* image_size for software lineart is counted in bits */ 1162 if (sp->software_lineart == 1) 1163 sp->image_size /= 8; 1164 return 0; 1165} 1166 1167const char * 1168pixma_get_string (pixma_t * s, pixma_string_index_t i) 1169{ 1170 switch (i) 1171 { 1172 case PIXMA_STRING_MODEL: 1173 return s->cfg->name; 1174 case PIXMA_STRING_ID: 1175 return s->id; 1176 case PIXMA_STRING_LAST: 1177 return NULL; 1178 } 1179 return NULL; 1180} 1181 1182const pixma_config_t * 1183pixma_get_config (pixma_t * s) 1184{ 1185 return s->cfg; 1186} 1187 1188void 1189pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n) 1190{ 1191 unsigned i; 1192 double r_gamma = 1.0 / gamma; 1193 double in_scale = 1.0 / (n - 1); 1194 1195 /* 8-bits gamma table 1196 * for generation 1 scanners 1197 */ 1198 if (n == 4096) 1199 { 1200 double out_scale = 255.0; 1201 1202 for (i = 0; (unsigned) i != n; i++) 1203 { 1204 table[i] = (int) (out_scale * pow (i * in_scale, r_gamma) + 0.5); 1205 } 1206 } 1207 1208 /* 16-bits gamma table */ 1209 else 1210 { 1211 double out_scale = 65535.0; 1212 uint16_t value; 1213 1214 for (i = 0; i < n; i++) 1215 { 1216 value = (uint16_t) (out_scale * pow (i * in_scale, r_gamma) + 0.5); 1217 table[2 * i] = (uint8_t) (value & 0xff); 1218 table[2 * i + 1] = (uint8_t) (value >> 8); 1219 } 1220 } 1221} 1222 1223int 1224pixma_find_scanners (const char **conf_devices, SANE_Bool local_only) 1225{ 1226 return pixma_collect_devices (conf_devices, pixma_devices, local_only); 1227} 1228 1229const char * 1230pixma_get_device_model (unsigned devnr) 1231{ 1232 const pixma_config_t *cfg = pixma_get_device_config (devnr); 1233 return (cfg) ? cfg->name : NULL; 1234} 1235 1236 1237int 1238pixma_get_device_status (pixma_t * s, pixma_device_status_t * status) 1239{ 1240 if (!status) 1241 return PIXMA_EINVAL; 1242 memset (status, 0, sizeof (*status)); 1243 return s->ops->get_status (s, status); 1244} 1245 1246unsigned 1247pixma_calc_calibrate (pixma_t * p) 1248{ 1249 pixma_scan_param_t * sp = p->param; 1250 if (sp->calibrate == PIXMA_CALIBRATE_ALWAYS) 1251 return 0x01; 1252 if (sp->calibrate == PIXMA_CALIBRATE_NEVER) 1253 return 0x00; 1254 /* sp->calibrate == PIXMA_CALIBRATE_ONCE */ 1255 if (sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP) 1256 return sp->adf_pageid == 0 ? 0x01 : 0x00; 1257 /* sp->source == PIXMA_SOURCE_FLATBED | TPU */ 1258 return sp->source == p->last_source ? 0x00 : 0x01; 1259} 1260 1261#if defined(HAVE_LIBXML2) 1262static const char * 1263format_xml_response(const char *resp_details) 1264{ 1265 if (strcmp(resp_details, "DeviceBusy") == 0) 1266 /* https://cromwell-intl.com/open-source/canon-pixma-printer-scanner.html */ 1267 return "DeviceBusy - Device not initialized (yet). " \ 1268 "Please check the USB power, try a different port or install the Ink Cartridges if the device supports them."; 1269 else if (strcmp(resp_details, "ScannerCarriageLockError") == 0) 1270 return "ScannerCarriageLockError - Please consult the manual to unlock the Carriage Lock."; 1271 else if (strcmp(resp_details, "PCScanning") == 0) 1272 return "PCScanning - Previous scan attempt was not completed. Try disconnecting and reconnecting the scanner. " \ 1273 "If the problem persists, consider reporting it as a bug at http://www.sane-project.org/bugs.html."; 1274 else if (strcmp(resp_details, "DeviceCheckError") == 0) 1275 return "DeviceCheckError - Device detected a fault. Contact the repair center."; 1276 else 1277 return resp_details; 1278} 1279 1280int 1281pixma_parse_xml_response(const char *xml_message) 1282{ 1283 int status = PIXMA_EPROTO; 1284 xmlDoc *doc = NULL; 1285 xmlNode *node = NULL; 1286 xmlChar *content = NULL; 1287 1288 doc = xmlReadMemory(xml_message, strlen(xml_message), "mem:device-resp.xml", NULL, 0); 1289 if (doc == NULL) { 1290 PDBG(pixma_dbg(10, "unable to parse xml response\n")); 1291 status = PIXMA_EINVAL; 1292 goto clean; 1293 } 1294 1295 node = xmlDocGetRootElement(doc); 1296 if (node == NULL) { 1297 status = PIXMA_EPROTO; 1298 goto clean; 1299 } 1300 1301 /* /cmd */ 1302 for (; node; node = node->next) { 1303 if (strcmp((const char*)node->name, "cmd") == 0) 1304 break; 1305 } 1306 if (!node) { 1307 status = PIXMA_EPROTO; 1308 goto clean; 1309 } 1310 1311 /* /cmd/contents */ 1312 for (node = node->children; node; node = node->next) { 1313 if (strcmp((const char*)node->name, "contents") == 0) 1314 break; 1315 } 1316 if (!node) { 1317 status = PIXMA_EPROTO; 1318 goto clean; 1319 } 1320 1321 /* /cmd/contents/param_set */ 1322 for (node = node->children; node; node = node->next) { 1323 if (strcmp((const char*)node->name, "param_set") == 0) 1324 break; 1325 } 1326 if (!node) { 1327 status = PIXMA_EPROTO; 1328 goto clean; 1329 } 1330 1331 /* /cmd/contents/param_set/response... */ 1332 for (node = node->children; node; node = node->next) 1333 { 1334 if (strcmp((const char*)node->name, "response") == 0) { 1335 content = xmlNodeGetContent(node); 1336 if (strcmp((const char*)content, "OK") == 0) 1337 status = PIXMA_STATUS_OK; 1338 else 1339 status = PIXMA_EINVAL; 1340 xmlFree(content); 1341 } else if (strcmp((const char*)node->name, "response_detail") == 0) { 1342 content = xmlNodeGetContent(node); 1343 if (strlen((const char*)content) > 0) { 1344 PDBG(pixma_dbg(0, "device response: %s\n", 1345 format_xml_response((const char*)content))); 1346 } 1347 xmlFree(content); 1348 } 1349 } 1350 1351clean: 1352 xmlFreeDoc(doc); 1353 return status; 1354} 1355#endif 1356