1/* sane - Scanner Access Now Easy. 2 3 This file is part of the SANE package, and implements a SANE backend 4 for various Canon DR-series scanners. 5 6 Copyright (C) 2008-2022 m. allan noah 7 8 Yabarana Corp. www.yabarana.com provided significant funding 9 EvriChart, Inc. www.evrichart.com provided funding and loaned equipment 10 Canon, USA. www.usa.canon.com loaned equipment 11 HPrint hprint.com.br provided funding and testing for DR-2510 support 12 Stone-IT www.stone-it.com provided funding for DR-2010 and DR-2050 support 13 Smartmatic www.smartmatic.com provided testing and changes for DR-X10C support 14 15 -------------------------------------------------------------------------- 16 17 This program is free software; you can redistribute it and/or 18 modify it under the terms of the GNU General Public License as 19 published by the Free Software Foundation; either version 2 of the 20 License, or (at your option) any later version. 21 22 This program is distributed in the hope that it will be useful, but 23 WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 General Public License for more details. 26 27 You should have received a copy of the GNU General Public License 28 along with this program. If not, see <https://www.gnu.org/licenses/>. 29 30 As a special exception, the authors of SANE give permission for 31 additional uses of the libraries contained in this release of SANE. 32 33 The exception is that, if you link a SANE library with other files 34 to produce an executable, this does not by itself cause the 35 resulting executable to be covered by the GNU General Public 36 License. Your use of that executable is in no way restricted on 37 account of linking the SANE library code into it. 38 39 This exception does not, however, invalidate any other reasons why 40 the executable file might be covered by the GNU General Public 41 License. 42 43 If you submit changes to SANE to the maintainers to be included in 44 a subsequent release, you agree by submitting the changes that 45 those changes may be distributed with this exception intact. 46 47 If you write modifications of your own for SANE, it is your choice 48 whether to permit this exception to apply to your modifications. 49 If you do not wish that, delete this exception notice. 50 51 -------------------------------------------------------------------------- 52 53 The source code is divided in sections which you can easily find by 54 searching for the tag "@@". 55 56 Section 1 - Init & static stuff 57 Section 2 - sane_init, _get_devices, _open & friends 58 Section 3 - sane_*_option functions 59 Section 4 - sane_start, _get_param, _read & friends 60 Section 5 - calibration functions 61 Section 6 - sane_close functions 62 Section 7 - misc functions 63 Section 8 - image processing functions 64 65 Changes: 66 v1 2008-10-29, MAN 67 - initial version 68 v2 2008-11-04, MAN 69 - round scanlines to even bytes 70 - spin RS and usb_clear_halt code into new function 71 - update various scsi payloads 72 - calloc out block so it gets set to 0 initially 73 v3 2008-11-07, MAN 74 - back window uses id 1 75 - add option and functions to read/send page counter 76 - add rif option 77 v4 2008-11-11, MAN 78 - eject document when sane_read() returns EOF 79 v5 2008-11-25, MAN 80 - remove EOF ejection code 81 - add SSM and GSM commands 82 - add dropout, doublefeed, and jpeg compression options 83 - disable adf backside 84 - fix adf duplex 85 - read two extra lines (ignore errors) at end of image 86 - only send scan command at beginning of batch 87 - fix bug in hexdump with 0 length string 88 - DR-7580 support 89 v6 2008-11-29, MAN 90 - fix adf simplex 91 - rename ssm_duplex to ssm_buffer 92 - add --buffer option 93 - reduce inter-page commands when buffering is enabled 94 - improve sense_handler output 95 - enable counter option 96 - drop unused code 97 v7 2008-11-29, MAN 98 - jpeg support (size rounding and header overwrite) 99 - call object_position(load) between pages even if buffering is on 100 - use request sense info bytes on short scsi reads 101 - byte swap color BGR to RGB 102 - round image width down, not up 103 - round image height down to even # of lines 104 - always transfer even # of lines per block 105 - scsi and jpeg don't require reading extra lines to reach EOF 106 - rename buffer option to buffermode to avoid conflict with scanimage 107 - send ssm_do and ssm_df during sane_start 108 - improve sense_handler output 109 v8 2008-12-07, MAN 110 - rename read/send_counter to read/send_panel 111 - enable control panel during init 112 - add options for all buttons 113 - call TUR twice in wait_scanner(), even if first succeeds 114 - disable rif 115 - enable brightness/contrast/threshold options 116 v9 2008-12-07, MAN 117 - add rollerdeskew and stapledetect options 118 - add rollerdeskew and stapledetect bits to ssm_df() 119 v10 2008-12-10, MAN 120 - add all documented request sense codes to sense_handler() 121 - fix color jpeg (remove unneeded BGR to RGB swapping code) 122 - add macros for LUT data 123 v11 2009-01-10, MAN 124 - send_panel() can disable too 125 - add cancel() to send d8 command 126 - call cancel() only after final read from scanner 127 - stop button requests cancel 128 v12 2009-01-21, MAN 129 - don't export private symbols 130 v13 2009-03-06, MAN 131 - new vendor ID for recent machines 132 - add usb ids for several new machines 133 v14 2009-03-07, MAN 134 - remove HARD_SELECT from counter (Legitimate, but API violation) 135 - attach to CR-series scanners as well 136 v15 2009-03-15, MAN 137 - add byte-oriented duplex interlace code 138 - add RRGGBB color interlace code 139 - add basic support for DR-2580C 140 v16 2009-03-20, MAN 141 - add more unknown setwindow bits 142 - add support for 16 byte status packets 143 - clean do_usb_cmd error handling (call reset more often) 144 - add basic support for DR-2050C, DR-2080C, DR-2510C 145 v17 2009-03-20, MAN 146 - set status packet size from config file 147 v18 2009-03-21, MAN 148 - rewrite config file parsing to reset options after each scanner 149 - add config options for vendor, model, version 150 - don't call inquiry if those 3 options are set 151 - remove default config file from code 152 - add initial gray deinterlacing code for DR-2510C 153 - rename do_usb_reset to do_usb_clear 154 v19 2009-03-22, MAN 155 - pad gray deinterlacing area for DR-2510C 156 - override tl_x and br_x for fixed width scanners 157 v20 2009-03-23, MAN 158 - improved macros for inquiry and set window 159 - shorten inquiry vpd length to match windows driver 160 - remove status-length config option 161 - add padded-read config option 162 - rewrite do_usb_cmd to pad reads and calloc/copy buffers 163 v21 2009-03-24, MAN 164 - correct rgb padding macro 165 - skip send_panel and ssm_df commands for DR-20xx scanners 166 v22 2009-03-25, MAN 167 - add deinterlacing code for DR-2510C in duplex and color 168 v23 2009-03-27, MAN 169 - rewrite all image data processing code 170 - handle more image interlacing formats 171 - re-enable binary mode on some scanners 172 - limit some machines to full-width scanning 173 v24 2009-04-02, MAN 174 - fix DR-2510C duplex deinterlacing code 175 - rewrite sane_read helpers to read until EOF 176 - update sane_start for scanners that don't use object_position 177 - don't call sanei_usb_clear_halt() if device is not open 178 - increase default buffer size to 4 megs 179 - set buffermode on by default 180 - hide modes and resolutions that DR-2510C lies about 181 - read_panel() logs front-end access to sensors instead of timing 182 - rewrite do_usb_cmd() to use remainder from RS info 183 v25 2009-04-12, MAN 184 - disable SANE_FRAME_JPEG 185 v26 2009-04-14, MAN (SANE 1.0.20) 186 - return cmd status for reads on sensors 187 - allow rs to adjust read length for all bad status responses 188 v27 2009-05-08, MAN 189 - bug fix in read_panel() 190 - initialize vars in do_usb_cmd() 191 - set buffermode off by default 192 - clear page counter during init and sane_start() 193 - eject previous page during init and sane_start() 194 - improved SSM_BUFF macros 195 - moved set_window() to after ssm-*() 196 - add coarse calibration (AFE offset/gain & per-channel exposure) 197 - add fine calibration (per-cell offset/gain) 198 - free image and fine cal buffers in sane_close() 199 - compare page counter of small scanners only in non-buffered mode 200 - add back-side gray mirroring code for DR-2580C 201 v28 2009-05-20, MAN 202 - use average instead of min/max for fine offset and gain 203 - rewrite supported resolution list as x and y arrays 204 - merge x and y resolution options into single option 205 - move scan params into two new structs, s->u and s->s 206 - sane_get_parameters() just returns values from s->u 207 - don't call wait_scanner() in object_position() 208 - don't call ssm_*() from option handler 209 - refactor sane_start() 210 - read_from_buffer() can workaround missing res, modes and cropping 211 - set most DR-2xxx machines to use the read_from_buffer workarounds 212 - set default threshold to 90 213 - add option for button #3 of some machines 214 - don't eject paper during init 215 - add DR-2010 quirks 216 - switch counter to HARD_SELECT, not SOFT 217 v29 2009-06-01, MAN 218 - split coarse and fine cal to run independently 219 - add side option 220 - reset scan params to user request if calibration fails 221 - better handling of sane_cancel 222 - better handling of errors during sane_start and sane_read 223 v30 2009-06-17, MAN 224 - add fine cal support for machines with internal buffer (2050/2080) 225 - support fixed-width machines that require even bytes per scanline 226 - pad end of scan with gray if scanner stops prematurely 227 - better handling of errors during calibration 228 - cleanup canceling debug messages 229 - remove old cancel() prototype 230 - small sleep before clearing usb halt condition 231 v31 2009-06-29, MAN 232 - reduce default buffer size to 2 megs 233 v32 2009-07-21, MAN 234 - crop/resample image data before buffering, not after 235 - shink image buffers to size of output image, not input 236 - correct some debug message 237 - better handling of EOF 238 - add intermediate param struct to existing user and scan versions 239 v33 2009-07-23, MAN 240 - add software brightness/contrast for dumb scanners 241 - add blocking mode to allow full-page manipulation options to run 242 - add swdespeck option and support code 243 - add swdeskew and swcrop options (disabled) 244 v34 2009-07-28, MAN 245 - add simplified Hough transform based deskewing code 246 - add extremity detecting cropping code 247 - use per-model background color to fill corners after deskew 248 - request and chop extra scanlines instead of rounding down 249 - remove padding dumb scanners add to top of front side 250 - sane_get_params uses intermediate struct instead of user struct 251 - if scanner stops, clone the last line until the end of buffer 252 - reset some intermediate params between duplex sides 253 v35 2010-02-09, MAN (SANE 1.0.21) 254 - cleanup #includes and copyright 255 - add SANE_I18N to static strings 256 - don't fail if scsi buffer is too small 257 v36 2011-01-03, MAN 258 - initial support for DR-3080 and DR-5060 259 - add code to clamp scan width to an arbitrary byte width boundary 260 - add code to prevent setting of brightness/threshold/contrast 261 - don't send dropout color command on non-color scanners 262 - initial support for DR-7090C 263 - update credits 264 v37 2011-01-26, MAN (SANE 1.0.22) 265 - don't center window when using flatbed 266 - improve request sense error messages 267 - enable flatbed for all known models 268 v38 2011-07-06, MAN 269 - initial support for DR-5020 270 - use ppl_mod instead of Bpl_mod, apply to all modes 271 - invert logic of read_panel tracking 272 - add ability to disable read_panel() 273 - automatically disable read/send_panel if unsupported 274 v39 2011-11-01, MAN 275 - DR-2580C pads the backside of duplex scans 276 v40 2012-11-01, MAN 277 - initial DR-9050C, DR-7550C, DR-6050C and DR-3010C support 278 v41 2013-07-31, MAN (SANE 1.0.24) 279 - initial P-208 and P-215 support 280 - bug fix for calibration of scanners with duplex_offset 281 - allow duplex_offset to be controlled from config file 282 v42 2013-12-09, MAN 283 - initial DR-G1100 support 284 - add support for paper sensors (P-215 & P-208) 285 - add initial support for card reader (P-215) 286 - removed unused var from do_scsi_cmd() 287 v43 2014-03-13, MAN 288 - initial DR-M140 support 289 - add extra_status config and code 290 - split status code into do_usb_status 291 - fix copy_line margin offset 292 - add new color interlacing modes and code 293 - comment out ssm2 294 - add timestamp to do_usb_cmd 295 v44 2014-03-26, MAN 296 - buffermode support for machines with ssm2 command 297 - DR-M140 needs always_op=0 298 v45 2014-03-29, MAN 299 - dropout support for machines with ssm2 command 300 - doublefeed support for machines with ssm2 command 301 v46 2014-04-09, MAN 302 - split debug level 30 into two levels 303 - simplify jpeg ifdefs 304 - add support for DR-M160 305 v47 2014-07-07, MAN 306 - initial DR-G1130 support 307 v48 2014-08-06, MAN 308 - set another unknown byte in buffermode for ssm2 309 - add another gettimeofday call at end of do_usb_cmd 310 - don't print 0 length line in hexdump 311 v49 2015-03-18, MAN 312 - initial support for DR-C125 313 v50 2015-08-23, MAN 314 - DR-C125 adds duplex padding on back side 315 - initial support for DR-C225 316 v51 2015-08-25, MAN (SANE 1.0.25) 317 - DR-C125 does not invert_tly, does need sw_lut 318 v52 2015-11-03, MAN 319 - set can_color=1 by default (recent models don't have 'C' in name) 320 - enable jpeg for DR-6080 321 - add must_downsample and must_fully_buffer 322 - improve dropout option handling 323 - add software dropout implementation for downsampled modes 324 v53 2015-11-06, MAN 325 - replace image processing methods with sanei_magic 326 - add swskip option 327 - reorder geometry group options 328 - use bg_color to fill missing image data 329 v54 2015-11-21, MAN 330 - br_x and br_y locked to page_width/height until changed 331 v55 2016-03-19, MAN 332 - fixed-width scanners were calculating left-side offset incorrectly in color 333 - initial support for DR-F120 334 - rename all DUPLEX_INTERLACE_* to indicate start and end of line 335 v56 2016-08-23, MAN 336 - initial support for P-150 337 v57 2019-02-24, manuarg 338 - complete support for X-10, including hardware cropping 339 v58 2019-11-10, MAN 340 - adjust wait_scanner to set runRS only as a last resort, bug #154 341 v59 2020-09-23, MAN 342 - restructure fine calibration code 343 - initial support for uploading fine calibration payloads 344 - improve DR-C225 support 345 v60 2020-11-28, MAN 346 - add new gray and color interlacing options for DR-C120 347 - initial support for DR-C120 and C130 348 - enable fine calibration for P-208 (per @sashacmc in !546) 349 v61 2021-02-13, MAN 350 - treat DR-P208 like P-208 (#356) 351 - treat DR-P215 like P-215 (#356) 352 - adjust wait_scanner to try one TUR with a long timeout (#142) 353 v62 2021-02-13, MAN 354 - allow config file to set inq and vpd lengths for DR-M1060 (#263) 355 - rewrite do_cmd() timeout handling 356 - remove long timeout TUR from v61 (did not help) 357 - allow config file to set initial tur timeout for DR-X10C (#142) 358 v63 2022-11-18, CQ, MAN 359 - add support for reading the total and roller counters 360 v64 2022-11-18, CQ, MAN 361 - add complete support for imprinters on X10C (#585) 362 363 SANE FLOW DIAGRAM 364 365 - sane_init() : initialize backend 366 . - sane_get_devices() : query list of scanner devices 367 . - sane_open() : open a particular scanner device 368 . . - sane_set_io_mode : set blocking mode 369 . . - sane_get_select_fd : get scanner fd 370 . . 371 . . - sane_get_option_descriptor() : get option information 372 . . - sane_control_option() : change option values 373 . . - sane_get_parameters() : returns estimated scan parameters 374 . . - (repeat previous 3 functions) 375 . . 376 . . - sane_start() : start image acquisition 377 . . - sane_get_parameters() : returns actual scan parameters 378 . . - sane_read() : read image data (from pipe) 379 . . (sane_read called multiple times; after sane_read returns EOF, 380 . . loop may continue with sane_start which may return a 2nd page 381 . . when doing duplex scans, or load the next page from the ADF) 382 . . 383 . . - sane_cancel() : cancel operation 384 . - sane_close() : close opened scanner device 385 - sane_exit() : terminate use of backend 386 387*/ 388 389/* 390 * @@ Section 1 - Init 391 */ 392 393#include "../include/sane/config.h" 394 395#include <string.h> /*memcpy...*/ 396#include <ctype.h> /*isspace*/ 397#include <math.h> /*tan*/ 398#include <unistd.h> /*usleep*/ 399#include <sys/time.h> /*gettimeofday*/ 400#include <time.h> /*localtime*/ 401#include <stdlib.h> /*strtol*/ 402 403#include "../include/sane/sanei_backend.h" 404#include "../include/sane/sanei_scsi.h" 405#include "../include/sane/sanei_usb.h" 406#include "../include/sane/saneopts.h" 407#include "../include/sane/sanei_config.h" 408#include "../include/sane/sanei_magic.h" 409 410#include "canon_dr-cmd.h" 411#include "canon_dr.h" 412 413#define DEBUG 1 414#define BUILD 64 415 416/* values for SANE_DEBUG_CANON_DR env var: 417 - errors 5 418 - function trace 10 419 - function detail 15 420 - get/setopt cmds 20 421 - scsi/usb trace 25 422 - scsi/usb writes 30 423 - scsi/usb reads 31 424 - useless noise 35 425*/ 426 427/* ------------------------------------------------------------------------- */ 428/* if JPEG support is not enabled in sane.h, we setup our own defines */ 429#ifndef SANE_FRAME_JPEG 430#define SANE_FRAME_JPEG 0x0B 431#define SANE_JPEG_DISABLED 1 432#endif 433/* ------------------------------------------------------------------------- */ 434#define STRING_FLATBED SANE_I18N("Flatbed") 435#define STRING_ADFFRONT SANE_I18N("ADF Front") 436#define STRING_ADFBACK SANE_I18N("ADF Back") 437#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex") 438#define STRING_CARDFRONT SANE_I18N("Card Front") 439#define STRING_CARDBACK SANE_I18N("Card Back") 440#define STRING_CARDDUPLEX SANE_I18N("Card Duplex") 441 442#define STRING_LINEART SANE_VALUE_SCAN_MODE_LINEART 443#define STRING_HALFTONE SANE_VALUE_SCAN_MODE_HALFTONE 444#define STRING_GRAYSCALE SANE_VALUE_SCAN_MODE_GRAY 445#define STRING_COLOR SANE_VALUE_SCAN_MODE_COLOR 446 447#define STRING_RED SANE_I18N("Red") 448#define STRING_GREEN SANE_I18N("Green") 449#define STRING_BLUE SANE_I18N("Blue") 450#define STRING_EN_RED SANE_I18N("Enhance Red") 451#define STRING_EN_GREEN SANE_I18N("Enhance Green") 452#define STRING_EN_BLUE SANE_I18N("Enhance Blue") 453 454#define STRING_NONE SANE_I18N("None") 455#define STRING_JPEG SANE_I18N("JPEG") 456 457#define STRING_IMPRINTER_8x12_FONT SANE_I18N("8x12") 458#define STRING_IMPRINTER_12x12_FONT SANE_I18N("12x12") 459 460#define STRING_IMPRINTER_ADDON_BoW SANE_I18N("Black-on-White") 461#define STRING_IMPRINTER_ADDON_BoI SANE_I18N("Black-on-Image") 462#define STRING_IMPRINTER_ADDON_WoB SANE_I18N("White-on-Black") 463 464/* Also set via config file. */ 465static int global_buffer_size; 466static int global_buffer_size_default = 2 * 1024 * 1024; 467static int global_padded_read; 468static int global_padded_read_default = 0; 469static int global_extra_status; 470static int global_extra_status_default = 0; 471static int global_duplex_offset; 472static int global_duplex_offset_default = 0; 473static int global_inquiry_length; 474static int global_vpd_length; 475static int global_tur_timeout; 476static int global_tur_timeout_default = USB_PACKET_TIMEOUT/60; /* half second */ 477static char global_vendor_name[9]; 478static char global_model_name[17]; 479static char global_version_name[5]; 480 481/* 482 * used by attach* and sane_get_devices 483 * a ptr to a null term array of ptrs to SANE_Device structs 484 * a ptr to a single-linked list of scanner structs 485 */ 486static const SANE_Device **sane_devArray = NULL; 487static struct scanner *scanner_devList = NULL; 488 489/* 490 * @@ Section 2 - SANE & scanner init code 491 */ 492 493/* 494 * Called by SANE initially. 495 * 496 * From the SANE spec: 497 * This function must be called before any other SANE function can be 498 * called. The behavior of a SANE backend is undefined if this 499 * function is not called first. The version code of the backend is 500 * returned in the value pointed to by version_code. If that pointer 501 * is NULL, no version code is returned. Argument authorize is either 502 * a pointer to a function that is invoked when the backend requires 503 * authentication for a specific resource or NULL if the frontend does 504 * not support authentication. 505 */ 506SANE_Status 507sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 508{ 509 (void) authorize; /* get rid of compiler warning */ 510 511 DBG_INIT (); 512 DBG (10, "sane_init: start\n"); 513 514 if (version_code) 515 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 516 517 DBG (5, "sane_init: canon_dr backend %d.%d.%d, from %s\n", 518 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 519 520 DBG (10, "sane_init: finish\n"); 521 522 return SANE_STATUS_GOOD; 523} 524 525/* 526 * Called by SANE to find out about supported devices. 527 * 528 * From the SANE spec: 529 * This function can be used to query the list of devices that are 530 * available. If the function executes successfully, it stores a 531 * pointer to a NULL terminated array of pointers to SANE_Device 532 * structures in *device_list. The returned list is guaranteed to 533 * remain unchanged and valid until (a) another call to this function 534 * is performed or (b) a call to sane_exit() is performed. This 535 * function can be called repeatedly to detect when new devices become 536 * available. If argument local_only is true, only local devices are 537 * returned (devices directly attached to the machine that SANE is 538 * running on). If it is false, the device list includes all remote 539 * devices that are accessible to the SANE library. 540 * 541 * SANE does not require that this function is called before a 542 * sane_open() call is performed. A device name may be specified 543 * explicitly by a user which would make it unnecessary and 544 * undesirable to call this function first. 545 */ 546/* 547 * Read the config file, find scanners with help from sanei_* 548 * and store in global device structs 549 */ 550SANE_Status 551sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 552{ 553 SANE_Status ret = SANE_STATUS_GOOD; 554 struct scanner * s; 555 struct scanner * prev = NULL; 556 char line[PATH_MAX]; 557 const char *lp; 558 FILE *fp; 559 int num_devices=0; 560 int i=0; 561 562 (void) local_only; /* get rid of compiler warning */ 563 564 DBG (10, "sane_get_devices: start\n"); 565 566 /* mark all existing scanners as missing, attach_one will remove mark */ 567 for (s = scanner_devList; s; s = s->next) { 568 s->missing = 1; 569 } 570 571 sanei_usb_init(); 572 573 /* reset globals before reading the file */ 574 default_globals(); 575 576 fp = sanei_config_open (CANON_DR_CONFIG_FILE); 577 578 if (fp) { 579 580 DBG (15, "sane_get_devices: reading config file %s\n", 581 CANON_DR_CONFIG_FILE); 582 583 while (sanei_config_read (line, PATH_MAX, fp)) { 584 585 lp = line; 586 587 /* ignore comments */ 588 if (*lp == '#') 589 continue; 590 591 /* skip empty lines */ 592 if (*lp == 0) 593 continue; 594 595 if (!strncmp ("option", lp, 6) && isspace (lp[6])) { 596 597 lp += 6; 598 lp = sanei_config_skip_whitespace (lp); 599 600 /* BUFFERSIZE: > 4K */ 601 if (!strncmp (lp, "buffer-size", 11) && isspace (lp[11])) { 602 603 int buf; 604 lp += 11; 605 lp = sanei_config_skip_whitespace (lp); 606 buf = atoi (lp); 607 608 if (buf < 4096) { 609 DBG (5, "sane_get_devices: config option \"buffer-size\" " 610 "(%d) is < 4096, ignoring!\n", buf); 611 continue; 612 } 613 614 if (buf > global_buffer_size_default) { 615 DBG (5, "sane_get_devices: config option \"buffer-size\" " 616 "(%d) is > %d, scanning problems may result\n", buf, 617 global_buffer_size_default); 618 } 619 620 DBG (15, "sane_get_devices: setting \"buffer-size\" to %d\n", 621 buf); 622 623 global_buffer_size = buf; 624 } 625 626 /* PADDED READ: we clamp to 0 or 1 */ 627 else if (!strncmp (lp, "padded-read", 11) && isspace (lp[11])) { 628 629 int buf; 630 lp += 11; 631 lp = sanei_config_skip_whitespace (lp); 632 buf = atoi (lp); 633 634 if (buf < 0) { 635 DBG (5, "sane_get_devices: config option \"padded-read\" " 636 "(%d) is < 0, ignoring!\n", buf); 637 continue; 638 } 639 640 if (buf > 1) { 641 DBG (5, "sane_get_devices: config option \"padded-read\" " 642 "(%d) is > 1, ignoring!\n", buf); 643 continue; 644 } 645 646 DBG (15, "sane_get_devices: setting \"padded-read\" to %d\n", 647 buf); 648 649 global_padded_read = buf; 650 } 651 652 /* EXTRA STATUS: we clamp to 0 or 1 */ 653 else if (!strncmp (lp, "extra-status", 12) && isspace (lp[12])) { 654 655 int buf; 656 lp += 12; 657 lp = sanei_config_skip_whitespace (lp); 658 buf = atoi (lp); 659 660 if (buf < 0) { 661 DBG (5, "sane_get_devices: config option \"extra-status\" " 662 "(%d) is < 0, ignoring!\n", buf); 663 continue; 664 } 665 666 if (buf > 1) { 667 DBG (5, "sane_get_devices: config option \"extra-status\" " 668 "(%d) is > 1, ignoring!\n", buf); 669 continue; 670 } 671 672 DBG (15, "sane_get_devices: setting \"extra-status\" to %d\n", 673 buf); 674 675 global_extra_status = buf; 676 } 677 678 /* DUPLEXOFFSET: < 2400 */ 679 else if (!strncmp (lp, "duplex-offset", 13) && isspace (lp[13])) { 680 681 int buf; 682 lp += 13; 683 lp = sanei_config_skip_whitespace (lp); 684 buf = atoi (lp); 685 686 if (buf > 2400) { 687 DBG (5, "sane_get_devices: config option \"duplex-offset\" " 688 "(%d) is > 2400, ignoring!\n", buf); 689 continue; 690 } 691 692 if (buf < 0) { 693 DBG (5, "sane_get_devices: config option \"duplex-offset\" " 694 "(%d) is < 0, ignoring!\n", buf); 695 continue; 696 } 697 698 DBG (15, "sane_get_devices: setting \"duplex-offset\" to %d\n", 699 buf); 700 701 global_duplex_offset = buf; 702 } 703 704 /* INQUIRY_LENGTH: <= 0x30 */ 705 else if (!strncmp (lp, "inquiry-length", 14) && isspace (lp[14])) { 706 707 int buf; 708 lp += 14; 709 lp = sanei_config_skip_whitespace (lp); 710 buf = (int) strtol (lp,NULL,16); 711 712 if (buf > INQUIRY_std_max_len) { 713 DBG (5, "sane_get_devices: config option \"inquiry-length\" " 714 "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_std_max_len); 715 continue; 716 } 717 718 if (buf < 0) { 719 DBG (5, "sane_get_devices: config option \"inquiry-length\" " 720 "(%#04x) is < 0, ignoring!\n", buf); 721 continue; 722 } 723 724 DBG (15, "sane_get_devices: setting \"inquiry-length\" to %#04x\n", 725 buf); 726 727 global_inquiry_length = buf; 728 } 729 730 /* VPD_LENGTH: <= 0x30 */ 731 else if (!strncmp (lp, "vpd-length", 10) && isspace (lp[10])) { 732 733 int buf; 734 lp += 10; 735 lp = sanei_config_skip_whitespace (lp); 736 buf = (int) strtol (lp,NULL,16); 737 738 if (buf > INQUIRY_vpd_max_len) { 739 DBG (5, "sane_get_devices: config option \"vpd-length\" " 740 "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_vpd_max_len); 741 continue; 742 } 743 744 if (buf < 0) { 745 DBG (5, "sane_get_devices: config option \"vpd-length\" " 746 "(%#04x) is < 0, ignoring!\n", buf); 747 continue; 748 } 749 750 DBG (15, "sane_get_devices: setting \"vpd-length\" to %#04x\n", 751 buf); 752 753 global_vpd_length = buf; 754 } 755 756 /* TUR_TIMEOUT <= 60000 */ 757 else if (!strncmp (lp, "tur-timeout", 11) && isspace (lp[11])) { 758 759 int buf; 760 lp += 11; 761 lp = sanei_config_skip_whitespace (lp); 762 buf = atoi (lp); 763 764 if (buf > 60000) { 765 DBG (5, "sane_get_devices: config option \"tur-timeout\" " 766 "(%d) is > 60000, ignoring!\n", buf); 767 continue; 768 } 769 770 if (buf < 0) { 771 DBG (5, "sane_get_devices: config option \"tur-timeout\" " 772 "(%d) is < 0, ignoring!\n", buf); 773 continue; 774 } 775 776 DBG (15, "sane_get_devices: setting \"tur-timeout\" to %d\n", 777 buf); 778 779 global_tur_timeout = buf; 780 } 781 782 /* VENDOR: we ingest up to 8 bytes */ 783 else if (!strncmp (lp, "vendor-name", 11) && isspace (lp[11])) { 784 785 lp += 11; 786 lp = sanei_config_skip_whitespace (lp); 787 strncpy(global_vendor_name, lp, 8); 788 global_vendor_name[8] = 0; 789 790 DBG (15, "sane_get_devices: setting \"vendor-name\" to %s\n", 791 global_vendor_name); 792 } 793 794 /* MODEL: we ingest up to 16 bytes */ 795 else if (!strncmp (lp, "model-name", 10) && isspace (lp[10])) { 796 797 lp += 10; 798 lp = sanei_config_skip_whitespace (lp); 799 strncpy(global_model_name, lp, 16); 800 global_model_name[16] = 0; 801 802 DBG (15, "sane_get_devices: setting \"model-name\" to %s\n", 803 global_model_name); 804 } 805 806 /* VERSION: we ingest up to 4 bytes */ 807 else if (!strncmp (lp, "version-name", 12) && isspace (lp[12])) { 808 809 lp += 12; 810 lp = sanei_config_skip_whitespace (lp); 811 strncpy(global_version_name, lp, 4); 812 global_version_name[4] = 0; 813 814 DBG (15, "sane_get_devices: setting \"version-name\" to %s\n", 815 global_version_name); 816 } 817 818 else { 819 DBG (5, "sane_get_devices: config option \"%s\" unrecognized " 820 "- ignored.\n", lp); 821 } 822 } 823 else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) { 824 DBG (15, "sane_get_devices: looking for '%s'\n", lp); 825 sanei_usb_attach_matching_devices(lp, attach_one_usb); 826 827 /* re-default these after reading the usb line */ 828 default_globals(); 829 } 830 else if ((strncmp ("scsi", lp, 4) == 0) && isspace (lp[4])) { 831 DBG (15, "sane_get_devices: looking for '%s'\n", lp); 832 sanei_config_attach_matching_devices (lp, attach_one_scsi); 833 834 /* re-default these after reading the scsi line */ 835 default_globals(); 836 } 837 else{ 838 DBG (5, "sane_get_devices: config line \"%s\" unrecognized - " 839 "ignored.\n", lp); 840 } 841 } 842 fclose (fp); 843 } 844 845 else { 846 DBG (5, "sane_get_devices: missing required config file '%s'!\n", 847 CANON_DR_CONFIG_FILE); 848 } 849 850 /*delete missing scanners from list*/ 851 for (s = scanner_devList; s;) { 852 if(s->missing){ 853 DBG (5, "sane_get_devices: missing scanner %s\n",s->device_name); 854 855 /*splice s out of list by changing pointer in prev to next*/ 856 if(prev){ 857 prev->next = s->next; 858 free(s); 859 s=prev->next; 860 } 861 /*remove s from head of list, using prev to cache it*/ 862 else{ 863 prev = s; 864 s = s->next; 865 free(prev); 866 prev=NULL; 867 868 /*reset head to next s*/ 869 scanner_devList = s; 870 } 871 } 872 else{ 873 prev = s; 874 s=prev->next; 875 } 876 } 877 878 for (s = scanner_devList; s; s=s->next) { 879 DBG (15, "sane_get_devices: found scanner %s\n",s->device_name); 880 num_devices++; 881 } 882 883 DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices); 884 885 if (sane_devArray) 886 free (sane_devArray); 887 888 sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*)); 889 if (!sane_devArray) 890 return SANE_STATUS_NO_MEM; 891 892 for (s = scanner_devList; s; s=s->next) { 893 sane_devArray[i++] = (SANE_Device *)&s->sane; 894 } 895 sane_devArray[i] = 0; 896 897 if(device_list){ 898 *device_list = sane_devArray; 899 } 900 901 DBG (10, "sane_get_devices: finish\n"); 902 903 return ret; 904} 905 906/* callbacks used by sane_get_devices */ 907static SANE_Status 908attach_one_scsi (const char *device_name) 909{ 910 return attach_one(device_name,CONNECTION_SCSI); 911} 912 913static SANE_Status 914attach_one_usb (const char *device_name) 915{ 916 return attach_one(device_name,CONNECTION_USB); 917} 918 919/* build the scanner struct and link to global list 920 * unless struct is already loaded, then pretend 921 */ 922static SANE_Status 923attach_one (const char *device_name, int connType) 924{ 925 struct scanner *s; 926 int ret; 927 928 DBG (10, "attach_one: start\n"); 929 DBG (15, "attach_one: looking for '%s'\n", device_name); 930 931 for (s = scanner_devList; s; s = s->next) { 932 if (strcmp (s->device_name, device_name) == 0){ 933 DBG (10, "attach_one: already attached!\n"); 934 s->missing = 0; 935 return SANE_STATUS_GOOD; 936 } 937 } 938 939 /* build a scanner struct to hold it */ 940 if ((s = calloc (sizeof (*s), 1)) == NULL) 941 return SANE_STATUS_NO_MEM; 942 943 /* config file settings */ 944 s->buffer_size = global_buffer_size; 945 s->padded_read = global_padded_read; 946 s->extra_status = global_extra_status; 947 s->duplex_offset = global_duplex_offset; 948 s->inquiry_length = global_inquiry_length; 949 s->vpd_length = global_vpd_length; 950 s->tur_timeout = global_tur_timeout; 951 952 /* copy the device name */ 953 strcpy (s->device_name, device_name); 954 955 /* connect the fd */ 956 s->connection = connType; 957 s->fd = -1; 958 ret = connect_fd(s); 959 if(ret != SANE_STATUS_GOOD){ 960 free (s); 961 return ret; 962 } 963 964 /* query the device to load its vendor/model/version, */ 965 /* if config file doesn't give all three */ 966 if ( !strlen(global_vendor_name) 967 || !strlen(global_model_name) 968 || !strlen(global_version_name) 969 ){ 970 ret = init_inquire (s); 971 if (ret != SANE_STATUS_GOOD) { 972 disconnect_fd(s); 973 free (s); 974 DBG (5, "attach_one: inquiry failed\n"); 975 return ret; 976 } 977 } 978 979 /* override any inquiry settings with those from config file */ 980 if(strlen(global_vendor_name)) 981 strcpy(s->vendor_name, global_vendor_name); 982 if(strlen(global_model_name)) 983 strcpy(s->model_name, global_model_name); 984 if(strlen(global_version_name)) 985 strcpy(s->version_name, global_version_name); 986 987 /* load detailed specs/capabilities from the device */ 988 /* if a model cannot support inquiry vpd, this function will die */ 989 ret = init_vpd (s); 990 if (ret != SANE_STATUS_GOOD) { 991 disconnect_fd(s); 992 free (s); 993 DBG (5, "attach_one: vpd failed\n"); 994 return ret; 995 } 996 997 /* clean up the scanner struct based on model */ 998 /* this is the big piece of model specific code */ 999 ret = init_model (s); 1000 if (ret != SANE_STATUS_GOOD) { 1001 disconnect_fd(s); 1002 free (s); 1003 DBG (5, "attach_one: model failed\n"); 1004 return ret; 1005 } 1006 1007 /* this detects imprinters if they are available */ 1008 ret = init_imprinters (s); 1009 if (ret != SANE_STATUS_GOOD) { 1010 DBG (5, "attach_one: errors while trying to detect optional imprinters, continuing\n"); 1011 } 1012 1013 /* enable/read the buttons */ 1014 ret = init_panel (s); 1015 if (ret != SANE_STATUS_GOOD) { 1016 disconnect_fd(s); 1017 free (s); 1018 DBG (5, "attach_one: model failed\n"); 1019 return ret; 1020 } 1021 1022 /* enable/read the lifecycle counters */ 1023 ret = init_counters (s); 1024 if (ret != SANE_STATUS_GOOD) { 1025 DBG (5, "attach_one: unable to detect lifecycle counters, continuing\n"); 1026 return ret; 1027 } 1028 1029 /* sets SANE option 'values' to good defaults */ 1030 ret = init_user (s); 1031 if (ret != SANE_STATUS_GOOD) { 1032 disconnect_fd(s); 1033 free (s); 1034 DBG (5, "attach_one: user failed\n"); 1035 return ret; 1036 } 1037 1038 ret = init_options (s); 1039 if (ret != SANE_STATUS_GOOD) { 1040 disconnect_fd(s); 1041 free (s); 1042 DBG (5, "attach_one: options failed\n"); 1043 return ret; 1044 } 1045 1046 /* load strings into sane_device struct */ 1047 s->sane.name = s->device_name; 1048 s->sane.vendor = s->vendor_name; 1049 s->sane.model = s->model_name; 1050 s->sane.type = "scanner"; 1051 1052 /* change name in sane_device struct if scanner has serial number 1053 ret = init_serial (s); 1054 if (ret == SANE_STATUS_GOOD) { 1055 s->sane.name = s->serial_name; 1056 } 1057 else{ 1058 DBG (5, "attach_one: serial number unsupported?\n"); 1059 } 1060 */ 1061 1062 /* we close the connection, so that another backend can talk to scanner */ 1063 disconnect_fd(s); 1064 1065 /* store this scanner in global vars */ 1066 s->next = scanner_devList; 1067 scanner_devList = s; 1068 1069 DBG (10, "attach_one: finish\n"); 1070 1071 return SANE_STATUS_GOOD; 1072} 1073 1074/* 1075 * connect the fd in the scanner struct 1076 */ 1077static SANE_Status 1078connect_fd (struct scanner *s) 1079{ 1080 SANE_Status ret; 1081 int buffer_size = s->buffer_size; 1082 1083 DBG (10, "connect_fd: start\n"); 1084 1085 if(s->fd > -1){ 1086 DBG (5, "connect_fd: already open\n"); 1087 ret = SANE_STATUS_GOOD; 1088 } 1089 else if (s->connection == CONNECTION_USB) { 1090 DBG (15, "connect_fd: opening USB device (%s)\n", s->device_name); 1091 ret = sanei_usb_open (s->device_name, &(s->fd)); 1092 if(!ret){ 1093 ret = sanei_usb_clear_halt(s->fd); 1094 } 1095 } 1096 else { 1097 DBG (15, "connect_fd: opening SCSI device (%s)\n", s->device_name); 1098 ret = sanei_scsi_open_extended (s->device_name, &(s->fd), sense_handler, s, 1099 &s->buffer_size); 1100 if(!ret && buffer_size != s->buffer_size){ 1101 DBG (5, "connect_fd: cannot get requested buffer size (%d/%d)\n", 1102 buffer_size, s->buffer_size); 1103 } 1104 } 1105 1106 if(ret == SANE_STATUS_GOOD){ 1107 1108 /* first generation usb scanners can get flaky if not closed 1109 * properly after last use. very first commands sent to device 1110 * must be prepared to correct this- see wait_scanner() */ 1111 ret = wait_scanner(s); 1112 if (ret != SANE_STATUS_GOOD) { 1113 DBG (5, "connect_fd: could not wait_scanner\n"); 1114 disconnect_fd(s); 1115 } 1116 1117 } 1118 else{ 1119 DBG (5, "connect_fd: could not open device: %d\n", ret); 1120 } 1121 1122 DBG (10, "connect_fd: finish\n"); 1123 1124 return ret; 1125} 1126 1127/* 1128 * This routine will check if a certain device is a Canon scanner 1129 * It also copies interesting data from INQUIRY into the handle structure 1130 */ 1131static SANE_Status 1132init_inquire (struct scanner *s) 1133{ 1134 int i; 1135 SANE_Status ret; 1136 1137 unsigned char cmd[INQUIRY_len]; 1138 size_t cmdLen = INQUIRY_len; 1139 1140 unsigned char in[INQUIRY_std_max_len]; 1141 size_t inLen = s->inquiry_length; 1142 1143 DBG (10, "init_inquire: start\n"); 1144 1145 memset(cmd,0,cmdLen); 1146 set_SCSI_opcode(cmd, INQUIRY_code); 1147 set_IN_return_size (cmd, inLen); 1148 set_IN_evpd (cmd, 0); 1149 set_IN_page_code (cmd, 0); 1150 1151 ret = do_cmd ( 1152 s, 1, 0, 1153 cmd, cmdLen, 1154 NULL, 0, 1155 in, &inLen 1156 ); 1157 1158 if (ret != SANE_STATUS_GOOD){ 1159 DBG (10, "init_inquire: failed: %d\n", ret); 1160 return ret; 1161 } 1162 1163 if (get_IN_periph_devtype (in) != IN_periph_devtype_scanner){ 1164 DBG (5, "The device at '%s' is not a scanner.\n", s->device_name); 1165 return SANE_STATUS_INVAL; 1166 } 1167 1168 get_IN_vendor (in, s->vendor_name); 1169 get_IN_product (in, s->model_name); 1170 get_IN_version (in, s->version_name); 1171 1172 s->vendor_name[8] = 0; 1173 s->model_name[16] = 0; 1174 s->version_name[4] = 0; 1175 1176 /* gobble trailing spaces */ 1177 for (i = 7; s->vendor_name[i] == ' ' && i >= 0; i--) 1178 s->vendor_name[i] = 0; 1179 for (i = 15; s->model_name[i] == ' ' && i >= 0; i--) 1180 s->model_name[i] = 0; 1181 for (i = 3; s->version_name[i] == ' ' && i >= 0; i--) 1182 s->version_name[i] = 0; 1183 1184 /*check for vendor name*/ 1185 if (strcmp ("CANON", s->vendor_name)) { 1186 DBG (5, "The device at '%s' is reported to be made by '%s'\n", 1187 s->device_name, s->vendor_name); 1188 DBG (5, "This backend only supports Canon products.\n"); 1189 return SANE_STATUS_INVAL; 1190 } 1191 1192 /*check for model name*/ 1193 if (strncmp ("DR", s->model_name, 2) 1194 && strncmp ("CR", s->model_name, 2) 1195 && strncmp ("P-", s->model_name, 2) 1196 && strncmp ("R", s->model_name, 1) 1197 ) { 1198 DBG (5, "The device at '%s' is reported to be a '%s'\n", 1199 s->device_name, s->model_name); 1200 DBG (5, "This backend only supports Canon P-, CR & DR-series products.\n"); 1201 return SANE_STATUS_INVAL; 1202 } 1203 1204 DBG (15, "init_inquire: Found %s scanner %s version %s at %s\n", 1205 s->vendor_name, s->model_name, s->version_name, s->device_name); 1206 1207 DBG (10, "init_inquire: finish\n"); 1208 1209 return SANE_STATUS_GOOD; 1210} 1211 1212/* 1213 * Use INQUIRY VPD to setup more detail about the scanner 1214 */ 1215static SANE_Status 1216init_vpd (struct scanner *s) 1217{ 1218 SANE_Status ret; 1219 1220 unsigned char cmd[INQUIRY_len]; 1221 size_t cmdLen = INQUIRY_len; 1222 1223 unsigned char in[INQUIRY_vpd_max_len]; 1224 size_t inLen = s->vpd_length; 1225 1226 DBG (10, "init_vpd: start\n"); 1227 1228 /* get EVPD */ 1229 memset(cmd,0,cmdLen); 1230 set_SCSI_opcode(cmd, INQUIRY_code); 1231 set_IN_return_size (cmd, inLen); 1232 set_IN_evpd (cmd, 1); 1233 set_IN_page_code (cmd, 0xf0); 1234 1235 ret = do_cmd ( 1236 s, 1, 0, 1237 cmd, cmdLen, 1238 NULL, 0, 1239 in, &inLen 1240 ); 1241 1242 DBG (15, "init_vpd: length=%0x\n",get_IN_page_length (in)); 1243 1244 /* This scanner supports vital product data. 1245 * Use this data to set dpi-lists etc. */ 1246 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { 1247 1248 DBG (15, "standard options\n"); 1249 1250 s->basic_x_res = get_IN_basic_x_res (in); 1251 DBG (15, " basic x res: %d dpi\n",s->basic_x_res); 1252 1253 s->basic_y_res = get_IN_basic_y_res (in); 1254 DBG (15, " basic y res: %d dpi\n",s->basic_y_res); 1255 1256 s->step_x_res = get_IN_step_x_res (in); 1257 DBG (15, " step x res: %d dpi\n", s->step_x_res); 1258 1259 s->step_y_res = get_IN_step_y_res (in); 1260 DBG (15, " step y res: %d dpi\n", s->step_y_res); 1261 1262 s->max_x_res = get_IN_max_x_res (in); 1263 DBG (15, " max x res: %d dpi\n", s->max_x_res); 1264 1265 s->max_y_res = get_IN_max_y_res (in); 1266 DBG (15, " max y res: %d dpi\n", s->max_y_res); 1267 1268 s->min_x_res = get_IN_min_x_res (in); 1269 DBG (15, " min x res: %d dpi\n", s->min_x_res); 1270 1271 s->min_y_res = get_IN_min_y_res (in); 1272 DBG (15, " min y res: %d dpi\n", s->min_y_res); 1273 1274 /* some scanners list B&W resolutions. */ 1275 s->std_res_x[DPI_60] = get_IN_std_res_60 (in); 1276 s->std_res_y[DPI_60] = s->std_res_x[DPI_60]; 1277 DBG (15, " 60 dpi: %d\n", s->std_res_x[DPI_60]); 1278 1279 s->std_res_x[DPI_75] = get_IN_std_res_75 (in); 1280 s->std_res_y[DPI_75] = s->std_res_x[DPI_75]; 1281 DBG (15, " 75 dpi: %d\n", s->std_res_x[DPI_75]); 1282 1283 s->std_res_x[DPI_100] = get_IN_std_res_100 (in); 1284 s->std_res_y[DPI_100] = s->std_res_x[DPI_100]; 1285 DBG (15, " 100 dpi: %d\n", s->std_res_x[DPI_100]); 1286 1287 s->std_res_x[DPI_120] = get_IN_std_res_120 (in); 1288 s->std_res_y[DPI_120] = s->std_res_x[DPI_120]; 1289 DBG (15, " 120 dpi: %d\n", s->std_res_x[DPI_120]); 1290 1291 s->std_res_x[DPI_150] = get_IN_std_res_150 (in); 1292 s->std_res_y[DPI_150] = s->std_res_x[DPI_150]; 1293 DBG (15, " 150 dpi: %d\n", s->std_res_x[DPI_150]); 1294 1295 s->std_res_x[DPI_160] = get_IN_std_res_160 (in); 1296 s->std_res_y[DPI_160] = s->std_res_x[DPI_160]; 1297 DBG (15, " 160 dpi: %d\n", s->std_res_x[DPI_160]); 1298 1299 s->std_res_x[DPI_180] = get_IN_std_res_180 (in); 1300 s->std_res_y[DPI_180] = s->std_res_x[DPI_180]; 1301 DBG (15, " 180 dpi: %d\n", s->std_res_x[DPI_180]); 1302 1303 s->std_res_x[DPI_200] = get_IN_std_res_200 (in); 1304 s->std_res_y[DPI_200] = s->std_res_x[DPI_200]; 1305 DBG (15, " 200 dpi: %d\n", s->std_res_x[DPI_200]); 1306 1307 s->std_res_x[DPI_240] = get_IN_std_res_240 (in); 1308 s->std_res_y[DPI_240] = s->std_res_x[DPI_240]; 1309 DBG (15, " 240 dpi: %d\n", s->std_res_x[DPI_240]); 1310 1311 s->std_res_x[DPI_300] = get_IN_std_res_300 (in); 1312 s->std_res_y[DPI_300] = s->std_res_x[DPI_300]; 1313 DBG (15, " 300 dpi: %d\n", s->std_res_x[DPI_300]); 1314 1315 s->std_res_x[DPI_320] = get_IN_std_res_320 (in); 1316 s->std_res_y[DPI_320] = s->std_res_x[DPI_320]; 1317 DBG (15, " 320 dpi: %d\n", s->std_res_x[DPI_320]); 1318 1319 s->std_res_x[DPI_400] = get_IN_std_res_400 (in); 1320 s->std_res_y[DPI_400] = s->std_res_x[DPI_400]; 1321 DBG (15, " 400 dpi: %d\n", s->std_res_x[DPI_400]); 1322 1323 s->std_res_x[DPI_480] = get_IN_std_res_480 (in); 1324 s->std_res_y[DPI_480] = s->std_res_x[DPI_480]; 1325 DBG (15, " 480 dpi: %d\n", s->std_res_x[DPI_480]); 1326 1327 s->std_res_x[DPI_600] = get_IN_std_res_600 (in); 1328 s->std_res_y[DPI_600] = s->std_res_x[DPI_600]; 1329 DBG (15, " 600 dpi: %d\n", s->std_res_x[DPI_600]); 1330 1331 s->std_res_x[DPI_800] = get_IN_std_res_800 (in); 1332 s->std_res_y[DPI_800] = s->std_res_x[DPI_800]; 1333 DBG (15, " 800 dpi: %d\n", s->std_res_x[DPI_800]); 1334 1335 s->std_res_x[DPI_1200] = get_IN_std_res_1200 (in); 1336 s->std_res_y[DPI_1200] = s->std_res_x[DPI_1200]; 1337 DBG (15, " 1200 dpi: %d\n", s->std_res_x[DPI_1200]); 1338 1339 /* maximum window width and length are reported in basic units.*/ 1340 s->max_x = get_IN_window_width(in) * 1200 / s->basic_x_res; 1341 DBG(15, " max width: %d (%2.2f in)\n",s->max_x,(float)s->max_x/1200); 1342 1343 s->max_y = get_IN_window_length(in) * 1200 / s->basic_y_res; 1344 DBG(15, " max length: %d (%2.2f in)\n",s->max_y,(float)s->max_y/1200); 1345 1346 DBG (15, " AWD: %d\n", get_IN_awd(in)); 1347 DBG (15, " CE Emphasis: %d\n", get_IN_ce_emphasis(in)); 1348 DBG (15, " C Emphasis: %d\n", get_IN_c_emphasis(in)); 1349 DBG (15, " High quality: %d\n", get_IN_high_quality(in)); 1350 1351 /* known modes FIXME more here? */ 1352 s->can_grayscale = get_IN_multilevel (in); 1353 DBG (15, " grayscale: %d\n", s->can_grayscale); 1354 1355 s->can_halftone = get_IN_half_tone (in); 1356 DBG (15, " halftone: %d\n", s->can_halftone); 1357 1358 s->can_monochrome = get_IN_monochrome (in); 1359 DBG (15, " monochrome: %d\n", s->can_monochrome); 1360 1361 s->can_overflow = get_IN_overflow(in); 1362 DBG (15, " overflow: %d\n", s->can_overflow); 1363 } 1364 /*FIXME no vpd, set some defaults? */ 1365 else{ 1366 DBG (5, "init_vpd: Your scanner does not support VPD?\n"); 1367 DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n"); 1368 DBG (5, "init_vpd: with details of your scanner model.\n"); 1369 } 1370 1371 DBG (10, "init_vpd: finish\n"); 1372 1373 return ret; 1374} 1375 1376/* 1377 * get model specific info that is not in vpd, and correct 1378 * errors in vpd data. struct is already initialized to 0. 1379 */ 1380static SANE_Status 1381init_model (struct scanner *s) 1382{ 1383 1384 DBG (10, "init_model: start\n"); 1385 1386 s->reverse_by_mode[MODE_LINEART] = 1; 1387 s->reverse_by_mode[MODE_HALFTONE] = 1; 1388 s->reverse_by_mode[MODE_GRAYSCALE] = 0; 1389 s->reverse_by_mode[MODE_COLOR] = 0; 1390 1391 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RGB; 1392 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RGB; 1393 1394 s->always_op = 1; 1395 s->has_df = 1; 1396 s->has_btc = 1; 1397 s->has_counter = 1; 1398 s->has_adf = 1; 1399 s->has_duplex = 1; 1400 s->has_buffer = 1; 1401 s->can_read_panel = 1; 1402 s->can_write_panel = 1; 1403 s->has_ssm = 1; 1404 1405 s->brightness_steps = 255; 1406 s->contrast_steps = 255; 1407 s->threshold_steps = 255; 1408 1409 s->ppl_mod = 1; 1410 s->bg_color = 0xee; 1411 1412 /* assume these are same as adf, override below */ 1413 s->valid_x = s->max_x; 1414 s->max_x_fb = s->max_x; 1415 s->max_y_fb = s->max_y; 1416 1417 /* missing from vpd- we will unset these for some machines below */ 1418 s->can_color = 1; 1419 s->can_read_lifecycle_counters = 1; 1420 1421 /* specific settings missing from vpd */ 1422 if (strstr (s->model_name,"DR-9080")){ 1423 s->has_comp_JPEG = 1; 1424 s->rgb_format = 2; 1425 } 1426 1427 else if (strstr (s->model_name,"DR-6080") 1428 || strstr (s->model_name,"DR-7580")){ 1429 s->has_comp_JPEG = 1; 1430 s->can_color = 0; 1431 } 1432 1433 else if (strstr (s->model_name,"DR-7090")){ 1434 s->has_flatbed = 1; 1435 } 1436 1437 else if (strstr (s->model_name,"DR-9050") 1438 || strstr (s->model_name,"DR-7550") 1439 || strstr (s->model_name,"DR-6050") 1440 || strstr (s->model_name,"DR-G1100") 1441 || strstr (s->model_name,"DR-G1130") 1442 ){ 1443 1444 /*missing*/ 1445 s->std_res_x[DPI_100]=1; 1446 s->std_res_y[DPI_100]=1; 1447 s->std_res_x[DPI_150]=1; 1448 s->std_res_y[DPI_150]=1; 1449 s->std_res_x[DPI_200]=1; 1450 s->std_res_y[DPI_200]=1; 1451 s->std_res_x[DPI_240]=1; 1452 s->std_res_y[DPI_240]=1; 1453 s->std_res_x[DPI_300]=1; 1454 s->std_res_y[DPI_300]=1; 1455 s->std_res_x[DPI_400]=1; 1456 s->std_res_y[DPI_400]=1; 1457 s->std_res_x[DPI_600]=1; 1458 s->std_res_y[DPI_600]=1; 1459 1460 /*weirdness*/ 1461 s->has_ssm = 0; 1462 s->has_ssm2 = 1; 1463 } 1464 1465 else if (strstr (s->model_name,"DR-4080") 1466 || strstr (s->model_name,"DR-4580") 1467 || strstr (s->model_name,"DR-7080")){ 1468 s->has_flatbed = 1; 1469 } 1470 1471 else if (strstr (s->model_name,"DR-2580")){ 1472 s->invert_tly = 1; 1473 s->rgb_format = 1; 1474 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB; 1475 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB; 1476 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG; 1477 s->duplex_interlace = DUPLEX_INTERLACE_FBfb; 1478 s->need_ccal = 1; 1479 s->fcal_src = FCAL_SRC_SCAN; 1480 s->fcal_dest = FCAL_DEST_SW; 1481 /*s->duplex_offset = 432; now set in config file*/ 1482 s->duplex_offset_side = SIDE_BACK; 1483 1484 /*lies*/ 1485 s->can_halftone=0; 1486 s->can_monochrome=0; 1487 } 1488 1489 else if (strstr (s->model_name,"DR-2510") 1490 || strstr (s->model_name,"DR-2010") 1491 ){ 1492 s->rgb_format = 1; 1493 s->always_op = 0; 1494 s->unknown_byte2 = 0x80; 1495 s->fixed_width = 1; 1496 s->valid_x = 8.5 * 1200; 1497 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510; 1498 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510; 1499 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510; 1500 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510; 1501 s->duplex_interlace = DUPLEX_INTERLACE_2510; 1502 /*s->duplex_offset = 400; now set in config file*/ 1503 s->need_ccal = 1; 1504 s->fcal_src = FCAL_SRC_SCAN; 1505 s->fcal_dest = FCAL_DEST_SW; 1506 s->sw_lut = 1; 1507 /*s->invert_tly = 1;*/ 1508 1509 /*only in Y direction, so we trash them in X*/ 1510 s->std_res_x[DPI_100]=0; 1511 s->std_res_x[DPI_150]=0; 1512 s->std_res_x[DPI_200]=0; 1513 s->std_res_x[DPI_240]=0; 1514 s->std_res_x[DPI_400]=0; 1515 1516 /*lies*/ 1517 s->can_halftone=0; 1518 s->can_monochrome=0; 1519 } 1520 1521 else if (strstr (s->model_name,"R40") 1522 ){ 1523 /* confirmed */ 1524 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_C120; 1525 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_C120; 1526 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_C120; 1527 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_C120; 1528 s->duplex_interlace = DUPLEX_INTERLACE_2510; 1529 /*s->duplex_offset = 320; now set in config file*/ 1530 s->fixed_width = 1; 1531 s->need_ccal = 1; 1532 s->fcal_src = FCAL_SRC_SCAN; 1533 s->fcal_dest = FCAL_DEST_SW; 1534 s->rgb_format = 1; 1535 s->sw_lut = 1; 1536 1537 /*only in Y direction, so we trash them in X*/ 1538 s->std_res_x[DPI_100]=0; 1539 s->std_res_x[DPI_150]=0; 1540 s->std_res_x[DPI_200]=0; 1541 s->std_res_x[DPI_240]=0; 1542 s->std_res_x[DPI_400]=0; 1543 1544 /* suspected settings */ 1545 s->ccal_version = 3; 1546 s->has_df_ultra = 1; 1547 } 1548 1549 /* copied from 2510, possibly incorrect */ 1550 else if (strstr (s->model_name,"DR-3010")){ 1551 s->rgb_format = 1; 1552 s->always_op = 0; 1553 s->unknown_byte2 = 0x80; 1554 s->fixed_width = 1; 1555 s->valid_x = 8.5 * 1200; 1556 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510; 1557 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510; 1558 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510; 1559 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510; 1560 s->duplex_interlace = DUPLEX_INTERLACE_2510; 1561 /*s->duplex_offset = 400; now set in config file*/ 1562 s->need_ccal = 1; 1563 s->fcal_src = FCAL_SRC_SCAN; 1564 s->fcal_dest = FCAL_DEST_SW; 1565 s->sw_lut = 1; 1566 s->invert_tly = 1; 1567 1568 /*only in Y direction, so we trash them in X*/ 1569 s->std_res_x[DPI_100]=0; 1570 s->std_res_x[DPI_150]=0; 1571 s->std_res_x[DPI_200]=0; 1572 s->std_res_x[DPI_240]=0; 1573 s->std_res_x[DPI_400]=0; 1574 1575 /*lies*/ 1576 s->can_halftone=0; 1577 s->can_monochrome=0; 1578 } 1579 1580 else if (strstr (s->model_name,"DR-2050") 1581 || strstr (s->model_name,"DR-2080")){ 1582 s->can_write_panel = 0; 1583 s->has_df = 0; 1584 s->fixed_width = 1; 1585 s->even_Bpl = 1; 1586 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB; 1587 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB; 1588 s->duplex_interlace = DUPLEX_INTERLACE_FBfb; 1589 s->fcal_src = FCAL_SRC_HW; 1590 s->fcal_dest = FCAL_DEST_SW; 1591 s->bg_color = 0x08; 1592 /*s->duplex_offset = 840; now set in config file*/ 1593 s->sw_lut = 1; 1594 1595 /*lies*/ 1596 s->can_halftone=0; 1597 s->can_monochrome=0; 1598 } 1599 1600 else if (strstr (s->model_name,"DR-3080")){ 1601 s->can_write_panel = 0; 1602 s->has_df = 0; 1603 s->has_btc = 0; 1604 } 1605 1606 else if (strstr (s->model_name,"DR-5060F")){ 1607 s->can_write_panel = 0; 1608 s->has_df = 0; 1609 s->has_btc = 0; 1610 s->ppl_mod = 32; 1611 s->reverse_by_mode[MODE_LINEART] = 0; 1612 s->reverse_by_mode[MODE_HALFTONE] = 0; 1613 s->can_color = 0; 1614 } 1615 1616 else if (strstr (s->model_name,"DR-5020")){ 1617 s->can_read_panel = 0; 1618 s->can_write_panel = 0; 1619 s->has_df = 0; 1620 s->has_btc = 0; 1621 s->ppl_mod = 32; 1622 s->reverse_by_mode[MODE_LINEART] = 0; 1623 s->reverse_by_mode[MODE_HALFTONE] = 0; 1624 s->can_color = 0; 1625 } 1626 1627 /* all copied from P-215 */ 1628 else if (strstr (s->model_name, "P-150")) { 1629 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB; 1630 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB; 1631 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG; 1632 s->duplex_interlace = DUPLEX_INTERLACE_FBfb; 1633 s->need_ccal = 1; 1634 s->invert_tly = 1; 1635 s->unknown_byte2 = 0x88; 1636 s->rgb_format = 1; 1637 s->has_ssm_pay_head_len = 1; 1638 s->ppl_mod = 8; 1639 s->ccal_version = 3; 1640 s->can_read_sensors = 1; 1641 s->has_card = 1; 1642 } 1643 1644 else if (strstr (s->model_name, "P-208") 1645 || strstr (s->model_name,"DR-P208")){ 1646 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB; 1647 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB; 1648 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG; 1649 s->duplex_interlace = DUPLEX_INTERLACE_FBfb; 1650 s->need_ccal = 1; 1651 s->fcal_src = FCAL_SRC_SCAN; 1652 s->fcal_dest = FCAL_DEST_SW; 1653 s->invert_tly = 1; 1654 s->unknown_byte2 = 0x88; 1655 s->rgb_format = 1; 1656 s->has_ssm_pay_head_len = 1; 1657 s->ppl_mod = 8; 1658 s->ccal_version = 3; 1659 s->can_read_sensors = 1; 1660 } 1661 1662 else if (strstr (s->model_name, "P-215") 1663 || strstr (s->model_name,"DR-P215")){ 1664 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB; 1665 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB; 1666 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG; 1667 s->duplex_interlace = DUPLEX_INTERLACE_FBfb; 1668 s->need_ccal = 1; 1669 s->invert_tly = 1; 1670 s->unknown_byte2 = 0x88; 1671 s->rgb_format = 1; 1672 s->has_ssm_pay_head_len = 1; 1673 s->ppl_mod = 8; 1674 s->ccal_version = 3; 1675 s->can_read_sensors = 1; 1676 s->has_card = 1; 1677 } 1678 1679 else if (strstr (s->model_name,"DR-M160")){ 1680 1681 /*missing*/ 1682 s->std_res_x[DPI_100]=1; 1683 s->std_res_y[DPI_100]=1; 1684 s->std_res_x[DPI_150]=1; 1685 s->std_res_y[DPI_150]=1; 1686 s->std_res_x[DPI_200]=1; 1687 s->std_res_y[DPI_200]=1; 1688 s->std_res_x[DPI_300]=1; 1689 s->std_res_y[DPI_300]=1; 1690 s->std_res_x[DPI_400]=1; 1691 s->std_res_y[DPI_400]=1; 1692 s->std_res_x[DPI_600]=1; 1693 s->std_res_y[DPI_600]=1; 1694 1695 s->has_comp_JPEG = 1; 1696 s->rgb_format = 1; 1697 s->has_df_ultra = 1; 1698 1699 s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_GBR; 1700 s->color_inter_by_res[DPI_150] = COLOR_INTERLACE_GBR; 1701 s->color_inter_by_res[DPI_200] = COLOR_INTERLACE_BRG; 1702 s->color_inter_by_res[DPI_400] = COLOR_INTERLACE_GBR; 1703 1704 /*weirdness*/ 1705 s->always_op = 0; 1706 s->fixed_width = 1; 1707 s->invert_tly = 1; 1708 s->can_write_panel = 0; 1709 s->has_ssm = 0; 1710 s->has_ssm2 = 1; 1711 s->duplex_interlace = DUPLEX_INTERLACE_FfBb; 1712 s->duplex_offset_side = SIDE_FRONT; 1713 1714 /*lies*/ 1715 s->can_halftone=0; 1716 s->can_monochrome=0; 1717 } 1718 1719 else if (strstr (s->model_name,"DR-M140")){ 1720 1721 /*missing*/ 1722 s->std_res_x[DPI_100]=1; 1723 s->std_res_y[DPI_100]=1; 1724 s->std_res_x[DPI_150]=1; 1725 s->std_res_y[DPI_150]=1; 1726 s->std_res_x[DPI_200]=1; 1727 s->std_res_y[DPI_200]=1; 1728 s->std_res_x[DPI_300]=1; 1729 s->std_res_y[DPI_300]=1; 1730 s->std_res_x[DPI_400]=1; 1731 s->std_res_y[DPI_400]=1; 1732 s->std_res_x[DPI_600]=1; 1733 s->std_res_y[DPI_600]=1; 1734 1735 s->has_comp_JPEG = 1; 1736 s->rgb_format = 1; 1737 s->has_df_ultra = 1; 1738 1739 s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_GBR; 1740 s->color_inter_by_res[DPI_150] = COLOR_INTERLACE_GBR; 1741 s->color_inter_by_res[DPI_200] = COLOR_INTERLACE_BRG; 1742 s->color_inter_by_res[DPI_400] = COLOR_INTERLACE_GBR; 1743 1744 /*weirdness*/ 1745 s->always_op = 0; 1746 s->fixed_width = 1; 1747 s->invert_tly = 1; 1748 s->can_write_panel = 0; 1749 s->has_ssm = 0; 1750 s->has_ssm2 = 1; 1751 s->duplex_interlace = DUPLEX_INTERLACE_FfBb; 1752 s->duplex_offset_side = SIDE_BACK; 1753 1754 /*lies*/ 1755 s->can_halftone=0; 1756 s->can_monochrome=0; 1757 } 1758 1759 else if (strstr (s->model_name,"DR-C120") 1760 || strstr (s->model_name,"DR-C130") 1761 ){ 1762 1763 /*confirmed settings*/ 1764 s->need_ccal = 1; 1765 s->ccal_version = 3; 1766 1767 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_C120; 1768 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_C120; 1769 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_C120; 1770 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_C120; 1771 s->duplex_interlace = DUPLEX_INTERLACE_2510; 1772 s->duplex_offset_side = SIDE_BACK; 1773 s->unknown_byte2 = 0x88; 1774 s->fcal_src = FCAL_SRC_SCAN; 1775 s->fcal_dest = FCAL_DEST_SW; 1776 s->sw_lut = 1; 1777 s->rgb_format = 1; 1778 /*s->duplex_offset = 400; now set in config file*/ 1779 1780 /*only in Y direction, so we trash them in X*/ 1781 s->std_res_x[DPI_100]=0; 1782 s->std_res_x[DPI_150]=0; 1783 s->std_res_x[DPI_200]=0; 1784 s->std_res_x[DPI_240]=0; 1785 s->std_res_x[DPI_400]=0; 1786 1787 /*suspected settings*/ 1788 s->always_op = 0; 1789 s->fixed_width = 1; 1790 s->valid_x = 8.5 * 1200; 1791 } 1792 else if (strstr (s->model_name,"DR-C125")){ 1793 1794 /*confirmed settings*/ 1795 s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510; 1796 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510; 1797 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510; 1798 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510; 1799 s->duplex_interlace = DUPLEX_INTERLACE_2510; 1800 s->duplex_offset_side = SIDE_BACK; 1801 s->unknown_byte2 = 0x88; 1802 s->need_ccal = 1; 1803 s->ccal_version = 3; 1804 s->fcal_src = FCAL_SRC_SCAN; 1805 s->fcal_dest = FCAL_DEST_SW; 1806 s->sw_lut = 1; 1807 s->rgb_format = 1; 1808 /*s->duplex_offset = 400; now set in config file*/ 1809 1810 /*only in Y direction, so we trash them in X*/ 1811 s->std_res_x[DPI_100]=0; 1812 s->std_res_x[DPI_150]=0; 1813 s->std_res_x[DPI_200]=0; 1814 s->std_res_x[DPI_240]=0; 1815 s->std_res_x[DPI_400]=0; 1816 1817 /*suspected settings*/ 1818 s->always_op = 0; 1819 s->fixed_width = 1; 1820 s->valid_x = 8.5 * 1200; 1821 } 1822 1823 else if (strstr (s->model_name,"DR-C225")){ 1824 1825 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB; 1826 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB; 1827 s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG; 1828 s->duplex_interlace = DUPLEX_INTERLACE_PER_CHANNEL; 1829 1830 s->unknown_byte2 = 0x88; 1831 s->need_ccal = 1; 1832 s->ccal_version = 3; 1833 s->fcal_src = FCAL_SRC_SCAN; 1834 s->fcal_dest = FCAL_DEST_HW; 1835 s->invert_tly = 1; 1836 s->rgb_format = 1; 1837 /*s->duplex_offset = 400; now set in config file*/ 1838 1839 /*only in Y direction, so we trash them in X*/ 1840 s->std_res_x[DPI_100]=0; 1841 s->std_res_x[DPI_150]=0; 1842 s->std_res_x[DPI_200]=0; 1843 s->std_res_x[DPI_240]=0; 1844 s->std_res_x[DPI_400]=0; 1845 1846 /*suspected settings*/ 1847 s->always_op = 0; 1848 s->fixed_width = 1; 1849 s->valid_x = 8.5 * 1200; 1850 } 1851 1852 else if (strstr (s->model_name,"DR-F120")){ 1853 /* TODO items: 1854 * * has_rif = 0 ? is this correct 1855 * * has_comp_JPEG = 0 ? is this correct 1856 * * need_ccal = need_fcal = need_fcal_buffer = ccal_version = 0 ? is this correct 1857 */ 1858 1859 /* Required for USB coms */ 1860 s->has_ssm = 0; 1861 s->has_ssm2 = 1; 1862 1863 /*missing*/ 1864 s->std_res_x[DPI_100] = 1; 1865 s->std_res_y[DPI_100] = 1; 1866 // DPI_150 not supported 1867 s->std_res_x[DPI_200] = 1; 1868 s->std_res_y[DPI_200] = 1; 1869 s->std_res_x[DPI_300] = 1; 1870 s->std_res_y[DPI_300] = 1; 1871 // DPI_400 not supported 1872 s->std_res_x[DPI_600]= 1; 1873 s->std_res_y[DPI_600] = 1; 1874 // DPI_1200 not supported 1875 // NOTE: This scanner supports higher resolutions 1876 // in the Y direction, but 600 is maximum in X 1877 1878 // This is true however only the ADF is ever selected in hardware 1879 // FIXME: What extra option is needed to select this in the USB comms 1880 s->has_flatbed = 1; 1881 1882 /* duplex */ 1883 s->duplex_interlace = DUPLEX_INTERLACE_fFBb; 1884 s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_GBR; 1885 s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_GBR; 1886 s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_RGB; 1887 s->color_inter_by_res[DPI_600] = COLOR_INTERLACE_RGB; 1888 s->duplex_offset_side = SIDE_BACK; 1889 1890 /* weirdness */ 1891 s->fixed_width = 1; 1892 1893 /* lies */ 1894 s->can_halftone = 0; 1895 } 1896 1897 else if (strstr (s->model_name,"DR-X10C")){ 1898 int i = 0; 1899 1900 /* Required for USB coms */ 1901 s->has_ssm = 0; 1902 s->has_ssm2 = 1; 1903 1904 /* missing */ 1905 s->std_res_x[DPI_100]=1; 1906 s->std_res_y[DPI_100]=1; 1907 s->std_res_x[DPI_150]=1; 1908 s->std_res_y[DPI_150]=1; 1909 s->std_res_x[DPI_200]=1; 1910 s->std_res_y[DPI_200]=1; 1911 s->std_res_x[DPI_240]=1; 1912 s->std_res_y[DPI_240]=1; 1913 s->std_res_x[DPI_300]=1; 1914 s->std_res_y[DPI_300]=1; 1915 s->std_res_x[DPI_400]=1; 1916 s->std_res_y[DPI_400]=1; 1917 s->std_res_x[DPI_600]=1; 1918 s->std_res_y[DPI_600]=1; 1919 1920 s->has_hwcrop = 1; 1921 1922 /*valid horizontal offsets for post-imprinter*/ 1923 s->post_imprinter_h_offset_list[++i] = 21; 1924 s->post_imprinter_h_offset_list[++i] = 35; 1925 s->post_imprinter_h_offset_list[++i] = 47; 1926 s->post_imprinter_h_offset_list[++i] = 59; 1927 s->post_imprinter_h_offset_list[++i] = 72; 1928 s->post_imprinter_h_offset_list[++i] = 99; 1929 s->post_imprinter_h_offset_list[++i] = 114; 1930 s->post_imprinter_h_offset_list[++i] = 143; 1931 s->post_imprinter_h_offset_list[++i] = 155; 1932 s->post_imprinter_h_offset_list[++i] = 167; 1933 s->post_imprinter_h_offset_list[++i] = 196; 1934 s->post_imprinter_h_offset_list[++i] = 211; 1935 s->post_imprinter_h_offset_list[++i] = 239; 1936 s->post_imprinter_h_offset_list[++i] = 251; 1937 s->post_imprinter_h_offset_list[++i] = 263; 1938 s->post_imprinter_h_offset_list[++i] = 275; 1939 s->post_imprinter_h_offset_list[++i] = 289; 1940 s->post_imprinter_h_offset_list[0] = i; 1941 1942 i = 0; 1943 /*valid horizontal offsets for pre-imprinter*/ 1944 s->pre_imprinter_h_offset_list[++i] = 14; 1945 s->pre_imprinter_h_offset_list[++i] = 28; 1946 s->pre_imprinter_h_offset_list[++i] = 41; 1947 s->pre_imprinter_h_offset_list[++i] = 53; 1948 s->pre_imprinter_h_offset_list[++i] = 65; 1949 s->pre_imprinter_h_offset_list[++i] = 106; 1950 s->pre_imprinter_h_offset_list[0] = i; 1951 1952 /*valid vertical offsets for imprinters*/ 1953 s->imprinter_v_offset_range.min = 0; 1954 s->imprinter_v_offset_range.max = 500; 1955 s->imprinter_v_offset_range.quant = 1; 1956 1957 i = 0; 1958 /*valid font angles for imprinters*/ 1959 s->imprinter_font_angle_list[++i] = 0; 1960 s->imprinter_font_angle_list[++i] = 90; 1961 s->imprinter_font_angle_list[++i] = 180; 1962 s->imprinter_font_angle_list[++i] = 270; 1963 s->imprinter_font_angle_list[0] = i; 1964 1965 i = 0; 1966 s->imprint_font_size_list[i++] = STRING_IMPRINTER_8x12_FONT; 1967 s->imprint_font_size_list[i++] = STRING_IMPRINTER_12x12_FONT; 1968 s->imprint_font_size_list[i] = NULL; 1969 1970 i = 0; 1971 s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_BoI; 1972 s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_BoW; 1973 s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_WoB; 1974 s->imprint_addon_mode_list[i++] = STRING_NONE; 1975 s->imprint_addon_mode_list[i] = NULL; 1976 } 1977 1978 DBG (10, "init_model: finish\n"); 1979 1980 return SANE_STATUS_GOOD; 1981} 1982 1983/* 1984 * try to detect imprinters. 1985 */ 1986static SANE_Status 1987init_imprinters (struct scanner *s) 1988{ 1989 SANE_Status ret = SANE_STATUS_GOOD; 1990 1991 s->has_pre_imprinter = 0; 1992 s->has_post_imprinter = 0; 1993 1994 ret = detect_imprinter(s,R_PRE_IMPRINTER); 1995 if(ret != SANE_STATUS_GOOD){ 1996 return ret; 1997 } 1998 1999 ret = detect_imprinter(s,R_POST_IMPRINTER); 2000 if(ret != SANE_STATUS_GOOD){ 2001 return ret; 2002 } 2003 2004 return ret; 2005} 2006 2007/* 2008 * This function enables the buttons and preloads the current panel values 2009 */ 2010static SANE_Status 2011init_panel (struct scanner *s) 2012{ 2013 SANE_Status ret = SANE_STATUS_GOOD; 2014 2015 DBG (10, "init_panel: start\n"); 2016 2017 ret = read_panel(s,0); 2018 if(ret){ 2019 DBG (5, "init_panel: disabling read_panel\n"); 2020 s->can_read_panel = 0; 2021 ret = SANE_STATUS_GOOD; 2022 } 2023 2024 s->panel_enable_led = 1; 2025 s->panel_counter = 0; 2026 ret = send_panel(s); 2027 if(ret){ 2028 DBG (5, "init_panel: disabling send_panel\n"); 2029 s->can_write_panel = 0; 2030 ret = SANE_STATUS_GOOD; 2031 } 2032 2033 DBG (10, "init_panel: finish\n"); 2034 2035 return ret; 2036} 2037 2038/* 2039 * This function disables the lifecycle counters if not available 2040 */ 2041static SANE_Status 2042init_counters (struct scanner *s) 2043{ 2044 SANE_Status ret = SANE_STATUS_GOOD; 2045 2046 DBG (10, "init_counters: start\n"); 2047 2048 ret = read_counters(s); 2049 if(ret){ 2050 DBG (5, "init_counters: disabling lifecycle counters\n"); 2051 s->can_read_lifecycle_counters = 0; 2052 return ret; 2053 } 2054 2055 DBG (10, "init_counters: finish\n"); 2056 2057 return ret; 2058} 2059 2060/* 2061 * set good default user values. 2062 * struct is already initialized to 0. 2063 */ 2064static SANE_Status 2065init_user (struct scanner *s) 2066{ 2067 2068 DBG (10, "init_user: start\n"); 2069 2070 /* source */ 2071 if(s->has_flatbed) 2072 s->u.source = SOURCE_FLATBED; 2073 else if(s->has_adf) 2074 s->u.source = SOURCE_ADF_FRONT; 2075 else if(s->has_card) 2076 s->u.source = SOURCE_CARD_FRONT; 2077 2078 /* scan mode */ 2079 if(s->can_monochrome) 2080 s->u.mode=MODE_LINEART; 2081 else if(s->can_halftone) 2082 s->u.mode=MODE_HALFTONE; 2083 else if(s->can_grayscale) 2084 s->u.mode=MODE_GRAYSCALE; 2085 else if(s->can_color) 2086 s->u.mode=MODE_COLOR; 2087 2088 /*x and y res*/ 2089 s->u.dpi_x = s->basic_x_res; 2090 s->u.dpi_y = s->basic_x_res; 2091 2092 /* page width US-Letter */ 2093 s->u.page_x = 8.5 * 1200; 2094 if(s->u.page_x > s->valid_x){ 2095 s->u.page_x = s->valid_x; 2096 } 2097 2098 /* page height US-Letter */ 2099 s->u.page_y = 11 * 1200; 2100 if(s->u.page_y > s->max_y){ 2101 s->u.page_y = s->max_y; 2102 } 2103 2104 /* bottom-right x */ 2105 s->u.br_x = s->u.page_x; 2106 2107 /* bottom-right y */ 2108 s->u.br_y = s->u.page_y; 2109 2110 s->threshold = 90; 2111 s->compress_arg = 50; 2112 2113 s->pre_imprint.h_offset = 65; 2114 s->post_imprint.h_offset = 155; 2115 s->post_imprint_addon_mode = ADDON_BoI; 2116 2117 DBG (10, "init_user: finish\n"); 2118 2119 return SANE_STATUS_GOOD; 2120} 2121 2122/* 2123 * This function presets the "option" array to blank 2124 */ 2125static SANE_Status 2126init_options (struct scanner *s) 2127{ 2128 int i; 2129 2130 DBG (10, "init_options: start\n"); 2131 2132 memset (s->opt, 0, sizeof (s->opt)); 2133 for (i = 0; i < NUM_OPTIONS; ++i) { 2134 s->opt[i].name = "filler"; 2135 s->opt[i].size = sizeof (SANE_Word); 2136 s->opt[i].cap = SANE_CAP_INACTIVE; 2137 } 2138 2139 /* go ahead and setup the first opt, because 2140 * frontend may call control_option on it 2141 * before calling get_option_descriptor 2142 */ 2143 s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; 2144 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 2145 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 2146 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 2147 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 2148 2149 DBG (10, "init_options: finish\n"); 2150 2151 return SANE_STATUS_GOOD; 2152} 2153 2154/* 2155 * From the SANE spec: 2156 * This function is used to establish a connection to a particular 2157 * device. The name of the device to be opened is passed in argument 2158 * name. If the call completes successfully, a handle for the device 2159 * is returned in *h. As a special case, specifying a zero-length 2160 * string as the device requests opening the first available device 2161 * (if there is such a device). 2162 */ 2163SANE_Status 2164sane_open (SANE_String_Const name, SANE_Handle * handle) 2165{ 2166 struct scanner *dev = NULL; 2167 struct scanner *s = NULL; 2168 SANE_Status ret; 2169 2170 DBG (10, "sane_open: start\n"); 2171 2172 if(scanner_devList){ 2173 DBG (15, "sane_open: searching currently attached scanners\n"); 2174 } 2175 else{ 2176 DBG (15, "sane_open: no scanners currently attached, attaching\n"); 2177 2178 ret = sane_get_devices(NULL,0); 2179 if(ret != SANE_STATUS_GOOD){ 2180 return ret; 2181 } 2182 } 2183 2184 if(name[0] == 0){ 2185 DBG (15, "sane_open: no device requested, using default\n"); 2186 s = scanner_devList; 2187 } 2188 else{ 2189 DBG (15, "sane_open: device %s requested\n", name); 2190 2191 for (dev = scanner_devList; dev; dev = dev->next) { 2192 if (strcmp (dev->sane.name, name) == 0 2193 || strcmp (dev->device_name, name) == 0) { /*always allow sanei devname*/ 2194 s = dev; 2195 break; 2196 } 2197 } 2198 } 2199 2200 if (!s) { 2201 DBG (5, "sane_open: no device found\n"); 2202 return SANE_STATUS_INVAL; 2203 } 2204 2205 DBG (15, "sane_open: device %s found\n", s->sane.name); 2206 2207 *handle = s; 2208 2209 /* connect the fd so we can talk to scanner */ 2210 ret = connect_fd(s); 2211 if(ret != SANE_STATUS_GOOD){ 2212 return ret; 2213 } 2214 2215 DBG (10, "sane_open: finish\n"); 2216 2217 return SANE_STATUS_GOOD; 2218} 2219 2220/* 2221 * @@ Section 3 - SANE Options functions 2222 */ 2223 2224/* 2225 * Returns the options we know. 2226 * 2227 * From the SANE spec: 2228 * This function is used to access option descriptors. The function 2229 * returns the option descriptor for option number n of the device 2230 * represented by handle h. Option number 0 is guaranteed to be a 2231 * valid option. Its value is an integer that specifies the number of 2232 * options that are available for device handle h (the count includes 2233 * option 0). If n is not a valid option index, the function returns 2234 * NULL. The returned option descriptor is guaranteed to remain valid 2235 * (and at the returned address) until the device is closed. 2236 */ 2237const SANE_Option_Descriptor * 2238sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 2239{ 2240 struct scanner *s = handle; 2241 int i; 2242 SANE_Option_Descriptor *opt = &s->opt[option]; 2243 2244 DBG (20, "sane_get_option_descriptor: %d\n", option); 2245 2246 if ((unsigned) option >= NUM_OPTIONS) 2247 return NULL; 2248 2249 /* "Mode" group -------------------------------------------------------- */ 2250 if(option==OPT_STANDARD_GROUP){ 2251 opt->name = SANE_NAME_STANDARD; 2252 opt->title = SANE_TITLE_STANDARD; 2253 opt->desc = SANE_DESC_STANDARD; 2254 opt->type = SANE_TYPE_GROUP; 2255 opt->constraint_type = SANE_CONSTRAINT_NONE; 2256 } 2257 2258 /* source */ 2259 if(option==OPT_SOURCE){ 2260 i=0; 2261 if(s->has_flatbed){ 2262 s->source_list[i++]=STRING_FLATBED; 2263 } 2264 if(s->has_adf){ 2265 s->source_list[i++]=STRING_ADFFRONT; 2266 2267 if(s->has_back){ 2268 s->source_list[i++]=STRING_ADFBACK; 2269 } 2270 if(s->has_duplex){ 2271 s->source_list[i++]=STRING_ADFDUPLEX; 2272 } 2273 } 2274 if(s->has_card){ 2275 s->source_list[i++]=STRING_CARDFRONT; 2276 2277 if(s->has_back){ 2278 s->source_list[i++]=STRING_CARDBACK; 2279 } 2280 if(s->has_duplex){ 2281 s->source_list[i++]=STRING_CARDDUPLEX; 2282 } 2283 } 2284 s->source_list[i]=NULL; 2285 2286 opt->name = SANE_NAME_SCAN_SOURCE; 2287 opt->title = SANE_TITLE_SCAN_SOURCE; 2288 opt->desc = SANE_DESC_SCAN_SOURCE; 2289 opt->type = SANE_TYPE_STRING; 2290 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2291 opt->constraint.string_list = s->source_list; 2292 opt->size = maxStringSize (opt->constraint.string_list); 2293 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2294 } 2295 2296 /* scan mode */ 2297 if(option==OPT_MODE){ 2298 i=0; 2299 if(s->can_monochrome || s->can_grayscale || s->can_color){ 2300 s->mode_list[i++]=STRING_LINEART; 2301 } 2302 if(s->can_halftone){ 2303 s->mode_list[i++]=STRING_HALFTONE; 2304 } 2305 if(s->can_grayscale || s->can_color){ 2306 s->mode_list[i++]=STRING_GRAYSCALE; 2307 } 2308 if(s->can_color){ 2309 s->mode_list[i++]=STRING_COLOR; 2310 } 2311 s->mode_list[i]=NULL; 2312 2313 opt->name = SANE_NAME_SCAN_MODE; 2314 opt->title = SANE_TITLE_SCAN_MODE; 2315 opt->desc = SANE_DESC_SCAN_MODE; 2316 opt->type = SANE_TYPE_STRING; 2317 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2318 opt->constraint.string_list = s->mode_list; 2319 opt->size = maxStringSize (opt->constraint.string_list); 2320 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2321 } 2322 2323 /* resolution */ 2324 /* some scanners only support fixed res 2325 * build a list of possible choices */ 2326 /* we actually only look at the y resolution choices, 2327 * and interpolate the image data as required for limited x resolutions */ 2328 if(option==OPT_RES){ 2329 i=0; 2330 if(s->std_res_y[DPI_60] && s->max_y_res >= 60 && s->min_y_res <= 60){ 2331 s->res_list[++i] = 60; 2332 } 2333 if(s->std_res_y[DPI_75] && s->max_y_res >= 75 && s->min_y_res <= 75){ 2334 s->res_list[++i] = 75; 2335 } 2336 if(s->std_res_y[DPI_100] && s->max_y_res >= 100 && s->min_y_res <= 100){ 2337 s->res_list[++i] = 100; 2338 } 2339 if(s->std_res_y[DPI_120] && s->max_y_res >= 120 && s->min_y_res <= 120){ 2340 s->res_list[++i] = 120; 2341 } 2342 if(s->std_res_y[DPI_150] && s->max_y_res >= 150 && s->min_y_res <= 150){ 2343 s->res_list[++i] = 150; 2344 } 2345 if(s->std_res_y[DPI_160] && s->max_y_res >= 160 && s->min_y_res <= 160){ 2346 s->res_list[++i] = 160; 2347 } 2348 if(s->std_res_y[DPI_180] && s->max_y_res >= 180 && s->min_y_res <= 180){ 2349 s->res_list[++i] = 180; 2350 } 2351 if(s->std_res_y[DPI_200] && s->max_y_res >= 200 && s->min_y_res <= 200){ 2352 s->res_list[++i] = 200; 2353 } 2354 if(s->std_res_y[DPI_240] && s->max_y_res >= 240 && s->min_y_res <= 240){ 2355 s->res_list[++i] = 240; 2356 } 2357 if(s->std_res_y[DPI_300] && s->max_y_res >= 300 && s->min_y_res <= 300){ 2358 s->res_list[++i] = 300; 2359 } 2360 if(s->std_res_y[DPI_320] && s->max_y_res >= 320 && s->min_y_res <= 320){ 2361 s->res_list[++i] = 320; 2362 } 2363 if(s->std_res_y[DPI_400] && s->max_y_res >= 400 && s->min_y_res <= 400){ 2364 s->res_list[++i] = 400; 2365 } 2366 if(s->std_res_y[DPI_480] && s->max_y_res >= 480 && s->min_y_res <= 480){ 2367 s->res_list[++i] = 480; 2368 } 2369 if(s->std_res_y[DPI_600] && s->max_y_res >= 600 && s->min_y_res <= 600){ 2370 s->res_list[++i] = 600; 2371 } 2372 if(s->std_res_y[DPI_800] && s->max_y_res >= 800 && s->min_y_res <= 800){ 2373 s->res_list[++i] = 800; 2374 } 2375 if(s->std_res_y[DPI_1200] && s->max_y_res >= 1200 && s->min_y_res <= 1200){ 2376 s->res_list[++i] = 1200; 2377 } 2378 s->res_list[0] = i; 2379 2380 opt->name = SANE_NAME_SCAN_RESOLUTION; 2381 opt->title = SANE_TITLE_SCAN_RESOLUTION; 2382 opt->desc = SANE_DESC_SCAN_RESOLUTION; 2383 opt->type = SANE_TYPE_INT; 2384 opt->unit = SANE_UNIT_DPI; 2385 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2386 2387 if(s->step_y_res){ 2388 s->res_range.min = s->min_y_res; 2389 s->res_range.max = s->max_y_res; 2390 s->res_range.quant = s->step_y_res; 2391 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2392 opt->constraint.range = &s->res_range; 2393 } 2394 else{ 2395 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; 2396 opt->constraint.word_list = s->res_list; 2397 } 2398 } 2399 2400 /* "Geometry" group ---------------------------------------------------- */ 2401 if(option==OPT_GEOMETRY_GROUP){ 2402 opt->name = SANE_NAME_GEOMETRY; 2403 opt->title = SANE_TITLE_GEOMETRY; 2404 opt->desc = SANE_DESC_GEOMETRY; 2405 opt->type = SANE_TYPE_GROUP; 2406 opt->constraint_type = SANE_CONSTRAINT_NONE; 2407 } 2408 2409 /* top-left x */ 2410 if(option==OPT_TL_X){ 2411 /* values stored in 1200 dpi units */ 2412 /* must be converted to MM for sane */ 2413 s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); 2414 s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)); 2415 s->tl_x_range.quant = MM_PER_UNIT_FIX; 2416 2417 opt->name = SANE_NAME_SCAN_TL_X; 2418 opt->title = SANE_TITLE_SCAN_TL_X; 2419 opt->desc = SANE_DESC_SCAN_TL_X; 2420 opt->type = SANE_TYPE_FIXED; 2421 opt->unit = SANE_UNIT_MM; 2422 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2423 opt->constraint.range = &(s->tl_x_range); 2424 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2425 } 2426 2427 /* top-left y */ 2428 if(option==OPT_TL_Y){ 2429 /* values stored in 1200 dpi units */ 2430 /* must be converted to MM for sane */ 2431 s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); 2432 s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)); 2433 s->tl_y_range.quant = MM_PER_UNIT_FIX; 2434 2435 opt->name = SANE_NAME_SCAN_TL_Y; 2436 opt->title = SANE_TITLE_SCAN_TL_Y; 2437 opt->desc = SANE_DESC_SCAN_TL_Y; 2438 opt->type = SANE_TYPE_FIXED; 2439 opt->unit = SANE_UNIT_MM; 2440 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2441 opt->constraint.range = &(s->tl_y_range); 2442 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2443 } 2444 2445 /* bottom-right x */ 2446 if(option==OPT_BR_X){ 2447 /* values stored in 1200 dpi units */ 2448 /* must be converted to MM for sane */ 2449 s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); 2450 s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)); 2451 s->br_x_range.quant = MM_PER_UNIT_FIX; 2452 2453 opt->name = SANE_NAME_SCAN_BR_X; 2454 opt->title = SANE_TITLE_SCAN_BR_X; 2455 opt->desc = SANE_DESC_SCAN_BR_X; 2456 opt->type = SANE_TYPE_FIXED; 2457 opt->unit = SANE_UNIT_MM; 2458 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2459 opt->constraint.range = &(s->br_x_range); 2460 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2461 } 2462 2463 /* bottom-right y */ 2464 if(option==OPT_BR_Y){ 2465 /* values stored in 1200 dpi units */ 2466 /* must be converted to MM for sane */ 2467 s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); 2468 s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)); 2469 s->br_y_range.quant = MM_PER_UNIT_FIX; 2470 2471 opt->name = SANE_NAME_SCAN_BR_Y; 2472 opt->title = SANE_TITLE_SCAN_BR_Y; 2473 opt->desc = SANE_DESC_SCAN_BR_Y; 2474 opt->type = SANE_TYPE_FIXED; 2475 opt->unit = SANE_UNIT_MM; 2476 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2477 opt->constraint.range = &(s->br_y_range); 2478 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2479 } 2480 2481 /* page width */ 2482 if(option==OPT_PAGE_WIDTH){ 2483 /* values stored in 1200 dpi units */ 2484 /* must be converted to MM for sane */ 2485 s->paper_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); 2486 s->paper_x_range.max = SCANNER_UNIT_TO_FIXED_MM(s->valid_x); 2487 s->paper_x_range.quant = MM_PER_UNIT_FIX; 2488 2489 opt->name = SANE_NAME_PAGE_WIDTH; 2490 opt->title = SANE_TITLE_PAGE_WIDTH; 2491 opt->desc = SANE_DESC_PAGE_WIDTH; 2492 opt->type = SANE_TYPE_FIXED; 2493 opt->unit = SANE_UNIT_MM; 2494 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2495 opt->constraint.range = &s->paper_x_range; 2496 2497 if(s->has_adf || s->has_card){ 2498 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2499 if(s->u.source == SOURCE_FLATBED){ 2500 opt->cap |= SANE_CAP_INACTIVE; 2501 } 2502 } 2503 else{ 2504 opt->cap = SANE_CAP_INACTIVE; 2505 } 2506 } 2507 2508 /* page height */ 2509 if(option==OPT_PAGE_HEIGHT){ 2510 /* values stored in 1200 dpi units */ 2511 /* must be converted to MM for sane */ 2512 s->paper_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); 2513 s->paper_y_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_y); 2514 s->paper_y_range.quant = MM_PER_UNIT_FIX; 2515 2516 opt->name = SANE_NAME_PAGE_HEIGHT; 2517 opt->title = SANE_TITLE_PAGE_HEIGHT; 2518 opt->desc = SANE_DESC_PAGE_HEIGHT; 2519 opt->type = SANE_TYPE_FIXED; 2520 opt->unit = SANE_UNIT_MM; 2521 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2522 opt->constraint.range = &s->paper_y_range; 2523 2524 if(s->has_adf || s->has_card){ 2525 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2526 if(s->u.source == SOURCE_FLATBED){ 2527 opt->cap |= SANE_CAP_INACTIVE; 2528 } 2529 } 2530 else{ 2531 opt->cap = SANE_CAP_INACTIVE; 2532 } 2533 } 2534 2535 /* "Enhancement" group ------------------------------------------------- */ 2536 if(option==OPT_ENHANCEMENT_GROUP){ 2537 opt->name = SANE_NAME_ENHANCEMENT; 2538 opt->title = SANE_TITLE_ENHANCEMENT; 2539 opt->desc = SANE_DESC_ENHANCEMENT; 2540 opt->type = SANE_TYPE_GROUP; 2541 opt->constraint_type = SANE_CONSTRAINT_NONE; 2542 } 2543 2544 /* brightness */ 2545 if(option==OPT_BRIGHTNESS){ 2546 opt->name = SANE_NAME_BRIGHTNESS; 2547 opt->title = SANE_TITLE_BRIGHTNESS; 2548 opt->desc = SANE_DESC_BRIGHTNESS; 2549 opt->type = SANE_TYPE_INT; 2550 opt->unit = SANE_UNIT_NONE; 2551 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2552 opt->constraint.range = &s->brightness_range; 2553 s->brightness_range.quant=1; 2554 2555 /* some have hardware brightness (always 0 to 255?) */ 2556 /* some use LUT or GT (-127 to +127)*/ 2557 if (s->brightness_steps){ 2558 s->brightness_range.min=-127; 2559 s->brightness_range.max=127; 2560 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2561 } 2562 else{ 2563 opt->cap = SANE_CAP_INACTIVE; 2564 } 2565 } 2566 2567 /* contrast */ 2568 if(option==OPT_CONTRAST){ 2569 opt->name = SANE_NAME_CONTRAST; 2570 opt->title = SANE_TITLE_CONTRAST; 2571 opt->desc = SANE_DESC_CONTRAST; 2572 opt->type = SANE_TYPE_INT; 2573 opt->unit = SANE_UNIT_NONE; 2574 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2575 opt->constraint.range = &s->contrast_range; 2576 s->contrast_range.quant=1; 2577 2578 /* some have hardware contrast (always 0 to 255?) */ 2579 /* some use LUT or GT (-127 to +127)*/ 2580 if (s->contrast_steps){ 2581 s->contrast_range.min=-127; 2582 s->contrast_range.max=127; 2583 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2584 } 2585 else { 2586 opt->cap = SANE_CAP_INACTIVE; 2587 } 2588 } 2589 2590 /*threshold*/ 2591 if(option==OPT_THRESHOLD){ 2592 opt->name = SANE_NAME_THRESHOLD; 2593 opt->title = SANE_TITLE_THRESHOLD; 2594 opt->desc = SANE_DESC_THRESHOLD; 2595 opt->type = SANE_TYPE_INT; 2596 opt->unit = SANE_UNIT_NONE; 2597 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2598 opt->constraint.range = &s->threshold_range; 2599 s->threshold_range.min=0; 2600 s->threshold_range.max=s->threshold_steps; 2601 s->threshold_range.quant=1; 2602 2603 if (s->threshold_steps){ 2604 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2605 if(s->u.mode != MODE_LINEART){ 2606 opt->cap |= SANE_CAP_INACTIVE; 2607 } 2608 } 2609 else { 2610 opt->cap = SANE_CAP_INACTIVE; 2611 } 2612 } 2613 2614 if(option==OPT_RIF){ 2615 opt->name = "rif"; 2616 opt->title = "RIF"; 2617 opt->desc = "Reverse image format"; 2618 opt->type = SANE_TYPE_BOOL; 2619 opt->unit = SANE_UNIT_NONE; 2620 if (s->has_rif) 2621 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2622 else 2623 opt->cap = SANE_CAP_INACTIVE; 2624 } 2625 2626 /* "Advanced" group ------------------------------------------------------ */ 2627 if(option==OPT_ADVANCED_GROUP){ 2628 opt->name = SANE_NAME_ADVANCED; 2629 opt->title = SANE_TITLE_ADVANCED; 2630 opt->desc = SANE_DESC_ADVANCED; 2631 opt->type = SANE_TYPE_GROUP; 2632 opt->constraint_type = SANE_CONSTRAINT_NONE; 2633 } 2634 2635 /*image compression*/ 2636 if(option==OPT_COMPRESS){ 2637 i=0; 2638 s->compress_list[i++]=STRING_NONE; 2639 2640 if(s->has_comp_JPEG){ 2641#ifndef SANE_JPEG_DISABLED 2642 s->compress_list[i++]=STRING_JPEG; 2643#endif 2644 } 2645 2646 s->compress_list[i]=NULL; 2647 2648 opt->name = "compression"; 2649 opt->title = "Compression"; 2650 opt->desc = "Enable compressed data. May crash your front-end program"; 2651 opt->type = SANE_TYPE_STRING; 2652 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2653 opt->constraint.string_list = s->compress_list; 2654 opt->size = maxStringSize (opt->constraint.string_list); 2655 2656 if (i > 1){ 2657 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2658 if ( must_downsample(s) || s->s.mode < MODE_GRAYSCALE ){ 2659 opt->cap |= SANE_CAP_INACTIVE; 2660 } 2661 } 2662 else 2663 opt->cap = SANE_CAP_INACTIVE; 2664 } 2665 2666 /*image compression arg*/ 2667 if(option==OPT_COMPRESS_ARG){ 2668 2669 opt->name = "compression-arg"; 2670 opt->title = "Compression argument"; 2671 opt->desc = "Level of JPEG compression. 1 is small file, 100 is large file."; 2672 opt->type = SANE_TYPE_INT; 2673 opt->unit = SANE_UNIT_NONE; 2674 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2675 opt->constraint.range = &s->compress_arg_range; 2676 s->compress_arg_range.quant=1; 2677 2678 if(s->has_comp_JPEG){ 2679 s->compress_arg_range.min=0; 2680 s->compress_arg_range.max=100; 2681 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2682 2683 if(s->compress != COMP_JPEG){ 2684 opt->cap |= SANE_CAP_INACTIVE; 2685 } 2686 } 2687 else 2688 opt->cap = SANE_CAP_INACTIVE; 2689 } 2690 2691 /*double feed by length*/ 2692 if(option==OPT_DF_LENGTH){ 2693 opt->name = "df-length"; 2694 opt->title = "DF by length"; 2695 opt->desc = "Detect double feeds by comparing document lengths"; 2696 opt->type = SANE_TYPE_BOOL; 2697 opt->unit = SANE_UNIT_NONE; 2698 opt->constraint_type = SANE_CONSTRAINT_NONE; 2699 2700 if (1) 2701 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2702 else 2703 opt->cap = SANE_CAP_INACTIVE; 2704 } 2705 2706 /*double feed by thickness */ 2707 if(option==OPT_DF_THICKNESS){ 2708 2709 opt->name = "df-thickness"; 2710 opt->title = "DF by thickness"; 2711 opt->desc = "Detect double feeds using thickness sensor"; 2712 opt->type = SANE_TYPE_BOOL; 2713 opt->unit = SANE_UNIT_NONE; 2714 opt->constraint_type = SANE_CONSTRAINT_NONE; 2715 2716 if (1){ 2717 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2718 } 2719 else 2720 opt->cap = SANE_CAP_INACTIVE; 2721 } 2722 2723 /*deskew by roller*/ 2724 if(option==OPT_ROLLERDESKEW){ 2725 opt->name = "rollerdeskew"; 2726 opt->title = "Roller deskew"; 2727 opt->desc = "Request scanner to correct skewed pages mechanically"; 2728 opt->type = SANE_TYPE_BOOL; 2729 if (1) 2730 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2731 else 2732 opt->cap = SANE_CAP_INACTIVE; 2733 } 2734 2735 /*deskew by software*/ 2736 if(option==OPT_SWDESKEW){ 2737 opt->name = "swdeskew"; 2738 opt->title = "Software deskew"; 2739 opt->desc = "Request driver to rotate skewed pages digitally"; 2740 opt->type = SANE_TYPE_BOOL; 2741 if (1) 2742 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2743 else 2744 opt->cap = SANE_CAP_INACTIVE; 2745 } 2746 2747 /*software despeckle radius*/ 2748 if(option==OPT_SWDESPECK){ 2749 2750 opt->name = "swdespeck"; 2751 opt->title = "Software despeckle diameter"; 2752 opt->desc = "Maximum diameter of lone dots to remove from scan"; 2753 opt->type = SANE_TYPE_INT; 2754 opt->unit = SANE_UNIT_NONE; 2755 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2756 opt->constraint.range = &s->swdespeck_range; 2757 s->swdespeck_range.quant=1; 2758 2759 if(1){ 2760 s->swdespeck_range.min=0; 2761 s->swdespeck_range.max=9; 2762 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2763 } 2764 else 2765 opt->cap = SANE_CAP_INACTIVE; 2766 } 2767 2768 /*crop by software*/ 2769 if(option==OPT_SWCROP){ 2770 opt->name = "swcrop"; 2771 opt->title = "Software crop"; 2772 opt->desc = "Request driver to remove border from pages digitally"; 2773 opt->type = SANE_TYPE_BOOL; 2774 if (1) 2775 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2776 else 2777 opt->cap = SANE_CAP_INACTIVE; 2778 } 2779 2780 /* Software blank page skip */ 2781 if(option==OPT_SWSKIP){ 2782 2783 opt->name = "swskip"; 2784 opt->title = SANE_I18N ("Software blank skip percentage"); 2785 opt->desc = SANE_I18N("Request driver to discard pages with low percentage of dark pixels"); 2786 opt->type = SANE_TYPE_FIXED; 2787 opt->unit = SANE_UNIT_PERCENT; 2788 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2789 opt->constraint.range = &s->swskip_range; 2790 2791 s->swskip_range.quant=SANE_FIX(0.10001); 2792 s->swskip_range.min=SANE_FIX(0); 2793 s->swskip_range.max=SANE_FIX(100); 2794 2795 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 2796 } 2797 2798 /*staple detection*/ 2799 if(option==OPT_STAPLEDETECT){ 2800 opt->name = "stapledetect"; 2801 opt->title = "Staple detect"; 2802 opt->desc = "Request scanner to halt if stapled pages are detected"; 2803 opt->type = SANE_TYPE_BOOL; 2804 if (1) 2805 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2806 else 2807 opt->cap = SANE_CAP_INACTIVE; 2808 } 2809 2810 /*dropout color front*/ 2811 if(option==OPT_DROPOUT_COLOR_F){ 2812 s->do_color_list[0] = STRING_NONE; 2813 s->do_color_list[1] = STRING_RED; 2814 s->do_color_list[2] = STRING_GREEN; 2815 s->do_color_list[3] = STRING_BLUE; 2816 s->do_color_list[4] = STRING_EN_RED; 2817 s->do_color_list[5] = STRING_EN_GREEN; 2818 s->do_color_list[6] = STRING_EN_BLUE; 2819 s->do_color_list[7] = NULL; 2820 2821 opt->name = "dropout-front"; 2822 opt->title = "Dropout color front"; 2823 opt->desc = "One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink"; 2824 opt->type = SANE_TYPE_STRING; 2825 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2826 opt->constraint.string_list = s->do_color_list; 2827 opt->size = maxStringSize (opt->constraint.string_list); 2828 2829 if (1){ 2830 opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED; 2831 if(s->u.mode == MODE_COLOR) 2832 opt->cap |= SANE_CAP_INACTIVE; 2833 } 2834 else 2835 opt->cap = SANE_CAP_INACTIVE; 2836 } 2837 2838 /*dropout color back*/ 2839 if(option==OPT_DROPOUT_COLOR_B){ 2840 s->do_color_list[0] = STRING_NONE; 2841 s->do_color_list[1] = STRING_RED; 2842 s->do_color_list[2] = STRING_GREEN; 2843 s->do_color_list[3] = STRING_BLUE; 2844 s->do_color_list[4] = STRING_EN_RED; 2845 s->do_color_list[5] = STRING_EN_GREEN; 2846 s->do_color_list[6] = STRING_EN_BLUE; 2847 s->do_color_list[7] = NULL; 2848 2849 opt->name = "dropout-back"; 2850 opt->title = "Dropout color back"; 2851 opt->desc = "One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink"; 2852 opt->type = SANE_TYPE_STRING; 2853 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2854 opt->constraint.string_list = s->do_color_list; 2855 opt->size = maxStringSize (opt->constraint.string_list); 2856 2857 if (1){ 2858 opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED; 2859 if(s->u.mode == MODE_COLOR) 2860 opt->cap |= SANE_CAP_INACTIVE; 2861 } 2862 else 2863 opt->cap = SANE_CAP_INACTIVE; 2864 } 2865 2866 /*buffer mode*/ 2867 if(option==OPT_BUFFERMODE){ 2868 opt->name = "buffermode"; 2869 opt->title = "Buffer mode"; 2870 opt->desc = "Request scanner to read pages async into internal memory"; 2871 opt->type = SANE_TYPE_BOOL; 2872 if (s->has_buffer) 2873 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2874 else 2875 opt->cap = SANE_CAP_INACTIVE; 2876 } 2877 2878 if(option==OPT_SIDE){ 2879 opt->name = "side"; 2880 opt->title = "Duplex side"; 2881 opt->desc = "Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return."; 2882 opt->type = SANE_TYPE_BOOL; 2883 opt->unit = SANE_UNIT_NONE; 2884 opt->size = sizeof(SANE_Word); 2885 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2886 opt->constraint_type = SANE_CONSTRAINT_NONE; 2887 } 2888 2889 /*hardware crop*/ 2890 if(option==OPT_HW_CROP){ 2891 opt->name = "hwcrop"; 2892 opt->title = "Hardware crop"; 2893 opt->desc = "Request scanner to crop image automatically"; 2894 opt->type = SANE_TYPE_BOOL; 2895 if (s->has_hwcrop) 2896 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2897 else 2898 opt->cap = SANE_CAP_INACTIVE; 2899 } 2900 2901 /* "Imprinter" group --------------------------------------------------- */ 2902 if(option==OPT_IMPRINT_GROUP){ 2903 opt->name = "imprinter-options"; 2904 opt->title = SANE_I18N ("Imprinter Options"); 2905 opt->desc = SANE_I18N ("Controls for imprinter units"); 2906 opt->type = SANE_TYPE_GROUP; 2907 opt->constraint_type = SANE_CONSTRAINT_NONE; 2908 2909 /*flaming hack to get scanimage to hide group*/ 2910 if ( !(s->has_pre_imprinter || s->has_post_imprinter) ) 2911 opt->type = SANE_TYPE_BOOL; 2912 } 2913 2914 if(option==OPT_PRE_IMPRINT_SPECSTRING){ 2915 opt->name = "pre-imprint-string"; 2916 opt->title = "Pre-Imprinter string"; 2917 opt->desc = "String specifier for the pre-imprinter text"; 2918 opt->type = SANE_TYPE_STRING; 2919 opt->size = IMPRINT_SPECSTRING_LEN; 2920 if (s->has_pre_imprinter) 2921 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2922 else 2923 opt->cap = SANE_CAP_INACTIVE; 2924 } 2925 2926 if(option==OPT_PRE_IMPRINT_H_OFFSET){ 2927 opt->name = "pre-imprint-h-offset"; 2928 opt->title = "Pre-Imprinter horizontal offset"; 2929 opt->desc = "Integer specifying the horizontal positioning of the pre-imprinter"; 2930 opt->type = SANE_TYPE_INT; 2931 opt->unit = SANE_UNIT_MM; 2932 opt->size = sizeof(SANE_Word); 2933 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; 2934 opt->constraint.word_list = s->pre_imprinter_h_offset_list; 2935 if (s->has_pre_imprinter) 2936 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2937 else 2938 opt->cap = SANE_CAP_INACTIVE; 2939 } 2940 2941 if(option==OPT_PRE_IMPRINT_V_OFFSET){ 2942 opt->name = "pre-imprint-v-offset"; 2943 opt->title = "Pre-Imprinter vertical offset"; 2944 opt->desc = "Integer specifying the vertical positioning of the pre-imprinter"; 2945 opt->type = SANE_TYPE_INT; 2946 opt->unit = SANE_UNIT_MM; 2947 opt->size = sizeof(SANE_Word); 2948 opt->constraint_type = SANE_CONSTRAINT_RANGE; 2949 opt->constraint.range = &s->imprinter_v_offset_range; 2950 if (s->has_pre_imprinter) 2951 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2952 else 2953 opt->cap = SANE_CAP_INACTIVE; 2954 } 2955 2956 if(option==OPT_PRE_IMPRINT_FONT_SIZE){ 2957 opt->name = "pre-imprint-font-size"; 2958 opt->title = "Pre-Imprinter font size"; 2959 opt->desc = "Integer specifying the pre-imprint font size"; 2960 opt->type = SANE_TYPE_STRING; 2961 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 2962 opt->constraint.string_list = s->imprint_font_size_list; 2963 opt->size = maxStringSize (opt->constraint.string_list); 2964 if (s->has_pre_imprinter) 2965 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2966 else 2967 opt->cap = SANE_CAP_INACTIVE; 2968 } 2969 2970 if(option==OPT_PRE_IMPRINT_FONT_ROT){ 2971 opt->name = "pre-imprint-font-rot"; 2972 opt->title = "Pre-Imprinter font rotation"; 2973 opt->desc = "Integer specifying the pre-imprint font rotation"; 2974 opt->type = SANE_TYPE_INT; 2975 opt->unit = SANE_UNIT_NONE; 2976 opt->size = sizeof(SANE_Word); 2977 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; 2978 opt->constraint.word_list = s->imprinter_font_angle_list; 2979 if (s->has_pre_imprinter) 2980 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2981 else 2982 opt->cap = SANE_CAP_INACTIVE; 2983 } 2984 2985 if(option==OPT_PRE_IMPRINT_SPACING){ 2986 opt->name = "pre-imprint-spacing"; 2987 opt->title = "Pre-Imprinter spacing"; 2988 opt->desc = "Enables the pre-imprint extra spacing"; 2989 opt->type = SANE_TYPE_BOOL; 2990 if (s->has_pre_imprinter) 2991 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 2992 else 2993 opt->cap = SANE_CAP_INACTIVE; 2994 } 2995 2996 if(option==OPT_POST_IMPRINT_SPECSTRING){ 2997 opt->name = "post-imprint-string"; 2998 opt->title = "Post-Imprinter string"; 2999 opt->desc = "String specifier for the post-imprinter text"; 3000 opt->type = SANE_TYPE_STRING; 3001 opt->size = IMPRINT_SPECSTRING_LEN; 3002 if (s->has_post_imprinter) 3003 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3004 else 3005 opt->cap = SANE_CAP_INACTIVE; 3006 } 3007 3008 if(option==OPT_POST_IMPRINT_H_OFFSET){ 3009 opt->name = "post-imprint-h-offset"; 3010 opt->title = "Post-Imprinter horizontal offset"; 3011 opt->desc = "Integer specifying the horizontal positioning of the post-imprinter"; 3012 opt->type = SANE_TYPE_INT; 3013 opt->unit = SANE_UNIT_MM; 3014 opt->size = sizeof(SANE_Word); 3015 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; 3016 opt->constraint.word_list = s->post_imprinter_h_offset_list; 3017 if (s->has_post_imprinter) 3018 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3019 else 3020 opt->cap = SANE_CAP_INACTIVE; 3021 } 3022 3023 if(option==OPT_POST_IMPRINT_V_OFFSET){ 3024 opt->name = "post-imprint-v-offset"; 3025 opt->title = "Post-Imprinter vertical offset"; 3026 opt->desc = "Integer specifying the vertical positioning of the post-imprinter"; 3027 opt->type = SANE_TYPE_INT; 3028 opt->unit = SANE_UNIT_MM; 3029 opt->size = sizeof(SANE_Word); 3030 opt->constraint_type = SANE_CONSTRAINT_RANGE; 3031 opt->constraint.range = &s->imprinter_v_offset_range; 3032 if (s->has_post_imprinter) 3033 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3034 else 3035 opt->cap = SANE_CAP_INACTIVE; 3036 } 3037 3038 if(option==OPT_POST_IMPRINT_FONT_SIZE){ 3039 opt->name = "post-imprint-font-size"; 3040 opt->title = "Post-Imprinter font size"; 3041 opt->desc = "Integer specifying the post-imprint font size"; 3042 opt->type = SANE_TYPE_STRING; 3043 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 3044 opt->constraint.string_list = s->imprint_font_size_list; 3045 opt->size = maxStringSize (opt->constraint.string_list); 3046 if (s->has_post_imprinter) 3047 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3048 else 3049 opt->cap = SANE_CAP_INACTIVE; 3050 } 3051 3052 if(option==OPT_POST_IMPRINT_FONT_ROT){ 3053 opt->name = "post-imprint-font-rot"; 3054 opt->title = "Post-Imprinter font rotation"; 3055 opt->desc = "Integer specifying the post-imprint font rotation"; 3056 opt->type = SANE_TYPE_INT; 3057 opt->unit = SANE_UNIT_NONE; 3058 opt->size = sizeof(SANE_Word); 3059 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; 3060 opt->constraint.word_list = s->imprinter_font_angle_list; 3061 if (s->has_post_imprinter) 3062 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3063 else 3064 opt->cap = SANE_CAP_INACTIVE; 3065 } 3066 3067 if(option==OPT_POST_IMPRINT_SPACING){ 3068 opt->name = "post-imprint-spacing"; 3069 opt->title = "Post-Imprinter spacing"; 3070 opt->desc = "Enables the post-imprint extra spacing"; 3071 opt->type = SANE_TYPE_BOOL; 3072 if (s->has_post_imprinter) 3073 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3074 else 3075 opt->cap = SANE_CAP_INACTIVE; 3076 } 3077 3078 if(option==OPT_POST_IMPRINT_ADDON_MODE){ 3079 opt->name = "post-imprint-addon-mode"; 3080 opt->title = "Post-Imprinter addon mode"; 3081 opt->desc = "Integer specifying the type of post-imprint addon rendered in the scanned image"; 3082 opt->type = SANE_TYPE_STRING; 3083 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; 3084 opt->constraint.string_list = s->imprint_addon_mode_list; 3085 opt->size = maxStringSize (opt->constraint.string_list); 3086 if (s->has_post_imprinter) 3087 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 3088 else 3089 opt->cap = SANE_CAP_INACTIVE; 3090 } 3091 3092 /* "Sensor" group ------------------------------------------------------ */ 3093 if(option==OPT_SENSOR_GROUP){ 3094 opt->name = SANE_NAME_SENSORS; 3095 opt->title = SANE_TITLE_SENSORS; 3096 opt->desc = SANE_DESC_SENSORS; 3097 opt->type = SANE_TYPE_GROUP; 3098 opt->constraint_type = SANE_CONSTRAINT_NONE; 3099 } 3100 3101 if(option==OPT_START){ 3102 opt->name = "start"; 3103 opt->title = "Start/1 button"; 3104 opt->desc = "Big green or small 1 button"; 3105 opt->type = SANE_TYPE_BOOL; 3106 opt->unit = SANE_UNIT_NONE; 3107 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3108 if(!s->can_read_panel) 3109 opt->cap = SANE_CAP_INACTIVE; 3110 } 3111 3112 if(option==OPT_STOP){ 3113 opt->name = "stop"; 3114 opt->title = "Stop/2 button"; 3115 opt->desc = "Small orange or small 2 button"; 3116 opt->type = SANE_TYPE_BOOL; 3117 opt->unit = SANE_UNIT_NONE; 3118 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3119 if(!s->can_read_panel) 3120 opt->cap = SANE_CAP_INACTIVE; 3121 } 3122 3123 if(option==OPT_BUTT3){ 3124 opt->name = "button-3"; 3125 opt->title = "3 button"; 3126 opt->desc = "Small 3 button"; 3127 opt->type = SANE_TYPE_BOOL; 3128 opt->unit = SANE_UNIT_NONE; 3129 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3130 if(!s->can_read_panel) 3131 opt->cap = SANE_CAP_INACTIVE; 3132 } 3133 3134 if(option==OPT_NEWFILE){ 3135 opt->name = "newfile"; 3136 opt->title = "New File button"; 3137 opt->desc = "New File button"; 3138 opt->type = SANE_TYPE_BOOL; 3139 opt->unit = SANE_UNIT_NONE; 3140 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3141 if(!s->can_read_panel) 3142 opt->cap = SANE_CAP_INACTIVE; 3143 } 3144 3145 if(option==OPT_COUNTONLY){ 3146 opt->name = "countonly"; 3147 opt->title = "Count Only button"; 3148 opt->desc = "Count Only button"; 3149 opt->type = SANE_TYPE_BOOL; 3150 opt->unit = SANE_UNIT_NONE; 3151 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3152 if(!s->can_read_panel) 3153 opt->cap = SANE_CAP_INACTIVE; 3154 } 3155 3156 if(option==OPT_BYPASSMODE){ 3157 opt->name = "bypassmode"; 3158 opt->title = "Bypass Mode button"; 3159 opt->desc = "Bypass Mode button"; 3160 opt->type = SANE_TYPE_BOOL; 3161 opt->unit = SANE_UNIT_NONE; 3162 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3163 if(!s->can_read_panel) 3164 opt->cap = SANE_CAP_INACTIVE; 3165 } 3166 3167 if(option==OPT_COUNTER){ 3168 opt->name = "counter"; 3169 opt->title = "Counter"; 3170 opt->desc = "Scan counter"; 3171 opt->type = SANE_TYPE_INT; 3172 opt->unit = SANE_UNIT_NONE; 3173 opt->constraint_type = SANE_CONSTRAINT_RANGE; 3174 opt->constraint.range = &s->counter_range; 3175 s->counter_range.min=0; 3176 s->counter_range.max=500; 3177 s->counter_range.quant=1; 3178 3179 if (s->can_read_panel && s->has_counter) 3180 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3181 else 3182 opt->cap = SANE_CAP_INACTIVE; 3183 } 3184 3185 if(option==OPT_ROLLERCOUNTER){ 3186 opt->name = "roller-counter"; 3187 opt->title = "Roller Counter"; 3188 opt->desc = "Scans since last roller replacement"; 3189 opt->type = SANE_TYPE_INT; 3190 opt->unit = SANE_UNIT_NONE; 3191 opt->constraint_type = SANE_CONSTRAINT_NONE; 3192 3193 if (s->can_read_lifecycle_counters) 3194 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3195 else 3196 opt->cap = SANE_CAP_INACTIVE; 3197 } 3198 3199 if(option==OPT_TOTALCOUNTER){ 3200 opt->name = "total-counter"; 3201 opt->title = "Total Counter"; 3202 opt->desc = "Total scan count of the device"; 3203 opt->type = SANE_TYPE_INT; 3204 opt->unit = SANE_UNIT_NONE; 3205 opt->constraint_type = SANE_CONSTRAINT_NONE; 3206 3207 if (s->can_read_lifecycle_counters) 3208 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3209 else 3210 opt->cap = SANE_CAP_INACTIVE; 3211 } 3212 3213 if(option==OPT_ADF_LOADED){ 3214 opt->name = "adf-loaded"; 3215 opt->title = "ADF Loaded"; 3216 opt->desc = "Paper available in ADF input hopper"; 3217 opt->type = SANE_TYPE_BOOL; 3218 opt->unit = SANE_UNIT_NONE; 3219 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3220 if(!s->can_read_sensors) 3221 opt->cap = SANE_CAP_INACTIVE; 3222 } 3223 3224 if(option==OPT_CARD_LOADED){ 3225 opt->name = "card-loaded"; 3226 opt->title = "Card Loaded"; 3227 opt->desc = "Paper available in card reader"; 3228 opt->type = SANE_TYPE_BOOL; 3229 opt->unit = SANE_UNIT_NONE; 3230 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 3231 if(!s->can_read_sensors || !s->has_card) 3232 opt->cap = SANE_CAP_INACTIVE; 3233 } 3234 3235 return opt; 3236} 3237 3238/** 3239 * Gets or sets an option value. 3240 * 3241 * From the SANE spec: 3242 * This function is used to set or inquire the current value of option 3243 * number n of the device represented by handle h. The manner in which 3244 * the option is controlled is specified by parameter action. The 3245 * possible values of this parameter are described in more detail 3246 * below. The value of the option is passed through argument val. It 3247 * is a pointer to the memory that holds the option value. The memory 3248 * area pointed to by v must be big enough to hold the entire option 3249 * value (determined by member size in the corresponding option 3250 * descriptor). 3251 * 3252 * The only exception to this rule is that when setting the value of a 3253 * string option, the string pointed to by argument v may be shorter 3254 * since the backend will stop reading the option value upon 3255 * encountering the first NUL terminator in the string. If argument i 3256 * is not NULL, the value of *i will be set to provide details on how 3257 * well the request has been met. 3258 */ 3259SANE_Status 3260sane_control_option (SANE_Handle handle, SANE_Int option, 3261 SANE_Action action, void *val, SANE_Int * info) 3262{ 3263 struct scanner *s = (struct scanner *) handle; 3264 SANE_Int dummy = 0; 3265 SANE_Status ret = SANE_STATUS_GOOD; 3266 3267 /* Make sure that all those statements involving *info cannot break (better 3268 * than having to do "if (info) ..." everywhere!) 3269 */ 3270 if (info == 0) 3271 info = &dummy; 3272 3273 if (option >= NUM_OPTIONS) { 3274 DBG (5, "sane_control_option: %d too big\n", option); 3275 return SANE_STATUS_INVAL; 3276 } 3277 3278 if (!SANE_OPTION_IS_ACTIVE (s->opt[option].cap)) { 3279 DBG (5, "sane_control_option: %d inactive\n", option); 3280 return SANE_STATUS_INVAL; 3281 } 3282 3283 /* 3284 * SANE_ACTION_GET_VALUE: We have to find out the current setting and 3285 * return it in a human-readable form (often, text). 3286 */ 3287 if (action == SANE_ACTION_GET_VALUE) { 3288 SANE_Word * val_p = (SANE_Word *) val; 3289 3290 DBG (20, "sane_control_option: get value for '%s' (%d)\n", s->opt[option].name,option); 3291 3292 switch (option) { 3293 3294 case OPT_NUM_OPTS: 3295 *val_p = NUM_OPTIONS; 3296 return SANE_STATUS_GOOD; 3297 3298 case OPT_SOURCE: 3299 if(s->u.source == SOURCE_FLATBED){ 3300 strcpy (val, STRING_FLATBED); 3301 } 3302 else if(s->u.source == SOURCE_ADF_FRONT){ 3303 strcpy (val, STRING_ADFFRONT); 3304 } 3305 else if(s->u.source == SOURCE_ADF_BACK){ 3306 strcpy (val, STRING_ADFBACK); 3307 } 3308 else if(s->u.source == SOURCE_ADF_DUPLEX){ 3309 strcpy (val, STRING_ADFDUPLEX); 3310 } 3311 else if(s->u.source == SOURCE_CARD_FRONT){ 3312 strcpy (val, STRING_CARDFRONT); 3313 } 3314 else if(s->u.source == SOURCE_CARD_BACK){ 3315 strcpy (val, STRING_CARDBACK); 3316 } 3317 else if(s->u.source == SOURCE_CARD_DUPLEX){ 3318 strcpy (val, STRING_CARDDUPLEX); 3319 } 3320 return SANE_STATUS_GOOD; 3321 3322 case OPT_MODE: 3323 if(s->u.mode == MODE_LINEART){ 3324 strcpy (val, STRING_LINEART); 3325 } 3326 else if(s->u.mode == MODE_HALFTONE){ 3327 strcpy (val, STRING_HALFTONE); 3328 } 3329 else if(s->u.mode == MODE_GRAYSCALE){ 3330 strcpy (val, STRING_GRAYSCALE); 3331 } 3332 else if(s->u.mode == MODE_COLOR){ 3333 strcpy (val, STRING_COLOR); 3334 } 3335 return SANE_STATUS_GOOD; 3336 3337 case OPT_RES: 3338 *val_p = s->u.dpi_x; 3339 return SANE_STATUS_GOOD; 3340 3341 case OPT_TL_X: 3342 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.tl_x); 3343 return SANE_STATUS_GOOD; 3344 3345 case OPT_TL_Y: 3346 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.tl_y); 3347 return SANE_STATUS_GOOD; 3348 3349 case OPT_BR_X: 3350 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.br_x); 3351 return SANE_STATUS_GOOD; 3352 3353 case OPT_BR_Y: 3354 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.br_y); 3355 return SANE_STATUS_GOOD; 3356 3357 case OPT_PAGE_WIDTH: 3358 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.page_x); 3359 return SANE_STATUS_GOOD; 3360 3361 case OPT_PAGE_HEIGHT: 3362 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.page_y); 3363 return SANE_STATUS_GOOD; 3364 3365 case OPT_BRIGHTNESS: 3366 *val_p = s->brightness; 3367 return SANE_STATUS_GOOD; 3368 3369 case OPT_CONTRAST: 3370 *val_p = s->contrast; 3371 return SANE_STATUS_GOOD; 3372 3373 case OPT_THRESHOLD: 3374 *val_p = s->threshold; 3375 return SANE_STATUS_GOOD; 3376 3377 case OPT_RIF: 3378 *val_p = s->rif; 3379 return SANE_STATUS_GOOD; 3380 3381 /* Advanced Group */ 3382 case OPT_COMPRESS: 3383 if(s->compress == COMP_JPEG){ 3384 strcpy (val, STRING_JPEG); 3385 } 3386 else{ 3387 strcpy (val, STRING_NONE); 3388 } 3389 return SANE_STATUS_GOOD; 3390 3391 case OPT_COMPRESS_ARG: 3392 *val_p = s->compress_arg; 3393 return SANE_STATUS_GOOD; 3394 3395 case OPT_DF_LENGTH: 3396 *val_p = s->df_length; 3397 return SANE_STATUS_GOOD; 3398 3399 case OPT_DF_THICKNESS: 3400 *val_p = s->df_thickness; 3401 return SANE_STATUS_GOOD; 3402 3403 case OPT_ROLLERDESKEW: 3404 *val_p = s->rollerdeskew; 3405 return SANE_STATUS_GOOD; 3406 3407 case OPT_SWDESKEW: 3408 *val_p = s->swdeskew; 3409 return SANE_STATUS_GOOD; 3410 3411 case OPT_SWDESPECK: 3412 *val_p = s->swdespeck; 3413 return SANE_STATUS_GOOD; 3414 3415 case OPT_SWCROP: 3416 *val_p = s->swcrop; 3417 return SANE_STATUS_GOOD; 3418 3419 case OPT_SWSKIP: 3420 *val_p = SANE_FIX(s->swskip); 3421 return SANE_STATUS_GOOD; 3422 3423 case OPT_STAPLEDETECT: 3424 *val_p = s->stapledetect; 3425 return SANE_STATUS_GOOD; 3426 3427 case OPT_DROPOUT_COLOR_F: 3428 switch (s->dropout_color[SIDE_FRONT]) { 3429 case COLOR_NONE: 3430 strcpy (val, STRING_NONE); 3431 break; 3432 case COLOR_RED: 3433 strcpy (val, STRING_RED); 3434 break; 3435 case COLOR_GREEN: 3436 strcpy (val, STRING_GREEN); 3437 break; 3438 case COLOR_BLUE: 3439 strcpy (val, STRING_BLUE); 3440 break; 3441 case COLOR_EN_RED: 3442 strcpy (val, STRING_EN_RED); 3443 break; 3444 case COLOR_EN_GREEN: 3445 strcpy (val, STRING_EN_GREEN); 3446 break; 3447 case COLOR_EN_BLUE: 3448 strcpy (val, STRING_EN_BLUE); 3449 break; 3450 } 3451 return SANE_STATUS_GOOD; 3452 3453 case OPT_DROPOUT_COLOR_B: 3454 switch (s->dropout_color[SIDE_BACK]) { 3455 case COLOR_NONE: 3456 strcpy (val, STRING_NONE); 3457 break; 3458 case COLOR_RED: 3459 strcpy (val, STRING_RED); 3460 break; 3461 case COLOR_GREEN: 3462 strcpy (val, STRING_GREEN); 3463 break; 3464 case COLOR_BLUE: 3465 strcpy (val, STRING_BLUE); 3466 break; 3467 case COLOR_EN_RED: 3468 strcpy (val, STRING_EN_RED); 3469 break; 3470 case COLOR_EN_GREEN: 3471 strcpy (val, STRING_EN_GREEN); 3472 break; 3473 case COLOR_EN_BLUE: 3474 strcpy (val, STRING_EN_BLUE); 3475 break; 3476 } 3477 return SANE_STATUS_GOOD; 3478 3479 case OPT_BUFFERMODE: 3480 *val_p = s->buffermode; 3481 return SANE_STATUS_GOOD; 3482 3483 case OPT_SIDE: 3484 *val_p = s->side; 3485 return SANE_STATUS_GOOD; 3486 3487 case OPT_HW_CROP: 3488 *val_p = s->hwcrop; 3489 return SANE_STATUS_GOOD; 3490 3491 case OPT_PRE_IMPRINT_SPECSTRING: 3492 strcpy(val, s->pre_imprint.specstring); 3493 return SANE_STATUS_GOOD; 3494 3495 case OPT_PRE_IMPRINT_H_OFFSET: 3496 *val_p = s->pre_imprint.h_offset; 3497 return SANE_STATUS_GOOD; 3498 3499 case OPT_PRE_IMPRINT_V_OFFSET: 3500 *val_p = s->pre_imprint.v_offset; 3501 return SANE_STATUS_GOOD; 3502 3503 case OPT_PRE_IMPRINT_FONT_SIZE: 3504 switch (s->pre_imprint.font_size){ 3505 case IMPRINTER_12x12_FONT: 3506 strcpy(val, STRING_IMPRINTER_12x12_FONT); 3507 break; 3508 3509 case IMPRINTER_8x12_FONT: 3510 strcpy(val, STRING_IMPRINTER_8x12_FONT); 3511 break; 3512 } 3513 return SANE_STATUS_GOOD; 3514 3515 case OPT_PRE_IMPRINT_FONT_ROT: 3516 switch (s->pre_imprint.font_rot){ 3517 case IMPRINTER_0_FONT_ROT: 3518 *val_p = 0; 3519 break; 3520 3521 case IMPRINTER_90_FONT_ROT: 3522 *val_p = 90; 3523 break; 3524 3525 case IMPRINTER_180_FONT_ROT: 3526 *val_p = 180; 3527 break; 3528 3529 case IMPRINTER_270_FONT_ROT: 3530 *val_p = 270; 3531 break; 3532 } 3533 return SANE_STATUS_GOOD; 3534 3535 case OPT_PRE_IMPRINT_SPACING: 3536 *val_p = s->pre_imprint.spacing; 3537 return SANE_STATUS_GOOD; 3538 3539 case OPT_POST_IMPRINT_SPECSTRING: 3540 strcpy(val, s->post_imprint.specstring); 3541 return SANE_STATUS_GOOD; 3542 3543 case OPT_POST_IMPRINT_H_OFFSET: 3544 *val_p = s->post_imprint.h_offset; 3545 return SANE_STATUS_GOOD; 3546 3547 case OPT_POST_IMPRINT_V_OFFSET: 3548 *val_p = s->post_imprint.v_offset; 3549 return SANE_STATUS_GOOD; 3550 3551 case OPT_POST_IMPRINT_FONT_SIZE: 3552 switch (s->post_imprint.font_size){ 3553 case IMPRINTER_12x12_FONT: 3554 strcpy(val, STRING_IMPRINTER_12x12_FONT); 3555 break; 3556 3557 case IMPRINTER_8x12_FONT: 3558 strcpy(val, STRING_IMPRINTER_8x12_FONT); 3559 break; 3560 } 3561 return SANE_STATUS_GOOD; 3562 3563 case OPT_POST_IMPRINT_FONT_ROT: 3564 switch (s->post_imprint.font_rot){ 3565 case IMPRINTER_0_FONT_ROT: 3566 *val_p = 0; 3567 break; 3568 3569 case IMPRINTER_90_FONT_ROT: 3570 *val_p = 90; 3571 break; 3572 3573 case IMPRINTER_180_FONT_ROT: 3574 *val_p = 180; 3575 break; 3576 3577 case IMPRINTER_270_FONT_ROT: 3578 *val_p = 270; 3579 break; 3580 } 3581 return SANE_STATUS_GOOD; 3582 3583 case OPT_POST_IMPRINT_SPACING: 3584 *val_p = s->post_imprint.spacing; 3585 return SANE_STATUS_GOOD; 3586 3587 case OPT_POST_IMPRINT_ADDON_MODE: 3588 switch (s->post_imprint_addon_mode){ 3589 case ADDON_BoW: 3590 strcpy(val, STRING_IMPRINTER_ADDON_BoW); 3591 break; 3592 3593 case ADDON_BoI: 3594 strcpy(val, STRING_IMPRINTER_ADDON_BoI); 3595 break; 3596 3597 case ADDON_WoB: 3598 strcpy(val, STRING_IMPRINTER_ADDON_WoB); 3599 break; 3600 3601 case ADDON_DISABLED: 3602 strcpy(val, STRING_NONE); 3603 break; 3604 } 3605 return SANE_STATUS_GOOD; 3606 3607 /* Sensor Group */ 3608 case OPT_START: 3609 ret = read_panel(s,OPT_START); 3610 *val_p = s->panel_start; 3611 return ret; 3612 3613 case OPT_STOP: 3614 ret = read_panel(s,OPT_STOP); 3615 *val_p = s->panel_stop; 3616 return ret; 3617 3618 case OPT_BUTT3: 3619 ret = read_panel(s,OPT_BUTT3); 3620 *val_p = s->panel_butt3; 3621 return ret; 3622 3623 case OPT_NEWFILE: 3624 ret = read_panel(s,OPT_NEWFILE); 3625 *val_p = s->panel_new_file; 3626 return ret; 3627 3628 case OPT_COUNTONLY: 3629 ret = read_panel(s,OPT_COUNTONLY); 3630 *val_p = s->panel_count_only; 3631 return ret; 3632 3633 case OPT_BYPASSMODE: 3634 ret = read_panel(s,OPT_BYPASSMODE); 3635 *val_p = s->panel_bypass_mode; 3636 return ret; 3637 3638 case OPT_COUNTER: 3639 ret = read_panel(s,OPT_COUNTER); 3640 *val_p = s->panel_counter; 3641 return ret; 3642 3643 case OPT_ROLLERCOUNTER: 3644 ret = read_counters(s); 3645 *val_p = s->roller_counter; 3646 return ret; 3647 3648 case OPT_TOTALCOUNTER: 3649 ret = read_counters(s); 3650 *val_p = s->total_counter; 3651 return ret; 3652 3653 case OPT_ADF_LOADED: 3654 ret = read_sensors(s,OPT_ADF_LOADED); 3655 *val_p = s->sensor_adf_loaded; 3656 return ret; 3657 3658 case OPT_CARD_LOADED: 3659 ret = read_sensors(s,OPT_CARD_LOADED); 3660 *val_p = s->sensor_card_loaded; 3661 return ret; 3662 } 3663 } 3664 else if (action == SANE_ACTION_SET_VALUE) { 3665 int tmp; 3666 SANE_Word val_c; 3667 SANE_Status status; 3668 3669 DBG (20, "sane_control_option: set value for '%s' (%d)\n", s->opt[option].name,option); 3670 3671 if ( s->started ) { 3672 DBG (5, "sane_control_option: can't set, device busy\n"); 3673 return SANE_STATUS_DEVICE_BUSY; 3674 } 3675 3676 if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap)) { 3677 DBG (5, "sane_control_option: not settable\n"); 3678 return SANE_STATUS_INVAL; 3679 } 3680 3681 status = sanei_constrain_value (s->opt + option, val, info); 3682 if (status != SANE_STATUS_GOOD) { 3683 DBG (5, "sane_control_option: bad value\n"); 3684 return status; 3685 } 3686 3687 /* may have been changed by constrain, so don't copy until now */ 3688 val_c = *(SANE_Word *)val; 3689 3690 /* 3691 * Note - for those options which can assume one of a list of 3692 * valid values, we can safely assume that they will have 3693 * exactly one of those values because that's what 3694 * sanei_constrain_value does. Hence no "else: invalid" branches 3695 * below. 3696 */ 3697 switch (option) { 3698 3699 /* Mode Group */ 3700 case OPT_SOURCE: 3701 if (!strcmp (val, STRING_ADFFRONT)) { 3702 tmp = SOURCE_ADF_FRONT; 3703 } 3704 else if (!strcmp (val, STRING_ADFBACK)) { 3705 tmp = SOURCE_ADF_BACK; 3706 } 3707 else if (!strcmp (val, STRING_ADFDUPLEX)) { 3708 tmp = SOURCE_ADF_DUPLEX; 3709 } 3710 else if (!strcmp (val, STRING_CARDFRONT)) { 3711 tmp = SOURCE_CARD_FRONT; 3712 } 3713 else if (!strcmp (val, STRING_CARDBACK)) { 3714 tmp = SOURCE_CARD_BACK; 3715 } 3716 else if (!strcmp (val, STRING_CARDDUPLEX)) { 3717 tmp = SOURCE_CARD_DUPLEX; 3718 } 3719 else{ 3720 tmp = SOURCE_FLATBED; 3721 } 3722 3723 if (s->u.source == tmp) 3724 return SANE_STATUS_GOOD; 3725 3726 s->u.source = tmp; 3727 3728 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3729 return SANE_STATUS_GOOD; 3730 3731 case OPT_MODE: 3732 if (!strcmp (val, STRING_LINEART)) { 3733 tmp = MODE_LINEART; 3734 } 3735 else if (!strcmp (val, STRING_HALFTONE)) { 3736 tmp = MODE_HALFTONE; 3737 } 3738 else if (!strcmp (val, STRING_GRAYSCALE)) { 3739 tmp = MODE_GRAYSCALE; 3740 } 3741 else{ 3742 tmp = MODE_COLOR; 3743 } 3744 3745 if (tmp == s->u.mode) 3746 return SANE_STATUS_GOOD; 3747 3748 s->u.mode = tmp; 3749 3750 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3751 return SANE_STATUS_GOOD; 3752 3753 case OPT_RES: 3754 3755 if (s->u.dpi_x == val_c && s->u.dpi_y == val_c) 3756 return SANE_STATUS_GOOD; 3757 3758 s->u.dpi_x = val_c; 3759 s->u.dpi_y = val_c; 3760 3761 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3762 return SANE_STATUS_GOOD; 3763 3764 /* Geometry Group */ 3765 case OPT_TL_X: 3766 if (s->u.tl_x == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3767 return SANE_STATUS_GOOD; 3768 3769 s->u.tl_x = FIXED_MM_TO_SCANNER_UNIT(val_c); 3770 3771 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3772 return SANE_STATUS_GOOD; 3773 3774 case OPT_TL_Y: 3775 if (s->u.tl_y == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3776 return SANE_STATUS_GOOD; 3777 3778 s->u.tl_y = FIXED_MM_TO_SCANNER_UNIT(val_c); 3779 3780 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3781 return SANE_STATUS_GOOD; 3782 3783 case OPT_BR_X: 3784 if (s->u.br_x == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3785 return SANE_STATUS_GOOD; 3786 3787 s->u.br_x = FIXED_MM_TO_SCANNER_UNIT(val_c); 3788 3789 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3790 return SANE_STATUS_GOOD; 3791 3792 case OPT_BR_Y: 3793 if (s->u.br_y == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3794 return SANE_STATUS_GOOD; 3795 3796 s->u.br_y = FIXED_MM_TO_SCANNER_UNIT(val_c); 3797 3798 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 3799 return SANE_STATUS_GOOD; 3800 3801 case OPT_PAGE_WIDTH: 3802 if (s->u.page_x == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3803 return SANE_STATUS_GOOD; 3804 3805 /* if full width image, and paper size is changed, 3806 change the image size to match new paper */ 3807 if (s->u.tl_x == 0 && s->u.br_x == s->u.page_x){ 3808 DBG (20, "sane_control_option: br_x tracking page_width\n"); 3809 s->u.br_x = FIXED_MM_TO_SCANNER_UNIT(val_c); 3810 *info |= SANE_INFO_RELOAD_PARAMS; 3811 } 3812 3813 s->u.page_x = FIXED_MM_TO_SCANNER_UNIT(val_c); 3814 3815 *info |= SANE_INFO_RELOAD_OPTIONS; 3816 return SANE_STATUS_GOOD; 3817 3818 case OPT_PAGE_HEIGHT: 3819 if (s->u.page_y == FIXED_MM_TO_SCANNER_UNIT(val_c)) 3820 return SANE_STATUS_GOOD; 3821 3822 /* if full height image, and paper size is changed, 3823 change the image size to match new paper */ 3824 if (s->u.tl_y == 0 && s->u.br_y == s->u.page_y){ 3825 DBG (20, "sane_control_option: br_y tracking page_height\n"); 3826 s->u.br_y = FIXED_MM_TO_SCANNER_UNIT(val_c); 3827 *info |= SANE_INFO_RELOAD_PARAMS; 3828 } 3829 3830 s->u.page_y = FIXED_MM_TO_SCANNER_UNIT(val_c); 3831 3832 *info |= SANE_INFO_RELOAD_OPTIONS; 3833 return SANE_STATUS_GOOD; 3834 3835 /* Enhancement Group */ 3836 case OPT_BRIGHTNESS: 3837 s->brightness = val_c; 3838 return SANE_STATUS_GOOD; 3839 3840 case OPT_CONTRAST: 3841 s->contrast = val_c; 3842 return SANE_STATUS_GOOD; 3843 3844 case OPT_THRESHOLD: 3845 s->threshold = val_c; 3846 return SANE_STATUS_GOOD; 3847 3848 case OPT_RIF: 3849 s->rif = val_c; 3850 return SANE_STATUS_GOOD; 3851 3852 /* Advanced Group */ 3853 case OPT_COMPRESS: 3854 if (!strcmp (val, STRING_JPEG)) { 3855 s->compress = COMP_JPEG; 3856 } 3857 else{ 3858 s->compress = COMP_NONE; 3859 } 3860 return SANE_STATUS_GOOD; 3861 3862 case OPT_COMPRESS_ARG: 3863 s->compress_arg = val_c; 3864 return SANE_STATUS_GOOD; 3865 3866 case OPT_DF_LENGTH: 3867 s->df_length = val_c; 3868 return SANE_STATUS_GOOD; 3869 3870 case OPT_DF_THICKNESS: 3871 s->df_thickness = val_c; 3872 return SANE_STATUS_GOOD; 3873 3874 case OPT_ROLLERDESKEW: 3875 s->rollerdeskew = val_c; 3876 return SANE_STATUS_GOOD; 3877 3878 case OPT_SWDESKEW: 3879 s->swdeskew = val_c; 3880 return SANE_STATUS_GOOD; 3881 3882 case OPT_SWDESPECK: 3883 s->swdespeck = val_c; 3884 return SANE_STATUS_GOOD; 3885 3886 case OPT_SWCROP: 3887 s->swcrop = val_c; 3888 return SANE_STATUS_GOOD; 3889 3890 case OPT_SWSKIP: 3891 s->swskip = SANE_UNFIX(val_c); 3892 return SANE_STATUS_GOOD; 3893 3894 case OPT_STAPLEDETECT: 3895 s->stapledetect = val_c; 3896 return SANE_STATUS_GOOD; 3897 3898 case OPT_DROPOUT_COLOR_F: 3899 if (!strcmp(val, STRING_NONE)) 3900 s->dropout_color[SIDE_FRONT] = COLOR_NONE; 3901 else if (!strcmp(val, STRING_RED)) 3902 s->dropout_color[SIDE_FRONT] = COLOR_RED; 3903 else if (!strcmp(val, STRING_GREEN)) 3904 s->dropout_color[SIDE_FRONT] = COLOR_GREEN; 3905 else if (!strcmp(val, STRING_BLUE)) 3906 s->dropout_color[SIDE_FRONT] = COLOR_BLUE; 3907 else if (!strcmp(val, STRING_EN_RED)) 3908 s->dropout_color[SIDE_FRONT] = COLOR_EN_RED; 3909 else if (!strcmp(val, STRING_EN_GREEN)) 3910 s->dropout_color[SIDE_FRONT] = COLOR_EN_GREEN; 3911 else if (!strcmp(val, STRING_EN_BLUE)) 3912 s->dropout_color[SIDE_FRONT] = COLOR_EN_BLUE; 3913 return SANE_STATUS_GOOD; 3914 3915 case OPT_DROPOUT_COLOR_B: 3916 if (!strcmp(val, STRING_NONE)) 3917 s->dropout_color[SIDE_BACK] = COLOR_NONE; 3918 else if (!strcmp(val, STRING_RED)) 3919 s->dropout_color[SIDE_BACK] = COLOR_RED; 3920 else if (!strcmp(val, STRING_GREEN)) 3921 s->dropout_color[SIDE_BACK] = COLOR_GREEN; 3922 else if (!strcmp(val, STRING_BLUE)) 3923 s->dropout_color[SIDE_BACK] = COLOR_BLUE; 3924 else if (!strcmp(val, STRING_EN_RED)) 3925 s->dropout_color[SIDE_BACK] = COLOR_EN_RED; 3926 else if (!strcmp(val, STRING_EN_GREEN)) 3927 s->dropout_color[SIDE_BACK] = COLOR_EN_GREEN; 3928 else if (!strcmp(val, STRING_EN_BLUE)) 3929 s->dropout_color[SIDE_BACK] = COLOR_EN_BLUE; 3930 return SANE_STATUS_GOOD; 3931 3932 case OPT_BUFFERMODE: 3933 s->buffermode = val_c; 3934 return SANE_STATUS_GOOD; 3935 3936 case OPT_HW_CROP: 3937 s->hwcrop = val_c; 3938 return SANE_STATUS_GOOD; 3939 3940 case OPT_PRE_IMPRINT_SPECSTRING: 3941 if (strlen(val) < IMPRINT_SPECSTRING_LEN){ 3942 strncpy(s->pre_imprint.specstring, val, IMPRINT_SPECSTRING_LEN); 3943 return SANE_STATUS_GOOD; 3944 } 3945 DBG (5, "sane_control_option: pre-imprint spec string '%s' exceed the limit of %d characters\n", (SANE_String)val, IMPRINT_SPECSTRING_LEN); 3946 return SANE_STATUS_INVAL; 3947 3948 case OPT_PRE_IMPRINT_H_OFFSET: 3949 s->pre_imprint.h_offset = val_c; 3950 return SANE_STATUS_GOOD; 3951 3952 case OPT_PRE_IMPRINT_V_OFFSET: 3953 s->pre_imprint.v_offset = val_c; 3954 return SANE_STATUS_GOOD; 3955 3956 case OPT_PRE_IMPRINT_FONT_SIZE: 3957 if (!strcmp (val, STRING_IMPRINTER_12x12_FONT)) { 3958 s->pre_imprint.font_size = IMPRINTER_12x12_FONT; 3959 } 3960 if (!strcmp (val, STRING_IMPRINTER_8x12_FONT)) { 3961 s->pre_imprint.font_size = IMPRINTER_8x12_FONT; 3962 } 3963 return SANE_STATUS_GOOD; 3964 3965 case OPT_PRE_IMPRINT_FONT_ROT: 3966 switch (val_c){ 3967 case 0: 3968 s->pre_imprint.font_rot = IMPRINTER_0_FONT_ROT; 3969 break; 3970 3971 case 90: 3972 s->pre_imprint.font_rot = IMPRINTER_90_FONT_ROT; 3973 break; 3974 3975 case 180: 3976 s->pre_imprint.font_rot = IMPRINTER_180_FONT_ROT; 3977 break; 3978 3979 case 270: 3980 s->pre_imprint.font_rot = IMPRINTER_270_FONT_ROT; 3981 break; 3982 } 3983 return SANE_STATUS_GOOD; 3984 3985 case OPT_PRE_IMPRINT_SPACING: 3986 s->pre_imprint.spacing = val_c; 3987 return SANE_STATUS_GOOD; 3988 3989 case OPT_POST_IMPRINT_SPECSTRING: 3990 if (strlen(val) < IMPRINT_SPECSTRING_LEN){ 3991 strncpy(s->post_imprint.specstring, val, IMPRINT_SPECSTRING_LEN); 3992 return SANE_STATUS_GOOD; 3993 } 3994 DBG (5, "sane_control_option: post-imprint spec string '%s' exceed the limit of %d characters\n", (SANE_String)val, IMPRINT_SPECSTRING_LEN); 3995 return SANE_STATUS_INVAL; 3996 3997 case OPT_POST_IMPRINT_H_OFFSET: 3998 s->post_imprint.h_offset = val_c; 3999 return SANE_STATUS_GOOD; 4000 4001 case OPT_POST_IMPRINT_V_OFFSET: 4002 s->post_imprint.v_offset = val_c; 4003 return SANE_STATUS_GOOD; 4004 4005 case OPT_POST_IMPRINT_FONT_SIZE: 4006 if (!strcmp (val, STRING_IMPRINTER_12x12_FONT)) { 4007 s->post_imprint.font_size = IMPRINTER_12x12_FONT; 4008 } 4009 if (!strcmp (val, STRING_IMPRINTER_8x12_FONT)) { 4010 s->post_imprint.font_size = IMPRINTER_8x12_FONT; 4011 } 4012 return SANE_STATUS_GOOD; 4013 4014 case OPT_POST_IMPRINT_FONT_ROT: 4015 switch (val_c){ 4016 case 0: 4017 s->post_imprint.font_rot = IMPRINTER_0_FONT_ROT; 4018 break; 4019 4020 case 90: 4021 s->post_imprint.font_rot = IMPRINTER_90_FONT_ROT; 4022 break; 4023 4024 case 180: 4025 s->post_imprint.font_rot = IMPRINTER_180_FONT_ROT; 4026 break; 4027 4028 case 270: 4029 s->post_imprint.font_rot = IMPRINTER_270_FONT_ROT; 4030 break; 4031 } 4032 return SANE_STATUS_GOOD; 4033 4034 case OPT_POST_IMPRINT_SPACING: 4035 s->post_imprint.spacing = val_c; 4036 return SANE_STATUS_GOOD; 4037 4038 case OPT_POST_IMPRINT_ADDON_MODE: 4039 if (!strcmp (val, STRING_IMPRINTER_ADDON_BoW)) { 4040 s->post_imprint_addon_mode = ADDON_BoW; 4041 } 4042 if (!strcmp (val, STRING_IMPRINTER_ADDON_BoI)) { 4043 s->post_imprint_addon_mode = ADDON_BoI; 4044 } 4045 if (!strcmp (val, STRING_IMPRINTER_ADDON_WoB)) { 4046 s->post_imprint_addon_mode = ADDON_WoB; 4047 } 4048 if (!strcmp (val, STRING_NONE)) { 4049 s->post_imprint_addon_mode = ADDON_DISABLED; 4050 } 4051 return SANE_STATUS_GOOD; 4052 4053 } 4054 } /* else */ 4055 4056 return SANE_STATUS_INVAL; 4057} 4058 4059static SANE_Status 4060ssm_buffer (struct scanner *s) 4061{ 4062 SANE_Status ret = SANE_STATUS_GOOD; 4063 4064 DBG (10, "ssm_buffer: start\n"); 4065 4066 if(s->has_ssm){ 4067 4068 unsigned char cmd[SET_SCAN_MODE_len]; 4069 size_t cmdLen = SET_SCAN_MODE_len; 4070 4071 unsigned char out[SSM_PAY_len]; 4072 size_t outLen = SSM_PAY_len; 4073 4074 memset(cmd,0,cmdLen); 4075 set_SCSI_opcode(cmd, SET_SCAN_MODE_code); 4076 set_SSM_pf(cmd, 1); 4077 set_SSM_pay_len(cmd, outLen); 4078 4079 memset(out,0,outLen); 4080 if(s->has_ssm_pay_head_len){ 4081 set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); 4082 } 4083 set_SSM_page_code(out, SM_pc_buffer); 4084 set_SSM_page_len(out, SSM_PAGE_len); 4085 4086 if(s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX){ 4087 set_SSM_BUFF_duplex(out, 1); 4088 } 4089 if(s->s.source == SOURCE_FLATBED){ 4090 set_SSM_BUFF_fb(out, 1); 4091 } 4092 else if(s->s.source >= SOURCE_CARD_FRONT){ 4093 set_SSM_BUFF_card(out, 1); 4094 } 4095 if(s->buffermode){ 4096 set_SSM_BUFF_async(out, 1); 4097 } 4098 if(0){ 4099 set_SSM_BUFF_ald(out, 1); 4100 } 4101 if(0){ 4102 set_SSM_BUFF_unk(out,1); 4103 } 4104 4105 ret = do_cmd ( 4106 s, 1, 0, 4107 cmd, cmdLen, 4108 out, outLen, 4109 NULL, NULL 4110 ); 4111 } 4112 4113 else if(s->has_ssm2){ 4114 4115 unsigned char cmd[SET_SCAN_MODE2_len]; 4116 size_t cmdLen = SET_SCAN_MODE2_len; 4117 4118 unsigned char out[SSM2_PAY_len]; 4119 size_t outLen = SSM2_PAY_len; 4120 4121 memset(cmd,0,cmdLen); 4122 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4123 set_SSM2_page_code(cmd, SM2_pc_buffer); 4124 set_SSM2_pay_len(cmd, outLen); 4125 4126 memset(out,0,outLen); 4127 set_SSM2_BUFF_unk(out, !s->buffermode); 4128 set_SSM2_BUFF_unk2(out, 0x40); 4129 set_SSM2_BUFF_sync(out, !s->buffermode); 4130 4131 ret = do_cmd ( 4132 s, 1, 0, 4133 cmd, cmdLen, 4134 out, outLen, 4135 NULL, NULL 4136 ); 4137 } 4138 4139 else{ 4140 DBG (10, "ssm_buffer: unsupported\n"); 4141 } 4142 4143 DBG (10, "ssm_buffer: finish\n"); 4144 4145 return ret; 4146} 4147 4148static SANE_Status 4149ssm_df (struct scanner *s) 4150{ 4151 SANE_Status ret = SANE_STATUS_GOOD; 4152 4153 DBG (10, "ssm_df: start\n"); 4154 4155 if(!s->has_df){ 4156 DBG (10, "ssm_df: unsupported, finishing\n"); 4157 return ret; 4158 } 4159 4160 if(s->has_ssm){ 4161 4162 unsigned char cmd[SET_SCAN_MODE_len]; 4163 size_t cmdLen = SET_SCAN_MODE_len; 4164 4165 unsigned char out[SSM_PAY_len]; 4166 size_t outLen = SSM_PAY_len; 4167 4168 memset(cmd,0,cmdLen); 4169 set_SCSI_opcode(cmd, SET_SCAN_MODE_code); 4170 set_SSM_pf(cmd, 1); 4171 set_SSM_pay_len(cmd, outLen); 4172 4173 memset(out,0,outLen); 4174 if(s->has_ssm_pay_head_len){ 4175 set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); 4176 } 4177 set_SSM_page_code(out, SM_pc_df); 4178 set_SSM_page_len(out, SSM_PAGE_len); 4179 4180 /* deskew by roller */ 4181 if(s->rollerdeskew){ 4182 set_SSM_DF_deskew_roll(out, 1); 4183 } 4184 4185 /* staple detection */ 4186 if(s->stapledetect){ 4187 set_SSM_DF_staple(out, 1); 4188 } 4189 4190 /* thickness */ 4191 if(s->df_thickness){ 4192 set_SSM_DF_thick(out, 1); 4193 } 4194 4195 /* length */ 4196 if(s->df_length){ 4197 set_SSM_DF_len(out, 1); 4198 } 4199 4200 ret = do_cmd ( 4201 s, 1, 0, 4202 cmd, cmdLen, 4203 out, outLen, 4204 NULL, NULL 4205 ); 4206 4207 } 4208 4209 else if(s->has_ssm2){ 4210 4211 unsigned char cmd[SET_SCAN_MODE2_len]; 4212 size_t cmdLen = SET_SCAN_MODE2_len; 4213 4214 unsigned char out[SSM2_PAY_len]; 4215 size_t outLen = SSM2_PAY_len; 4216 4217 /* send ultrasonic offsets first */ 4218 if(s->df_thickness && s->has_df_ultra){ 4219 memset(cmd,0,cmdLen); 4220 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4221 set_SSM2_page_code(cmd, SM2_pc_ultra); 4222 set_SSM2_pay_len(cmd, outLen); 4223 4224 memset(out,0,outLen); 4225 set_SSM2_ULTRA_top(out, 0); 4226 set_SSM2_ULTRA_bot(out, 0); 4227 4228 ret = do_cmd ( 4229 s, 1, 0, 4230 cmd, cmdLen, 4231 out, outLen, 4232 NULL, NULL 4233 ); 4234 } 4235 4236 memset(cmd,0,cmdLen); 4237 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4238 set_SSM2_page_code(cmd, SM2_pc_df); 4239 set_SSM2_pay_len(cmd, outLen); 4240 4241 memset(out,0,outLen); 4242 4243 /* thickness */ 4244 if(s->df_thickness){ 4245 set_SSM2_DF_thick(out, 1); 4246 } 4247 4248 /* length */ 4249 if(s->df_length){ 4250 set_SSM2_DF_len(out, 1); 4251 } 4252 4253 /* staple detection */ 4254 if(s->stapledetect){ 4255 set_SSM2_DF_staple(out, 1); 4256 } 4257 4258 int requires_postimprint = s->has_post_imprinter && (strlen(s->post_imprint.specstring) > 0); 4259 int requires_preimprint = s->has_pre_imprinter && (strlen(s->pre_imprint.specstring) > 0); 4260 if (s->has_post_imprinter) 4261 set_SSM2_DF_post_addon(out, requires_postimprint); 4262 if (requires_postimprint || requires_preimprint){ 4263 set_SSM2_DF_imprint(out, 1); 4264 } 4265 4266 ret = do_cmd ( 4267 s, 1, 0, 4268 cmd, cmdLen, 4269 out, outLen, 4270 NULL, NULL 4271 ); 4272 4273 } 4274 4275 else{ 4276 DBG (10, "ssm_df: unsupported\n"); 4277 } 4278 4279 DBG (10, "ssm_df: finish\n"); 4280 4281 return ret; 4282} 4283 4284static SANE_Status 4285ssm2_hw_enhancement (struct scanner *s) 4286{ 4287 SANE_Status ret = SANE_STATUS_GOOD; 4288 4289 DBG (10, "ssm2_hw_enhancement: start\n"); 4290 4291 if(s->has_ssm2){ 4292 unsigned char cmd[SET_SCAN_MODE2_len]; 4293 size_t cmdLen = SET_SCAN_MODE2_len; 4294 4295 unsigned char out[SSM2_PAY_len]; 4296 size_t outLen = SSM2_PAY_len; 4297 4298 memset(cmd,0,cmdLen); 4299 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4300 set_SSM2_page_code(cmd, SM2_pc_hw_enhancement); 4301 set_SSM2_pay_len(cmd, outLen); 4302 4303 memset(out,0,outLen); 4304 4305 if(s->rollerdeskew){ 4306 set_SSM2_roller_deskew(out, 1); 4307 } 4308 4309 if(s->hwcrop){ 4310 set_SSM2_hw_crop(out, 1); 4311 } 4312 4313 ret = do_cmd ( 4314 s, 1, 0, 4315 cmd, cmdLen, 4316 out, outLen, 4317 NULL, NULL 4318 ); 4319 4320 } 4321 4322 else{ 4323 DBG (10, "ssm2_hw_enhancement: unsupported\n"); 4324 } 4325 4326 DBG (10, "ssm2_hw_enhancement: finish\n"); 4327 4328 return ret; 4329} 4330 4331static SANE_Status 4332ssm_do (struct scanner *s) 4333{ 4334 SANE_Status ret = SANE_STATUS_GOOD; 4335 4336 DBG (10, "ssm_do: start\n"); 4337 4338 if(!s->can_color){ 4339 DBG (10, "ssm_do: unsupported, finishing\n"); 4340 return ret; 4341 } 4342 4343 if(s->s.mode == MODE_COLOR){ 4344 DBG (10, "ssm_do: unneeded, finishing\n"); 4345 return ret; 4346 } 4347 4348 if(s->has_ssm){ 4349 4350 unsigned char cmd[SET_SCAN_MODE_len]; 4351 size_t cmdLen = SET_SCAN_MODE_len; 4352 4353 unsigned char out[SSM_PAY_len]; 4354 size_t outLen = SSM_PAY_len; 4355 4356 memset(cmd,0,cmdLen); 4357 set_SCSI_opcode(cmd, SET_SCAN_MODE_code); 4358 set_SSM_pf(cmd, 1); 4359 set_SSM_pay_len(cmd, outLen); 4360 4361 memset(out,0,outLen); 4362 if(s->has_ssm_pay_head_len){ 4363 set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); 4364 } 4365 set_SSM_page_code(out, SM_pc_dropout); 4366 set_SSM_page_len(out, SSM_PAGE_len); 4367 4368 set_SSM_DO_unk1(out, 0x03); 4369 4370 switch(s->dropout_color[SIDE_FRONT]){ 4371 case COLOR_RED: 4372 set_SSM_DO_unk2(out, 0x05); 4373 set_SSM_DO_f_do(out,SSM_DO_red); 4374 break; 4375 case COLOR_GREEN: 4376 set_SSM_DO_unk2(out, 0x05); 4377 set_SSM_DO_f_do(out,SSM_DO_green); 4378 break; 4379 case COLOR_BLUE: 4380 set_SSM_DO_unk2(out, 0x05); 4381 set_SSM_DO_f_do(out,SSM_DO_blue); 4382 break; 4383 case COLOR_EN_RED: 4384 set_SSM_DO_unk2(out, 0x05); 4385 set_SSM_DO_f_en(out,SSM_DO_red); 4386 break; 4387 case COLOR_EN_GREEN: 4388 set_SSM_DO_unk2(out, 0x05); 4389 set_SSM_DO_f_en(out,SSM_DO_green); 4390 break; 4391 case COLOR_EN_BLUE: 4392 set_SSM_DO_unk2(out, 0x05); 4393 set_SSM_DO_f_en(out,SSM_DO_blue); 4394 break; 4395 } 4396 4397 switch(s->dropout_color[SIDE_BACK]){ 4398 case COLOR_RED: 4399 set_SSM_DO_unk2(out, 0x05); 4400 set_SSM_DO_b_do(out,SSM_DO_red); 4401 break; 4402 case COLOR_GREEN: 4403 set_SSM_DO_unk2(out, 0x05); 4404 set_SSM_DO_b_do(out,SSM_DO_green); 4405 break; 4406 case COLOR_BLUE: 4407 set_SSM_DO_unk2(out, 0x05); 4408 set_SSM_DO_b_do(out,SSM_DO_blue); 4409 break; 4410 case COLOR_EN_RED: 4411 set_SSM_DO_unk2(out, 0x05); 4412 set_SSM_DO_b_en(out,SSM_DO_red); 4413 break; 4414 case COLOR_EN_GREEN: 4415 set_SSM_DO_unk2(out, 0x05); 4416 set_SSM_DO_b_en(out,SSM_DO_green); 4417 break; 4418 case COLOR_EN_BLUE: 4419 set_SSM_DO_unk2(out, 0x05); 4420 set_SSM_DO_b_en(out,SSM_DO_blue); 4421 break; 4422 } 4423 4424 ret = do_cmd ( 4425 s, 1, 0, 4426 cmd, cmdLen, 4427 out, outLen, 4428 NULL, NULL 4429 ); 4430 4431 } 4432 4433 else if(s->has_ssm2){ 4434 4435 unsigned char cmd[SET_SCAN_MODE2_len]; 4436 size_t cmdLen = SET_SCAN_MODE2_len; 4437 4438 unsigned char out[SSM2_PAY_len]; 4439 size_t outLen = SSM2_PAY_len; 4440 4441 memset(cmd,0,cmdLen); 4442 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4443 set_SSM2_page_code(cmd, SM2_pc_dropout); 4444 set_SSM2_pay_len(cmd, outLen); 4445 4446 memset(out,0,outLen); 4447 4448 switch(s->dropout_color[SIDE_FRONT]){ 4449 case COLOR_RED: 4450 set_SSM2_DO_do(out,SSM_DO_red); 4451 break; 4452 case COLOR_GREEN: 4453 set_SSM2_DO_do(out,SSM_DO_green); 4454 break; 4455 case COLOR_BLUE: 4456 set_SSM2_DO_do(out,SSM_DO_blue); 4457 break; 4458 case COLOR_EN_RED: 4459 set_SSM2_DO_en(out,SSM_DO_red); 4460 break; 4461 case COLOR_EN_GREEN: 4462 set_SSM2_DO_en(out,SSM_DO_green); 4463 break; 4464 case COLOR_EN_BLUE: 4465 set_SSM2_DO_en(out,SSM_DO_blue); 4466 break; 4467 } 4468 4469 ret = do_cmd ( 4470 s, 1, 0, 4471 cmd, cmdLen, 4472 out, outLen, 4473 NULL, NULL 4474 ); 4475 4476 if(ret == SANE_STATUS_GOOD && 4477 (s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX)){ 4478 4479 memset(cmd,0,cmdLen); 4480 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 4481 set_SSM2_page_code(cmd, SM2_pc_dropout); 4482 set_SSM2_DO_side(cmd, SIDE_BACK); 4483 set_SSM2_pay_len(cmd, outLen); 4484 4485 memset(out,0,outLen); 4486 4487 switch(s->dropout_color[SIDE_BACK]){ 4488 case COLOR_RED: 4489 set_SSM2_DO_do(out,SSM_DO_red); 4490 break; 4491 case COLOR_GREEN: 4492 set_SSM2_DO_do(out,SSM_DO_green); 4493 break; 4494 case COLOR_BLUE: 4495 set_SSM2_DO_do(out,SSM_DO_blue); 4496 break; 4497 case COLOR_EN_RED: 4498 set_SSM2_DO_en(out,SSM_DO_red); 4499 break; 4500 case COLOR_EN_GREEN: 4501 set_SSM2_DO_en(out,SSM_DO_green); 4502 break; 4503 case COLOR_EN_BLUE: 4504 set_SSM2_DO_en(out,SSM_DO_blue); 4505 break; 4506 } 4507 4508 ret = do_cmd ( 4509 s, 1, 0, 4510 cmd, cmdLen, 4511 out, outLen, 4512 NULL, NULL 4513 ); 4514 } 4515 } 4516 4517 else{ 4518 DBG (10, "ssm_do: unsupported\n"); 4519 } 4520 4521 DBG (10, "ssm_do: finish\n"); 4522 4523 return ret; 4524} 4525 4526static SANE_Status 4527read_counters(struct scanner *s) 4528{ 4529 SANE_Status ret = SANE_STATUS_GOOD; 4530 4531 unsigned char cmd[READ_len]; 4532 size_t cmdLen = READ_len; 4533 4534 unsigned char in[R_COUNTERS_len]; 4535 size_t inLen = R_COUNTERS_len; 4536 4537 if (!s->can_read_lifecycle_counters){ 4538 DBG(10, "read_counters: unsupported\n"); 4539 return ret; 4540 } 4541 4542 DBG(10, "read_counters: start\n"); 4543 4544 memset(cmd,0,cmdLen); 4545 set_SCSI_opcode(cmd, READ_code); 4546 set_R_datatype_code(cmd, SR_datatype_counters); 4547 set_R_xfer_length(cmd, inLen); 4548 4549 ret = do_cmd( 4550 s, 1, 0, 4551 cmd, cmdLen, 4552 NULL, 0, 4553 in, &inLen 4554 ); 4555 4556 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF){ 4557 4558 s->total_counter = get_R_COUNTERS_total(in); 4559 s->roller_counter = s->total_counter - get_R_COUNTERS_last_srv(in); 4560 4561 DBG(10, "read_counters: total counter: %d roller_counter %d \n",s->total_counter,s->roller_counter); 4562 ret = SANE_STATUS_GOOD; 4563 }else{ 4564 DBG(10, "read_counters: ERROR: %d\n",ret); 4565 } 4566 4567 return ret; 4568} 4569 4570static SANE_Status 4571read_sensors(struct scanner *s,SANE_Int option) 4572{ 4573 SANE_Status ret=SANE_STATUS_GOOD; 4574 4575 unsigned char cmd[READ_len]; 4576 size_t cmdLen = READ_len; 4577 4578 unsigned char in[R_SENSORS_len]; 4579 size_t inLen = R_SENSORS_len; 4580 4581 DBG (10, "read_sensors: start %d\n", option); 4582 4583 if(!s->can_read_sensors){ 4584 DBG (10, "read_sensors: unsupported, finishing\n"); 4585 return ret; 4586 } 4587 4588 /* only run this if frontend has already read the last time we got it */ 4589 /* or if we don't care for such bookkeeping (private use) */ 4590 if (!option || !s->sensors_read[option-OPT_ADF_LOADED]) { 4591 4592 DBG (15, "read_sensors: running\n"); 4593 4594 memset(cmd,0,cmdLen); 4595 set_SCSI_opcode(cmd, READ_code); 4596 set_R_datatype_code (cmd, SR_datatype_sensors); 4597 set_R_xfer_length (cmd, inLen); 4598 4599 ret = do_cmd ( 4600 s, 1, 0, 4601 cmd, cmdLen, 4602 NULL, 0, 4603 in, &inLen 4604 ); 4605 4606 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { 4607 /*set flags indicating there is data to read*/ 4608 memset(s->sensors_read,1,sizeof(s->sensors_read)); 4609 4610 s->sensor_adf_loaded = get_R_SENSORS_adf(in); 4611 s->sensor_card_loaded = get_R_SENSORS_card(in); 4612 4613 ret = SANE_STATUS_GOOD; 4614 } 4615 } 4616 4617 if(option) 4618 s->sensors_read[option-OPT_ADF_LOADED] = 0; 4619 4620 DBG (10, "read_sensors: finish\n"); 4621 4622 return ret; 4623} 4624 4625static SANE_Status 4626read_panel(struct scanner *s,SANE_Int option) 4627{ 4628 SANE_Status ret=SANE_STATUS_GOOD; 4629 4630 unsigned char cmd[READ_len]; 4631 size_t cmdLen = READ_len; 4632 4633 unsigned char in[R_PANEL_len]; 4634 size_t inLen = R_PANEL_len; 4635 4636 DBG (10, "read_panel: start %d\n", option); 4637 4638 if(!s->can_read_panel){ 4639 DBG (10, "read_panel: unsupported, finishing\n"); 4640 return ret; 4641 } 4642 4643 /* only run this if frontend has already read the last time we got it */ 4644 /* or if we don't care for such bookkeeping (private use) */ 4645 if (!option || !s->panel_read[option-OPT_START]) { 4646 4647 DBG (15, "read_panel: running\n"); 4648 4649 memset(cmd,0,cmdLen); 4650 set_SCSI_opcode(cmd, READ_code); 4651 set_R_datatype_code (cmd, SR_datatype_panel); 4652 set_R_xfer_length (cmd, inLen); 4653 4654 ret = do_cmd ( 4655 s, 1, 0, 4656 cmd, cmdLen, 4657 NULL, 0, 4658 in, &inLen 4659 ); 4660 4661 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { 4662 /*set flags indicating there is data to read*/ 4663 memset(s->panel_read,1,sizeof(s->panel_read)); 4664 4665 s->panel_start = get_R_PANEL_start(in); 4666 s->panel_stop = get_R_PANEL_stop(in); 4667 s->panel_butt3 = get_R_PANEL_butt3(in); 4668 s->panel_new_file = get_R_PANEL_new_file(in); 4669 s->panel_count_only = get_R_PANEL_count_only(in); 4670 s->panel_bypass_mode = get_R_PANEL_bypass_mode(in); 4671 s->panel_enable_led = get_R_PANEL_enable_led(in); 4672 s->panel_counter = get_R_PANEL_counter(in); 4673 4674 ret = SANE_STATUS_GOOD; 4675 } 4676 } 4677 4678 if(option) 4679 s->panel_read[option-OPT_START] = 0; 4680 4681 DBG (10, "read_panel: finish %d\n",s->panel_counter); 4682 4683 return ret; 4684} 4685 4686static SANE_Status 4687send_panel(struct scanner *s) 4688{ 4689 SANE_Status ret=SANE_STATUS_GOOD; 4690 4691 unsigned char cmd[SEND_len]; 4692 size_t cmdLen = SEND_len; 4693 4694 unsigned char out[S_PANEL_len]; 4695 size_t outLen = S_PANEL_len; 4696 4697 DBG (10, "send_panel: start\n"); 4698 4699 if(!s->can_write_panel){ 4700 DBG (10, "send_panel: unsupported, finishing\n"); 4701 return ret; 4702 } 4703 4704 memset(cmd,0,cmdLen); 4705 set_SCSI_opcode(cmd, SEND_code); 4706 set_S_xfer_datatype (cmd, SR_datatype_panel); 4707 set_S_xfer_length (cmd, outLen); 4708 4709 memset(out,0,outLen); 4710 set_S_PANEL_enable_led(out,s->panel_enable_led); 4711 set_S_PANEL_counter(out,s->panel_counter); 4712 4713 ret = do_cmd ( 4714 s, 1, 0, 4715 cmd, cmdLen, 4716 out, outLen, 4717 NULL, NULL 4718 ); 4719 4720 if (ret == SANE_STATUS_EOF) { 4721 ret = SANE_STATUS_GOOD; 4722 } 4723 4724 DBG (10, "send_panel: finish %d\n", ret); 4725 4726 return ret; 4727} 4728 4729/* 4730 * Request the size of the scanned image 4731 */ 4732/* we should really be updating s->s and s->i instead */ 4733static SANE_Status 4734get_pixelsize(struct scanner *s) 4735{ 4736 SANE_Status ret = SANE_STATUS_GOOD; 4737 4738 unsigned char cmd[READ_len]; 4739 size_t cmdLen = READ_len; 4740 4741 unsigned char in[R_PSIZE_len]; 4742 size_t inLen = R_PSIZE_len; 4743 4744 int i = 0; 4745 const int MAX_TRIES = 5; 4746 4747 DBG (10, "get_pixelsize: start\n"); 4748 4749 if(!s->hwcrop){ 4750 DBG (10, "get_pixelsize: unneeded, finishing\n"); 4751 return ret; 4752 } 4753 4754 memset(cmd,0,cmdLen); 4755 set_SCSI_opcode(cmd, READ_code); 4756 set_R_datatype_code(cmd, SR_datatype_pixelsize); 4757 set_R_xfer_lid(cmd, 0x02); 4758 set_R_xfer_length(cmd, inLen); 4759 4760 /* May need to retry/block until the scanner is done */ 4761 for(i=0;i<MAX_TRIES;i++){ 4762 ret = do_cmd ( 4763 s, 1, 0, 4764 cmd, cmdLen, 4765 NULL, 0, 4766 in, &inLen 4767 ); 4768 4769 if(ret != SANE_STATUS_GOOD){ 4770 DBG (10, "get_pixelsize: error reading, status = %d\n", ret); 4771 break; 4772 } 4773 4774 if(get_R_PSIZE_width(in) > 0 && get_R_PSIZE_length(in) > 0){ 4775 DBG (15, "get_pixelsize: w:%d h:%d\n", 4776 get_R_PSIZE_width(in) * s->u.dpi_x / 1200, 4777 get_R_PSIZE_length(in) * s->u.dpi_y / 1200); 4778 4779 /* 4780 * Round up to byte boundary if needed. 4781 * For 1 bpp the resulting size may not fit in a byte boundary. 4782 */ 4783 int remainder = (get_R_PSIZE_width(in) * s->u.dpi_x / 1200) % 8; 4784 4785 if (s->u.mode < MODE_GRAYSCALE && remainder) 4786 { 4787 int rounded_up = (8 - remainder) + (get_R_PSIZE_width(in) * s->u.dpi_x / 1200); 4788 4789 s->u.br_x = rounded_up * 1200 / s->u.dpi_x; 4790 } 4791 else{ 4792 s->u.br_x = get_R_PSIZE_width(in); 4793 } 4794 4795 s->u.tl_x = 0; 4796 s->u.br_y = get_R_PSIZE_length(in); 4797 s->u.tl_y = 0; 4798 4799 s->u.page_x = s->u.br_x; 4800 s->u.page_y = s->u.br_y; 4801 4802 update_params(s,0); 4803 clean_params(s); 4804 break; 4805 } 4806 4807 else{ 4808 DBG (10, "get_pixelsize: error reading, status = %d w:%d h:%d\n", 4809 ret, get_R_PSIZE_width(in), get_R_PSIZE_length(in)); 4810 ret = SANE_STATUS_INVAL; 4811 usleep(1000000); 4812 } 4813 } 4814 DBG (10, "get_pixelsize: finish\n"); 4815 4816 return ret; 4817} 4818 4819/* 4820 * @@ Section 4 - SANE scanning functions 4821 */ 4822/* 4823 * Called by SANE to retrieve information about the type of data 4824 * that the current scan will return. 4825 * 4826 * From the SANE spec: 4827 * This function is used to obtain the current scan parameters. The 4828 * returned parameters are guaranteed to be accurate between the time 4829 * a scan has been started (sane_start() has been called) and the 4830 * completion of that request. Outside of that window, the returned 4831 * values are best-effort estimates of what the parameters will be 4832 * when sane_start() gets invoked. 4833 * 4834 * Calling this function before a scan has actually started allows, 4835 * for example, to get an estimate of how big the scanned image will 4836 * be. The parameters passed to this function are the handle h of the 4837 * device for which the parameters should be obtained and a pointer p 4838 * to a parameter structure. 4839 */ 4840SANE_Status 4841sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 4842{ 4843 SANE_Status ret = SANE_STATUS_GOOD; 4844 struct scanner *s = (struct scanner *) handle; 4845 4846 DBG (10, "sane_get_parameters: start\n"); 4847 4848 if(!s->started){ 4849 ret = update_params(s,0); 4850 if(ret){ 4851 DBG (5, "sane_get_parameters: up error, returning %d\n", ret); 4852 return ret; 4853 } 4854 } 4855 4856 /* this backend only sends single frame images */ 4857 params->last_frame = 1; 4858 4859 params->format = s->i.format; 4860 params->lines = s->i.height; 4861 params->depth = s->i.bpp; 4862 if(params->depth == 24) params->depth = 8; 4863 params->pixels_per_line = s->i.width; 4864 params->bytes_per_line = s->i.Bpl; 4865 4866 DBG(15,"sane_get_parameters: x: max=%d, page=%d, gpw=%d, res=%d\n", 4867 s->valid_x, s->i.page_x, get_page_width(s), s->i.dpi_x); 4868 4869 DBG(15,"sane_get_parameters: y: max=%d, page=%d, gph=%d, res=%d\n", 4870 s->max_y, s->i.page_y, get_page_height(s), s->i.dpi_y); 4871 4872 DBG(15,"sane_get_parameters: area: tlx=%d, brx=%d, tly=%d, bry=%d\n", 4873 s->i.tl_x, s->i.br_x, s->i.tl_y, s->i.br_y); 4874 4875 DBG (15, "sane_get_parameters: params: ppl=%d, Bpl=%d, lines=%d\n", 4876 params->pixels_per_line, params->bytes_per_line, params->lines); 4877 4878 DBG (15, "sane_get_parameters: params: format=%d, depth=%d, last=%d\n", 4879 params->format, params->depth, params->last_frame); 4880 4881 DBG (10, "sane_get_parameters: finish\n"); 4882 4883 return ret; 4884} 4885 4886SANE_Status 4887update_params(struct scanner *s, int calib) 4888{ 4889 SANE_Status ret = SANE_STATUS_GOOD; 4890 4891 DBG (10, "update_params: start\n"); 4892 4893 s->u.width = (s->u.br_x - s->u.tl_x) * s->u.dpi_x / 1200; 4894 s->u.height = (s->u.br_y - s->u.tl_y) * s->u.dpi_y / 1200; 4895 4896 if (s->u.mode == MODE_COLOR) { 4897 s->u.format = SANE_FRAME_RGB; 4898 s->u.bpp = 24; 4899 } 4900 else if (s->u.mode == MODE_GRAYSCALE) { 4901 s->u.format = SANE_FRAME_GRAY; 4902 s->u.bpp = 8; 4903 } 4904 else { 4905 s->u.format = SANE_FRAME_GRAY; 4906 s->u.bpp = 1; 4907 4908 /* round down to byte boundary */ 4909 s->u.width -= s->u.width % 8; 4910 } 4911 4912 /* round down to pixel boundary for some scanners */ 4913 s->u.width -= s->u.width % s->ppl_mod; 4914 4915 /* jpeg requires 8x8 squares */ 4916 if(s->compress == COMP_JPEG && s->u.mode >= MODE_GRAYSCALE){ 4917 s->u.format = SANE_FRAME_JPEG; 4918 s->u.width -= s->u.width % 8; 4919 s->u.height -= s->u.height % 8; 4920 } 4921 4922 s->u.Bpl = s->u.width * s->u.bpp / 8; 4923 s->u.valid_Bpl = s->u.Bpl; 4924 s->u.valid_width = s->u.width; 4925 4926 DBG (15, "update_params: user params: w:%d h:%d m:%d f:%d b:%d\n", 4927 s->u.width, s->u.height, s->u.mode, s->u.format, s->u.bpp); 4928 DBG (15, "update_params: user params: B:%d vB:%d vw:%d\n", 4929 s->u.Bpl, s->u.valid_Bpl, s->u.valid_width); 4930 DBG (15, "update_params: user params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n", 4931 s->u.br_x, s->u.tl_x, s->u.dpi_x, s->u.br_y, s->u.tl_y, s->u.dpi_y); 4932 4933 /* some scanners are limited in their valid scan params 4934 * make a second version of the params struct, but 4935 * override the user's values with what the scanner can actually do */ 4936 4937 memcpy(&s->s,&s->u,sizeof(struct img_params)); 4938 4939 /*********** missing modes (move up to valid one) **************/ 4940 if(s->s.mode == MODE_LINEART && !s->can_monochrome){ 4941 s->s.mode = MODE_GRAYSCALE; 4942 s->s.format = SANE_FRAME_GRAY; 4943 s->s.bpp = 8; 4944 } 4945 if(s->s.mode == MODE_GRAYSCALE && !s->can_grayscale){ 4946 s->s.mode = MODE_COLOR; 4947 s->s.format = SANE_FRAME_RGB; 4948 s->s.bpp = 24; 4949 } 4950 if(s->s.mode == MODE_COLOR && !s->can_color){ 4951 DBG (5, "update_params: no valid mode\n"); 4952 return SANE_STATUS_INVAL; 4953 } 4954 4955 /********** missing resolutions (move up to valid one) *********/ 4956 if(!s->step_x_res){ 4957 int i; 4958 for(i=0;i<DPI_1200;i++){ 4959 4960 /* this res is smaller or invalid, skip it */ 4961 if(s->s.dpi_x > dpi_list[i] || !s->std_res_x[i]) 4962 continue; 4963 4964 /* same & valid res, done */ 4965 if(s->s.dpi_x == dpi_list[i]) 4966 break; 4967 4968 /* different & valid res, switch */ 4969 s->s.dpi_x = dpi_list[i]; 4970 break; 4971 } 4972 4973 if(i > DPI_1200){ 4974 DBG (5, "update_params: no dpi\n"); 4975 return SANE_STATUS_INVAL; 4976 } 4977 } 4978 4979 /*********** weird scan area (increase to valid one) *********/ 4980 if(s->fixed_width){ 4981 s->s.tl_x = 0; 4982 s->s.br_x = s->max_x; 4983 s->s.page_x = s->max_x; 4984 } 4985 4986 /*recalculate new params*/ 4987 s->s.width = (s->s.br_x - s->s.tl_x) * s->s.dpi_x / 1200; 4988 4989 /* round down to byte boundary */ 4990 if(s->s.mode < MODE_GRAYSCALE){ 4991 s->s.width -= s->s.width % 8; 4992 } 4993 4994 /* round down to pixel boundary for some scanners */ 4995 s->s.width -= s->s.width % s->ppl_mod; 4996 4997 s->s.valid_width = s->s.width; 4998 s->s.valid_Bpl = s->s.valid_width * s->s.bpp / 8; 4999 5000 /* some machines (DR-2050) require even bytes per scanline */ 5001 /* increase width and Bpl, but not valid_width and valid_Bpl */ 5002 if(s->even_Bpl && (s->s.width % 2)){ 5003 s->s.width++; 5004 } 5005 5006 s->s.Bpl = s->s.width * s->s.bpp / 8; 5007 5008 /* figure out how many valid bytes per line (2510 is padded) */ 5009 if(s->color_interlace[SIDE_FRONT] == COLOR_INTERLACE_2510){ 5010 s->s.valid_Bpl = s->s.Bpl*11/12; 5011 s->s.valid_width = s->s.width*11/12; 5012 } 5013 5014 /* some scanners need longer scans because front/back is offset */ 5015 if((s->u.source == SOURCE_ADF_DUPLEX || s->u.source == SOURCE_CARD_DUPLEX) 5016 && s->duplex_offset && !calib) 5017 s->s.height = (s->u.br_y-s->u.tl_y+s->duplex_offset) * s->u.dpi_y / 1200; 5018 5019 /* round lines up to even number */ 5020 s->s.height += s->s.height % 2; 5021 5022 DBG (15, "update_params: scan params: w:%d h:%d m:%d f:%d b:%d\n", 5023 s->s.width, s->s.height, s->s.mode, s->s.format, s->s.bpp); 5024 DBG (15, "update_params: scan params: B:%d vB:%d vw:%d\n", 5025 s->s.Bpl, s->s.valid_Bpl, s->s.valid_width); 5026 DBG (15, "update_params: scan params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n", 5027 s->s.br_x, s->s.tl_x, s->s.dpi_x, s->s.br_y, s->s.tl_y, s->s.dpi_y); 5028 5029 /* make a third (intermediate) version of the params struct, 5030 * currently identical to the user's params. this is what 5031 * we actually will send back to the user (though buffer_xxx 5032 * functions might change these values after this runs) */ 5033 5034 /* calibration code needs the data just as it comes from the scanner */ 5035 if(calib) 5036 memcpy(&s->i,&s->s,sizeof(struct img_params)); 5037 /* normal scans need the data cleaned for presentation to the user */ 5038 else{ 5039 memcpy(&s->i,&s->u,sizeof(struct img_params)); 5040 /*dumb scanners pad the top of front page in duplex*/ 5041 if(s->i.source == SOURCE_ADF_DUPLEX || s->i.source == SOURCE_CARD_DUPLEX) 5042 s->i.skip_lines[s->duplex_offset_side] = s->duplex_offset * s->i.dpi_y / 1200; 5043 } 5044 5045 DBG (15, "update_params: i params: w:%d h:%d m:%d f:%d b:%d\n", 5046 s->i.width, s->i.height, s->i.mode, s->i.format, s->i.bpp); 5047 DBG (15, "update_params: i params: B:%d vB:%d vw:%d\n", 5048 s->i.Bpl, s->i.valid_Bpl, s->i.valid_width); 5049 DBG (15, "update_params: i params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n", 5050 s->i.br_x, s->i.tl_x, s->i.dpi_x, s->i.br_y, s->i.tl_y, s->i.dpi_y); 5051 5052 DBG (10, "update_params: finish\n"); 5053 return ret; 5054} 5055 5056/* simplify handling cmd SANE_STATUS_EOF as SANE_STATUS_GOOD */ 5057SANE_Status 5058send_cmd(struct scanner *s, unsigned char* cmd, size_t cmdLen, 5059 unsigned char* out, size_t outLen, 5060 unsigned char * inBuff, size_t * inLen) 5061{ 5062 SANE_Status ret=SANE_STATUS_GOOD; 5063 5064 ret = do_cmd ( 5065 s, 1, 0, 5066 cmd, cmdLen, 5067 out, outLen, 5068 inBuff, inLen 5069 ); 5070 5071 if (ret == SANE_STATUS_EOF) { 5072 ret = SANE_STATUS_GOOD; 5073 } 5074 5075 return ret; 5076} 5077 5078SANE_Status 5079send_imprint_positioning(struct scanner* s, int is_postimprint, int enabled) 5080{ 5081 unsigned char cmd[SET_SCAN_MODE2_len]; 5082 size_t cmdLen=SET_SCAN_MODE2_len; 5083 5084 unsigned char out[SSM2_PAY_len]; 5085 size_t outLen=SSM2_PAY_len; 5086 5087 unsigned char out_prefix[5]={ 0x01, 0x00, 0x60, 0x00, 0x60 }; 5088 size_t outPrefixLen=5; 5089 5090 memset(cmd,0,cmdLen); 5091 set_SCSI_opcode(cmd,SET_SCAN_MODE2_code); 5092 set_SSM2_page_code(cmd,SM2_pc_imprinter_settings); 5093 if (is_postimprint) 5094 set_SSM2_postimprint_cmd(cmd); 5095 set_SSM2_pay_len(cmd,outLen); 5096 5097 memset(out,0,outLen); 5098 memcpy(out,out_prefix,outPrefixLen); 5099 5100 int h_offset; 5101 int v_offset; 5102 if (is_postimprint){ 5103 if (s->post_imprint_addon_mode != ADDON_DISABLED) 5104 set_SSM2_postimprint_addon(out); 5105 h_offset = s->post_imprint.h_offset; 5106 v_offset = s->post_imprint.v_offset; 5107 5108 if (enabled) 5109 DBG (10, "send_imprint_positioning: post-imprinter: h_offset: %d v_offset: %d\n",h_offset,v_offset); 5110 }else{ 5111 h_offset = s->pre_imprint.h_offset; 5112 v_offset = s->pre_imprint.v_offset; 5113 if (enabled) 5114 DBG (10, "send_imprint_positioning: pre-imprinter: h_offset: %d v_offset: %d\n",h_offset,v_offset); 5115 } 5116 if(!enabled) 5117 h_offset = v_offset = 0; 5118 set_SSM2_imprint_hoffset(out,h_offset); 5119 set_SSM2_imprint_voffset(out,v_offset); 5120 5121 return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL); 5122} 5123 5124SANE_Status 5125send_imprint_specstring(struct scanner* s, int is_postimprint) 5126{ 5127 unsigned char cmd[SET_SCAN_MODE2_len]; 5128 size_t cmdLen = SET_SCAN_MODE2_len; 5129 5130 unsigned char out[SSM2_IMPRINTER_STRING_PAY_len]; 5131 size_t outLen = SSM2_IMPRINTER_STRING_PAY_len; 5132 5133 memset(cmd,0,cmdLen); 5134 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 5135 set_SSM2_page_code(cmd, SM2_pc_imprinter_specstring); 5136 if (is_postimprint) 5137 set_SSM2_postimprint_cmd(cmd); 5138 set_SSM2_pay_len(cmd, outLen); 5139 5140 memset(out,0,outLen); 5141 /* most of these bytes have yet to be identified to specific functionalities, 5142 as they never seem to change under different imprinting mode */ 5143 unsigned char out_prefix[32] = { 5144 0x01, 0x00, 5145 0x60, 0x00, 5146 0x60, 0x00, 5147 0x00, 0x00, 5148 0x00, 0x00, 5149 0x00, 0x00, 5150 0x03, 0x00, 5151 0x00, 0x00, 5152 0x01, 0x00, 5153 0x00, 0x00, 5154 0x00, 0x00, 5155 0x00, 0x00, 5156 0x00, 0x00, 5157 0x00, 0x01, 5158 0x04, 0x00, 5159 0x00, 0x00 5160 }; 5161 memcpy(out, out_prefix, 32); 5162 if (is_postimprint){ 5163 set_SSM2_imprint_fontsize(out, s->post_imprint.font_size); 5164 set_SSM2_imprint_fontrot(out, s->post_imprint.font_rot); 5165 set_SSM2_imprint_spacing(out, s->post_imprint.spacing); 5166 if (s->post_imprint_addon_mode != ADDON_DISABLED) 5167 set_SSM2_imprint_addonmode(out, s->post_imprint_addon_mode); 5168 strcpy((SANE_Char*)(out + 45), (SANE_String_Const) s->post_imprint.specstring); 5169 DBG (10, "send_imprint_specstring: post-imprinter: font size: %d rotation: %d spacing: %d text: '%s' imprint-addon-mode: %d\n",s->post_imprint.font_size,s->post_imprint.font_rot,s->post_imprint.spacing,s->post_imprint.specstring,s->post_imprint_addon_mode); 5170 }else{ 5171 set_SSM2_imprint_fontsize(out, s->pre_imprint.font_size); 5172 set_SSM2_imprint_fontrot(out, s->pre_imprint.font_rot); 5173 set_SSM2_imprint_spacing(out, s->pre_imprint.spacing); 5174 strcpy((SANE_Char*)(out + 45), (SANE_String_Const) s->pre_imprint.specstring); 5175 DBG (10, "send_imprint_specstring: pre-imprinter: font size: %d rotation: %d spacing: %d text: '%s'\n",s->pre_imprint.font_size,s->pre_imprint.font_rot,s->pre_imprint.spacing,s->pre_imprint.specstring); 5176 } 5177 5178 return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL); 5179} 5180 5181SANE_Status 5182send_imprint_date_and_time(struct scanner* s) 5183{ 5184 unsigned char cmd[SET_SCAN_MODE2_len]; 5185 size_t cmdLen = SET_SCAN_MODE2_len; 5186 5187 unsigned char out[SSM2_PAY_len]; 5188 size_t outLen = SSM2_PAY_len; 5189 5190 memset(cmd,0,cmdLen); 5191 set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); 5192 set_SSM2_page_code(cmd, SM2_pc_date_time); 5193 set_SSM2_pay_len(cmd, outLen); 5194 5195 memset(out,0,outLen); 5196 5197 time_t t = time(NULL); 5198 struct tm tM = *localtime(&t); 5199 5200 set_SSM2_imprint_year(out, tM.tm_year + 1900); 5201 set_SSM2_imprint_month(out, tM.tm_mon + 1); 5202 set_SSM2_imprint_day(out, tM.tm_mday); 5203 set_SSM2_imprint_hour(out, tM.tm_hour); 5204 set_SSM2_imprint_min(out, tM.tm_min); 5205 set_SSM2_imprint_sec(out, tM.tm_sec); 5206 5207 return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL); 5208} 5209 5210SANE_Status 5211load_imprinting_settings(struct scanner *s) 5212{ 5213 SANE_Status ret = SANE_STATUS_GOOD; 5214 5215 int requires_preimprint = (strlen(s->pre_imprint.specstring) > 0); 5216 int requires_postimprint = (strlen(s->post_imprint.specstring) > 0); 5217 int send_date_time = (s->has_pre_imprinter && requires_preimprint) || (s->has_post_imprinter && requires_postimprint); 5218 5219 if (s->has_pre_imprinter){ 5220 ret = send_imprint_positioning(s, 0, requires_preimprint); 5221 DBG(10, "load_imprinting_settings: send_pre_imprint_positioning = %d \n", ret); 5222 if (ret != SANE_STATUS_GOOD) 5223 return ret; 5224 if (requires_preimprint){ 5225 ret = send_imprint_specstring(s, 0); 5226 DBG(10, "load_imprinting_settings: send_pre_imprint_specstring = %d \n", ret); 5227 if (ret != SANE_STATUS_GOOD) 5228 return ret; 5229 } 5230 } 5231 5232 if (s->has_post_imprinter){ 5233 ret = send_imprint_positioning(s, 1, requires_postimprint); 5234 DBG(10, "load_imprinting_settings: send_post_imprint_positioning = %d \n", ret); 5235 if (ret != SANE_STATUS_GOOD) 5236 return ret; 5237 if (requires_postimprint){ 5238 ret = send_imprint_specstring(s, 1); 5239 DBG(10, "load_imprinting_settings: send_post_imprint_specstring = %d \n", ret); 5240 if (ret != SANE_STATUS_GOOD) 5241 return ret; 5242 } 5243 } 5244 5245 if (send_date_time){ 5246 ret = send_imprint_date_and_time(s); 5247 DBG(10, "load_imprinting_settings: send_imprint_date_and_time = %d \n", ret); 5248 } 5249 return ret; 5250} 5251 5252static SANE_Status 5253detect_imprinter(struct scanner *s,SANE_Int option) 5254{ 5255 SANE_Status ret = SANE_STATUS_GOOD; 5256 5257 unsigned char cmd[READ_len]; 5258 size_t cmdLen = READ_len; 5259 5260 unsigned char in[R_IMPRINTER_len]; 5261 size_t inLen = R_IMPRINTER_len; 5262 5263 DBG (10, "detect_imprinter: start %d\n", option); 5264 5265 memset(cmd,0,cmdLen); 5266 set_SCSI_opcode(cmd, READ_code); 5267 set_R_datatype_code(cmd, SR_datatype_imprinters); 5268 set_R_xfer_uid(cmd, option); 5269 set_R_xfer_length(cmd, inLen); 5270 5271 ret = do_cmd( 5272 s, 1, 0, 5273 cmd, cmdLen, 5274 NULL, 0, 5275 in, &inLen 5276 ); 5277 5278 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { 5279 ret = SANE_STATUS_GOOD; 5280 } 5281 5282 int imprinter_found = get_R_IMPRINTER_found(in); 5283 const char* imprinter_type = "unknown"; 5284 if (option == R_PRE_IMPRINTER){ 5285 s->has_pre_imprinter = imprinter_found; 5286 imprinter_type = "pre-imprinter"; 5287 } 5288 else if (option == R_POST_IMPRINTER){ 5289 s->has_post_imprinter = imprinter_found; 5290 imprinter_type = "post-imprinter"; 5291 } 5292 5293 DBG (10, "detect_imprinter: type: %s. found status bit: %d \n",imprinter_type,imprinter_found); 5294 5295 return ret; 5296} 5297 5298/* reset image size parameters after buffer_xxx functions changed them */ 5299SANE_Status 5300update_i_params(struct scanner *s) 5301{ 5302 SANE_Status ret = SANE_STATUS_GOOD; 5303 5304 DBG (10, "update_i_params: start\n"); 5305 5306 s->i.width = s->u.width; 5307 s->i.Bpl = s->u.Bpl; 5308 5309 DBG (10, "update_i_params: finish\n"); 5310 return ret; 5311} 5312 5313/* 5314 * Called by SANE when a page acquisition operation is to be started. 5315 * commands: set window, object pos, and scan 5316 * 5317 * this will be called between sides of a duplex scan, 5318 * and at the start of each page of an adf batch. 5319 * hence, we spend a lot of time playing with s->started, etc. 5320 */ 5321SANE_Status 5322sane_start (SANE_Handle handle) 5323{ 5324 struct scanner *s = handle; 5325 SANE_Status ret = SANE_STATUS_GOOD; 5326 5327 DBG (10, "sane_start: start\n"); 5328 DBG (15, "started=%d, side=%d, source=%d\n", 5329 s->started, s->side, s->u.source); 5330 5331 /* undo any prior sane_cancel calls */ 5332 s->cancelled=0; 5333 5334 /* protect this block from sane_cancel */ 5335 s->reading=1; 5336 5337 /* not finished with current side, error */ 5338 if (s->started && !s->u.eof[s->side]) { 5339 DBG(5,"sane_start: previous transfer not finished?"); 5340 return SANE_STATUS_INVAL; 5341 } 5342 5343 /* batch start? inititalize struct and scanner */ 5344 if(!s->started){ 5345 5346 /* load side marker */ 5347 if(s->u.source == SOURCE_ADF_BACK || s->u.source == SOURCE_CARD_BACK){ 5348 s->side = SIDE_BACK; 5349 } 5350 else{ 5351 s->side = SIDE_FRONT; 5352 } 5353 5354 /* eject paper leftover*/ 5355 if(object_position (s, SANE_FALSE)){ 5356 DBG (5, "sane_start: ERROR: cannot eject page\n"); 5357 } 5358 5359 /* wait for scanner to finish eject */ 5360 ret = wait_scanner (s); 5361 if (ret != SANE_STATUS_GOOD) { 5362 DBG (5, "sane_start: ERROR: cannot wait scanner\n"); 5363 goto errors; 5364 } 5365 5366 /* load the brightness/contrast lut with linear slope for calibration */ 5367 ret = load_lut (s->lut, 8, 8, 0, 255, 0, 0); 5368 if (ret != SANE_STATUS_GOOD) { 5369 DBG (5, "sane_start: ERROR: cannot load lut\n"); 5370 goto errors; 5371 } 5372 5373 /* AFE cal */ 5374 ret = calibrate_AFE(s); 5375 if (ret != SANE_STATUS_GOOD) { 5376 DBG (5, "sane_start: ERROR: cannot cal afe\n"); 5377 goto errors; 5378 } 5379 5380 /* fine cal */ 5381 ret = calibrate_fine(s); 5382 if (ret != SANE_STATUS_GOOD) { 5383 DBG (5, "sane_start: ERROR: cannot cal fine\n"); 5384 goto errors; 5385 } 5386 5387 if (s->has_pre_imprinter || s->has_post_imprinter){ 5388 ret = load_imprinting_settings(s); 5389 if (ret != SANE_STATUS_GOOD) { 5390 DBG (5, "sane_start: ERROR: invalid imprinting settings\n"); 5391 goto errors; 5392 } 5393 } 5394 5395 /* reset the page counter after calibration */ 5396 s->panel_counter = 0; 5397 s->prev_page = 0; 5398 if(send_panel(s)){ 5399 DBG (5, "sane_start: ERROR: cannot send panel\n"); 5400 } 5401 5402 /* we should really be updating s->s and s->i instead */ 5403 if(s->hwcrop){ 5404 s->u.br_x = s->max_x; 5405 s->u.tl_x = 0; 5406 s->u.br_y = s->max_y; 5407 s->u.tl_y = 0; 5408 s->u.page_x = s->max_x; 5409 s->u.page_y = s->max_y; 5410 } 5411 5412 /* load our own private copy of scan params */ 5413 ret = update_params(s,0); 5414 if (ret != SANE_STATUS_GOOD) { 5415 DBG (5, "sane_start: ERROR: cannot update_params\n"); 5416 goto errors; 5417 } 5418 5419 /* set window command */ 5420 ret = set_window(s); 5421 if (ret != SANE_STATUS_GOOD) { 5422 DBG (5, "sane_start: ERROR: cannot set window\n"); 5423 goto errors; 5424 } 5425 5426 /* buffer/duplex/ald/fb/card command */ 5427 ret = ssm_buffer(s); 5428 if (ret != SANE_STATUS_GOOD) { 5429 DBG (5, "sane_start: ERROR: cannot ssm buffer\n"); 5430 goto errors; 5431 } 5432 5433 /* dropout color command */ 5434 ret = ssm_do(s); 5435 if (ret != SANE_STATUS_GOOD) { 5436 DBG (5, "sane_start: ERROR: cannot ssm do\n"); 5437 goto errors; 5438 } 5439 5440 /* double feed detection command */ 5441 ret = ssm_df(s); 5442 if (ret != SANE_STATUS_GOOD) { 5443 DBG (5, "sane_start: ERROR: cannot ssm df\n"); 5444 goto errors; 5445 } 5446 5447 ret = ssm2_hw_enhancement(s); 5448 if (ret != SANE_STATUS_GOOD) { 5449 DBG (5, "sane_start: ERROR: cannot ssm2 hw enhancement\n"); 5450 goto errors; 5451 } 5452 5453 /* clean scan params for new scan */ 5454 ret = clean_params(s); 5455 if (ret != SANE_STATUS_GOOD) { 5456 DBG (5, "sane_start: ERROR: cannot clean_params\n"); 5457 goto errors; 5458 } 5459 5460 /* make large buffers to hold the images */ 5461 ret = image_buffers(s,1); 5462 if (ret != SANE_STATUS_GOOD) { 5463 DBG (5, "sane_start: ERROR: cannot load buffers\n"); 5464 goto errors; 5465 } 5466 5467 /* load the brightness/contrast lut with user choices */ 5468 ret = load_lut (s->lut, 8, 8, 0, 255, s->contrast, s->brightness); 5469 if (ret != SANE_STATUS_GOOD) { 5470 DBG (5, "sane_start: ERROR: cannot load lut\n"); 5471 goto errors; 5472 } 5473 5474 /* card reader dislikes op? */ 5475 if(s->s.source < SOURCE_CARD_FRONT){ 5476 /* grab next page */ 5477 ret = object_position (s, SANE_TRUE); 5478 if (ret != SANE_STATUS_GOOD) { 5479 DBG (5, "sane_start: ERROR: cannot load page\n"); 5480 goto errors; 5481 } 5482 5483 /* wait for scanner to finish load */ 5484 ret = wait_scanner (s); 5485 if (ret != SANE_STATUS_GOOD) { 5486 DBG (5, "sane_start: ERROR: cannot wait scanner\n"); 5487 goto errors; 5488 } 5489 } 5490 5491 /* start scanning */ 5492 ret = start_scan (s,0); 5493 if (ret != SANE_STATUS_GOOD) { 5494 DBG (5, "sane_start: ERROR: cannot start_scan\n"); 5495 goto errors; 5496 } 5497 5498 ret = get_pixelsize(s); 5499 if (ret != SANE_STATUS_GOOD) { 5500 DBG (5, "sane_start: ERROR: cannot get pixel size\n"); 5501 goto errors; 5502 } 5503 5504 s->started = 1; 5505 } 5506 5507 /* stuff done for subsequent images */ 5508 else{ 5509 5510 /* duplex needs to switch sides */ 5511 if(s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX){ 5512 s->side = !s->side; 5513 } 5514 5515 /* reset the intermediate params */ 5516 ret = update_i_params(s); 5517 if (ret != SANE_STATUS_GOOD) { 5518 DBG (5, "sane_start: ERROR: cannot update_i_params\n"); 5519 goto errors; 5520 } 5521 5522 /* set clean defaults with new sheet of paper */ 5523 /* don't reset the transfer vars on backside of duplex page */ 5524 /* otherwise buffered back page will be lost */ 5525 /* ingest paper with adf (no-op for fb) */ 5526 /* don't call object pos or scan on back side of duplex scan */ 5527 if(s->side == SIDE_FRONT || s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK){ 5528 5529 /* clean scan params for new scan */ 5530 ret = clean_params(s); 5531 if (ret != SANE_STATUS_GOOD) { 5532 DBG (5, "sane_start: ERROR: cannot clean_params\n"); 5533 goto errors; 5534 } 5535 5536 /* big scanners and small ones in non-buff mode: OP to detect paper */ 5537 if(s->always_op || !s->buffermode){ 5538 ret = object_position (s, SANE_TRUE); 5539 if (ret != SANE_STATUS_GOOD) { 5540 DBG (5, "sane_start: ERROR: cannot load page\n"); 5541 goto errors; 5542 } 5543 5544 /* user wants unbuffered scans */ 5545 /* send scan command */ 5546 if(!s->buffermode){ 5547 ret = start_scan (s,0); 5548 if (ret != SANE_STATUS_GOOD) { 5549 DBG (5, "sane_start: ERROR: cannot start_scan\n"); 5550 goto errors; 5551 } 5552 } 5553 } 5554 5555 /* small, buffering scanners check for more pages by reading counter */ 5556 else{ 5557 ret = read_panel (s, OPT_COUNTER); 5558 if (ret != SANE_STATUS_GOOD) { 5559 DBG (5, "sane_start: ERROR: cannot load page\n"); 5560 goto errors; 5561 } 5562 if(s->prev_page == s->panel_counter){ 5563 DBG (5, "sane_start: same counter (%d) no paper?\n",s->prev_page); 5564 ret = SANE_STATUS_NO_DOCS; 5565 goto errors; 5566 } 5567 DBG (5, "sane_start: diff counter (%d/%d)\n", 5568 s->prev_page,s->panel_counter); 5569 } 5570 5571 ret = get_pixelsize(s); 5572 if (ret != SANE_STATUS_GOOD) { 5573 DBG (5, "sane_start: ERROR: cannot get pixel size\n"); 5574 goto errors; 5575 } 5576 } 5577 } 5578 5579 /* reset jpeg params on each page */ 5580 s->jpeg_stage=JPEG_STAGE_NONE; 5581 s->jpeg_ff_offset=0; 5582 5583 DBG (15, "started=%d, side=%d, source=%d\n", 5584 s->started, s->side, s->u.source); 5585 5586 /* certain options require the entire image to 5587 * be collected from the scanner before we can 5588 * tell the user the size of the image. the sane 5589 * API has no way to inform the frontend of this, 5590 * so we block and buffer. yuck */ 5591 if(must_fully_buffer(s)){ 5592 5593 /* get image */ 5594 while(!s->s.eof[s->side] && !ret){ 5595 SANE_Int len = 0; 5596 ret = sane_read((SANE_Handle)s, NULL, 0, &len); 5597 } 5598 5599 /* check for errors */ 5600 if (ret != SANE_STATUS_GOOD) { 5601 DBG (5, "sane_start: ERROR: cannot buffer image\n"); 5602 goto errors; 5603 } 5604 5605 DBG (5, "sane_start: OK: done buffering\n"); 5606 5607 /* finished buffering, adjust image as required */ 5608 if(s->swdeskew){ 5609 buffer_deskew(s,s->side); 5610 } 5611 if(s->swcrop){ 5612 buffer_crop(s,s->side); 5613 } 5614 if(s->swdespeck){ 5615 buffer_despeck(s,s->side); 5616 } 5617 if(s->swskip){ 5618 /* Skipping means throwing out this image. 5619 * Pretend the user read the whole thing 5620 * and call sane_start again. 5621 * This assumes we are running in batch mode. */ 5622 if(buffer_isblank(s,s->side)){ 5623 s->u.eof[s->side] = 1; 5624 return sane_start(handle); 5625 } 5626 } 5627 } 5628 5629 ret = check_for_cancel(s); 5630 s->reading = 0; 5631 5632 DBG (10, "sane_start: finish %d\n", ret); 5633 return ret; 5634 5635 errors: 5636 DBG (10, "sane_start: error %d\n", ret); 5637 s->started = 0; 5638 s->cancelled = 0; 5639 s->reading = 0; 5640 return ret; 5641} 5642 5643/* 5644 * cleans params for new scan 5645 */ 5646static SANE_Status 5647clean_params (struct scanner *s) 5648{ 5649 SANE_Status ret = SANE_STATUS_GOOD; 5650 5651 DBG (10, "clean_params: start\n"); 5652 5653 s->u.eof[0]=0; 5654 s->u.eof[1]=0; 5655 s->u.bytes_sent[0]=0; 5656 s->u.bytes_sent[1]=0; 5657 s->u.bytes_tot[0]=0; 5658 s->u.bytes_tot[1]=0; 5659 5660 s->i.eof[0]=0; 5661 s->i.eof[1]=0; 5662 s->i.bytes_sent[0]=0; 5663 s->i.bytes_sent[1]=0; 5664 s->i.bytes_tot[0]=0; 5665 s->i.bytes_tot[1]=0; 5666 5667 s->s.eof[0]=0; 5668 s->s.eof[1]=0; 5669 s->s.bytes_sent[0]=0; 5670 s->s.bytes_sent[1]=0; 5671 s->s.bytes_tot[0]=0; 5672 s->s.bytes_tot[1]=0; 5673 5674 /* store the number of front bytes */ 5675 if ( s->u.source != SOURCE_ADF_BACK && s->u.source != SOURCE_CARD_BACK ) 5676 s->u.bytes_tot[SIDE_FRONT] = s->u.Bpl * s->u.height; 5677 5678 if ( s->i.source != SOURCE_ADF_BACK && s->i.source != SOURCE_CARD_BACK ) 5679 s->i.bytes_tot[SIDE_FRONT] = s->i.Bpl * s->i.height; 5680 5681 if ( s->s.source != SOURCE_ADF_BACK && s->s.source != SOURCE_CARD_BACK ) 5682 s->s.bytes_tot[SIDE_FRONT] = s->s.Bpl * s->s.height; 5683 5684 /* store the number of back bytes */ 5685 if ( s->u.source == SOURCE_ADF_DUPLEX || s->u.source == SOURCE_ADF_BACK 5686 || s->u.source == SOURCE_CARD_DUPLEX || s->u.source == SOURCE_CARD_BACK ) 5687 s->u.bytes_tot[SIDE_BACK] = s->u.Bpl * s->u.height; 5688 5689 if ( s->i.source == SOURCE_ADF_DUPLEX || s->i.source == SOURCE_ADF_BACK 5690 || s->i.source == SOURCE_CARD_DUPLEX || s->i.source == SOURCE_CARD_BACK ) 5691 s->i.bytes_tot[SIDE_BACK] = s->i.Bpl * s->i.height; 5692 5693 if ( s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_ADF_BACK 5694 || s->s.source == SOURCE_CARD_DUPLEX || s->s.source == SOURCE_CARD_BACK ) 5695 s->s.bytes_tot[SIDE_BACK] = s->s.Bpl * s->s.height; 5696 5697 DBG (10, "clean_params: finish\n"); 5698 5699 return ret; 5700} 5701 5702/* 5703 * frees/callocs buffers to hold the scan data 5704 */ 5705static SANE_Status 5706image_buffers (struct scanner *s, int setup) 5707{ 5708 SANE_Status ret = SANE_STATUS_GOOD; 5709 int side; 5710 5711 DBG (10, "image_buffers: start\n"); 5712 5713 for(side=0;side<2;side++){ 5714 5715 /* free current buffer */ 5716 if (s->buffers[side]) { 5717 DBG (15, "image_buffers: free buffer %d.\n",side); 5718 free(s->buffers[side]); 5719 s->buffers[side] = NULL; 5720 } 5721 5722 /* build new buffer if asked */ 5723 if(s->i.bytes_tot[side] && setup){ 5724 s->buffers[side] = calloc (1,s->i.bytes_tot[side]); 5725 if (!s->buffers[side]) { 5726 DBG (5, "image_buffers: Error, no buffer %d.\n",side); 5727 return SANE_STATUS_NO_MEM; 5728 } 5729 } 5730 } 5731 5732 DBG (10, "image_buffers: finish\n"); 5733 5734 return ret; 5735} 5736 5737/* 5738 * This routine issues a SCSI SET WINDOW command to the scanner, using the 5739 * values currently in the s->s param structure. 5740 */ 5741static SANE_Status 5742set_window (struct scanner *s) 5743{ 5744 SANE_Status ret = SANE_STATUS_GOOD; 5745 5746 /* The command specifies the number of bytes in the data phase 5747 * the data phase has a header, followed by 1 window desc block 5748 * the header specifies the number of bytes in 1 window desc block 5749 */ 5750 5751 unsigned char cmd[SET_WINDOW_len]; 5752 size_t cmdLen = SET_WINDOW_len; 5753 5754 unsigned char out[SW_header_len + SW_desc_len]; 5755 size_t outLen = SW_header_len + SW_desc_len; 5756 5757 unsigned char * header = out; /*header*/ 5758 unsigned char * desc1 = out + SW_header_len; /*descriptor*/ 5759 5760 DBG (10, "set_window: start\n"); 5761 5762 /*build the payload*/ 5763 memset(out,0,outLen); 5764 5765 /* set window desc size in header */ 5766 set_WPDB_wdblen(header, SW_desc_len); 5767 5768 /* init the window block */ 5769 if (s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK) { 5770 set_WD_wid (desc1, WD_wid_back); 5771 } 5772 else{ 5773 set_WD_wid (desc1, WD_wid_front); 5774 } 5775 5776 set_WD_Xres (desc1, s->s.dpi_x); 5777 set_WD_Yres (desc1, s->s.dpi_y); 5778 5779 /* some machines need max width */ 5780 if(s->fixed_width){ 5781 set_WD_ULX (desc1, 0); 5782 set_WD_width (desc1, s->max_x); 5783 } 5784 5785 /* or they align left */ 5786 else if(s->u.source == SOURCE_FLATBED){ 5787 set_WD_ULX (desc1, s->s.tl_x); 5788 set_WD_width (desc1, s->s.width * 1200/s->s.dpi_x); 5789 } 5790 5791 /* or we have to center the window ourselves */ 5792 else{ 5793 set_WD_ULX (desc1, (s->max_x - s->s.page_x) / 2 + s->s.tl_x); 5794 set_WD_width (desc1, s->s.width * 1200/s->s.dpi_x); 5795 } 5796 5797 /* some models require that the tly value be inverted? */ 5798 if(s->invert_tly) 5799 set_WD_ULY (desc1, ~s->s.tl_y); 5800 else 5801 set_WD_ULY (desc1, s->s.tl_y); 5802 5803 set_WD_length (desc1, s->s.height * 1200/s->s.dpi_y); 5804 5805 if(s->has_btc){ 5806 /*convert our common -127 to +127 range into HW's range 5807 *FIXME: this code assumes hardware range of 0-255 */ 5808 set_WD_brightness (desc1, s->brightness+128); 5809 5810 set_WD_threshold (desc1, s->threshold); 5811 5812 /*convert our common -127 to +127 range into HW's range 5813 *FIXME: this code assumes hardware range of 0-255 */ 5814 set_WD_contrast (desc1, s->contrast+128); 5815 } 5816 5817 set_WD_composition (desc1, s->s.mode); 5818 5819 if(s->s.bpp == 24) 5820 set_WD_bitsperpixel (desc1, 8); 5821 else 5822 set_WD_bitsperpixel (desc1, s->s.bpp); 5823 5824 if(s->s.mode == MODE_HALFTONE){ 5825 /*set_WD_ht_type(desc1, s->ht_type); 5826 set_WD_ht_pattern(desc1, s->ht_pattern);*/ 5827 } 5828 5829 set_WD_rif (desc1, s->rif); 5830 set_WD_rgb(desc1, s->rgb_format); 5831 set_WD_padding(desc1, s->padding); 5832 5833 /*FIXME: what is this? */ 5834 set_WD_reserved2(desc1, s->unknown_byte2); 5835 5836 set_WD_compress_type(desc1, COMP_NONE); 5837 set_WD_compress_arg(desc1, 0); 5838 5839 /* some scanners support jpeg image compression, for color/gs only */ 5840 if(s->s.format == SANE_FRAME_JPEG){ 5841 set_WD_compress_type(desc1, COMP_JPEG); 5842 set_WD_compress_arg(desc1, s->compress_arg); 5843 } 5844 5845 /*build the command*/ 5846 memset(cmd,0,cmdLen); 5847 set_SCSI_opcode(cmd, SET_WINDOW_code); 5848 set_SW_xferlen(cmd, outLen); 5849 5850 ret = do_cmd ( 5851 s, 1, 0, 5852 cmd, cmdLen, 5853 out, outLen, 5854 NULL, NULL 5855 ); 5856 5857 if (!ret && (s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX)) { 5858 set_WD_wid (desc1, WD_wid_back); 5859 ret = do_cmd ( 5860 s, 1, 0, 5861 cmd, cmdLen, 5862 out, outLen, 5863 NULL, NULL 5864 ); 5865 } 5866 5867 DBG (10, "set_window: finish\n"); 5868 5869 return ret; 5870} 5871 5872/* 5873 * Issues the SCSI OBJECT POSITION command if an ADF is in use. 5874 */ 5875static SANE_Status 5876object_position (struct scanner *s, int i_load) 5877{ 5878 SANE_Status ret = SANE_STATUS_GOOD; 5879 5880 unsigned char cmd[OBJECT_POSITION_len]; 5881 size_t cmdLen = OBJECT_POSITION_len; 5882 5883 DBG (10, "object_position: start\n"); 5884 5885 if (s->u.source == SOURCE_FLATBED) { 5886 DBG (10, "object_position: flatbed no-op\n"); 5887 return SANE_STATUS_GOOD; 5888 } 5889 5890 memset(cmd,0,cmdLen); 5891 set_SCSI_opcode(cmd, OBJECT_POSITION_code); 5892 5893 if (i_load) { 5894 DBG (15, "object_position: load\n"); 5895 set_OP_autofeed (cmd, OP_Feed); 5896 } 5897 else { 5898 DBG (15, "object_position: eject\n"); 5899 set_OP_autofeed (cmd, OP_Discharge); 5900 } 5901 5902 ret = do_cmd ( 5903 s, 1, 0, 5904 cmd, cmdLen, 5905 NULL, 0, 5906 NULL, NULL 5907 ); 5908 if (ret != SANE_STATUS_GOOD) 5909 return ret; 5910 5911 DBG (10, "object_position: finish\n"); 5912 5913 return ret; 5914} 5915 5916/* 5917 * Issues SCAN command. 5918 * 5919 * (This doesn't actually read anything, it just tells the scanner 5920 * to start scanning.) 5921 */ 5922static SANE_Status 5923start_scan (struct scanner *s, int type) 5924{ 5925 SANE_Status ret = SANE_STATUS_GOOD; 5926 5927 unsigned char cmd[SCAN_len]; 5928 size_t cmdLen = SCAN_len; 5929 5930 unsigned char out[] = {WD_wid_front, WD_wid_back}; 5931 size_t outLen = 2; 5932 5933 DBG (10, "start_scan: start\n"); 5934 5935 /* calibration scans use 0xff or 0xfe */ 5936 if(type){ 5937 out[0] = type; 5938 out[1] = type; 5939 } 5940 5941 if (s->s.source != SOURCE_ADF_DUPLEX && s->s.source != SOURCE_CARD_DUPLEX) { 5942 outLen--; 5943 if(s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK) { 5944 out[0] = WD_wid_back; 5945 } 5946 } 5947 5948 memset(cmd,0,cmdLen); 5949 set_SCSI_opcode(cmd, SCAN_code); 5950 set_SC_xfer_length (cmd, outLen); 5951 5952 ret = do_cmd ( 5953 s, 1, 0, 5954 cmd, cmdLen, 5955 out, outLen, 5956 NULL, NULL 5957 ); 5958 5959 DBG (10, "start_scan: finish\n"); 5960 5961 return ret; 5962} 5963 5964/* 5965 * Called by SANE to read data. 5966 * 5967 * From the SANE spec: 5968 * This function is used to read image data from the device 5969 * represented by handle h. Argument buf is a pointer to a memory 5970 * area that is at least maxlen bytes long. The number of bytes 5971 * returned is stored in *len. A backend must set this to zero when 5972 * the call fails (i.e., when a status other than SANE_STATUS_GOOD is 5973 * returned). 5974 * 5975 * When the call succeeds, the number of bytes returned can be 5976 * anywhere in the range from 0 to maxlen bytes. 5977 */ 5978SANE_Status 5979sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len) 5980{ 5981 struct scanner *s = (struct scanner *) handle; 5982 SANE_Status ret=SANE_STATUS_GOOD; 5983 5984 DBG (10, "sane_read: start\n"); 5985 5986 *len=0; 5987 5988 /* maybe cancelled? */ 5989 if(!s->started){ 5990 DBG (5, "sane_read: not started, call sane_start\n"); 5991 return SANE_STATUS_CANCELLED; 5992 } 5993 5994 /* sane_start required between sides */ 5995 if(s->u.bytes_sent[s->side] == s->i.bytes_tot[s->side]){ 5996 s->u.eof[s->side] = 1; 5997 DBG (15, "sane_read: returning eof\n"); 5998 return SANE_STATUS_EOF; 5999 } 6000 6001 s->reading = 1; 6002 6003 /* double width pnm interlacing */ 6004 if((s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX) 6005 && s->s.format <= SANE_FRAME_RGB 6006 && s->duplex_interlace != DUPLEX_INTERLACE_NONE 6007 ){ 6008 6009 /* buffer both sides */ 6010 if(!s->s.eof[SIDE_FRONT] || !s->s.eof[SIDE_BACK]){ 6011 ret = read_from_scanner_duplex(s, 0); 6012 if(ret){ 6013 DBG(5,"sane_read: front returning %d\n",ret); 6014 goto errors; 6015 } 6016 /*read last block, update counter*/ 6017 if(s->s.eof[SIDE_FRONT] && s->s.eof[SIDE_BACK]){ 6018 s->prev_page++; 6019 DBG(15,"sane_read: duplex counter %d\n",s->prev_page); 6020 } 6021 } 6022 } 6023 6024 /* simplex or non-alternating duplex */ 6025 else{ 6026 if(!s->s.eof[s->side]){ 6027 ret = read_from_scanner(s, s->side, 0); 6028 if(ret){ 6029 DBG(5,"sane_read: side %d returning %d\n",s->side,ret); 6030 goto errors; 6031 } 6032 /*read last block, update counter*/ 6033 if(s->s.eof[s->side]){ 6034 s->prev_page++; 6035 DBG(15,"sane_read: side %d counter %d\n",s->side,s->prev_page); 6036 } 6037 } 6038 } 6039 6040 /* copy a block from buffer to frontend */ 6041 ret = read_from_buffer(s,buf,max_len,len,s->side); 6042 if(ret) 6043 goto errors; 6044 6045 ret = check_for_cancel(s); 6046 s->reading = 0; 6047 6048 DBG (10, "sane_read: finish %d\n", ret); 6049 return ret; 6050 6051 errors: 6052 DBG (10, "sane_read: error %d\n", ret); 6053 s->reading = 0; 6054 s->cancelled = 0; 6055 s->started = 0; 6056 return ret; 6057} 6058 6059static SANE_Status 6060read_from_scanner(struct scanner *s, int side, int exact) 6061{ 6062 SANE_Status ret=SANE_STATUS_GOOD; 6063 6064 unsigned char cmd[READ_len]; 6065 size_t cmdLen = READ_len; 6066 6067 unsigned char * in; 6068 size_t inLen = 0; 6069 6070 size_t bytes = s->buffer_size; 6071 size_t remain = s->s.bytes_tot[side] - s->s.bytes_sent[side]; 6072 6073 DBG (10, "read_from_scanner: start\n"); 6074 6075 /* all requests must end on line boundary */ 6076 bytes -= (bytes % s->s.Bpl); 6077 6078 /* some larger scanners require even bytes per block */ 6079 if(bytes % 2){ 6080 bytes -= s->s.Bpl; 6081 } 6082 6083 /* usually (image) we want to read too much data, and get RS */ 6084 /* sometimes (calib) we want to do an exact read */ 6085 if(exact && bytes > remain){ 6086 bytes = remain; 6087 } 6088 6089 DBG(15, "read_from_scanner: si:%d to:%d rx:%d re:%lu bu:%d pa:%lu ex:%d\n", 6090 side, s->s.bytes_tot[side], s->s.bytes_sent[side], 6091 (unsigned long)remain, s->buffer_size, (unsigned long)bytes, exact); 6092 6093 inLen = bytes; 6094 in = malloc(inLen); 6095 if(!in){ 6096 DBG(5, "read_from_scanner: not enough mem for buffer: %d\n",(int)inLen); 6097 return SANE_STATUS_NO_MEM; 6098 } 6099 6100 memset(cmd,0,cmdLen); 6101 set_SCSI_opcode(cmd, READ_code); 6102 set_R_datatype_code (cmd, SR_datatype_image); 6103 6104 set_R_xfer_length (cmd, inLen); 6105 6106 ret = do_cmd ( 6107 s, 1, 0, 6108 cmd, cmdLen, 6109 NULL, 0, 6110 in, &inLen 6111 ); 6112 6113 if (ret == SANE_STATUS_GOOD) { 6114 DBG(15, "read_from_scanner: got GOOD, returning GOOD %lu\n", (unsigned long)inLen); 6115 } 6116 else if (ret == SANE_STATUS_EOF) { 6117 DBG(15, "read_from_scanner: got EOF, finishing %lu\n", (unsigned long)inLen); 6118 } 6119 else if (ret == SANE_STATUS_DEVICE_BUSY) { 6120 DBG(5, "read_from_scanner: got BUSY, returning GOOD\n"); 6121 inLen = 0; 6122 ret = SANE_STATUS_GOOD; 6123 } 6124 else { 6125 DBG(5, "read_from_scanner: error reading data block status = %d\n",ret); 6126 inLen = 0; 6127 } 6128 6129 /* this is jpeg data, we need to fix the missing image size */ 6130 if(s->s.format == SANE_FRAME_JPEG){ 6131 6132 /* look for the SOF header near the beginning */ 6133 if(s->jpeg_stage == JPEG_STAGE_NONE || s->jpeg_ff_offset < 0x0d){ 6134 6135 size_t i; 6136 6137 for(i=0;i<inLen;i++){ 6138 6139 /* about to change stage */ 6140 if(s->jpeg_stage == JPEG_STAGE_NONE && in[i] == 0xff){ 6141 s->jpeg_ff_offset=0; 6142 continue; 6143 } 6144 6145 s->jpeg_ff_offset++; 6146 6147 /* last byte was an ff, this byte is SOF */ 6148 if(s->jpeg_ff_offset == 1 && in[i] == 0xc0){ 6149 s->jpeg_stage = JPEG_STAGE_SOF; 6150 continue; 6151 } 6152 6153 if(s->jpeg_stage == JPEG_STAGE_SOF){ 6154 6155 /* lines in start of frame, overwrite it */ 6156 if(s->jpeg_ff_offset == 5){ 6157 in[i] = (s->s.height >> 8) & 0xff; 6158 continue; 6159 } 6160 if(s->jpeg_ff_offset == 6){ 6161 in[i] = s->s.height & 0xff; 6162 continue; 6163 } 6164 6165 /* width in start of frame, overwrite it */ 6166 if(s->jpeg_ff_offset == 7){ 6167 in[i] = (s->s.width >> 8) & 0xff; 6168 continue; 6169 } 6170 if(s->jpeg_ff_offset == 8){ 6171 in[i] = s->s.width & 0xff; 6172 continue; 6173 } 6174 } 6175 } 6176 } 6177 } 6178 6179 /*scanner may have sent more data than we asked for, chop it*/ 6180 if(inLen > remain){ 6181 inLen = remain; 6182 } 6183 6184 /* we've got some data, descramble and store it */ 6185 if(inLen){ 6186 copy_simplex(s,in,inLen,side); 6187 } 6188 6189 free(in); 6190 6191 /* we've read all data, but not eof. clear and pretend */ 6192 if(exact && inLen == remain){ 6193 DBG (10, "read_from_scanner: exact read, clearing\n"); 6194 ret = object_position (s,SANE_FALSE); 6195 if(ret){ 6196 return ret; 6197 } 6198 ret = SANE_STATUS_EOF; 6199 } 6200 6201 if(ret == SANE_STATUS_EOF){ 6202 6203 /* this is jpeg data, we need to change the total size */ 6204 if(s->s.format == SANE_FRAME_JPEG){ 6205 s->s.bytes_tot[side] = s->s.bytes_sent[side]; 6206 s->i.bytes_tot[side] = s->i.bytes_sent[side]; 6207 s->u.bytes_tot[side] = s->i.bytes_sent[side]; 6208 } 6209 6210 /* this is non-jpeg data, fill remainder, change rx'd size */ 6211 else{ 6212 fill_image(s,side); 6213 } 6214 6215 s->i.eof[side] = 1; 6216 s->s.eof[side] = 1; 6217 ret = SANE_STATUS_GOOD; 6218 } 6219 6220 DBG(15, "read_from_scanner: sto:%d srx:%d sef:%d uto:%d urx:%d uef:%d\n", 6221 s->s.bytes_tot[side], s->s.bytes_sent[side], s->s.eof[side], 6222 s->u.bytes_tot[side], s->u.bytes_sent[side], s->u.eof[side]); 6223 6224 DBG (10, "read_from_scanner: finish\n"); 6225 6226 return ret; 6227} 6228 6229/* cheaper scanners interlace duplex scans on a byte basis 6230 * this code requests double width lines from scanner */ 6231static SANE_Status 6232read_from_scanner_duplex(struct scanner *s,int exact) 6233{ 6234 SANE_Status ret=SANE_STATUS_GOOD; 6235 6236 unsigned char cmd[READ_len]; 6237 size_t cmdLen = READ_len; 6238 6239 unsigned char * in; 6240 size_t inLen = 0; 6241 6242 size_t bytes = s->buffer_size; 6243 size_t remain = s->s.bytes_tot[SIDE_FRONT] + s->s.bytes_tot[SIDE_BACK] 6244 - s->s.bytes_sent[SIDE_FRONT] - s->s.bytes_sent[SIDE_BACK]; 6245 6246 DBG (10, "read_from_scanner_duplex: start\n"); 6247 6248 /* all requests must end on WIDE line boundary */ 6249 bytes -= (bytes % (s->s.Bpl*2)); 6250 6251 /* usually (image) we want to read too much data, and get RS */ 6252 /* sometimes (calib) we want to do an exact read */ 6253 if(exact && bytes > remain){ 6254 bytes = remain; 6255 } 6256 6257 DBG(15, "read_from_scanner_duplex: re:%lu bu:%d pa:%lu ex:%d\n", 6258 (unsigned long)remain, s->buffer_size, (unsigned long)bytes, exact); 6259 6260 inLen = bytes; 6261 in = malloc(inLen); 6262 if(!in){ 6263 DBG(5, "read_from_scanner_duplex: not enough mem for buffer: %d\n", 6264 (int)inLen); 6265 return SANE_STATUS_NO_MEM; 6266 } 6267 6268 memset(cmd,0,cmdLen); 6269 set_SCSI_opcode(cmd, READ_code); 6270 set_R_datatype_code (cmd, SR_datatype_image); 6271 6272 set_R_xfer_length (cmd, inLen); 6273 6274 ret = do_cmd ( 6275 s, 1, 0, 6276 cmd, cmdLen, 6277 NULL, 0, 6278 in, &inLen 6279 ); 6280 6281 if (ret == SANE_STATUS_GOOD) { 6282 DBG(15, "read_from_scanner_duplex: got GOOD, returning GOOD %lu\n", (unsigned long)inLen); 6283 } 6284 else if (ret == SANE_STATUS_EOF) { 6285 DBG(15, "read_from_scanner_duplex: got EOF, finishing %lu\n", (unsigned long)inLen); 6286 } 6287 else if (ret == SANE_STATUS_DEVICE_BUSY) { 6288 DBG(5, "read_from_scanner_duplex: got BUSY, returning GOOD\n"); 6289 inLen = 0; 6290 ret = SANE_STATUS_GOOD; 6291 } 6292 else { 6293 DBG(5, "read_from_scanner_duplex: error reading data block status = %d\n", 6294 ret); 6295 inLen = 0; 6296 } 6297 6298 /*scanner may have sent more data than we asked for, chop it*/ 6299 if(inLen > remain){ 6300 inLen = remain; 6301 } 6302 6303 /* we've got some data, descramble and store it */ 6304 if(inLen){ 6305 copy_duplex(s,in,inLen); 6306 } 6307 6308 free(in); 6309 6310 /* we've read all data, but not eof. clear and pretend */ 6311 if(exact && inLen == remain){ 6312 DBG (10, "read_from_scanner_duplex: exact read, clearing\n"); 6313 ret = object_position (s,SANE_FALSE); 6314 if(ret){ 6315 return ret; 6316 } 6317 ret = SANE_STATUS_EOF; 6318 } 6319 6320 if(ret == SANE_STATUS_EOF){ 6321 6322 /* this is jpeg data, we need to change the total size */ 6323 if(s->s.format == SANE_FRAME_JPEG){ 6324 s->s.bytes_tot[SIDE_FRONT] = s->s.bytes_sent[SIDE_FRONT]; 6325 s->s.bytes_tot[SIDE_BACK] = s->s.bytes_sent[SIDE_BACK]; 6326 s->i.bytes_tot[SIDE_FRONT] = s->i.bytes_sent[SIDE_FRONT]; 6327 s->i.bytes_tot[SIDE_BACK] = s->i.bytes_sent[SIDE_BACK]; 6328 s->u.bytes_tot[SIDE_FRONT] = s->i.bytes_sent[SIDE_FRONT]; 6329 s->u.bytes_tot[SIDE_BACK] = s->i.bytes_sent[SIDE_BACK]; 6330 } 6331 6332 /* this is non-jpeg data, fill remainder, change rx'd size */ 6333 else{ 6334 fill_image(s,SIDE_FRONT); 6335 fill_image(s,SIDE_BACK); 6336 } 6337 6338 s->i.eof[SIDE_FRONT] = 1; 6339 s->i.eof[SIDE_BACK] = 1; 6340 s->s.eof[SIDE_FRONT] = 1; 6341 s->s.eof[SIDE_BACK] = 1; 6342 ret = SANE_STATUS_GOOD; 6343 } 6344 6345 DBG (10, "read_from_scanner_duplex: finish\n"); 6346 6347 return ret; 6348} 6349 6350/* these functions copy image data from input buffer to scanner struct 6351 * descrambling it, and putting it in the right side buffer */ 6352/* NOTE: they assume buffer is scanline aligned */ 6353static SANE_Status 6354copy_simplex(struct scanner *s, unsigned char * buf, int len, int side) 6355{ 6356 SANE_Status ret=SANE_STATUS_GOOD; 6357 int i, j; 6358 int bwidth = s->s.Bpl; 6359 int pwidth = s->s.width; 6360 int t = bwidth/3; 6361 int f = bwidth/4; 6362 int tw = bwidth/12; 6363 6364 unsigned char * line = NULL; 6365 int line_next = 0; 6366 int inter = get_color_inter(s,side,s->s.dpi_x); 6367 6368 /* jpeg data should not pass thru this function, so copy and bail out */ 6369 if(s->s.format > SANE_FRAME_RGB){ 6370 DBG (15, "copy_simplex: jpeg bulk copy\n"); 6371 memcpy(s->buffers[side]+s->i.bytes_sent[side], buf, len); 6372 s->i.bytes_sent[side] += len; 6373 s->s.bytes_sent[side] += len; 6374 return ret; 6375 } 6376 6377 DBG (15, "copy_simplex: per-line copy\n"); 6378 6379 line = malloc(bwidth); 6380 if(!line) return SANE_STATUS_NO_MEM; 6381 6382 /* ingest each line */ 6383 for(i=0; i<len; i+=bwidth){ 6384 6385 int lineNum = s->s.bytes_sent[side] / bwidth; 6386 6387 /*increment number of bytes rx'd from scanner*/ 6388 s->s.bytes_sent[side] += bwidth; 6389 6390 /*have some padding from scanner to drop*/ 6391 if ( lineNum < s->i.skip_lines[side] 6392 || lineNum - s->i.skip_lines[side] >= s->i.height 6393 ){ 6394 continue; 6395 } 6396 6397 line_next = 0; 6398 6399 if(s->s.format == SANE_FRAME_GRAY){ 6400 6401 switch (s->gray_interlace[side]) { 6402 6403 /* one line has the following format: ggg...GGG 6404 * where the 'capital' letters are the beginning of the line */ 6405 case GRAY_INTERLACE_gG: 6406 DBG (17, "copy_simplex: gray, gG\n"); 6407 for (j=bwidth-1; j>=0; j--){ 6408 line[line_next++] = buf[i+j]; 6409 } 6410 break; 6411 6412 case GRAY_INTERLACE_2510: 6413 DBG (17, "copy_simplex: gray, 2510\n"); 6414 6415 /* first read head (third byte of every three) */ 6416 for(j=bwidth-1;j>=0;j-=3){ 6417 line[line_next++] = buf[i+j]; 6418 } 6419 /* second read head (first byte of every three) */ 6420 for(j=bwidth*3/4-3;j>=0;j-=3){ 6421 line[line_next++] = buf[i+j]; 6422 } 6423 /* third read head (second byte of every three) */ 6424 for(j=bwidth-2;j>=0;j-=3){ 6425 line[line_next++] = buf[i+j]; 6426 } 6427 /* padding */ 6428 for(j=0;j<tw;j++){ 6429 line[line_next++] = 0; 6430 } 6431 break; 6432 6433 case GRAY_INTERLACE_C120: 6434 DBG (17, "copy_simplex: gray, C120\n"); 6435 6436 /* first read head (third byte of every three) */ 6437 for(j=bwidth-1;j>=0;j-=3){ 6438 line[line_next++] = buf[i+j]; 6439 } 6440 /* second read head (first byte of every three) */ 6441 for(j=bwidth-3;j>=0;j-=3){ 6442 line[line_next++] = buf[i+j]; 6443 } 6444 /* third read head (second byte of every three) */ 6445 for(j=bwidth-2;j>=0;j-=3){ 6446 line[line_next++] = buf[i+j]; 6447 } 6448 break; 6449 } 6450 } 6451 6452 else if (s->s.format == SANE_FRAME_RGB){ 6453 6454 switch (inter) { 6455 6456 /* scanner returns color data as bgrbgr... */ 6457 case COLOR_INTERLACE_BGR: 6458 DBG (17, "copy_simplex: color, BGR\n"); 6459 for (j=0; j<pwidth; j++){ 6460 line[line_next++] = buf[i+j*3+2]; 6461 line[line_next++] = buf[i+j*3+1]; 6462 line[line_next++] = buf[i+j*3]; 6463 } 6464 break; 6465 6466 /* scanner returns color data as gbrgbr... */ 6467 case COLOR_INTERLACE_GBR: 6468 DBG (17, "copy_simplex: color, GBR\n"); 6469 for (j=0; j<pwidth; j++){ 6470 line[line_next++] = buf[i+j*3+2]; 6471 line[line_next++] = buf[i+j*3]; 6472 line[line_next++] = buf[i+j*3+1]; 6473 } 6474 break; 6475 6476 /* scanner returns color data as brgbrg... */ 6477 case COLOR_INTERLACE_BRG: 6478 DBG (17, "copy_simplex: color, BRG\n"); 6479 for (j=0; j<pwidth; j++){ 6480 line[line_next++] = buf[i+j*3+1]; 6481 line[line_next++] = buf[i+j*3+2]; 6482 line[line_next++] = buf[i+j*3]; 6483 } 6484 break; 6485 6486 /* one line has the following format: RRR...rrrGGG...gggBBB...bbb */ 6487 case COLOR_INTERLACE_RRGGBB: 6488 DBG (17, "copy_simplex: color, RRGGBB\n"); 6489 for (j=0; j<pwidth; j++){ 6490 line[line_next++] = buf[i+j]; 6491 line[line_next++] = buf[i+pwidth+j]; 6492 line[line_next++] = buf[i+2*pwidth+j]; 6493 } 6494 break; 6495 6496 /* one line has the following format: rrr...RRRggg...GGGbbb...BBB 6497 * where the 'capital' letters are the beginning of the line */ 6498 case COLOR_INTERLACE_rRgGbB: 6499 DBG (17, "copy_simplex: color, rRgGbB\n"); 6500 for (j=pwidth-1; j>=0; j--){ 6501 line[line_next++] = buf[i+j]; 6502 line[line_next++] = buf[i+pwidth+j]; 6503 line[line_next++] = buf[i+2*pwidth+j]; 6504 } 6505 break; 6506 6507 case COLOR_INTERLACE_2510: 6508 DBG (17, "copy_simplex: color, 2510\n"); 6509 6510 /* first read head (third byte of every three) */ 6511 for(j=t-1;j>=0;j-=3){ 6512 line[line_next++] = buf[i+j]; 6513 line[line_next++] = buf[i+t+j]; 6514 line[line_next++] = buf[i+2*t+j]; 6515 } 6516 /* second read head (first byte of every three) */ 6517 for(j=f-3;j>=0;j-=3){ 6518 line[line_next++] = buf[i+j]; 6519 line[line_next++] = buf[i+t+j]; 6520 line[line_next++] = buf[i+2*t+j]; 6521 } 6522 /* third read head (second byte of every three) */ 6523 for(j=t-2;j>=0;j-=3){ 6524 line[line_next++] = buf[i+j]; 6525 line[line_next++] = buf[i+t+j]; 6526 line[line_next++] = buf[i+2*t+j]; 6527 } 6528 /* padding */ 6529 for(j=0;j<tw;j++){ 6530 line[line_next++] = 0; 6531 } 6532 break; 6533 6534 case COLOR_INTERLACE_C120: 6535 DBG (17, "copy_simplex: color, C120\n"); 6536 6537 /* first read head (third byte of every three) */ 6538 for(j=t-1;j>=0;j-=3){ 6539 line[line_next++] = buf[i+j]; 6540 line[line_next++] = buf[i+t+j]; 6541 line[line_next++] = buf[i+2*t+j]; 6542 } 6543 /* second read head (first byte of every three) */ 6544 for(j=t-3;j>=0;j-=3){ 6545 line[line_next++] = buf[i+j]; 6546 line[line_next++] = buf[i+t+j]; 6547 line[line_next++] = buf[i+2*t+j]; 6548 } 6549 /* third read head (second byte of every three) */ 6550 for(j=t-2;j>=0;j-=3){ 6551 line[line_next++] = buf[i+j]; 6552 line[line_next++] = buf[i+t+j]; 6553 line[line_next++] = buf[i+2*t+j]; 6554 } 6555 break; 6556 } 6557 } 6558 6559 /* nothing sent above? just copy one line of the block */ 6560 /* used by uninterlaced gray/color */ 6561 if(!line_next){ 6562 DBG (17, "copy_simplex: default\n"); 6563 memcpy(line+line_next,buf+i,bwidth); 6564 line_next = bwidth; 6565 } 6566 6567 /* invert image if scanner needs it for this mode */ 6568 if(s->reverse_by_mode[s->s.mode]){ 6569 for(j=0; j<line_next; j++){ 6570 line[j] ^= 0xff; 6571 } 6572 } 6573 6574 /* apply calibration if we have it */ 6575 if(s->f_offset[side]){ 6576 DBG (17, "copy_simplex: apply offset\n"); 6577 for(j=0; j<s->s.valid_Bpl; j++){ 6578 int curr = line[j] - s->f_offset[side][j]; 6579 if(curr < 0) curr = 0; 6580 line[j] = curr; 6581 } 6582 } 6583 6584 if(s->f_gain[side]){ 6585 DBG (17, "copy_simplex: apply gain\n"); 6586 for(j=0; j<s->s.valid_Bpl; j++){ 6587 int curr = line[j] * 240/s->f_gain[side][j]; 6588 if(curr > 255) curr = 255; 6589 line[j] = curr; 6590 } 6591 } 6592 6593 /* apply brightness and contrast if hardware cannot do it */ 6594 if(s->sw_lut && (s->s.mode == MODE_COLOR || s->s.mode == MODE_GRAYSCALE)){ 6595 DBG (17, "copy_simplex: apply brightness/contrast\n"); 6596 for(j=0; j<s->s.valid_Bpl; j++){ 6597 line[j] = s->lut[line[j]]; 6598 } 6599 } 6600 6601 /*copy the line into the buffer*/ 6602 ret = copy_line(s,line,side); 6603 if(ret){ 6604 break; 6605 } 6606 } 6607 6608 free(line); 6609 6610 DBG (10, "copy_simplex: finished\n"); 6611 6612 return ret; 6613} 6614 6615/* split the data between two buffers, hand them to copy_simplex() 6616 * assumes that the buffer aligns to a double-wide line boundary */ 6617static SANE_Status 6618copy_duplex(struct scanner *s, unsigned char * buf, int len) 6619{ 6620 SANE_Status ret=SANE_STATUS_GOOD; 6621 int i,j; 6622 int pwidth = s->s.width; 6623 int bwidth = s->s.Bpl; 6624 int dbwidth = 2*bwidth; 6625 unsigned char * front; 6626 unsigned char * back; 6627 int flen=0, blen=0; 6628 6629 DBG (10, "copy_duplex: start\n"); 6630 6631 /*split the input into two simplex output buffers*/ 6632 front = calloc(1,len/2); 6633 if(!front){ 6634 DBG (5, "copy_duplex: no front mem\n"); 6635 return SANE_STATUS_NO_MEM; 6636 } 6637 back = calloc(1,len/2); 6638 if(!back){ 6639 DBG (5, "copy_duplex: no back mem\n"); 6640 free(front); 6641 return SANE_STATUS_NO_MEM; 6642 } 6643 6644 if(s->duplex_interlace == DUPLEX_INTERLACE_2510){ 6645 6646 DBG (10, "copy_duplex: 2510\n"); 6647 6648 for(i=0; i<len; i+=dbwidth){ 6649 6650 for(j=0;j<dbwidth;j+=6){ 6651 6652 /* we are actually only partially descrambling, 6653 * copy_simplex() does the rest */ 6654 6655 /* front */ 6656 /* 2nd head: 2nd byte -> 1st byte */ 6657 /* 3rd head: 4th byte -> 2nd byte */ 6658 /* 1st head: 5th byte -> 3rd byte */ 6659 front[flen++] = buf[i+j+2]; 6660 front[flen++] = buf[i+j+4]; 6661 front[flen++] = buf[i+j+5]; 6662 6663 /* back */ 6664 /* 2nd head: 3rd byte -> 1st byte */ 6665 /* 3rd head: 0th byte -> 2nd byte */ 6666 /* 1st head: 1st byte -> 3rd byte */ 6667 back[blen++] = buf[i+j+3]; 6668 back[blen++] = buf[i+j]; 6669 back[blen++] = buf[i+j+1]; 6670 } 6671 } 6672 } 6673 6674 /* line is in 6 sections, front red, back red, front green, etc. */ 6675 else if(s->duplex_interlace == DUPLEX_INTERLACE_PER_CHANNEL){ 6676 6677 DBG (10, "copy_duplex: per channel\n"); 6678 6679 for(i=0; i<len; i+=dbwidth){ 6680 for(j=0;j<3;j++){ 6681 memcpy(front+flen,buf+i+j*pwidth*2,pwidth); 6682 flen+=pwidth; 6683 memcpy(back+blen,buf+i+j*pwidth*2+pwidth,pwidth); 6684 blen+=pwidth; 6685 } 6686 } 6687 } 6688 6689 /* full line of front, then full line of back */ 6690 else if(s->duplex_interlace == DUPLEX_INTERLACE_FfBb || s->duplex_interlace == DUPLEX_INTERLACE_fFBb){ 6691 for(i=0; i<len; i+=dbwidth){ 6692 if(s->duplex_interlace == DUPLEX_INTERLACE_FfBb){ 6693 memcpy(front+flen,buf+i,bwidth); 6694 }else{ 6695 rmemcpy(front+flen,buf+i,bwidth,3); // only 24bit color is supported 6696 } 6697 flen+=bwidth; 6698 memcpy(back+blen,buf+i+bwidth,bwidth); 6699 blen+=bwidth; 6700 } 6701 } 6702 6703 /*just alternating bytes, FBfb*/ 6704 else { 6705 for(i=0; i<len; i+=2){ 6706 front[flen++] = buf[i]; 6707 back[blen++] = buf[i+1]; 6708 } 6709 } 6710 6711 copy_simplex(s,front,flen,SIDE_FRONT); 6712 copy_simplex(s,back,blen,SIDE_BACK); 6713 6714 free(front); 6715 free(back); 6716 6717 DBG (10, "copy_duplex: finished\n"); 6718 6719 return ret; 6720} 6721 6722/* 6723 * Reverse memcpy designed to mirror a line of data. 6724 * Use stride size to account for the number of bytes per pixel 6725 */ 6726static void rmemcpy(void* dest, const void* src, size_t count, size_t stride) { 6727 char* dstptr = (char*)dest; 6728 char* srcptr = (char*)src; 6729 srcptr += count; 6730 while (count) { 6731 srcptr -= stride; 6732 memcpy(dstptr, srcptr, stride); 6733 dstptr += stride; 6734 count -= stride; 6735 } 6736} 6737 6738/* downsample a single line from scanner's size to user's size */ 6739/* and copy into final buffer */ 6740static SANE_Status 6741copy_line(struct scanner *s, unsigned char * buff, int side) 6742{ 6743 SANE_Status ret=SANE_STATUS_GOOD; 6744 int spwidth = s->s.width; 6745 int sbwidth = s->s.Bpl; 6746 int ibwidth = s->i.Bpl; 6747 unsigned char * line; 6748 int offset = 0; 6749 int i, j; 6750 6751 DBG (20, "copy_line: start\n"); 6752 6753 /* the 'standard' case: non-stupid scan */ 6754 if(s->s.width == s->i.width 6755 && s->s.dpi_x == s->i.dpi_x 6756 && s->s.mode == s->i.mode 6757 ){ 6758 6759 memcpy(s->buffers[side]+s->i.bytes_sent[side], buff, sbwidth); 6760 s->i.bytes_sent[side] += sbwidth; 6761 6762 DBG (20, "copy_line: finished smart\n"); 6763 return ret; 6764 } 6765 6766 /* the 'corner' case: stupid scan */ 6767 6768 /*setup 24 bit color single line buffer*/ 6769 line = malloc(spwidth*3); 6770 if(!line) return SANE_STATUS_NO_MEM; 6771 6772 /*load single line color buffer*/ 6773 switch (s->s.mode) { 6774 6775 case MODE_COLOR: 6776 if(must_downsample(s) && s->dropout_color[side]){ 6777 switch(s->dropout_color[side]){ 6778 case COLOR_RED: 6779 for(i=0;i<spwidth;i++) 6780 line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3]; 6781 break; 6782 case COLOR_GREEN: 6783 for(i=0;i<spwidth;i++) 6784 line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3+1]; 6785 break; 6786 case COLOR_BLUE: 6787 for(i=0;i<spwidth;i++) 6788 line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3+2]; 6789 break; 6790 case COLOR_EN_RED: 6791 for(i=0;i<spwidth;i++){ 6792 line[i*3] = (buff[i*3+1] + buff[i*3+2])/2; 6793 line[i*3+1] = buff[i*3+1]; 6794 line[i*3+2] = buff[i*3+2]; 6795 } 6796 break; 6797 case COLOR_EN_GREEN: 6798 for(i=0;i<spwidth;i++){ 6799 line[i*3] = buff[i*3]; 6800 line[i*3+1] = (buff[i*3] + buff[i*3+2])/2; 6801 line[i*3+2] = buff[i*3+2]; 6802 } 6803 break; 6804 case COLOR_EN_BLUE: 6805 for(i=0;i<spwidth;i++){ 6806 line[i*3] = buff[i*3]; 6807 line[i*3+1] = buff[i*3+1]; 6808 line[i*3+2] = (buff[i*3] + buff[i*3+1])/2; 6809 } 6810 break; 6811 } 6812 } 6813 else{ 6814 memcpy(line, buff, sbwidth); 6815 } 6816 break; 6817 6818 case MODE_GRAYSCALE: 6819 for(i=0;i<spwidth;i++){ 6820 line[i*3] = line[i*3+1] = line[i*3+2] = buff[i]; 6821 } 6822 break; 6823 6824 default: 6825 for(i=0;i<sbwidth;i++){ 6826 unsigned char curr = buff[i]; 6827 6828 line[i*24+0] = line[i*24+1] = line[i*24+2] = ((curr >> 7) & 1) ?0:255; 6829 line[i*24+3] = line[i*24+4] = line[i*24+5] = ((curr >> 6) & 1) ?0:255; 6830 line[i*24+6] = line[i*24+7] = line[i*24+8] = ((curr >> 5) & 1) ?0:255; 6831 line[i*24+9] = line[i*24+10] = line[i*24+11] = ((curr >> 4) & 1) ?0:255; 6832 line[i*24+12] = line[i*24+13] = line[i*24+14] =((curr >> 3) & 1) ?0:255; 6833 line[i*24+15] = line[i*24+16] = line[i*24+17] =((curr >> 2) & 1) ?0:255; 6834 line[i*24+18] = line[i*24+19] = line[i*24+20] =((curr >> 1) & 1) ?0:255; 6835 line[i*24+21] = line[i*24+22] = line[i*24+23] =((curr >> 0) & 1) ?0:255; 6836 } 6837 break; 6838 } 6839 6840 /* scan is higher res than user wanted, scale it */ 6841 /*FIXME: interpolate instead */ 6842 if(s->i.dpi_x != s->s.dpi_x){ 6843 for(i=0;i<spwidth;i++){ 6844 int source = i * s->s.dpi_x/s->i.dpi_x * 3; 6845 6846 if(source+2 >= spwidth*3) 6847 break; 6848 6849 line[i*3] = line[source]; 6850 line[i*3+1] = line[source+1]; 6851 line[i*3+2] = line[source+2]; 6852 } 6853 } 6854 6855 /* scan is wider than user wanted, skip some pixels on left side */ 6856 if(s->i.width != s->s.width){ 6857 offset = ((s->valid_x-s->i.page_x) / 2 + s->i.tl_x) * s->i.dpi_x/1200; 6858 } 6859 6860 /* change mode, store line in buffer */ 6861 switch (s->i.mode) { 6862 6863 case MODE_COLOR: 6864 memcpy(s->buffers[side]+s->i.bytes_sent[side], line+(offset*3), ibwidth); 6865 s->i.bytes_sent[side] += ibwidth; 6866 break; 6867 6868 case MODE_GRAYSCALE: 6869 for(i=0;i<ibwidth;i++){ 6870 int source = (offset+i)*3; 6871 s->buffers[side][s->i.bytes_sent[side]++] 6872 = ((int)line[source] + line[source+1] + line[source+2])/3; 6873 } 6874 break; 6875 6876 default: 6877 /*loop over output bytes*/ 6878 for(i=0;i<ibwidth;i++){ 6879 6880 unsigned char curr = 0; 6881 int thresh = s->threshold*3; 6882 6883 /*loop over output bits*/ 6884 for(j=0;j<8;j++){ 6885 int source = offset*3 + i*24 + j*3; 6886 if( (line[source] + line[source+1] + line[source+2]) < thresh ){ 6887 curr |= 1 << (7-j); 6888 } 6889 } 6890 6891 s->buffers[side][s->i.bytes_sent[side]++] = curr; 6892 } 6893 break; 6894 } 6895 6896 free(line); 6897 6898 DBG (20, "copy_line: finish stupid\n"); 6899 6900 return ret; 6901} 6902 6903static SANE_Status 6904read_from_buffer(struct scanner *s, SANE_Byte * buf, SANE_Int max_len, 6905 SANE_Int * len, int side) 6906{ 6907 SANE_Status ret=SANE_STATUS_GOOD; 6908 int bytes = max_len; 6909 int remain = s->i.bytes_sent[side] - s->u.bytes_sent[side]; 6910 6911 DBG (10, "read_from_buffer: start\n"); 6912 6913 /* figure out the max amount to transfer */ 6914 if(bytes > remain) 6915 bytes = remain; 6916 6917 *len = bytes; 6918 6919 /*FIXME this needs to timeout eventually */ 6920 if(!bytes){ 6921 DBG(5,"read_from_buffer: nothing to do\n"); 6922 return SANE_STATUS_GOOD; 6923 } 6924 6925 DBG(15, "read_from_buffer: si:%d to:%d tx:%d bu:%d pa:%d\n", side, 6926 s->i.bytes_tot[side], s->u.bytes_sent[side], max_len, bytes); 6927 6928 /* copy to caller */ 6929 memcpy(buf,s->buffers[side]+s->u.bytes_sent[side],bytes); 6930 s->u.bytes_sent[side] += bytes; 6931 6932 DBG (10, "read_from_buffer: finished\n"); 6933 6934 return ret; 6935} 6936 6937/* fill remainder of buffer with background if scanner stops early */ 6938static SANE_Status 6939fill_image(struct scanner *s,int side) 6940{ 6941 SANE_Status ret=SANE_STATUS_GOOD; 6942 6943 unsigned char bg_color = calc_bg_color(s); 6944 int fill_bytes = s->i.bytes_tot[side]-s->i.bytes_sent[side]; 6945 6946 if(!fill_bytes){ 6947 return ret; 6948 } 6949 6950 DBG (15, "fill_image: side:%d bytes:%d bg_color:%02x\n", side, fill_bytes, bg_color); 6951 6952 /* fill the rest with bg_color */ 6953 memset(s->buffers[side]+s->i.bytes_sent[side],bg_color,fill_bytes); 6954 6955 /* pretend we got all the data from scanner */ 6956 s->i.bytes_sent[side] = s->i.bytes_tot[side]; 6957 s->s.bytes_sent[side] = s->s.bytes_tot[side]; 6958 6959 return ret; 6960} 6961 6962/* return the bg color based on scanner settings */ 6963static unsigned char 6964calc_bg_color(struct scanner *s) 6965{ 6966 unsigned char bg_color = s->lut[s->bg_color]; 6967 6968 if(s->u.mode <= MODE_HALFTONE) 6969 bg_color = (bg_color<s->threshold)?0xff:0x00; 6970 6971 return bg_color; 6972} 6973 6974/* 6975 * @@ Section 5 - calibration functions 6976 */ 6977 6978#if 0 6979static SANE_Status 6980foo_AFE(struct scanner *s) 6981{ 6982 SANE_Status ret = SANE_STATUS_GOOD; 6983 6984 unsigned char cmd[] = { 6985 0x3b, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 6986 }; 6987 size_t cmdLen = 12; 6988 6989 unsigned char in[4]; 6990 size_t inLen = 4; 6991 6992 DBG (10, "foo_AFE: start\n"); 6993 6994 ret = do_cmd ( 6995 s, 1, 0, 6996 cmd, cmdLen, 6997 NULL, 0, 6998 in, &inLen 6999 ); 7000 if (ret != SANE_STATUS_GOOD) 7001 return ret; 7002 7003 DBG (10, "foo_AFE: finish\n"); 7004 7005 return ret; 7006} 7007#endif 7008 7009/* 7010 * makes several scans, adjusts coarse calibration 7011 */ 7012static SANE_Status 7013calibrate_AFE (struct scanner *s) 7014{ 7015 SANE_Status ret = SANE_STATUS_GOOD; 7016 int i, j, k; 7017 int min, max; 7018 int lines = 8; 7019 7020 /*buffer these for later*/ 7021 int old_tl_y = s->u.tl_y; 7022 int old_br_y = s->u.br_y; 7023 int old_mode = s->u.mode; 7024 int old_source = s->u.source; 7025 7026 DBG (10, "calibrate_AFE: start\n"); 7027 7028 if(!s->need_ccal){ 7029 DBG (10, "calibrate_AFE: not required\n"); 7030 return ret; 7031 } 7032 7033 /* always cal with a short scan in duplex color */ 7034 s->u.tl_y = 0; 7035 s->u.br_y = lines * 1200 / s->u.dpi_y; 7036 s->u.mode = MODE_COLOR; 7037 s->u.source = SOURCE_ADF_DUPLEX; 7038 7039 /* load our own private copy of scan params */ 7040 ret = update_params(s,1); 7041 if (ret != SANE_STATUS_GOOD) { 7042 DBG (5, "calibrate_AFE: ERROR: cannot update_params\n"); 7043 goto cleanup; 7044 } 7045 7046 if(s->c_res == s->s.dpi_x && s->c_mode == s->s.mode){ 7047 DBG (10, "calibrate_AFE: already done\n"); 7048 goto cleanup; 7049 } 7050 7051 /* clean scan params for new scan */ 7052 ret = clean_params(s); 7053 if (ret != SANE_STATUS_GOOD) { 7054 DBG (5, "calibrate_AFE: ERROR: cannot clean_params\n"); 7055 goto cleanup; 7056 } 7057 7058 /* make buffers to hold the images */ 7059 ret = image_buffers(s,1); 7060 if (ret != SANE_STATUS_GOOD) { 7061 DBG (5, "calibrate_AFE: ERROR: cannot load buffers\n"); 7062 goto cleanup; 7063 } 7064 7065 /*blast the existing fine cal data so reading code won't apply it*/ 7066 ret = offset_buffers(s,0); 7067 ret = gain_buffers(s,0); 7068 7069 /* need to tell it we want duplex */ 7070 ret = ssm_buffer(s); 7071 if (ret != SANE_STATUS_GOOD) { 7072 DBG (5, "calibrate_AFE: ERROR: cannot ssm buffer\n"); 7073 goto cleanup; 7074 } 7075 7076 /* set window command */ 7077 ret = set_window(s); 7078 if (ret != SANE_STATUS_GOOD) { 7079 DBG (5, "calibrate_AFE: ERROR: cannot set window\n"); 7080 goto cleanup; 7081 } 7082 7083 /* first pass (black offset), lamp off, no offset/gain/exposure */ 7084 DBG (15, "calibrate_AFE: offset\n"); 7085 7086 /* blast all the existing coarse cal data */ 7087 for(i=0;i<2;i++){ 7088 s->c_gain[i] = 1; 7089 s->c_offset[i] = 1; 7090 for(j=0;j<3;j++){ 7091 s->c_exposure[i][j] = 0; 7092 } 7093 } 7094 7095 ret = write_AFE(s); 7096 if (ret != SANE_STATUS_GOOD) { 7097 DBG (5, "calibrate_AFE: ERROR: cannot write afe\n"); 7098 goto cleanup; 7099 } 7100 7101 ret = calibration_scan(s,0xff); 7102 if (ret != SANE_STATUS_GOOD) { 7103 DBG (5, "calibrate_AFE: ERROR: cannot make offset cal scan\n"); 7104 goto cleanup; 7105 } 7106 7107 for(i=0;i<2;i++){ 7108 min = 255; 7109 for(j=0; j<s->s.valid_Bpl; j++){ 7110 if(s->buffers[i][j] < min) 7111 min = s->buffers[i][j]; 7112 } 7113 s->c_offset[i] = min*3-2; 7114 DBG (15, "calibrate_AFE: offset %d %d %02x\n", i, min, s->c_offset[i]); 7115 } 7116 7117 /*handle second pass (per channel exposure), lamp on, overexposed*/ 7118 DBG (15, "calibrate_AFE: exposure\n"); 7119 for(i=0;i<2;i++){ 7120 for(j=0; j<3; j++){ 7121 s->c_exposure[i][j] = 0x320; 7122 } 7123 } 7124 7125 ret = write_AFE(s); 7126 if (ret != SANE_STATUS_GOOD) { 7127 DBG (5, "calibrate_AFE: ERROR: cannot write afe\n"); 7128 goto cleanup; 7129 } 7130 7131 ret = calibration_scan(s,0xfe); 7132 if (ret != SANE_STATUS_GOOD) { 7133 DBG (5, "calibrate_AFE: ERROR: cannot make exposure cal scan\n"); 7134 goto cleanup; 7135 } 7136 7137 for(i=0;i<2;i++){ /*sides*/ 7138 for(j=0;j<3;j++){ /*channels*/ 7139 max = 0; 7140 for(k=j; k<s->s.valid_Bpl; k+=3){ /*bytes*/ 7141 if(s->buffers[i][k] > max) 7142 max = s->buffers[i][k]; 7143 } 7144 7145 /*generally we reduce the exposure (smaller number) */ 7146 if(old_mode == MODE_COLOR) 7147 s->c_exposure[i][j] = s->c_exposure[i][j] * 102/max; 7148 else 7149 s->c_exposure[i][j] = s->c_exposure[i][j] * 64/max; 7150 7151 DBG (15, "calibrate_AFE: exp %d %d %d %02x\n", i, j, max, 7152 s->c_exposure[i][j]); 7153 } 7154 } 7155 7156 /*handle third pass (gain), lamp on with current offset/exposure */ 7157 DBG (15, "calibrate_AFE: gain\n"); 7158 7159 ret = write_AFE(s); 7160 if (ret != SANE_STATUS_GOOD) { 7161 DBG (5, "calibrate_AFE: ERROR: cannot write afe\n"); 7162 goto cleanup; 7163 } 7164 7165 ret = calibration_scan(s,0xfe); 7166 if (ret != SANE_STATUS_GOOD) { 7167 DBG (5, "calibrate_AFE: ERROR: cannot make gain cal scan\n"); 7168 goto cleanup; 7169 } 7170 7171 for(i=0;i<2;i++){ 7172 max = 0; 7173 for(j=0; j<s->s.valid_Bpl; j++){ 7174 if(s->buffers[i][j] > max) 7175 max = s->buffers[i][j]; 7176 } 7177 7178 if(old_mode == MODE_COLOR) 7179 s->c_gain[i] = (250-max)*4/5; 7180 else 7181 s->c_gain[i] = (125-max)*4/5; 7182 7183 if(s->c_gain[i] < 1) 7184 s->c_gain[i] = 1; 7185 7186 DBG (15, "calibrate_AFE: gain %d %d %02x\n", i, max, s->c_gain[i]); 7187 } 7188 7189 /*handle fourth pass (offset again), lamp off*/ 7190#if 0 7191 DBG (15, "calibrate_AFE: offset2\n"); 7192 7193 ret = write_AFE(s); 7194 if (ret != SANE_STATUS_GOOD) { 7195 DBG (5, "calibrate_AFE: ERROR: cannot write afe\n"); 7196 goto cleanup; 7197 } 7198 7199 ret = calibration_scan(s,0xff); 7200 if (ret != SANE_STATUS_GOOD) { 7201 DBG (5, "calibrate_AFE: ERROR: cannot make offset2 cal scan\n"); 7202 goto cleanup; 7203 } 7204 7205 for(i=0;i<2;i++){ 7206 min = 255; 7207 for(j=0; j<s->s.valid_Bpl; j++){ 7208 if(s->buffers[i][j] < min) 7209 min = s->buffers[i][j]; 7210 } 7211 /*s->c_offset[i] += min*3-2;*/ 7212 DBG (15, "calibrate_AFE: offset2 %d %d %02x\n", i, min, s->c_offset[i]); 7213 } 7214#endif 7215 7216 /*send final afe params to scanner*/ 7217 ret = write_AFE(s); 7218 if (ret != SANE_STATUS_GOOD) { 7219 DBG (5, "calibrate_AFE: ERROR: cannot write afe\n"); 7220 goto cleanup; 7221 } 7222 7223 /* log current cal type */ 7224 s->c_res = s->s.dpi_x; 7225 s->c_mode = s->s.mode; 7226 7227 cleanup: 7228 7229 /* recover user settings */ 7230 s->u.tl_y = old_tl_y; 7231 s->u.br_y = old_br_y; 7232 s->u.mode = old_mode; 7233 s->u.source = old_source; 7234 7235 DBG (10, "calibrate_AFE: finish %d\n",ret); 7236 7237 return ret; 7238} 7239 7240/* 7241 * fine calibration produces a per-cell offset and gain value, 7242 * which is then used to adjust the output from the scanner. 7243 * There is quite a bit of variation here, with different models 7244 * needing different types/amounts of help from the software. 7245 * 7246 * This function is a common entry point for all variations. 7247 */ 7248static SANE_Status 7249calibrate_fine (struct scanner *s) 7250{ 7251 SANE_Status ret = SANE_STATUS_GOOD; 7252 7253 DBG (10, "calibrate_fine: start\n"); 7254 7255 if(s->fcal_src == FCAL_SRC_NONE || s->fcal_dest == FCAL_DEST_NONE){ 7256 DBG (10, "calibrate_fine: not required\n"); 7257 goto cleanup; 7258 } 7259 7260 /* don't recalibrate if we've already done it with these params */ 7261 if(s->f_res == s->s.dpi_x && s->f_mode == s->s.mode){ 7262 DBG (10, "calibrate_fine: already done\n"); 7263 goto cleanup; 7264 } 7265 7266 /* get calibration data from scanner memory */ 7267 if(s->fcal_src == FCAL_SRC_HW){ 7268 ret = calibrate_fine_src_hw(s); 7269 if (ret != SANE_STATUS_GOOD) 7270 goto cleanup; 7271 } 7272 7273 /* get calibration data by making scans */ 7274 if(s->fcal_src == FCAL_SRC_SCAN){ 7275 ret = calibrate_fine_src_scan(s); 7276 if (ret != SANE_STATUS_GOOD) 7277 goto cleanup; 7278 } 7279 7280 /* send calibration data to scanner */ 7281 if(s->fcal_dest == FCAL_DEST_HW){ 7282 ret = calibrate_fine_dest_hw(s); 7283 if (ret != SANE_STATUS_GOOD) 7284 goto cleanup; 7285 } 7286 7287 /* log current cal settings so we won't recalibrate on next scan with same params */ 7288 s->f_res = s->s.dpi_x; 7289 s->f_mode = s->s.mode; 7290 7291 cleanup: 7292 7293 DBG (10, "calibrate_fine: finish %d\n",ret); 7294 7295 return ret; 7296} 7297 7298 7299/* extracts fine calibration data from scanner memory */ 7300static SANE_Status 7301calibrate_fine_src_hw (struct scanner *s) 7302{ 7303 SANE_Status ret = SANE_STATUS_GOOD; 7304 int i, j, k; 7305 7306 unsigned char cmd[READ_len]; 7307 size_t cmdLen = READ_len; 7308 7309 unsigned char * in = NULL; 7310 size_t inLen = 0, reqLen = 0; 7311 7312 /*buffer these for later*/ 7313 int old_tl_y = s->u.tl_y; 7314 int old_br_y = s->u.br_y; 7315 int old_source = s->u.source; 7316 7317 DBG (10, "calibrate_fine_src_hw: start\n"); 7318 7319 /* pretend we are doing a 1 line scan in duplex */ 7320 s->u.tl_y = 0; 7321 s->u.br_y = 1200 / s->u.dpi_y; 7322 s->u.source = SOURCE_ADF_DUPLEX; 7323 7324 /* load our own private copy of scan params */ 7325 ret = update_params(s,1); 7326 if (ret != SANE_STATUS_GOOD) { 7327 DBG (5, "calibrate_fine_src_hw: ERROR: cannot update_params\n"); 7328 goto cleanup; 7329 } 7330 7331 /* clean scan params for new scan */ 7332 ret = clean_params(s); 7333 if (ret != SANE_STATUS_GOOD) { 7334 DBG (5, "calibrate_fine_src_hw: ERROR: cannot clean_params\n"); 7335 goto cleanup; 7336 } 7337 7338 /*calibration buffers in scanner are single color channel, but duplex*/ 7339 reqLen = s->s.width*2; 7340 7341 in = malloc(reqLen); 7342 if (!in) { 7343 DBG (5, "calibrate_fine_src_hw: ERROR: cannot malloc in\n"); 7344 ret = SANE_STATUS_NO_MEM; 7345 goto cleanup; 7346 } 7347 7348 /*fine offset*/ 7349 ret = offset_buffers(s,1); 7350 if (ret != SANE_STATUS_GOOD) { 7351 DBG (5, "calibrate_fine_src_hw: ERROR: cannot load offset buffers\n"); 7352 goto cleanup; 7353 } 7354 7355 DBG (10, "calibrate_fine_src_hw: %d %x\n", s->s.dpi_x/10, s->s.dpi_x/10); 7356 7357 memset(cmd,0,cmdLen); 7358 set_SCSI_opcode(cmd, READ_code); 7359 set_R_datatype_code (cmd, SR_datatype_fineoffset); 7360 set_R_xfer_lid (cmd, s->s.dpi_x/10); 7361 set_R_xfer_length (cmd, reqLen); 7362 7363 inLen = reqLen; 7364 7365 ret = do_cmd ( 7366 s, 1, 0, 7367 cmd, cmdLen, 7368 NULL, 0, 7369 in, &inLen 7370 ); 7371 if (ret != SANE_STATUS_GOOD) 7372 goto cleanup; 7373 7374 for(i=0;i<2;i++){ 7375 7376 /*color mode, expand offset across all three channels? */ 7377 if(s->s.format == SANE_FRAME_RGB){ 7378 for(j=0; j<s->s.valid_width; j++){ 7379 7380 /*red*/ 7381 s->f_offset[i][j*3] = in[j*2+i]; 7382 if(s->f_offset[i][j*3] < 1) 7383 s->f_offset[i][j*3] = 1; 7384 7385 /*green and blue, same as red*/ 7386 s->f_offset[i][j*3+1] = s->f_offset[i][j*3+2] = s->f_offset[i][j*3]; 7387 } 7388 } 7389 7390 /*gray mode, copy*/ 7391 else{ 7392 for(j=0; j<s->s.valid_width; j++){ 7393 7394 s->f_offset[i][j] = in[j*2+i]; 7395 if(s->f_offset[i][j] < 1) 7396 s->f_offset[i][j] = 1; 7397 } 7398 } 7399 } 7400 7401 /*fine gain*/ 7402 ret = gain_buffers(s,1); 7403 if (ret != SANE_STATUS_GOOD) { 7404 DBG (5, "calibrate_fine_src_hw: ERROR: cannot load gain buffers\n"); 7405 goto cleanup; 7406 } 7407 7408 memset(cmd,0,cmdLen); 7409 set_SCSI_opcode(cmd, READ_code); 7410 set_R_datatype_code (cmd, SR_datatype_finegain); 7411 set_R_xfer_lid (cmd, s->s.dpi_x/10); 7412 set_R_xfer_length (cmd, reqLen); 7413 7414 /*color gain split into three buffers, grab them and merge*/ 7415 if(s->s.format == SANE_FRAME_RGB){ 7416 7417 int codes[] = {R_FINE_uid_red,R_FINE_uid_green,R_FINE_uid_blue}; 7418 7419 for(k=0;k<3;k++){ 7420 7421 set_R_xfer_uid (cmd, codes[k]); 7422 inLen = reqLen; 7423 7424 ret = do_cmd ( 7425 s, 1, 0, 7426 cmd, cmdLen, 7427 NULL, 0, 7428 in, &inLen 7429 ); 7430 if (ret != SANE_STATUS_GOOD) 7431 goto cleanup; 7432 7433 for(i=0;i<2;i++){ 7434 for(j=0; j<s->s.valid_width; j++){ 7435 7436 s->f_gain[i][j*3+k] = in[j*2+i]*3/4; 7437 7438 if(s->f_gain[i][j*3+k] < 1) 7439 s->f_gain[i][j*3+k] = 1; 7440 } 7441 } 7442 } 7443 } 7444 7445 /*gray gain, copy*/ 7446 else{ 7447 7448 set_R_xfer_uid (cmd, R_FINE_uid_gray); 7449 inLen = reqLen; 7450 7451 ret = do_cmd ( 7452 s, 1, 0, 7453 cmd, cmdLen, 7454 NULL, 0, 7455 in, &inLen 7456 ); 7457 if (ret != SANE_STATUS_GOOD) 7458 goto cleanup; 7459 7460 for(i=0;i<2;i++){ 7461 for(j=0; j<s->s.valid_width; j++){ 7462 7463 s->f_gain[i][j] = in[j*2+i]*3/4; 7464 7465 if(s->f_gain[i][j] < 1) 7466 s->f_gain[i][j] = 1; 7467 } 7468 } 7469 } 7470 7471 cleanup: 7472 7473 if(in){ 7474 free(in); 7475 } 7476 7477 /* recover user settings */ 7478 s->u.tl_y = old_tl_y; 7479 s->u.br_y = old_br_y; 7480 s->u.source = old_source; 7481 7482 DBG (10, "calibrate_fine_src_hw: finish %d\n",ret); 7483 7484 return ret; 7485} 7486 7487/* 7488 * makes several scans, generates fine calibration data 7489 */ 7490static SANE_Status 7491calibrate_fine_src_scan (struct scanner *s) 7492{ 7493 SANE_Status ret = SANE_STATUS_GOOD; 7494 int i, j, k; 7495 int min, max; 7496 int lines = 8; 7497 7498 /*buffer these for later*/ 7499 int old_tl_y = s->u.tl_y; 7500 int old_br_y = s->u.br_y; 7501 int old_source = s->u.source; 7502 7503 DBG (10, "calibrate_fine_src_scan: start\n"); 7504 7505 /* always cal with a short scan in duplex */ 7506 s->u.tl_y = 0; 7507 s->u.br_y = lines * 1200 / s->u.dpi_y; 7508 s->u.source = SOURCE_ADF_DUPLEX; 7509 7510 /* load our own private copy of scan params */ 7511 ret = update_params(s,1); 7512 if (ret != SANE_STATUS_GOOD) { 7513 DBG (5, "calibrate_fine_src_scan: ERROR: cannot update_params\n"); 7514 goto cleanup; 7515 } 7516 7517 /* clean scan params for new scan */ 7518 ret = clean_params(s); 7519 if (ret != SANE_STATUS_GOOD) { 7520 DBG (5, "calibration_fine: ERROR: cannot clean_params\n"); 7521 goto cleanup; 7522 } 7523 7524 /* make buffers to hold the images */ 7525 ret = image_buffers(s,1); 7526 if (ret != SANE_STATUS_GOOD) { 7527 DBG (5, "calibrate_fine_src_scan: ERROR: cannot load buffers\n"); 7528 goto cleanup; 7529 } 7530 7531 /*blast the existing fine cal data so reading code won't apply it*/ 7532 ret = offset_buffers(s,0); 7533 ret = gain_buffers(s,0); 7534 7535 /* need to tell it we want duplex */ 7536 ret = ssm_buffer(s); 7537 if (ret != SANE_STATUS_GOOD) { 7538 DBG (5, "calibrate_fine_src_scan: ERROR: cannot ssm buffer\n"); 7539 goto cleanup; 7540 } 7541 7542 /* set window command */ 7543 ret = set_window(s); 7544 if (ret != SANE_STATUS_GOOD) { 7545 DBG (5, "calibrate_fine_src_scan: ERROR: cannot set window\n"); 7546 goto cleanup; 7547 } 7548 7549 /* first pass (fine offset), lamp off */ 7550 DBG (15, "calibrate_fine_src_scan: offset\n"); 7551 ret = calibration_scan(s,0xff); 7552 if (ret != SANE_STATUS_GOOD) { 7553 DBG (5, "calibrate_fine_src_scan: ERROR: cannot make offset cal scan\n"); 7554 goto cleanup; 7555 } 7556 7557 ret = offset_buffers(s,1); 7558 if (ret != SANE_STATUS_GOOD) { 7559 DBG (5, "calibrate_fine_src_scan: ERROR: cannot load offset buffers\n"); 7560 goto cleanup; 7561 } 7562 7563 for(i=0;i<2;i++){ 7564 for(j=0; j<s->s.valid_Bpl; j++){ 7565 min = 0; 7566 for(k=j;k<lines*s->s.Bpl;k+=s->s.Bpl){ 7567 min += s->buffers[i][k]; 7568 } 7569 s->f_offset[i][j] = min/lines; 7570 } 7571 hexdump(15, "off:", s->f_offset[i], s->s.valid_Bpl); 7572 } 7573 7574 /* second pass (fine gain), lamp on */ 7575 DBG (15, "calibrate_fine_src_scan: gain\n"); 7576 ret = calibration_scan(s,0xfe); 7577 if (ret != SANE_STATUS_GOOD) { 7578 DBG (5, "calibrate_fine_src_scan: ERROR: cannot make gain cal scan\n"); 7579 goto cleanup; 7580 } 7581 7582 ret = gain_buffers(s,1); 7583 if (ret != SANE_STATUS_GOOD) { 7584 DBG (5, "calibrate_fine_src_scan: ERROR: cannot load gain buffers\n"); 7585 goto cleanup; 7586 } 7587 7588 for(i=0;i<2;i++){ 7589 for(j=0; j<s->s.valid_Bpl; j++){ 7590 max = 0; 7591 for(k=j;k<lines*s->s.Bpl;k+=s->s.Bpl){ 7592 max += s->buffers[i][k]; 7593 } 7594 s->f_gain[i][j] = max/lines; 7595 7596 if(s->f_gain[i][j] < 1) 7597 s->f_gain[i][j] = 1; 7598 } 7599 hexdump(15, "gain:", s->f_gain[i], s->s.valid_Bpl); 7600 } 7601 7602 cleanup: 7603 7604 /* recover user settings */ 7605 s->u.tl_y = old_tl_y; 7606 s->u.br_y = old_br_y; 7607 s->u.source = old_source; 7608 7609 DBG (10, "calibrate_fine_src_scan: finish %d\n",ret); 7610 7611 return ret; 7612} 7613 7614/* write calibration data to scanner memory and delete from struct */ 7615static SANE_Status 7616calibrate_fine_dest_hw (struct scanner *s) 7617{ 7618 SANE_Status ret = SANE_STATUS_GOOD; 7619 int i, j, k; 7620 7621 unsigned char cmd[SEND_len]; 7622 size_t cmdLen = SEND_len; 7623 7624 unsigned char * out = NULL; 7625 size_t outLen = 0; 7626 7627 DBG (10, "calibrate_fine_dest_hw: start\n"); 7628 7629 /* calibration buffers in scanner are single color channel, but 16 bit, plus 4 byte header */ 7630 outLen = s->s.width*2 + 4; 7631 7632 out = calloc(outLen,1); 7633 if (!out) { 7634 DBG (5, "calibrate_fine_dest_hw: ERROR: cannot calloc out\n"); 7635 ret = SANE_STATUS_NO_MEM; 7636 goto cleanup; 7637 } 7638 7639 // sides 7640 for(i=0;i<2;i++){ 7641 7642 // colors 7643 for(j=0;j<3;j++){ 7644 7645 int codes[] = { 7646 S_FCAL_id_f_red, S_FCAL_id_f_green, S_FCAL_id_f_blue, 7647 S_FCAL_id_b_red, S_FCAL_id_b_green, S_FCAL_id_b_blue}; 7648 7649 // offset 7650 memset(cmd,0,cmdLen); 7651 set_SCSI_opcode(cmd, SEND_code); 7652 set_S_xfer_datatype (cmd, SR_datatype_fineoffset); 7653 set_S_xfer_length (cmd, outLen); 7654 7655 set_S_FCAL_datatype (out, codes[i*3+j]); 7656 7657 for(k=0; k<s->s.valid_width; k++){ 7658 out[4+k*2] = 0; 7659 7660 // TODO: calculate this instead of hardcode 7661 out[4+k*2+1] = 140; 7662 } 7663 7664 ret = do_cmd ( 7665 s, 1, 0, 7666 cmd, cmdLen, 7667 out, outLen, 7668 NULL, 0 7669 ); 7670 if (ret != SANE_STATUS_GOOD) 7671 goto cleanup; 7672 7673 // gain 7674 set_S_FCAL_datatype (out, codes[i*3+j] | 0x40); 7675 7676 for(k=0; k<s->s.valid_width; k++){ 7677 out[4+k*2] = 0; 7678 7679 // TODO: calculate this instead of hardcode 7680 out[4+k*2+1] = 40; 7681 } 7682 7683 ret = do_cmd ( 7684 s, 1, 0, 7685 cmd, cmdLen, 7686 out, outLen, 7687 NULL, 0 7688 ); 7689 if (ret != SANE_STATUS_GOOD) 7690 goto cleanup; 7691 7692 } 7693 } 7694 7695 cleanup: 7696 7697 /*blast the fine cal data we generated above, so reading code wont apply it*/ 7698 offset_buffers(s,0); 7699 gain_buffers(s,0); 7700 7701 if(out){ 7702 free(out); 7703 } 7704 7705 DBG (10, "calibrate_fine_dest_hw: finish %d\n",ret); 7706 7707 return ret; 7708} 7709 7710/* 7711 * does a simple scan, ingests entire duplex image into buffers 7712 */ 7713static SANE_Status 7714calibration_scan (struct scanner *s, int scan) 7715{ 7716 SANE_Status ret = SANE_STATUS_GOOD; 7717 7718 DBG (10, "calibration_scan: start\n"); 7719 7720 /* clean scan params for new scan */ 7721 ret = clean_params(s); 7722 if (ret != SANE_STATUS_GOOD) { 7723 DBG (5, "calibration_scan: ERROR: cannot clean_params\n"); 7724 return ret; 7725 } 7726 7727 /* start scanning */ 7728 ret = start_scan (s,scan); 7729 if (ret != SANE_STATUS_GOOD) { 7730 DBG (5, "calibration_scan: ERROR: cannot start_scan\n"); 7731 return ret; 7732 } 7733 7734 while(!s->s.eof[SIDE_FRONT] && !s->s.eof[SIDE_BACK]){ 7735 ret = read_from_scanner_duplex(s,1); 7736 } 7737 7738 DBG (10, "calibration_scan: finished\n"); 7739 7740 return ret; 7741} 7742 7743/* 7744 * sends AFE and exposure params 7745 */ 7746static SANE_Status 7747write_AFE(struct scanner *s) 7748{ 7749 SANE_Status ret = SANE_STATUS_GOOD; 7750 7751 unsigned char cmd[COR_CAL_len]; 7752 size_t cmdLen = COR_CAL_len; 7753 7754 /*use the longest payload for buffer*/ 7755 unsigned char pay[CC3_pay_len]; 7756 size_t payLen = CC3_pay_len; 7757 7758 DBG (10, "write_AFE: start\n"); 7759 7760 /* newer scanners use a longer cc payload */ 7761 if(s->ccal_version == 3){ 7762 7763 memset(cmd,0,cmdLen); 7764 set_SCSI_opcode(cmd, COR_CAL_code); 7765 set_CC_version(cmd,CC3_pay_ver); 7766 set_CC_xferlen(cmd,payLen); 7767 7768 memset(pay,0,payLen); 7769 7770 set_CC3_gain_f_r(pay,s->c_gain[SIDE_FRONT]); 7771 set_CC3_gain_f_g(pay,s->c_gain[SIDE_FRONT]); 7772 set_CC3_gain_f_b(pay,s->c_gain[SIDE_FRONT]); 7773 7774 set_CC3_off_f_r(pay,s->c_offset[SIDE_FRONT]); 7775 set_CC3_off_f_g(pay,s->c_offset[SIDE_FRONT]); 7776 set_CC3_off_f_b(pay,s->c_offset[SIDE_FRONT]); 7777 7778 set_CC3_exp_f_r(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]); 7779 set_CC3_exp_f_g(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]); 7780 set_CC3_exp_f_b(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]); 7781 7782 set_CC3_gain_b_r(pay,s->c_gain[SIDE_BACK]); 7783 set_CC3_gain_b_g(pay,s->c_gain[SIDE_BACK]); 7784 set_CC3_gain_b_b(pay,s->c_gain[SIDE_BACK]); 7785 7786 set_CC3_off_b_r(pay,s->c_offset[SIDE_BACK]); 7787 set_CC3_off_b_g(pay,s->c_offset[SIDE_BACK]); 7788 set_CC3_off_b_b(pay,s->c_offset[SIDE_BACK]); 7789 7790 set_CC3_exp_b_r(pay,s->c_exposure[SIDE_BACK][CHAN_RED]); 7791 set_CC3_exp_b_g(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]); 7792 set_CC3_exp_b_b(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]); 7793 } 7794 7795 else{ 7796 payLen = CC_pay_len; 7797 7798 memset(cmd,0,cmdLen); 7799 set_SCSI_opcode(cmd, COR_CAL_code); 7800 set_CC_version(cmd,CC_pay_ver); 7801 set_CC_xferlen(cmd,payLen); 7802 7803 memset(pay,0,payLen); 7804 set_CC_f_gain(pay,s->c_gain[SIDE_FRONT]); 7805 set_CC_unk1(pay,1); 7806 set_CC_f_offset(pay,s->c_offset[SIDE_FRONT]); 7807 set_CC_unk2(pay,1); 7808 set_CC_exp_f_r1(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]); 7809 set_CC_exp_f_g1(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]); 7810 set_CC_exp_f_b1(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]); 7811 set_CC_exp_f_r2(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]); 7812 set_CC_exp_f_g2(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]); 7813 set_CC_exp_f_b2(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]); 7814 7815 set_CC_b_gain(pay,s->c_gain[SIDE_BACK]); 7816 set_CC_b_offset(pay,s->c_offset[SIDE_BACK]); 7817 set_CC_exp_b_r1(pay,s->c_exposure[SIDE_BACK][CHAN_RED]); 7818 set_CC_exp_b_g1(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]); 7819 set_CC_exp_b_b1(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]); 7820 set_CC_exp_b_r2(pay,s->c_exposure[SIDE_BACK][CHAN_RED]); 7821 set_CC_exp_b_g2(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]); 7822 set_CC_exp_b_b2(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]); 7823 } 7824 7825 ret = do_cmd ( 7826 s, 1, 0, 7827 cmd, cmdLen, 7828 pay, payLen, 7829 NULL, NULL 7830 ); 7831 if (ret != SANE_STATUS_GOOD) 7832 return ret; 7833 7834 DBG (10, "write_AFE: finish\n"); 7835 7836 return ret; 7837} 7838 7839/* 7840 * frees/callocs buffers to hold the fine cal offset data 7841 */ 7842static SANE_Status 7843offset_buffers (struct scanner *s, int setup) 7844{ 7845 SANE_Status ret = SANE_STATUS_GOOD; 7846 int side; 7847 7848 DBG (10, "offset_buffers: start\n"); 7849 7850 for(side=0;side<2;side++){ 7851 7852 if (s->f_offset[side]) { 7853 DBG (15, "offset_buffers: free f_offset %d.\n",side); 7854 free(s->f_offset[side]); 7855 s->f_offset[side] = NULL; 7856 } 7857 7858 if(setup){ 7859 s->f_offset[side] = calloc (1,s->s.Bpl); 7860 if (!s->f_offset[side]) { 7861 DBG (5, "offset_buffers: error, no f_offset %d.\n",side); 7862 return SANE_STATUS_NO_MEM; 7863 } 7864 } 7865 } 7866 7867 DBG (10, "offset_buffers: finish\n"); 7868 7869 return ret; 7870} 7871 7872/* 7873 * frees/callocs buffers to hold the fine cal gain data 7874 */ 7875static SANE_Status 7876gain_buffers (struct scanner *s, int setup) 7877{ 7878 SANE_Status ret = SANE_STATUS_GOOD; 7879 int side; 7880 7881 DBG (10, "gain_buffers: start\n"); 7882 7883 for(side=0;side<2;side++){ 7884 7885 if (s->f_gain[side]) { 7886 DBG (15, "gain_buffers: free f_gain %d.\n",side); 7887 free(s->f_gain[side]); 7888 s->f_gain[side] = NULL; 7889 } 7890 7891 if(setup){ 7892 s->f_gain[side] = calloc (1,s->s.Bpl); 7893 if (!s->f_gain[side]) { 7894 DBG (5, "gain_buffers: error, no f_gain %d.\n",side); 7895 return SANE_STATUS_NO_MEM; 7896 } 7897 } 7898 } 7899 7900 DBG (10, "gain_buffers: finish\n"); 7901 7902 return ret; 7903} 7904 7905/* 7906 * @@ Section 6 - SANE cleanup functions 7907 */ 7908/* 7909 * Cancels a scan. 7910 * 7911 * It has been said on the mailing list that sane_cancel is a bit of a 7912 * misnomer because it is routinely called to signal the end of a 7913 * batch - quoting David Mosberger-Tang: 7914 * 7915 * > In other words, the idea is to have sane_start() be called, and 7916 * > collect as many images as the frontend wants (which could in turn 7917 * > consist of multiple frames each as indicated by frame-type) and 7918 * > when the frontend is done, it should call sane_cancel(). 7919 * > Sometimes it's better to think of sane_cancel() as "sane_stop()" 7920 * > but that name would have had some misleading connotations as 7921 * > well, that's why we stuck with "cancel". 7922 * 7923 * The current consensus regarding duplex and ADF scans seems to be 7924 * the following call sequence: sane_start; sane_read (repeat until 7925 * EOF); sane_start; sane_read... and then call sane_cancel if the 7926 * batch is at an end. I.e. do not call sane_cancel during the run but 7927 * as soon as you get a SANE_STATUS_NO_DOCS. 7928 * 7929 * From the SANE spec: 7930 * This function is used to immediately or as quickly as possible 7931 * cancel the currently pending operation of the device represented by 7932 * handle h. This function can be called at any time (as long as 7933 * handle h is a valid handle) but usually affects long-running 7934 * operations only (such as image acquisition). It is safe to call 7935 * this function asynchronously (e.g., from within a signal handler). 7936 * It is important to note that completion of this operation does not 7937 * imply that the currently pending operation has been cancelled. It 7938 * only guarantees that cancellation has been initiated. Cancellation 7939 * completes only when the cancelled call returns (typically with a 7940 * status value of SANE_STATUS_CANCELLED). Since the SANE API does 7941 * not require any other operations to be re-entrant, this implies 7942 * that a frontend must not call any other operation until the 7943 * cancelled operation has returned. 7944 */ 7945void 7946sane_cancel (SANE_Handle handle) 7947{ 7948 struct scanner * s = (struct scanner *) handle; 7949 7950 DBG (10, "sane_cancel: start\n"); 7951 s->cancelled = 1; 7952 7953 /* if there is no other running function to check, we do it */ 7954 if(!s->reading) 7955 check_for_cancel(s); 7956 7957 DBG (10, "sane_cancel: finish\n"); 7958} 7959 7960/* checks started and cancelled flags in scanner struct, 7961 * sends cancel command to scanner if required. don't call 7962 * this function asynchronously, wait for pending operation */ 7963static SANE_Status 7964check_for_cancel(struct scanner *s) 7965{ 7966 SANE_Status ret=SANE_STATUS_GOOD; 7967 7968 DBG (10, "check_for_cancel: start\n"); 7969 7970 if(s->started && s->cancelled){ 7971 unsigned char cmd[CANCEL_len]; 7972 size_t cmdLen = CANCEL_len; 7973 7974 DBG (15, "check_for_cancel: cancelling\n"); 7975 7976 /* cancel scan */ 7977 memset(cmd,0,cmdLen); 7978 set_SCSI_opcode(cmd, CANCEL_code); 7979 7980 ret = do_cmd ( 7981 s, 1, 0, 7982 cmd, cmdLen, 7983 NULL, 0, 7984 NULL, NULL 7985 ); 7986 if(ret){ 7987 DBG (5, "check_for_cancel: ignoring bad cancel: %d\n",ret); 7988 } 7989 7990 ret = object_position(s,SANE_FALSE); 7991 if(ret){ 7992 DBG (5, "check_for_cancel: ignoring bad eject: %d\n",ret); 7993 } 7994 7995 s->started = 0; 7996 s->cancelled = 0; 7997 ret = SANE_STATUS_CANCELLED; 7998 } 7999 else if(s->cancelled){ 8000 DBG (15, "check_for_cancel: already cancelled\n"); 8001 s->cancelled = 0; 8002 ret = SANE_STATUS_CANCELLED; 8003 } 8004 8005 DBG (10, "check_for_cancel: finish %d\n",ret); 8006 return ret; 8007} 8008 8009/* 8010 * Ends use of the scanner. 8011 * 8012 * From the SANE spec: 8013 * This function terminates the association between the device handle 8014 * passed in argument h and the device it represents. If the device is 8015 * presently active, a call to sane_cancel() is performed first. After 8016 * this function returns, handle h must not be used anymore. 8017 */ 8018void 8019sane_close (SANE_Handle handle) 8020{ 8021 struct scanner * s = (struct scanner *) handle; 8022 8023 DBG (10, "sane_close: start\n"); 8024 disconnect_fd(s); 8025 image_buffers(s,0); 8026 offset_buffers(s,0); 8027 gain_buffers(s,0); 8028 DBG (10, "sane_close: finish\n"); 8029} 8030 8031static SANE_Status 8032disconnect_fd (struct scanner *s) 8033{ 8034 DBG (10, "disconnect_fd: start\n"); 8035 8036 if(s->fd > -1){ 8037 if (s->connection == CONNECTION_USB) { 8038 DBG (15, "disconnecting usb device\n"); 8039 sanei_usb_close (s->fd); 8040 } 8041 else if (s->connection == CONNECTION_SCSI) { 8042 DBG (15, "disconnecting scsi device\n"); 8043 sanei_scsi_close (s->fd); 8044 } 8045 s->fd = -1; 8046 } 8047 8048 DBG (10, "disconnect_fd: finish\n"); 8049 8050 return SANE_STATUS_GOOD; 8051} 8052 8053/* 8054 * Terminates the backend. 8055 * 8056 * From the SANE spec: 8057 * This function must be called to terminate use of a backend. The 8058 * function will first close all device handles that still might be 8059 * open (it is recommended to close device handles explicitly through 8060 * a call to sane_close(), but backends are required to release all 8061 * resources upon a call to this function). After this function 8062 * returns, no function other than sane_init() may be called 8063 * (regardless of the status value returned by sane_exit(). Neglecting 8064 * to call this function may result in some resources not being 8065 * released properly. 8066 */ 8067void 8068sane_exit (void) 8069{ 8070 struct scanner *dev, *next; 8071 8072 DBG (10, "sane_exit: start\n"); 8073 8074 for (dev = scanner_devList; dev; dev = next) { 8075 disconnect_fd(dev); 8076 next = dev->next; 8077 free (dev); 8078 } 8079 8080 if (sane_devArray) 8081 free (sane_devArray); 8082 8083 scanner_devList = NULL; 8084 sane_devArray = NULL; 8085 8086 DBG (10, "sane_exit: finish\n"); 8087} 8088 8089 8090/* 8091 * @@ Section 7 - misc helper functions 8092 */ 8093static void 8094default_globals(void) 8095{ 8096 global_buffer_size = global_buffer_size_default; 8097 global_padded_read = global_padded_read_default; 8098 global_extra_status = global_extra_status_default; 8099 global_duplex_offset = global_duplex_offset_default; 8100 global_inquiry_length = INQUIRY_std_typ_len; 8101 global_vpd_length = INQUIRY_vpd_typ_len; 8102 global_tur_timeout = global_tur_timeout_default; 8103 global_vendor_name[0] = 0; 8104 global_model_name[0] = 0; 8105 global_version_name[0] = 0; 8106} 8107 8108/* 8109 * Called by the SANE SCSI core and our usb code on device errors 8110 * parses the request sense return data buffer, 8111 * decides the best SANE_Status for the problem, produces debug msgs, 8112 * and copies the sense buffer into the scanner struct 8113 */ 8114static SANE_Status 8115sense_handler (int fd, unsigned char * sensed_data, void *arg) 8116{ 8117 struct scanner *s = arg; 8118 unsigned int sense = get_RS_sense_key (sensed_data); 8119 unsigned int asc = get_RS_ASC (sensed_data); 8120 unsigned int ascq = get_RS_ASCQ (sensed_data); 8121 unsigned int eom = get_RS_EOM (sensed_data); 8122 unsigned int ili = get_RS_ILI (sensed_data); 8123 unsigned int info = get_RS_information (sensed_data); 8124 8125 DBG (5, "sense_handler: start\n"); 8126 8127 /* kill compiler warning */ 8128 (void) fd; 8129 8130 /* copy the rs return data into the scanner struct 8131 so that the caller can use it if he wants 8132 memcpy(&s->rs_buffer,sensed_data,RS_return_size); 8133 */ 8134 8135 DBG (5, "Sense=%#02x, ASC=%#02x, ASCQ=%#02x, EOM=%d, ILI=%d, info=%#08x\n", sense, asc, ascq, eom, ili, info); 8136 8137 switch (sense) { 8138 case 0: 8139 if (ili == 1) { 8140 s->rs_info = info; 8141 DBG (5, "No sense: EOM remainder:%d\n",info); 8142 return SANE_STATUS_EOF; 8143 } 8144 DBG (5, "No sense: unknown asc/ascq\n"); 8145 return SANE_STATUS_GOOD; 8146 8147 case 1: 8148 if (asc == 0x37 && ascq == 0x00) { 8149 DBG (5, "Recovered error: parameter rounded\n"); 8150 return SANE_STATUS_GOOD; 8151 } 8152 DBG (5, "Recovered error: unknown asc/ascq\n"); 8153 return SANE_STATUS_GOOD; 8154 8155 case 2: 8156 if (asc == 0x04 && ascq == 0x01) { 8157 DBG (5, "Not ready: previous command unfinished\n"); 8158 return SANE_STATUS_DEVICE_BUSY; 8159 } 8160 DBG (5, "Not ready: unknown asc/ascq\n"); 8161 return SANE_STATUS_DEVICE_BUSY; 8162 8163 case 3: 8164 if (asc == 0x36 && ascq == 0x00) { 8165 DBG (5, "Medium error: no cartridge\n"); 8166 return SANE_STATUS_IO_ERROR; 8167 } 8168 if (asc == 0x3a && ascq == 0x00) { 8169 DBG (5, "Medium error: hopper empty\n"); 8170 return SANE_STATUS_NO_DOCS; 8171 } 8172 if (asc == 0x80 && ascq == 0x00) { 8173 DBG (5, "Medium error: paper jam\n"); 8174 return SANE_STATUS_JAMMED; 8175 } 8176 if (asc == 0x80 && ascq == 0x01) { 8177 DBG (5, "Medium error: cover open\n"); 8178 return SANE_STATUS_COVER_OPEN; 8179 } 8180 if (asc == 0x81 && ascq == 0x01) { 8181 DBG (5, "Medium error: double feed\n"); 8182 return SANE_STATUS_JAMMED; 8183 } 8184 if (asc == 0x81 && ascq == 0x02) { 8185 DBG (5, "Medium error: skew detected\n"); 8186 return SANE_STATUS_JAMMED; 8187 } 8188 if (asc == 0x81 && ascq == 0x04) { 8189 DBG (5, "Medium error: staple detected\n"); 8190 return SANE_STATUS_JAMMED; 8191 } 8192 DBG (5, "Medium error: unknown asc/ascq\n"); 8193 return SANE_STATUS_IO_ERROR; 8194 8195 case 4: 8196 if (asc == 0x60 && ascq == 0x00) { 8197 DBG (5, "Hardware error: lamp error\n"); 8198 return SANE_STATUS_IO_ERROR; 8199 } 8200 if (asc == 0x80 && ascq == 0x01) { 8201 DBG (5, "Hardware error: CPU check error\n"); 8202 return SANE_STATUS_IO_ERROR; 8203 } 8204 if (asc == 0x80 && ascq == 0x02) { 8205 DBG (5, "Hardware error: RAM check error\n"); 8206 return SANE_STATUS_IO_ERROR; 8207 } 8208 if (asc == 0x80 && ascq == 0x03) { 8209 DBG (5, "Hardware error: ROM check error\n"); 8210 return SANE_STATUS_IO_ERROR; 8211 } 8212 if (asc == 0x80 && ascq == 0x04) { 8213 DBG (5, "Hardware error: hardware check error\n"); 8214 return SANE_STATUS_IO_ERROR; 8215 } 8216 DBG (5, "Hardware error: unknown asc/ascq\n"); 8217 return SANE_STATUS_IO_ERROR; 8218 8219 case 5: 8220 if (asc == 0x1a && ascq == 0x00) { 8221 DBG (5, "Illegal request: Parameter list error\n"); 8222 return SANE_STATUS_INVAL; 8223 } 8224 if (asc == 0x20 && ascq == 0x00) { 8225 DBG (5, "Illegal request: invalid command\n"); 8226 return SANE_STATUS_INVAL; 8227 } 8228 if (asc == 0x24 && ascq == 0x00) { 8229 DBG (5, "Illegal request: invalid CDB field\n"); 8230 return SANE_STATUS_INVAL; 8231 } 8232 if (asc == 0x25 && ascq == 0x00) { 8233 DBG (5, "Illegal request: unsupported logical unit\n"); 8234 return SANE_STATUS_UNSUPPORTED; 8235 } 8236 if (asc == 0x26 && ascq == 0x00) { 8237 DBG (5, "Illegal request: invalid field in parm list\n"); 8238 return SANE_STATUS_INVAL; 8239 } 8240 if (asc == 0x2c && ascq == 0x00) { 8241 DBG (5, "Illegal request: command sequence error\n"); 8242 return SANE_STATUS_INVAL; 8243 } 8244 if (asc == 0x2c && ascq == 0x01) { 8245 DBG (5, "Illegal request: too many windows\n"); 8246 return SANE_STATUS_INVAL; 8247 } 8248 if (asc == 0x3a && ascq == 0x00) { 8249 DBG (5, "Illegal request: no paper\n"); 8250 return SANE_STATUS_NO_DOCS; 8251 } 8252 if (asc == 0x3d && ascq == 0x00) { 8253 DBG (5, "Illegal request: invalid IDENTIFY\n"); 8254 return SANE_STATUS_INVAL; 8255 } 8256 if (asc == 0x55 && ascq == 0x00) { 8257 DBG (5, "Illegal request: scanner out of memory\n"); 8258 return SANE_STATUS_NO_MEM; 8259 } 8260 DBG (5, "Illegal request: unknown asc/ascq\n"); 8261 return SANE_STATUS_IO_ERROR; 8262 break; 8263 8264 case 6: 8265 if (asc == 0x29 && ascq == 0x00) { 8266 DBG (5, "Unit attention: device reset\n"); 8267 return SANE_STATUS_GOOD; 8268 } 8269 if (asc == 0x2a && ascq == 0x00) { 8270 DBG (5, "Unit attention: param changed by 2nd initiator\n"); 8271 return SANE_STATUS_GOOD; 8272 } 8273 DBG (5, "Unit attention: unknown asc/ascq\n"); 8274 return SANE_STATUS_IO_ERROR; 8275 break; 8276 8277 case 7: 8278 DBG (5, "Data protect: unknown asc/ascq\n"); 8279 return SANE_STATUS_IO_ERROR; 8280 8281 case 8: 8282 DBG (5, "Blank check: unknown asc/ascq\n"); 8283 return SANE_STATUS_IO_ERROR; 8284 8285 case 9: 8286 DBG (5, "Vendor defined: unknown asc/ascq\n"); 8287 return SANE_STATUS_IO_ERROR; 8288 8289 case 0xa: 8290 DBG (5, "Copy aborted: unknown asc/ascq\n"); 8291 return SANE_STATUS_IO_ERROR; 8292 8293 case 0xb: 8294 if (asc == 0x00 && ascq == 0x00) { 8295 DBG (5, "Aborted command: no sense/cancelled\n"); 8296 return SANE_STATUS_CANCELLED; 8297 } 8298 if (asc == 0x45 && ascq == 0x00) { 8299 DBG (5, "Aborted command: reselect failure\n"); 8300 return SANE_STATUS_IO_ERROR; 8301 } 8302 if (asc == 0x47 && ascq == 0x00) { 8303 DBG (5, "Aborted command: SCSI parity error\n"); 8304 return SANE_STATUS_IO_ERROR; 8305 } 8306 if (asc == 0x48 && ascq == 0x00) { 8307 DBG (5, "Aborted command: initiator error message\n"); 8308 return SANE_STATUS_IO_ERROR; 8309 } 8310 if (asc == 0x49 && ascq == 0x00) { 8311 DBG (5, "Aborted command: invalid message\n"); 8312 return SANE_STATUS_IO_ERROR; 8313 } 8314 if (asc == 0x80 && ascq == 0x00) { 8315 DBG (5, "Aborted command: timeout\n"); 8316 return SANE_STATUS_IO_ERROR; 8317 } 8318 DBG (5, "Aborted command: unknown asc/ascq\n"); 8319 return SANE_STATUS_IO_ERROR; 8320 break; 8321 8322 case 0xc: 8323 DBG (5, "Equal: unknown asc/ascq\n"); 8324 return SANE_STATUS_IO_ERROR; 8325 8326 case 0xd: 8327 DBG (5, "Volume overflow: unknown asc/ascq\n"); 8328 return SANE_STATUS_IO_ERROR; 8329 8330 case 0xe: 8331 if (asc == 0x3b && ascq == 0x0d) { 8332 DBG (5, "Miscompare: too many docs\n"); 8333 return SANE_STATUS_IO_ERROR; 8334 } 8335 if (asc == 0x3b && ascq == 0x0e) { 8336 DBG (5, "Miscompare: too few docs\n"); 8337 return SANE_STATUS_IO_ERROR; 8338 } 8339 DBG (5, "Miscompare: unknown asc/ascq\n"); 8340 return SANE_STATUS_IO_ERROR; 8341 8342 default: 8343 DBG (5, "Unknown Sense Code\n"); 8344 return SANE_STATUS_IO_ERROR; 8345 } 8346 8347 DBG (5, "sense_handler: should never happen!\n"); 8348 8349 return SANE_STATUS_IO_ERROR; 8350} 8351 8352/* 8353 * take a bunch of pointers, send commands to scanner 8354 */ 8355static SANE_Status 8356do_cmd(struct scanner *s, int runRS, int timeout, 8357 unsigned char * cmdBuff, size_t cmdLen, 8358 unsigned char * outBuff, size_t outLen, 8359 unsigned char * inBuff, size_t * inLen 8360) 8361{ 8362 if (s->connection == CONNECTION_SCSI) { 8363 return do_scsi_cmd(s, runRS, timeout, 8364 cmdBuff, cmdLen, 8365 outBuff, outLen, 8366 inBuff, inLen 8367 ); 8368 } 8369 if (s->connection == CONNECTION_USB) { 8370 return do_usb_cmd(s, runRS, timeout, 8371 cmdBuff, cmdLen, 8372 outBuff, outLen, 8373 inBuff, inLen 8374 ); 8375 } 8376 return SANE_STATUS_INVAL; 8377} 8378 8379static SANE_Status 8380do_scsi_cmd(struct scanner *s, int runRS, int timeout, 8381 unsigned char * cmdBuff, size_t cmdLen, 8382 unsigned char * outBuff, size_t outLen, 8383 unsigned char * inBuff, size_t * inLen 8384) 8385{ 8386 int ret; 8387 8388 /*shut up compiler*/ 8389 (void) runRS; 8390 (void) timeout; 8391 8392 DBG(10, "do_scsi_cmd: start\n"); 8393 8394 DBG(25, "cmd: writing %d bytes\n", (int)cmdLen); 8395 hexdump(30, "cmd: >>", cmdBuff, cmdLen); 8396 8397 if(outBuff && outLen){ 8398 DBG(25, "out: writing %d bytes\n", (int)outLen); 8399 hexdump(30, "out: >>", outBuff, outLen); 8400 } 8401 if (inBuff && inLen){ 8402 DBG(25, "in: reading %d bytes\n", (int)*inLen); 8403 memset(inBuff,0,*inLen); 8404 } 8405 8406 ret = sanei_scsi_cmd2(s->fd, cmdBuff, cmdLen, outBuff, outLen, inBuff, inLen); 8407 8408 if(ret != SANE_STATUS_GOOD && ret != SANE_STATUS_EOF){ 8409 DBG(5,"do_scsi_cmd: return '%s'\n",sane_strstatus(ret)); 8410 return ret; 8411 } 8412 8413 if (inBuff && inLen){ 8414 if(ret == SANE_STATUS_EOF){ 8415 DBG(25, "in: short read, remainder %lu bytes\n", (u_long)s->rs_info); 8416 *inLen -= s->rs_info; 8417 } 8418 hexdump(31, "in: <<", inBuff, *inLen); 8419 DBG(25, "in: read %d bytes\n", (int)*inLen); 8420 } 8421 8422 DBG(10, "do_scsi_cmd: finish\n"); 8423 8424 return ret; 8425} 8426 8427static SANE_Status 8428do_usb_cmd(struct scanner *s, int runRS, int timeout, 8429 unsigned char * cmdBuff, size_t cmdLen, 8430 unsigned char * outBuff, size_t outLen, 8431 unsigned char * inBuff, size_t * inLen 8432) 8433{ 8434 size_t cmdOffset = 0; 8435 size_t cmdLength = 0; 8436 size_t cmdActual = 0; 8437 unsigned char * cmdBuffer = NULL; 8438 8439 size_t outOffset = 0; 8440 size_t outLength = 0; 8441 size_t outActual = 0; 8442 unsigned char * outBuffer = NULL; 8443 8444 size_t inOffset = 0; 8445 size_t inLength = 0; 8446 size_t inActual = 0; 8447 unsigned char * inBuffer = NULL; 8448 8449 size_t extraLength = 0; 8450 int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT; 8451 8452 int ret = 0; 8453 int ret2 = 0; 8454 8455 struct timeval timer; 8456 gettimeofday(&timer,NULL); 8457 8458 DBG (10, "do_usb_cmd: start %lu %lu\n", (long unsigned int)timer.tv_sec, (long unsigned int)timer.tv_usec); 8459 8460 /* change timeout */ 8461 sanei_usb_set_timeout(actTimeout); 8462 8463 /****************************************************************/ 8464 /* the command stage */ 8465 { 8466 cmdOffset = USB_HEADER_LEN; 8467 cmdLength = cmdOffset+USB_COMMAND_LEN; 8468 cmdActual = cmdLength; 8469 8470 /* build buffer */ 8471 cmdBuffer = calloc(cmdLength,1); 8472 if(!cmdBuffer){ 8473 DBG(5,"cmd: no mem\n"); 8474 return SANE_STATUS_NO_MEM; 8475 } 8476 8477 /* build a USB packet around the SCSI command */ 8478 set_USB_CMD_xfer_length(cmdBuffer,cmdLength-4); 8479 cmdBuffer[5] = 1; 8480 cmdBuffer[6] = 0x90; 8481 memcpy(cmdBuffer+cmdOffset,cmdBuff,cmdLen); 8482 8483 /* write the command out */ 8484 DBG(25, "cmd: writing %d bytes, timeout %d\n", (int)cmdLength, actTimeout); 8485 hexdump(30, "cmd: >>", cmdBuffer, cmdLength); 8486 ret = sanei_usb_write_bulk(s->fd, cmdBuffer, &cmdActual); 8487 DBG(25, "cmd: wrote %d bytes, retVal %d\n", (int)cmdActual, ret); 8488 8489 if(cmdLength != cmdActual){ 8490 DBG(5,"cmd: wrong size %d/%d\n", (int)cmdLength, (int)cmdActual); 8491 free(cmdBuffer); 8492 return SANE_STATUS_IO_ERROR; 8493 } 8494 if(ret != SANE_STATUS_GOOD){ 8495 DBG(5,"cmd: write error '%s'\n",sane_strstatus(ret)); 8496 free(cmdBuffer); 8497 return ret; 8498 } 8499 free(cmdBuffer); 8500 } 8501 8502 /****************************************************************/ 8503 /* the extra status stage, used by few scanners */ 8504 /* this is like the regular status block, with an additional */ 8505 /* length component at the end */ 8506 if(s->extra_status){ 8507 ret2 = do_usb_status(s,runRS,timeout,&extraLength); 8508 8509 /* bail out on bad RS status */ 8510 if(ret2){ 8511 DBG(5,"extra: bad RS status, %d\n", ret2); 8512 return ret2; 8513 } 8514 } 8515 8516 /****************************************************************/ 8517 /* the output stage */ 8518 if(outBuff && outLen){ 8519 8520 outOffset = USB_HEADER_LEN; 8521 outLength = outOffset+outLen; 8522 outActual = outLength; 8523 8524 /* build outBuffer */ 8525 outBuffer = calloc(outLength,1); 8526 if(!outBuffer){ 8527 DBG(5,"out: no mem\n"); 8528 return SANE_STATUS_NO_MEM; 8529 } 8530 8531 /* build a USB packet around the SCSI command */ 8532 set_USB_OUT_xfer_length(outBuffer,outLength-4); 8533 outBuffer[5] = 2; 8534 outBuffer[6] = 0xb0; 8535 memcpy(outBuffer+outOffset,outBuff,outLen); 8536 8537 /* write the command out */ 8538 DBG(25, "out: writing %d bytes, timeout %d\n", (int)outLength, actTimeout); 8539 hexdump(30, "out: >>", outBuffer, outLength); 8540 ret = sanei_usb_write_bulk(s->fd, outBuffer, &outActual); 8541 DBG(25, "out: wrote %d bytes, retVal %d\n", (int)outActual, ret); 8542 8543 if(outLength != outActual){ 8544 DBG(5,"out: wrong size %d/%d\n", (int)outLength, (int)outActual); 8545 free(outBuffer); 8546 return SANE_STATUS_IO_ERROR; 8547 } 8548 if(ret != SANE_STATUS_GOOD){ 8549 DBG(5,"out: write error '%s'\n",sane_strstatus(ret)); 8550 free(outBuffer); 8551 return ret; 8552 } 8553 free(outBuffer); 8554 } 8555 8556 /****************************************************************/ 8557 /* the input stage */ 8558 if(inBuff && inLen){ 8559 8560 inOffset = 0; 8561 if(s->padded_read) 8562 inOffset = USB_HEADER_LEN; 8563 8564 inLength = inOffset+*inLen; 8565 inActual = inLength; 8566 8567 /* use the extra length to alter the amount of in we request */ 8568 if(s->extra_status && extraLength && *inLen > extraLength){ 8569 DBG(5,"in: adjust extra, %d %d\n", (int)*inLen, (int)extraLength); 8570 inActual = inOffset+extraLength; 8571 } 8572 8573 /*blast caller's copy in case we error out*/ 8574 *inLen = 0; 8575 8576 /* build inBuffer */ 8577 inBuffer = calloc(inActual,1); 8578 if(!inBuffer){ 8579 DBG(5,"in: no mem\n"); 8580 return SANE_STATUS_NO_MEM; 8581 } 8582 8583 DBG(25, "in: reading %d bytes, timeout %d\n", (int)inActual, actTimeout); 8584 ret = sanei_usb_read_bulk(s->fd, inBuffer, &inActual); 8585 DBG(25, "in: read %d bytes, retval %d\n", (int)inActual, ret); 8586 hexdump(31, "in: <<", inBuffer, inActual); 8587 8588 if(!inActual){ 8589 DBG(5,"in: got no data, clearing\n"); 8590 free(inBuffer); 8591 return do_usb_clear(s,1,runRS); 8592 } 8593 if(inActual < inOffset){ 8594 DBG(5,"in: read shorter than inOffset\n"); 8595 free(inBuffer); 8596 return SANE_STATUS_IO_ERROR; 8597 } 8598 if(ret != SANE_STATUS_GOOD){ 8599 DBG(5,"in: return error '%s'\n",sane_strstatus(ret)); 8600 free(inBuffer); 8601 return ret; 8602 } 8603 8604 /* note that inBuffer is not copied and freed here...*/ 8605 } 8606 8607 /****************************************************************/ 8608 /* the normal status stage */ 8609 ret2 = do_usb_status(s,runRS,timeout,&extraLength); 8610 8611 /* if status said EOF, adjust input with remainder count */ 8612 if(ret2 == SANE_STATUS_EOF && inBuffer){ 8613 8614 /* EOF is ok */ 8615 ret2 = SANE_STATUS_GOOD; 8616 8617 if(inActual < inLength - s->rs_info){ 8618 DBG(5,"in: we read < RS, ignoring RS: %d < %d (%d-%d)\n", 8619 (int)inActual,(int)(inLength-s->rs_info),(int)inLength,(int)s->rs_info); 8620 } 8621 else if(inActual > inLength - s->rs_info){ 8622 DBG(5,"in: we read > RS, using RS: %d to %d (%d-%d)\n", 8623 (int)inActual,(int)(inLength-s->rs_info),(int)inLength,(int)s->rs_info); 8624 inActual = inLength - s->rs_info; 8625 } 8626 } 8627 8628 /* bail out on bad RS status */ 8629 if(ret2){ 8630 if(inBuffer) free(inBuffer); 8631 DBG(5,"stat: bad RS status, %d\n", ret2); 8632 return ret2; 8633 } 8634 8635 /* now that we have read status, deal with input buffer */ 8636 if(inBuffer){ 8637 if(inLength != inActual){ 8638 ret = SANE_STATUS_EOF; 8639 DBG(5,"in: short read, %d/%d\n", (int)inLength,(int)inActual); 8640 } 8641 8642 /* ignore the USB packet around the SCSI command */ 8643 *inLen = inActual - inOffset; 8644 memcpy(inBuff,inBuffer+inOffset,*inLen); 8645 8646 free(inBuffer); 8647 } 8648 8649 gettimeofday(&timer,NULL); 8650 8651 DBG (10, "do_usb_cmd: finish %lu %lu\n", (long unsigned int)timer.tv_sec, (long unsigned int)timer.tv_usec); 8652 8653 return ret; 8654} 8655 8656static SANE_Status 8657do_usb_status(struct scanner *s, int runRS, int timeout, size_t * extraLength) 8658{ 8659 8660#define EXTRA_READ_len 4 8661 8662 size_t statPadding = 0; 8663 size_t statOffset = 0; 8664 size_t statLength = 0; 8665 size_t statActual = 0; 8666 unsigned char * statBuffer = NULL; 8667 8668 int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT; 8669 8670 int ret = 0; 8671 8672 if(s->padded_read) 8673 statPadding = USB_HEADER_LEN; 8674 8675 statLength = statPadding+USB_STATUS_LEN; 8676 statOffset = statLength-1; 8677 8678 if(s->extra_status) 8679 statLength += EXTRA_READ_len; 8680 8681 statActual = statLength; 8682 8683 /* change timeout */ 8684 sanei_usb_set_timeout(timeout ? timeout : USB_PACKET_TIMEOUT); 8685 8686 /* build statBuffer */ 8687 statBuffer = calloc(statLength,1); 8688 if(!statBuffer){ 8689 DBG(5,"stat: no mem\n"); 8690 return SANE_STATUS_NO_MEM; 8691 } 8692 8693 DBG(25, "stat: reading %d bytes, timeout %d\n", (int)statLength, actTimeout); 8694 ret = sanei_usb_read_bulk(s->fd, statBuffer, &statActual); 8695 DBG(25, "stat: read %d bytes, retval %d\n", (int)statActual, ret); 8696 hexdump(30, "stat: <<", statBuffer, statActual); 8697 8698 /*weird status*/ 8699 if(ret != SANE_STATUS_GOOD){ 8700 DBG(5,"stat: clearing error '%s'\n",sane_strstatus(ret)); 8701 ret = do_usb_clear(s,1,runRS); 8702 } 8703 /*short read*/ 8704 else if(statLength != statActual){ 8705 DBG(5,"stat: clearing short %d/%d\n",(int)statLength,(int)statActual); 8706 ret = do_usb_clear(s,1,runRS); 8707 } 8708 /*inspect the status byte of the response*/ 8709 else if(statBuffer[statOffset]){ 8710 DBG(5,"stat: status %d\n",statBuffer[statOffset]); 8711 ret = do_usb_clear(s,0,runRS); 8712 } 8713 8714 /*extract the extra length byte of the response*/ 8715 if(s->extra_status){ 8716 *extraLength = get_ES_length(statBuffer); 8717 DBG(15,"stat: extra %d\n",(int)*extraLength); 8718 } 8719 8720 free(statBuffer); 8721 8722 return ret; 8723} 8724 8725static SANE_Status 8726do_usb_clear(struct scanner *s, int clear, int runRS) 8727{ 8728 SANE_Status ret, ret2; 8729 8730 DBG (10, "do_usb_clear: start\n"); 8731 8732 usleep(100000); 8733 8734 if(clear){ 8735 DBG (15, "do_usb_clear: clear halt\n"); 8736 ret = sanei_usb_clear_halt(s->fd); 8737 if(ret != SANE_STATUS_GOOD){ 8738 DBG(5,"do_usb_clear: can't clear halt, returning %d\n", ret); 8739 return ret; 8740 } 8741 } 8742 8743 /* caller is interested in having RS run on errors */ 8744 if(runRS){ 8745 8746 unsigned char rs_cmd[REQUEST_SENSE_len]; 8747 size_t rs_cmdLen = REQUEST_SENSE_len; 8748 8749 unsigned char rs_in[RS_return_size]; 8750 size_t rs_inLen = RS_return_size; 8751 8752 memset(rs_cmd,0,rs_cmdLen); 8753 set_SCSI_opcode(rs_cmd, REQUEST_SENSE_code); 8754 set_RS_return_size(rs_cmd, rs_inLen); 8755 8756 DBG(25,"rs sub call >>\n"); 8757 ret2 = do_cmd( 8758 s, 0, 0, 8759 rs_cmd, rs_cmdLen, 8760 NULL,0, 8761 rs_in, &rs_inLen 8762 ); 8763 DBG(25,"rs sub call <<\n"); 8764 8765 if(ret2 == SANE_STATUS_EOF){ 8766 DBG(5,"rs: got EOF, returning IO_ERROR\n"); 8767 return SANE_STATUS_IO_ERROR; 8768 } 8769 if(ret2 != SANE_STATUS_GOOD){ 8770 DBG(5,"rs: return error '%s'\n",sane_strstatus(ret2)); 8771 return ret2; 8772 } 8773 8774 /* parse the rs data */ 8775 ret2 = sense_handler( 0, rs_in, (void *)s ); 8776 8777 DBG (10, "do_usb_clear: finish after RS\n"); 8778 return ret2; 8779 } 8780 8781 DBG (10, "do_usb_clear: finish with io error\n"); 8782 8783 return SANE_STATUS_IO_ERROR; 8784} 8785 8786static SANE_Status 8787wait_scanner(struct scanner *s) 8788{ 8789 SANE_Status ret = SANE_STATUS_GOOD; 8790 8791 unsigned char cmd[TEST_UNIT_READY_len]; 8792 size_t cmdLen = TEST_UNIT_READY_len; 8793 8794 DBG (10, "wait_scanner: start\n"); 8795 8796 memset(cmd,0,cmdLen); 8797 set_SCSI_opcode(cmd,TEST_UNIT_READY_code); 8798 8799 ret = do_cmd ( 8800 s, 0, s->tur_timeout, 8801 cmd, cmdLen, 8802 NULL, 0, 8803 NULL, NULL 8804 ); 8805 8806 if (ret != SANE_STATUS_GOOD) { 8807 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick.\n"); 8808 ret = do_cmd ( 8809 s, 0, s->tur_timeout, 8810 cmd, cmdLen, 8811 NULL, 0, 8812 NULL, NULL 8813 ); 8814 } 8815 if (ret != SANE_STATUS_GOOD) { 8816 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick again.\n"); 8817 ret = do_cmd ( 8818 s, 0, s->tur_timeout, 8819 cmd, cmdLen, 8820 NULL, 0, 8821 NULL, NULL 8822 ); 8823 } 8824 // some scanners (such as DR-F120) are OK but will not respond to commands 8825 // when in sleep mode. By checking the sense it wakes them up. 8826 if (ret != SANE_STATUS_GOOD) { 8827 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick and request sense.\n"); 8828 ret = do_cmd ( 8829 s, 1, s->tur_timeout, 8830 cmd, cmdLen, 8831 NULL, 0, 8832 NULL, NULL 8833 ); 8834 } 8835 if (ret != SANE_STATUS_GOOD) { 8836 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a fourth time.\n"); 8837 ret = do_cmd ( 8838 s, 0, s->tur_timeout, 8839 cmd, cmdLen, 8840 NULL, 0, 8841 NULL, NULL 8842 ); 8843 } 8844 8845 if (ret != SANE_STATUS_GOOD) { 8846 DBG (5, "wait_scanner: error '%s'\n", sane_strstatus (ret)); 8847 } 8848 8849 DBG (10, "wait_scanner: finish (status=%d)\n", ret); 8850 8851 return ret; 8852} 8853 8854/* Some scanners have per-resolution 8855 * color interlacing values, but most 8856 * don't. This helper can tell the 8857 * difference. 8858 */ 8859static int 8860get_color_inter(struct scanner *s, int side, int res) 8861{ 8862 int i; 8863 for(i=0;i<DPI_1200;i++){ 8864 if(res == dpi_list[i]) 8865 break; 8866 } 8867 8868 if(s->color_inter_by_res[i]) 8869 return s->color_inter_by_res[i]; 8870 8871 return s->color_interlace[side]; 8872} 8873 8874/* s->u.page_x stores the user setting 8875 * for the paper width in adf. sometimes, 8876 * we need a value that differs from this 8877 * due to using FB or overscan. 8878 */ 8879static int 8880get_page_width(struct scanner *s) 8881{ 8882 int width = s->u.page_x; 8883 8884 /* scanner max for fb */ 8885 if(s->u.source == SOURCE_FLATBED){ 8886 return s->max_x_fb; 8887 } 8888 8889 /* can't overscan larger than scanner max */ 8890 if(width > s->valid_x){ 8891 return s->valid_x; 8892 } 8893 8894 /* overscan adds a margin to both sides */ 8895 return width; 8896} 8897 8898/* s->u.page_y stores the user setting 8899 * for the paper height in adf. sometimes, 8900 * we need a value that differs from this 8901 * due to using FB or overscan. 8902 */ 8903static int 8904get_page_height(struct scanner *s) 8905{ 8906 int height = s->u.page_y; 8907 8908 /* scanner max for fb */ 8909 if(s->u.source == SOURCE_FLATBED){ 8910 return s->max_y_fb; 8911 } 8912 8913 /* can't overscan larger than scanner max */ 8914 if(height > s->max_y){ 8915 return s->max_y; 8916 } 8917 8918 /* overscan adds a margin to both sides */ 8919 return height; 8920} 8921 8922 8923/** 8924 * Convenience method to determine longest string size in a list. 8925 */ 8926static size_t 8927maxStringSize (const SANE_String_Const strings[]) 8928{ 8929 size_t size, max_size = 0; 8930 int i; 8931 8932 for (i = 0; strings[i]; ++i) { 8933 size = strlen (strings[i]) + 1; 8934 if (size > max_size) 8935 max_size = size; 8936 } 8937 8938 return max_size; 8939} 8940 8941/* 8942 * Prints a hex dump of the given buffer onto the debug output stream. 8943 */ 8944static void 8945hexdump (int level, char *comment, unsigned char *p, int l) 8946{ 8947 int i; 8948 char line[70]; /* 'xxx: xx xx ... xx xx abc */ 8949 char *hex = line+4; 8950 char *bin = line+53; 8951 8952 if(DBG_LEVEL < level) 8953 return; 8954 8955 line[0] = 0; 8956 8957 DBG (level, "%s\n", comment); 8958 8959 for (i = 0; i < l; i++, p++) { 8960 8961 /* at start of line */ 8962 if ((i % 16) == 0) { 8963 8964 /* not at start of first line, print current, reset */ 8965 if (i) { 8966 DBG (level, "%s\n", line); 8967 } 8968 8969 memset(line,0x20,69); 8970 line[69] = 0; 8971 hex = line + 4; 8972 bin = line + 53; 8973 8974 sprintf (line, "%3.3x:", i); 8975 } 8976 8977 /* the hex section */ 8978 sprintf (hex, " %2.2x", *p); 8979 hex += 3; 8980 *hex = ' '; 8981 8982 /* the char section */ 8983 if(*p >= 0x20 && *p <= 0x7e){ 8984 *bin=*p; 8985 } 8986 else{ 8987 *bin='.'; 8988 } 8989 bin++; 8990 } 8991 8992 /* print last (partial) line */ 8993 if (i) 8994 DBG (level, "%s\n", line); 8995} 8996 8997/** 8998 * An advanced method we don't support but have to define. 8999 */ 9000SANE_Status 9001sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking) 9002{ 9003 DBG (10, "sane_set_io_mode\n"); 9004 DBG (15, "%d %p\n", non_blocking, h); 9005 return SANE_STATUS_UNSUPPORTED; 9006} 9007 9008/** 9009 * An advanced method we don't support but have to define. 9010 */ 9011SANE_Status 9012sane_get_select_fd (SANE_Handle h, SANE_Int *fdp) 9013{ 9014 DBG (10, "sane_get_select_fd\n"); 9015 DBG (15, "%p %d\n", h, *fdp); 9016 return SANE_STATUS_UNSUPPORTED; 9017} 9018 9019/* 9020 * @@ Section 8 - Image processing functions 9021 */ 9022 9023/* Look in image for likely upper and left paper edges, then rotate 9024 * image so that upper left corner of paper is upper left of image. 9025 * FIXME: should we do this before we binarize instead of after? */ 9026static SANE_Status 9027buffer_deskew(struct scanner *s, int side) 9028{ 9029 SANE_Status ret = SANE_STATUS_GOOD; 9030 9031 unsigned char bg_color = calc_bg_color(s); 9032 9033 DBG (10, "buffer_deskew: start\n"); 9034 9035 ret = sane_get_parameters((SANE_Handle) s, &s->s_params); 9036 9037 /*only find skew on first image from a page, or if first image had error */ 9038 if(s->side == SIDE_FRONT || s->u.source == SOURCE_ADF_BACK || s->deskew_stat){ 9039 9040 s->deskew_stat = sanei_magic_findSkew( 9041 &s->s_params,s->buffers[side],s->u.dpi_x,s->u.dpi_y, 9042 &s->deskew_vals[0],&s->deskew_vals[1],&s->deskew_slope); 9043 9044 if(s->deskew_stat){ 9045 DBG (5, "buffer_deskew: bad findSkew, bailing\n"); 9046 goto cleanup; 9047 } 9048 } 9049 /* backside images can use a 'flipped' version of frontside data */ 9050 else{ 9051 s->deskew_slope *= -1; 9052 s->deskew_vals[0] = s->s_params.pixels_per_line - s->deskew_vals[0]; 9053 } 9054 9055 ret = sanei_magic_rotate(&s->s_params,s->buffers[side], 9056 s->deskew_vals[0],s->deskew_vals[1],s->deskew_slope,bg_color); 9057 9058 if(ret){ 9059 DBG(5,"buffer_deskew: rotate error: %d",ret); 9060 ret = SANE_STATUS_GOOD; 9061 goto cleanup; 9062 } 9063 9064 cleanup: 9065 DBG (10, "buffer_deskew: finish\n"); 9066 return ret; 9067} 9068 9069/* Look in image for likely left/right/bottom paper edges, then crop 9070 * image to match. Does not attempt to rotate the image. 9071 * FIXME: should we do this before we binarize instead of after? */ 9072static SANE_Status 9073buffer_crop(struct scanner *s, int side) 9074{ 9075 SANE_Status ret = SANE_STATUS_GOOD; 9076 9077 DBG (10, "buffer_crop: start\n"); 9078 9079 ret = sane_get_parameters((SANE_Handle) s, &s->s_params); 9080 9081 ret = sanei_magic_findEdges( 9082 &s->s_params,s->buffers[side],s->u.dpi_x,s->u.dpi_y, 9083 &s->crop_vals[0],&s->crop_vals[1],&s->crop_vals[2],&s->crop_vals[3]); 9084 9085 if(ret){ 9086 DBG (5, "buffer_crop: bad edges, bailing\n"); 9087 ret = SANE_STATUS_GOOD; 9088 goto cleanup; 9089 } 9090 9091 DBG (15, "buffer_crop: t:%d b:%d l:%d r:%d\n", 9092 s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]); 9093 9094 /* if we will later binarize this image, make sure the width 9095 * is a multiple of 8 pixels, by adjusting the right side */ 9096 if ( must_downsample(s) && s->u.mode < MODE_GRAYSCALE ){ 9097 s->crop_vals[3] -= (s->crop_vals[3]-s->crop_vals[2]) % 8; 9098 } 9099 9100 /* now crop the image */ 9101 ret = sanei_magic_crop(&s->s_params,s->buffers[side], 9102 s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]); 9103 9104 if(ret){ 9105 DBG (5, "buffer_crop: bad crop, bailing\n"); 9106 ret = SANE_STATUS_GOOD; 9107 goto cleanup; 9108 } 9109 9110 /* need to update user with new size */ 9111 s->i.width = s->s_params.pixels_per_line; 9112 s->i.height = s->s_params.lines; 9113 s->i.Bpl = s->s_params.bytes_per_line; 9114 9115 /* update image size counter to new, smaller size */ 9116 s->i.bytes_tot[side] = s->s_params.lines * s->s_params.bytes_per_line; 9117 s->i.bytes_sent[side] = s->i.bytes_tot[side]; 9118 s->u.bytes_sent[side] = 0; 9119 9120 cleanup: 9121 DBG (10, "buffer_crop: finish\n"); 9122 return ret; 9123} 9124 9125/* Look in image for disconnected 'spots' of the requested size. 9126 * Replace the spots with the average color of the surrounding pixels. 9127 * FIXME: should we do this before we binarize instead of after? */ 9128static SANE_Status 9129buffer_despeck(struct scanner *s, int side) 9130{ 9131 SANE_Status ret = SANE_STATUS_GOOD; 9132 9133 DBG (10, "buffer_despeck: start\n"); 9134 9135 ret = sane_get_parameters((SANE_Handle) s, &s->s_params); 9136 9137 ret = sanei_magic_despeck(&s->s_params,s->buffers[side],s->swdespeck); 9138 if(ret){ 9139 DBG (5, "buffer_despeck: bad despeck, bailing\n"); 9140 ret = SANE_STATUS_GOOD; 9141 goto cleanup; 9142 } 9143 9144 cleanup: 9145 DBG (10, "buffer_despeck: finish\n"); 9146 return ret; 9147} 9148 9149/* Look if image has too few dark pixels.*/ 9150static int 9151buffer_isblank(struct scanner *s, int side) 9152{ 9153 SANE_Status ret = SANE_STATUS_GOOD; 9154 int status = 0; 9155 9156 DBG (10, "buffer_isblank: start\n"); 9157 9158 ret = sane_get_parameters((SANE_Handle) s, &s->s_params); 9159 9160 ret = sanei_magic_isBlank2(&s->s_params, s->buffers[side], 9161 s->u.dpi_x, s->u.dpi_y, s->swskip); 9162 9163 if(ret == SANE_STATUS_NO_DOCS){ 9164 DBG (5, "buffer_isblank: blank!\n"); 9165 status = 1; 9166 } 9167 else if(ret){ 9168 DBG (5, "buffer_isblank: error %d\n",ret); 9169 } 9170 9171 DBG (10, "buffer_isblank: finished\n"); 9172 return status; 9173} 9174 9175/* certain options require the entire image to 9176 * be collected from the scanner before we can 9177 * tell the user the size of the image. */ 9178static int 9179must_fully_buffer(struct scanner *s) 9180{ 9181 9182 if( 9183 (s->swdeskew || s->swdespeck || s->swcrop) 9184 && s->s.format != SANE_FRAME_JPEG 9185 ){ 9186 return 1; 9187 } 9188 9189 return 0; 9190} 9191 9192/* certain scanners require the mode of the 9193 * image to be changed in software. */ 9194static int 9195must_downsample(struct scanner *s) 9196{ 9197 if(s->s.mode != s->i.mode 9198 && s->compress != COMP_JPEG 9199 ){ 9200 return 1; 9201 } 9202 9203 return 0; 9204} 9205 9206/* Function to build a lookup table (LUT), often 9207 used by scanners to implement brightness/contrast/gamma 9208 or by backends to speed binarization/thresholding 9209 9210 offset and slope inputs are -127 to +127 9211 9212 slope rotates line around central input/output val, 9213 0 makes horizontal line 9214 9215 pos zero neg 9216 . x . . x 9217 . x . . x 9218 out . x .xxxxxxxxxxx . x 9219 . x . . x 9220 ....x....... ............ .......x.... 9221 in in in 9222 9223 offset moves line vertically, and clamps to output range 9224 0 keeps the line crossing the center of the table 9225 9226 pos zero neg 9227 . xxxxxxxx . xx . 9228 . x . x . 9229 out x . x . x 9230 . . x . x 9231 ............ xx.......... xxxxxxxx.... 9232 in in 9233 9234 out_min/max provide bounds on output values, 9235 useful when building thresholding lut. 9236 0 and 255 are good defaults otherwise. 9237 */ 9238static SANE_Status 9239load_lut (unsigned char * lut, 9240 int in_bits, int out_bits, 9241 int out_min, int out_max, 9242 int slope, int offset) 9243{ 9244 SANE_Status ret = SANE_STATUS_GOOD; 9245 int i, j; 9246 double shift, rise; 9247 int max_in_val = (1 << in_bits) - 1; 9248 int max_out_val = (1 << out_bits) - 1; 9249 unsigned char * lut_p = lut; 9250 9251 DBG (10, "load_lut: start %d %d\n", slope, offset); 9252 9253 /* slope is converted to rise per unit run: 9254 * first [-127,127] to [-.999,.999] 9255 * then to [-PI/4,PI/4] then [0,PI/2] 9256 * then take the tangent (T.O.A) 9257 * then multiply by the normal linear slope 9258 * because the table may not be square, i.e. 1024x256*/ 9259 rise = tan((double)slope/128 * M_PI_4 + M_PI_4) * max_out_val / max_in_val; 9260 9261 /* line must stay vertically centered, so figure 9262 * out vertical offset at central input value */ 9263 shift = (double)max_out_val/2 - (rise*max_in_val/2); 9264 9265 /* convert the user offset setting to scale of output 9266 * first [-127,127] to [-1,1] 9267 * then to [-max_out_val/2,max_out_val/2]*/ 9268 shift += (double)offset / 127 * max_out_val / 2; 9269 9270 for(i=0;i<=max_in_val;i++){ 9271 j = rise*i + shift; 9272 9273 if(j<out_min){ 9274 j=out_min; 9275 } 9276 else if(j>out_max){ 9277 j=out_max; 9278 } 9279 9280 *lut_p=j; 9281 lut_p++; 9282 } 9283 9284 hexdump(5, "load_lut: ", lut, max_in_val+1); 9285 9286 DBG (10, "load_lut: finish\n"); 9287 return ret; 9288} 9289