1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci pie.c 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci Copyright (C) 2000 Simon Munton, based on the umax backend by Oliver Rauch 6141cc406Sopenharmony_ci 7141cc406Sopenharmony_ci This file is part of the SANE package. 8141cc406Sopenharmony_ci 9141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 10141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 11141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 12141cc406Sopenharmony_ci License, or (at your option) any later version. 13141cc406Sopenharmony_ci 14141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 15141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 16141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17141cc406Sopenharmony_ci General Public License for more details. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 20141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 23141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 24141cc406Sopenharmony_ci 25141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 26141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 27141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 28141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 29141cc406Sopenharmony_ci account of linking the SANE library code into it. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 32141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 33141cc406Sopenharmony_ci License. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 36141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 37141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 38141cc406Sopenharmony_ci 39141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 40141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 41141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. */ 42141cc406Sopenharmony_ci 43141cc406Sopenharmony_ci/* 44141cc406Sopenharmony_ci * 22-2-2003 set devlist to NULL in sane_exit() 45141cc406Sopenharmony_ci * set first_dev to NULL in sane_exit() 46141cc406Sopenharmony_ci * eliminated num_devices 47141cc406Sopenharmony_ci * 48141cc406Sopenharmony_ci * 23-7-2002 added TL_X > BR_X, TL_Y > BR_Y check in sane_start 49141cc406Sopenharmony_ci * 50141cc406Sopenharmony_ci * 17-9-2001 changed ADLIB to AdLib as the comparison is case sensitive and 51141cc406Sopenharmony_ci * the scanner returns AdLib 52141cc406Sopenharmony_ci * 53141cc406Sopenharmony_ci * 7-5-2001 removed removal of '\n' after sanei_config_read() 54141cc406Sopenharmony_ci * free devlist allocated in sane_get_devices() on sane_exit() 55141cc406Sopenharmony_ci * 56141cc406Sopenharmony_ci * 2-3-2001 improved the reordering of RGB data in pie_reader_process() 57141cc406Sopenharmony_ci * 58141cc406Sopenharmony_ci * 11-11-2000 eliminated some warnings about signed/unsigned comparisons 59141cc406Sopenharmony_ci * removed #undef NDEBUG and C++ style comments 60141cc406Sopenharmony_ci * 61141cc406Sopenharmony_ci * 1-10-2000 force gamma table to one to one mapping if lineart or halftone selected 62141cc406Sopenharmony_ci * 63141cc406Sopenharmony_ci * 30-9-2000 added ADLIB devices to scanner_str[] 64141cc406Sopenharmony_ci * 65141cc406Sopenharmony_ci * 29-9-2000 wasn't setting 'background is halftone bit' (BGHT) in halftone mode 66141cc406Sopenharmony_ci * 67141cc406Sopenharmony_ci * 27-9-2000 went public with build 4 68141cc406Sopenharmony_ci */ 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci#include "../include/sane/config.h" 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci#include <errno.h> 73141cc406Sopenharmony_ci#include <fcntl.h> 74141cc406Sopenharmony_ci#include <limits.h> 75141cc406Sopenharmony_ci#include <signal.h> 76141cc406Sopenharmony_ci#include <stdio.h> 77141cc406Sopenharmony_ci#include <stdlib.h> 78141cc406Sopenharmony_ci#include <string.h> 79141cc406Sopenharmony_ci#include <sys/types.h> 80141cc406Sopenharmony_ci#include <sys/wait.h> 81141cc406Sopenharmony_ci#include <unistd.h> 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ci#include "../include/sane/sane.h" 84141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 85141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 86141cc406Sopenharmony_ci#include "../include/sane/sanei_scsi.h" 87141cc406Sopenharmony_ci#include "../include/sane/sanei_debug.h" 88141cc406Sopenharmony_ci 89141cc406Sopenharmony_ci#define BACKEND_NAME pie 90141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 91141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci# include "../include/sane/sanei_thread.h" 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_ci#include "pie-scsidef.h" 96141cc406Sopenharmony_ci 97141cc406Sopenharmony_ci#define DBG_error0 0 98141cc406Sopenharmony_ci#define DBG_error 1 99141cc406Sopenharmony_ci#define DBG_sense 2 100141cc406Sopenharmony_ci#define DBG_warning 3 101141cc406Sopenharmony_ci#define DBG_inquiry 4 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci#define DBG_info 5 104141cc406Sopenharmony_ci#define DBG_info2 6 105141cc406Sopenharmony_ci#define DBG_proc 7 106141cc406Sopenharmony_ci#define DBG_read 8 107141cc406Sopenharmony_ci#define DBG_sane_init 10 108141cc406Sopenharmony_ci#define DBG_sane_proc 11 109141cc406Sopenharmony_ci#define DBG_sane_info 12 110141cc406Sopenharmony_ci#define DBG_sane_option 13 111141cc406Sopenharmony_ci#define DBG_dump 14 112141cc406Sopenharmony_ci 113141cc406Sopenharmony_ci#define BUILD 9 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_ci#define PIE_CONFIG_FILE "pie.conf" 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_ci#define LINEART_STR SANE_VALUE_SCAN_MODE_LINEART 118141cc406Sopenharmony_ci#define HALFTONE_STR SANE_VALUE_SCAN_MODE_HALFTONE 119141cc406Sopenharmony_ci#define GRAY_STR SANE_VALUE_SCAN_MODE_GRAY 120141cc406Sopenharmony_ci#define COLOR_STR SANE_VALUE_SCAN_MODE_COLOR 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci#define LINEART 1 123141cc406Sopenharmony_ci#define HALFTONE 2 124141cc406Sopenharmony_ci#define GRAYSCALE 3 125141cc406Sopenharmony_ci#define RGB 4 126141cc406Sopenharmony_ci 127141cc406Sopenharmony_ci#define CAL_MODE_PREVIEW (INQ_CAP_FAST_PREVIEW) 128141cc406Sopenharmony_ci#define CAL_MODE_FLATBED 0x00 129141cc406Sopenharmony_ci#define CAL_MODE_ADF (INQ_OPT_DEV_ADF) 130141cc406Sopenharmony_ci#define CAL_MODE_TRANPSARENCY (INQ_OPT_DEV_TP) 131141cc406Sopenharmony_ci#define CAL_MODE_TRANPSARENCY1 (INQ_OPT_DEV_TP1) 132141cc406Sopenharmony_ci 133141cc406Sopenharmony_ci#define min(a,b) (((a)<(b))?(a):(b)) 134141cc406Sopenharmony_ci#define max(a,b) (((a)>(b))?(a):(b)) 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci/* names of scanners that are supported because */ 138141cc406Sopenharmony_ci/* the inquiry_return_block is ok and driver is tested */ 139141cc406Sopenharmony_ci 140141cc406Sopenharmony_cistatic char *scanner_str[] = { 141141cc406Sopenharmony_ci "DEVCOM", "9636PRO", 142141cc406Sopenharmony_ci "DEVCOM", "9636S", 143141cc406Sopenharmony_ci "DEVCOM", "9630S", 144141cc406Sopenharmony_ci "PIE", "ScanAce 1236S", 145141cc406Sopenharmony_ci "PIE", "ScanAce 1230S", 146141cc406Sopenharmony_ci "PIE", "ScanAce II", 147141cc406Sopenharmony_ci "PIE", "ScanAce III", 148141cc406Sopenharmony_ci "PIE", "ScanAce Plus", 149141cc406Sopenharmony_ci "PIE", "ScanAce II Plus", 150141cc406Sopenharmony_ci "PIE", "ScanAce III Plus", 151141cc406Sopenharmony_ci "PIE", "ScanAce V", 152141cc406Sopenharmony_ci "PIE", "ScanMedia", 153141cc406Sopenharmony_ci "PIE", "ScanMedia II", 154141cc406Sopenharmony_ci "PIE", "ScanAce 630S", 155141cc406Sopenharmony_ci "PIE", "ScanAce 636S", 156141cc406Sopenharmony_ci "AdLib", "JetScan 630", 157141cc406Sopenharmony_ci "AdLib", "JetScan 636PRO", 158141cc406Sopenharmony_ci "END_OF_LIST" 159141cc406Sopenharmony_ci}; 160141cc406Sopenharmony_ci 161141cc406Sopenharmony_ci/* times (in us) to delay after certain commands. Scanner seems to lock up if it returns busy 162141cc406Sopenharmony_ci * status and commands are repeatedly reissued (by kernel error handler) */ 163141cc406Sopenharmony_ci 164141cc406Sopenharmony_ci#define DOWNLOAD_GAMMA_WAIT_TIME (1000000) 165141cc406Sopenharmony_ci#define SCAN_WAIT_TIME (1000000) 166141cc406Sopenharmony_ci#define SCAN_WARMUP_WAIT_TIME (500000) 167141cc406Sopenharmony_ci#define TUR_WAIT_TIME (500000) 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_ci/* options supported by the scanner */ 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_cienum Pie_Option 173141cc406Sopenharmony_ci{ 174141cc406Sopenharmony_ci OPT_NUM_OPTS = 0, 175141cc406Sopenharmony_ci 176141cc406Sopenharmony_ci /* ------------------------------------------- */ 177141cc406Sopenharmony_ci OPT_MODE_GROUP, 178141cc406Sopenharmony_ci OPT_MODE, 179141cc406Sopenharmony_ci OPT_RESOLUTION, 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci 182141cc406Sopenharmony_ci /* ------------------------------------------- */ 183141cc406Sopenharmony_ci 184141cc406Sopenharmony_ci OPT_GEOMETRY_GROUP, 185141cc406Sopenharmony_ci OPT_TL_X, /* top-left x */ 186141cc406Sopenharmony_ci OPT_TL_Y, /* top-left y */ 187141cc406Sopenharmony_ci OPT_BR_X, /* bottom-right x */ 188141cc406Sopenharmony_ci OPT_BR_Y, /* bottom-right y */ 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_ci /* ------------------------------------------- */ 191141cc406Sopenharmony_ci 192141cc406Sopenharmony_ci OPT_ENHANCEMENT_GROUP, 193141cc406Sopenharmony_ci 194141cc406Sopenharmony_ci OPT_HALFTONE_PATTERN, 195141cc406Sopenharmony_ci OPT_SPEED, 196141cc406Sopenharmony_ci OPT_THRESHOLD, 197141cc406Sopenharmony_ci 198141cc406Sopenharmony_ci OPT_GAMMA_VECTOR, 199141cc406Sopenharmony_ci OPT_GAMMA_VECTOR_R, 200141cc406Sopenharmony_ci OPT_GAMMA_VECTOR_G, 201141cc406Sopenharmony_ci OPT_GAMMA_VECTOR_B, 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci /* ------------------------------------------- */ 204141cc406Sopenharmony_ci 205141cc406Sopenharmony_ci OPT_ADVANCED_GROUP, 206141cc406Sopenharmony_ci OPT_PREVIEW, 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_ci /* must come last: */ 209141cc406Sopenharmony_ci NUM_OPTIONS 210141cc406Sopenharmony_ci}; 211141cc406Sopenharmony_ci 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci 214141cc406Sopenharmony_ci 215141cc406Sopenharmony_ci/* This defines the information needed during calibration */ 216141cc406Sopenharmony_ci 217141cc406Sopenharmony_cistruct Pie_cal_info 218141cc406Sopenharmony_ci{ 219141cc406Sopenharmony_ci int cal_type; 220141cc406Sopenharmony_ci int receive_bits; 221141cc406Sopenharmony_ci int send_bits; 222141cc406Sopenharmony_ci int num_lines; 223141cc406Sopenharmony_ci int pixels_per_line; 224141cc406Sopenharmony_ci}; 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci/* This structure holds the information about a physical scanner */ 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_citypedef struct Pie_Device 230141cc406Sopenharmony_ci{ 231141cc406Sopenharmony_ci struct Pie_Device *next; 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci char *devicename; /* name of the scanner device */ 234141cc406Sopenharmony_ci 235141cc406Sopenharmony_ci char vendor[9]; /* will be xxxxx */ 236141cc406Sopenharmony_ci char product[17]; /* e.g. "SuperVista_S12" or so */ 237141cc406Sopenharmony_ci char version[5]; /* e.g. V1.3 */ 238141cc406Sopenharmony_ci 239141cc406Sopenharmony_ci SANE_Device sane; 240141cc406Sopenharmony_ci SANE_Range dpi_range; 241141cc406Sopenharmony_ci SANE_Range x_range; 242141cc406Sopenharmony_ci SANE_Range y_range; 243141cc406Sopenharmony_ci 244141cc406Sopenharmony_ci SANE_Range exposure_range; 245141cc406Sopenharmony_ci SANE_Range shadow_range; 246141cc406Sopenharmony_ci SANE_Range highlight_range; 247141cc406Sopenharmony_ci 248141cc406Sopenharmony_ci int inquiry_len; /* length of inquiry return block */ 249141cc406Sopenharmony_ci 250141cc406Sopenharmony_ci int inquiry_x_res; /* maximum x-resolution */ 251141cc406Sopenharmony_ci int inquiry_y_res; /* maximum y-resolution */ 252141cc406Sopenharmony_ci int inquiry_pixel_resolution; 253141cc406Sopenharmony_ci double inquiry_fb_width; /* flatbed width in inches */ 254141cc406Sopenharmony_ci double inquiry_fb_length; /* flatbed length in inches */ 255141cc406Sopenharmony_ci 256141cc406Sopenharmony_ci int inquiry_trans_top_left_x; 257141cc406Sopenharmony_ci int inquiry_trans_top_left_y; 258141cc406Sopenharmony_ci double inquiry_trans_width; /* transparency width in inches */ 259141cc406Sopenharmony_ci double inquiry_trans_length; /* transparency length in inches */ 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci int inquiry_halftones; /* number of halftones supported */ 262141cc406Sopenharmony_ci int inquiry_filters; /* available colour filters */ 263141cc406Sopenharmony_ci int inquiry_color_depths; /* available colour depths */ 264141cc406Sopenharmony_ci int inquiry_color_format; /* colour format from scanner */ 265141cc406Sopenharmony_ci int inquiry_image_format; /* image data format */ 266141cc406Sopenharmony_ci int inquiry_scan_capability; /* additional scanner features, number of speeds */ 267141cc406Sopenharmony_ci int inquiry_optional_devices; /* optional devices */ 268141cc406Sopenharmony_ci int inquiry_enhancements; /* enhancements */ 269141cc406Sopenharmony_ci int inquiry_gamma_bits; /* no of bits used for gamma table */ 270141cc406Sopenharmony_ci int inquiry_fast_preview_res; /* fast preview resolution */ 271141cc406Sopenharmony_ci int inquiry_min_highlight; /* min highlight % that can be used */ 272141cc406Sopenharmony_ci int inquiry_max_shadow; /* max shadow % that can be used */ 273141cc406Sopenharmony_ci int inquiry_cal_eqn; /* which calibration equation to use */ 274141cc406Sopenharmony_ci int inquiry_min_exp; /* min exposure % */ 275141cc406Sopenharmony_ci int inquiry_max_exp; /* max exposure % */ 276141cc406Sopenharmony_ci 277141cc406Sopenharmony_ci SANE_String scan_mode_list[7]; /* holds names of types of scan (color, ...) */ 278141cc406Sopenharmony_ci 279141cc406Sopenharmony_ci SANE_String halftone_list[17]; /* holds the names of the halftone patterns from the scanner */ 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_ci SANE_String speed_list[9]; /* holds the names of available speeds */ 282141cc406Sopenharmony_ci 283141cc406Sopenharmony_ci int cal_info_count; /* number of calibration info sets */ 284141cc406Sopenharmony_ci struct Pie_cal_info *cal_info; /* points to the actual calibration information */ 285141cc406Sopenharmony_ci} 286141cc406Sopenharmony_ciPie_Device; 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci/* This structure holds information about an instance of an 'opened' scanner */ 289141cc406Sopenharmony_ci 290141cc406Sopenharmony_citypedef struct Pie_Scanner 291141cc406Sopenharmony_ci{ 292141cc406Sopenharmony_ci struct Pie_Scanner *next; 293141cc406Sopenharmony_ci Pie_Device *device; /* pointer to physical scanner */ 294141cc406Sopenharmony_ci 295141cc406Sopenharmony_ci int sfd; /* scanner file desc. */ 296141cc406Sopenharmony_ci int bufsize; /* max scsi buffer size */ 297141cc406Sopenharmony_ci 298141cc406Sopenharmony_ci SANE_Option_Descriptor opt[NUM_OPTIONS]; /* option descriptions for this instance */ 299141cc406Sopenharmony_ci Option_Value val[NUM_OPTIONS]; /* option settings for this instance */ 300141cc406Sopenharmony_ci SANE_Int *gamma_table[4]; /* gamma tables for this instance */ 301141cc406Sopenharmony_ci SANE_Range gamma_range; 302141cc406Sopenharmony_ci int gamma_length; /* size of gamma table */ 303141cc406Sopenharmony_ci 304141cc406Sopenharmony_ci int scanning; /* true if actually doing a scan */ 305141cc406Sopenharmony_ci SANE_Parameters params; 306141cc406Sopenharmony_ci 307141cc406Sopenharmony_ci SANE_Pid reader_pid; 308141cc406Sopenharmony_ci int pipe; 309141cc406Sopenharmony_ci int reader_fds; 310141cc406Sopenharmony_ci 311141cc406Sopenharmony_ci int colormode; /* whether RGB, GRAY, LINEART, HALFTONE */ 312141cc406Sopenharmony_ci int resolution; 313141cc406Sopenharmony_ci int cal_mode; /* set to value to compare cal_info mode to */ 314141cc406Sopenharmony_ci 315141cc406Sopenharmony_ci int cal_filter; /* set to indicate which filters will provide data for cal */ 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci int filter_offset1; /* offsets between colors in indexed scan mode */ 318141cc406Sopenharmony_ci int filter_offset2; 319141cc406Sopenharmony_ci 320141cc406Sopenharmony_ci int bytes_per_line; /* number of bytes per line */ 321141cc406Sopenharmony_ci 322141cc406Sopenharmony_ci} 323141cc406Sopenharmony_ciPie_Scanner; 324141cc406Sopenharmony_ci 325141cc406Sopenharmony_cistatic const SANE_Range percentage_range_100 = { 326141cc406Sopenharmony_ci 0 << SANE_FIXED_SCALE_SHIFT, /* minimum */ 327141cc406Sopenharmony_ci 100 << SANE_FIXED_SCALE_SHIFT, /* maximum */ 328141cc406Sopenharmony_ci 0 << SANE_FIXED_SCALE_SHIFT /* quantization */ 329141cc406Sopenharmony_ci}; 330141cc406Sopenharmony_ci 331141cc406Sopenharmony_cistatic Pie_Device *first_dev = NULL; 332141cc406Sopenharmony_cistatic Pie_Scanner *first_handle = NULL; 333141cc406Sopenharmony_cistatic const SANE_Device **devlist = NULL; 334141cc406Sopenharmony_ci 335141cc406Sopenharmony_ci 336141cc406Sopenharmony_ci 337141cc406Sopenharmony_cistatic SANE_Status pie_wait_scanner (Pie_Scanner * scanner); 338141cc406Sopenharmony_ci 339141cc406Sopenharmony_ci 340141cc406Sopenharmony_ci/* ---------------------------------- PIE DUMP_BUFFER ---------------------------------- */ 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci#define DBG_DUMP(level, buf, n) { if (DBG_LEVEL >= (level)) pie_dump_buffer(level,buf,n); } 343141cc406Sopenharmony_ci 344141cc406Sopenharmony_ci 345141cc406Sopenharmony_cistatic void 346141cc406Sopenharmony_cipie_dump_buffer (int level, unsigned char *buf, int n) 347141cc406Sopenharmony_ci{ 348141cc406Sopenharmony_ci char s[80], *p = s; 349141cc406Sopenharmony_ci int a = 0; 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_ci while (n--) 352141cc406Sopenharmony_ci { 353141cc406Sopenharmony_ci if ((a % 16) == 0) 354141cc406Sopenharmony_ci p += sprintf (p, " %04X ", a); 355141cc406Sopenharmony_ci 356141cc406Sopenharmony_ci p += sprintf (p, "%02X ", *buf++); 357141cc406Sopenharmony_ci 358141cc406Sopenharmony_ci if ((n == 0) || (a % 16) == 15) 359141cc406Sopenharmony_ci { 360141cc406Sopenharmony_ci DBG (level, "%s\n", s); 361141cc406Sopenharmony_ci p = s; 362141cc406Sopenharmony_ci } 363141cc406Sopenharmony_ci a++; 364141cc406Sopenharmony_ci } 365141cc406Sopenharmony_ci} 366141cc406Sopenharmony_ci 367141cc406Sopenharmony_ci/* ---------------------------------- PIE INIT ---------------------------------- */ 368141cc406Sopenharmony_ci 369141cc406Sopenharmony_cistatic void 370141cc406Sopenharmony_cipie_init (Pie_Device * dev) /* pie_init is called once while driver-initialization */ 371141cc406Sopenharmony_ci{ 372141cc406Sopenharmony_ci DBG (DBG_proc, "init\n"); 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci dev->cal_info_count = 0; 375141cc406Sopenharmony_ci dev->cal_info = NULL; 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci dev->devicename = NULL; 378141cc406Sopenharmony_ci dev->inquiry_len = 0; 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 381141cc406Sopenharmony_ci DBG (DBG_info, 382141cc406Sopenharmony_ci "variable scsi buffer size (usage of sanei_scsi_open_extended)\n"); 383141cc406Sopenharmony_ci#else 384141cc406Sopenharmony_ci DBG (DBG_info, "fixed scsi buffer size = %d bytes\n", 385141cc406Sopenharmony_ci sanei_scsi_max_request_size); 386141cc406Sopenharmony_ci#endif 387141cc406Sopenharmony_ci} 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci/* ---------------------------- SENSE_HANDLER ------------------------------ */ 391141cc406Sopenharmony_ci 392141cc406Sopenharmony_ci 393141cc406Sopenharmony_cistatic SANE_Status 394141cc406Sopenharmony_cisense_handler (__sane_unused__ int scsi_fd, unsigned char *result, __sane_unused__ void *arg) /* is called by sanei_scsi */ 395141cc406Sopenharmony_ci{ 396141cc406Sopenharmony_ci unsigned char asc, ascq, sensekey; 397141cc406Sopenharmony_ci int asc_ascq, len; 398141cc406Sopenharmony_ci /* Pie_Device *dev = arg; */ 399141cc406Sopenharmony_ci 400141cc406Sopenharmony_ci DBG (DBG_proc, "check condition sense handler\n"); 401141cc406Sopenharmony_ci 402141cc406Sopenharmony_ci sensekey = get_RS_sense_key (result); 403141cc406Sopenharmony_ci asc = get_RS_ASC (result); 404141cc406Sopenharmony_ci ascq = get_RS_ASCQ (result); 405141cc406Sopenharmony_ci asc_ascq = (int) (256 * asc + ascq); 406141cc406Sopenharmony_ci len = 7 + get_RS_additional_length (result); 407141cc406Sopenharmony_ci 408141cc406Sopenharmony_ci if (get_RS_error_code (result) != 0x70) 409141cc406Sopenharmony_ci { 410141cc406Sopenharmony_ci DBG (DBG_proc, "invalid sense key => handled as DEVICE BUSY!\n"); 411141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; /* sense key invalid */ 412141cc406Sopenharmony_ci } 413141cc406Sopenharmony_ci 414141cc406Sopenharmony_ci DBG (DBG_sense, "check condition sense: %s\n", sense_str[sensekey]); 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_ci if (get_RS_ILI (result) != 0) 417141cc406Sopenharmony_ci { 418141cc406Sopenharmony_ci DBG (DBG_sense, 419141cc406Sopenharmony_ci "-> ILI-ERROR: requested data length is larger than actual length\n"); 420141cc406Sopenharmony_ci } 421141cc406Sopenharmony_ci 422141cc406Sopenharmony_ci switch (sensekey) 423141cc406Sopenharmony_ci { 424141cc406Sopenharmony_ci case 0x00: /* no sense, could have been busy */ 425141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 426141cc406Sopenharmony_ci break; 427141cc406Sopenharmony_ci 428141cc406Sopenharmony_ci case 0x02: 429141cc406Sopenharmony_ci if (asc_ascq == 0x0401) 430141cc406Sopenharmony_ci DBG (DBG_sense, "-> Not Ready - Warming Up\n"); 431141cc406Sopenharmony_ci else if (asc_ascq == 0x0483) 432141cc406Sopenharmony_ci DBG (DBG_sense, "-> Not Ready - Need manual service\n"); 433141cc406Sopenharmony_ci else if (asc_ascq == 0x0881) 434141cc406Sopenharmony_ci DBG (DBG_sense, "-> Not Ready - Communication time out\n"); 435141cc406Sopenharmony_ci else 436141cc406Sopenharmony_ci DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc, 437141cc406Sopenharmony_ci ascq); 438141cc406Sopenharmony_ci break; 439141cc406Sopenharmony_ci 440141cc406Sopenharmony_ci case 0x03: /* medium error */ 441141cc406Sopenharmony_ci if (asc_ascq == 0x5300) 442141cc406Sopenharmony_ci DBG (DBG_sense, "-> Media load or eject failure\n"); 443141cc406Sopenharmony_ci else if (asc_ascq == 0x3a00) 444141cc406Sopenharmony_ci DBG (DBG_sense, "-> Media not present\n"); 445141cc406Sopenharmony_ci else if (asc_ascq == 0x3b05) 446141cc406Sopenharmony_ci DBG (DBG_sense, "-> Paper jam\n"); 447141cc406Sopenharmony_ci else if (asc_ascq == 0x3a80) 448141cc406Sopenharmony_ci DBG (DBG_sense, "-> ADF paper out\n"); 449141cc406Sopenharmony_ci else 450141cc406Sopenharmony_ci DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc, 451141cc406Sopenharmony_ci ascq); 452141cc406Sopenharmony_ci break; 453141cc406Sopenharmony_ci 454141cc406Sopenharmony_ci 455141cc406Sopenharmony_ci case 0x04: /* hardware error */ 456141cc406Sopenharmony_ci if (asc_ascq == 0x4081) 457141cc406Sopenharmony_ci DBG (DBG_sense, "-> CPU RAM failure\n"); 458141cc406Sopenharmony_ci else if (asc_ascq == 0x4082) 459141cc406Sopenharmony_ci DBG (DBG_sense, "-> Scanning system RAM failure\n"); 460141cc406Sopenharmony_ci else if (asc_ascq == 0x4083) 461141cc406Sopenharmony_ci DBG (DBG_sense, "-> Image buffer failure\n"); 462141cc406Sopenharmony_ci else if (asc_ascq == 0x0403) 463141cc406Sopenharmony_ci DBG (DBG_sense, "-> Manual intervention required\n"); 464141cc406Sopenharmony_ci else if (asc_ascq == 0x6200) 465141cc406Sopenharmony_ci DBG (DBG_sense, "-> Scan head position error\n"); 466141cc406Sopenharmony_ci else if (asc_ascq == 0x6000) 467141cc406Sopenharmony_ci DBG (DBG_sense, "-> Lamp or CCD failure\n"); 468141cc406Sopenharmony_ci else if (asc_ascq == 0x6081) 469141cc406Sopenharmony_ci DBG (DBG_sense, "-> Transparency lamp failure\n"); 470141cc406Sopenharmony_ci else if (asc_ascq == 0x8180) 471141cc406Sopenharmony_ci DBG (DBG_sense, "-> DC offset or black level calibration failure\n"); 472141cc406Sopenharmony_ci else if (asc_ascq == 0x8181) 473141cc406Sopenharmony_ci DBG (DBG_sense, 474141cc406Sopenharmony_ci "-> Integration time adjustment failure (too light)\n"); 475141cc406Sopenharmony_ci else if (asc_ascq == 0x8182) 476141cc406Sopenharmony_ci DBG (DBG_sense, 477141cc406Sopenharmony_ci "-> Integration time adjustment failure (too dark)\n"); 478141cc406Sopenharmony_ci else if (asc_ascq == 0x8183) 479141cc406Sopenharmony_ci DBG (DBG_sense, "-> Shading curve adjustment failure\n"); 480141cc406Sopenharmony_ci else if (asc_ascq == 0x8184) 481141cc406Sopenharmony_ci DBG (DBG_sense, "-> Gain adjustment failure\n"); 482141cc406Sopenharmony_ci else if (asc_ascq == 0x8185) 483141cc406Sopenharmony_ci DBG (DBG_sense, "-> Optical alignment failure\n"); 484141cc406Sopenharmony_ci else if (asc_ascq == 0x8186) 485141cc406Sopenharmony_ci DBG (DBG_sense, "-> Optical locating failure\n"); 486141cc406Sopenharmony_ci else if (asc_ascq == 0x8187) 487141cc406Sopenharmony_ci DBG (DBG_sense, "-> Scan pixel map less than 5100 pixels!\n"); 488141cc406Sopenharmony_ci else if (asc_ascq == 0x4700) 489141cc406Sopenharmony_ci DBG (DBG_sense, "-> Parity error on SCSI bus\n"); 490141cc406Sopenharmony_ci else if (asc_ascq == 0x4b00) 491141cc406Sopenharmony_ci DBG (DBG_sense, "-> Data phase error\n"); 492141cc406Sopenharmony_ci else 493141cc406Sopenharmony_ci DBG (DBG_sense, "-> unknown hardware error: asc=%d, ascq=%d\n", asc, 494141cc406Sopenharmony_ci ascq); 495141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 496141cc406Sopenharmony_ci break; 497141cc406Sopenharmony_ci 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci case 0x05: /* illegal request */ 500141cc406Sopenharmony_ci if (asc_ascq == 0x1a00) 501141cc406Sopenharmony_ci DBG (DBG_sense, "-> Parameter list length error\n"); 502141cc406Sopenharmony_ci else if (asc_ascq == 0x2c01) 503141cc406Sopenharmony_ci DBG (DBG_sense, "-> Too many windows specified\n"); 504141cc406Sopenharmony_ci else if (asc_ascq == 0x2c02) 505141cc406Sopenharmony_ci DBG (DBG_sense, "-> Invalid combination of windows\n"); 506141cc406Sopenharmony_ci else if (asc_ascq == 0x2c81) 507141cc406Sopenharmony_ci DBG (DBG_sense, "-> Illegal scanning frame\n"); 508141cc406Sopenharmony_ci else if (asc_ascq == 0x2400) 509141cc406Sopenharmony_ci DBG (DBG_sense, "-> Invalid field in CDB\n"); 510141cc406Sopenharmony_ci else if (asc_ascq == 0x2481) 511141cc406Sopenharmony_ci DBG (DBG_sense, "-> Request too many lines of data\n"); 512141cc406Sopenharmony_ci else if (asc_ascq == 0x2000) 513141cc406Sopenharmony_ci DBG (DBG_sense, "-> Invalid command OP code\n"); 514141cc406Sopenharmony_ci else if (asc_ascq == 0x2501) 515141cc406Sopenharmony_ci DBG (DBG_sense, "-> LUN not supported\n"); 516141cc406Sopenharmony_ci else if (asc_ascq == 0x2601) 517141cc406Sopenharmony_ci DBG (DBG_sense, "-> Parameter not supported\n"); 518141cc406Sopenharmony_ci else if (asc_ascq == 0x2602) 519141cc406Sopenharmony_ci DBG (DBG_sense, 520141cc406Sopenharmony_ci "-> Parameter value invalid - Parameter not specified\n"); 521141cc406Sopenharmony_ci else if (asc_ascq == 0x2603) 522141cc406Sopenharmony_ci DBG (DBG_sense, "-> Parameter value invalid - Invalid threshold\n"); 523141cc406Sopenharmony_ci else if (asc_ascq == 0x2680) 524141cc406Sopenharmony_ci DBG (DBG_sense, 525141cc406Sopenharmony_ci "-> Parameter value invalid - Control command sequence error\n"); 526141cc406Sopenharmony_ci else if (asc_ascq == 0x2681) 527141cc406Sopenharmony_ci DBG (DBG_sense, 528141cc406Sopenharmony_ci "-> Parameter value invalid - Grain setting (halftone pattern\n"); 529141cc406Sopenharmony_ci else if (asc_ascq == 0x2682) 530141cc406Sopenharmony_ci DBG (DBG_sense, 531141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal resolution setting\n"); 532141cc406Sopenharmony_ci else if (asc_ascq == 0x2683) 533141cc406Sopenharmony_ci DBG (DBG_sense, 534141cc406Sopenharmony_ci "-> Parameter value invalid - Invalid filter assignment\n"); 535141cc406Sopenharmony_ci else if (asc_ascq == 0x2684) 536141cc406Sopenharmony_ci DBG (DBG_sense, 537141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal gamma adjustment setting (look-up table)\n"); 538141cc406Sopenharmony_ci else if (asc_ascq == 0x2685) 539141cc406Sopenharmony_ci DBG (DBG_sense, 540141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal offset setting (digital brightness)\n"); 541141cc406Sopenharmony_ci else if (asc_ascq == 0x2686) 542141cc406Sopenharmony_ci DBG (DBG_sense, 543141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal bits per pixel setting\n"); 544141cc406Sopenharmony_ci else if (asc_ascq == 0x2687) 545141cc406Sopenharmony_ci DBG (DBG_sense, 546141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal contrast setting\n"); 547141cc406Sopenharmony_ci else if (asc_ascq == 0x2688) 548141cc406Sopenharmony_ci DBG (DBG_sense, 549141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal paper length setting\n"); 550141cc406Sopenharmony_ci else if (asc_ascq == 0x2689) 551141cc406Sopenharmony_ci DBG (DBG_sense, 552141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal highlight/shadow setting\n"); 553141cc406Sopenharmony_ci else if (asc_ascq == 0x268a) 554141cc406Sopenharmony_ci DBG (DBG_sense, 555141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal exposure time setting (analog brightness)\n"); 556141cc406Sopenharmony_ci else if (asc_ascq == 0x268b) 557141cc406Sopenharmony_ci DBG (DBG_sense, 558141cc406Sopenharmony_ci "-> Parameter value invalid - Invalid device select or device not exist\n"); 559141cc406Sopenharmony_ci else if (asc_ascq == 0x268c) 560141cc406Sopenharmony_ci DBG (DBG_sense, 561141cc406Sopenharmony_ci "-> Parameter value invalid - Illegal color packing\n"); 562141cc406Sopenharmony_ci else if (asc_ascq == 0x3d00) 563141cc406Sopenharmony_ci DBG (DBG_sense, "-> Invalid bits in identify field\n"); 564141cc406Sopenharmony_ci 565141cc406Sopenharmony_ci 566141cc406Sopenharmony_ci 567141cc406Sopenharmony_ci else if (asc_ascq == 0x4900) 568141cc406Sopenharmony_ci DBG (DBG_sense, "-> Invalid message\n"); 569141cc406Sopenharmony_ci else if (asc_ascq == 0x8101) 570141cc406Sopenharmony_ci DBG (DBG_sense, "-> Not enough memory for color packing\n"); 571141cc406Sopenharmony_ci 572141cc406Sopenharmony_ci if (len >= 0x11) 573141cc406Sopenharmony_ci { 574141cc406Sopenharmony_ci if (get_RS_SKSV (result) != 0) 575141cc406Sopenharmony_ci { 576141cc406Sopenharmony_ci if (get_RS_CD (result) == 0) 577141cc406Sopenharmony_ci { 578141cc406Sopenharmony_ci 579141cc406Sopenharmony_ci DBG (DBG_sense, "-> illegal parameter in CDB\n"); 580141cc406Sopenharmony_ci } 581141cc406Sopenharmony_ci else 582141cc406Sopenharmony_ci { 583141cc406Sopenharmony_ci DBG (DBG_sense, 584141cc406Sopenharmony_ci "-> illegal parameter is in the data parameters sent during data out phase\n"); 585141cc406Sopenharmony_ci } 586141cc406Sopenharmony_ci 587141cc406Sopenharmony_ci DBG (DBG_sense, "-> error detected in byte %d\n", 588141cc406Sopenharmony_ci get_RS_field_pointer (result)); 589141cc406Sopenharmony_ci } 590141cc406Sopenharmony_ci } 591141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 592141cc406Sopenharmony_ci break; 593141cc406Sopenharmony_ci 594141cc406Sopenharmony_ci 595141cc406Sopenharmony_ci case 0x06: /* unit attention */ 596141cc406Sopenharmony_ci if (asc_ascq == 0x2900) 597141cc406Sopenharmony_ci DBG (DBG_sense, "-> power on, reset or bus device reset\n"); 598141cc406Sopenharmony_ci if (asc_ascq == 0x8200) 599141cc406Sopenharmony_ci DBG (DBG_sense, 600141cc406Sopenharmony_ci "-> unit attention - calibration disable not granted\n"); 601141cc406Sopenharmony_ci if (asc_ascq == 0x8300) 602141cc406Sopenharmony_ci DBG (DBG_sense, "-> unit attention - calibration will be ignored\n"); 603141cc406Sopenharmony_ci else 604141cc406Sopenharmony_ci DBG (DBG_sense, "-> unit attention: asc=%d, ascq=%d\n", asc, ascq); 605141cc406Sopenharmony_ci break; 606141cc406Sopenharmony_ci 607141cc406Sopenharmony_ci 608141cc406Sopenharmony_ci case 0x09: /* vendor specific */ 609141cc406Sopenharmony_ci DBG (DBG_sense, "-> vendor specific sense-code: asc=%d, ascq=%d\n", asc, 610141cc406Sopenharmony_ci ascq); 611141cc406Sopenharmony_ci break; 612141cc406Sopenharmony_ci 613141cc406Sopenharmony_ci case 0x0b: 614141cc406Sopenharmony_ci if (asc_ascq == 0x0006) 615141cc406Sopenharmony_ci DBG (DBG_sense, "-> Received ABORT message from initiator\n"); 616141cc406Sopenharmony_ci if (asc_ascq == 0x4800) 617141cc406Sopenharmony_ci DBG (DBG_sense, "-> Initiator detected error message received\n"); 618141cc406Sopenharmony_ci if (asc_ascq == 0x4300) 619141cc406Sopenharmony_ci DBG (DBG_sense, "-> Message error\n"); 620141cc406Sopenharmony_ci if (asc_ascq == 0x4500) 621141cc406Sopenharmony_ci DBG (DBG_sense, "-> Select or re-select error\n"); 622141cc406Sopenharmony_ci else 623141cc406Sopenharmony_ci DBG (DBG_sense, "-> aborted command: asc=%d, ascq=%d\n", asc, ascq); 624141cc406Sopenharmony_ci break; 625141cc406Sopenharmony_ci 626141cc406Sopenharmony_ci } 627141cc406Sopenharmony_ci 628141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 629141cc406Sopenharmony_ci} 630141cc406Sopenharmony_ci 631141cc406Sopenharmony_ci 632141cc406Sopenharmony_ci/* -------------------------------- PIE PRINT INQUIRY ------------------------- */ 633141cc406Sopenharmony_ci 634141cc406Sopenharmony_ci 635141cc406Sopenharmony_cistatic void 636141cc406Sopenharmony_cipie_print_inquiry (Pie_Device * dev) 637141cc406Sopenharmony_ci{ 638141cc406Sopenharmony_ci DBG (DBG_inquiry, "INQUIRY:\n"); 639141cc406Sopenharmony_ci DBG (DBG_inquiry, "========\n"); 640141cc406Sopenharmony_ci DBG (DBG_inquiry, "\n"); 641141cc406Sopenharmony_ci DBG (DBG_inquiry, "vendor........................: '%s'\n", dev->vendor); 642141cc406Sopenharmony_ci DBG (DBG_inquiry, "product.......................: '%s'\n", dev->product); 643141cc406Sopenharmony_ci DBG (DBG_inquiry, "version.......................: '%s'\n", dev->version); 644141cc406Sopenharmony_ci 645141cc406Sopenharmony_ci DBG (DBG_inquiry, "X resolution..................: %d dpi\n", 646141cc406Sopenharmony_ci dev->inquiry_x_res); 647141cc406Sopenharmony_ci DBG (DBG_inquiry, "Y resolution..................: %d dpi\n", 648141cc406Sopenharmony_ci dev->inquiry_y_res); 649141cc406Sopenharmony_ci DBG (DBG_inquiry, "pixel resolution..............: %d dpi\n", 650141cc406Sopenharmony_ci dev->inquiry_pixel_resolution); 651141cc406Sopenharmony_ci DBG (DBG_inquiry, "fb width......................: %f in\n", 652141cc406Sopenharmony_ci dev->inquiry_fb_width); 653141cc406Sopenharmony_ci DBG (DBG_inquiry, "fb length.....................: %f in\n", 654141cc406Sopenharmony_ci dev->inquiry_fb_length); 655141cc406Sopenharmony_ci 656141cc406Sopenharmony_ci DBG (DBG_inquiry, "transparency width............: %f in\n", 657141cc406Sopenharmony_ci dev->inquiry_trans_width); 658141cc406Sopenharmony_ci DBG (DBG_inquiry, "transparency length...........: %f in\n", 659141cc406Sopenharmony_ci dev->inquiry_trans_length); 660141cc406Sopenharmony_ci DBG (DBG_inquiry, "transparency offset...........: %d,%d\n", 661141cc406Sopenharmony_ci dev->inquiry_trans_top_left_x, dev->inquiry_trans_top_left_y); 662141cc406Sopenharmony_ci 663141cc406Sopenharmony_ci DBG (DBG_inquiry, "# of halftones................: %d\n", 664141cc406Sopenharmony_ci dev->inquiry_halftones); 665141cc406Sopenharmony_ci 666141cc406Sopenharmony_ci DBG (DBG_inquiry, "One pass color................: %s\n", 667141cc406Sopenharmony_ci dev->inquiry_filters & INQ_ONE_PASS_COLOR ? "yes" : "no"); 668141cc406Sopenharmony_ci 669141cc406Sopenharmony_ci DBG (DBG_inquiry, "Filters.......................: %s%s%s%s (%02x)\n", 670141cc406Sopenharmony_ci dev->inquiry_filters & INQ_FILTER_RED ? "Red " : "", 671141cc406Sopenharmony_ci dev->inquiry_filters & INQ_FILTER_GREEN ? "Green " : "", 672141cc406Sopenharmony_ci dev->inquiry_filters & INQ_FILTER_BLUE ? "Blue " : "", 673141cc406Sopenharmony_ci dev->inquiry_filters & INQ_FILTER_NEUTRAL ? "Neutral " : "", 674141cc406Sopenharmony_ci dev->inquiry_filters); 675141cc406Sopenharmony_ci 676141cc406Sopenharmony_ci DBG (DBG_inquiry, "Color depths..................: %s%s%s%s%s%s (%02x)\n", 677141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_16 ? "16 bit " : "", 678141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_12 ? "12 bit " : "", 679141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_10 ? "10 bit " : "", 680141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_8 ? "8 bit " : "", 681141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_4 ? "4 bit " : "", 682141cc406Sopenharmony_ci dev->inquiry_color_depths & INQ_COLOR_DEPTH_1 ? "1 bit " : "", 683141cc406Sopenharmony_ci dev->inquiry_color_depths); 684141cc406Sopenharmony_ci 685141cc406Sopenharmony_ci DBG (DBG_inquiry, "Color Format..................: %s%s%s (%02x)\n", 686141cc406Sopenharmony_ci dev->inquiry_color_format & INQ_COLOR_FORMAT_INDEX ? "Indexed " : "", 687141cc406Sopenharmony_ci dev->inquiry_color_format & INQ_COLOR_FORMAT_LINE ? "Line " : "", 688141cc406Sopenharmony_ci dev->inquiry_color_format & INQ_COLOR_FORMAT_PIXEL ? "Pixel " : "", 689141cc406Sopenharmony_ci dev->inquiry_color_format); 690141cc406Sopenharmony_ci 691141cc406Sopenharmony_ci DBG (DBG_inquiry, "Image Format..................: %s%s%s%s (%02x)\n", 692141cc406Sopenharmony_ci dev->inquiry_image_format & INQ_IMG_FMT_OKLINE ? "OKLine " : "", 693141cc406Sopenharmony_ci dev->inquiry_image_format & INQ_IMG_FMT_BLK_ONE ? "BlackOne " : "", 694141cc406Sopenharmony_ci dev->inquiry_image_format & INQ_IMG_FMT_MOTOROLA ? "Motorola " : "", 695141cc406Sopenharmony_ci dev->inquiry_image_format & INQ_IMG_FMT_INTEL ? "Intel" : "", 696141cc406Sopenharmony_ci dev->inquiry_image_format); 697141cc406Sopenharmony_ci 698141cc406Sopenharmony_ci DBG (DBG_inquiry, 699141cc406Sopenharmony_ci "Scan Capability...............: %s%s%s%s%d speeds (%02x)\n", 700141cc406Sopenharmony_ci dev->inquiry_scan_capability & INQ_CAP_PWRSAV ? "PowerSave " : "", 701141cc406Sopenharmony_ci dev->inquiry_scan_capability & INQ_CAP_EXT_CAL ? "ExtCal " : "", 702141cc406Sopenharmony_ci dev->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW ? "FastPreview" : 703141cc406Sopenharmony_ci "", 704141cc406Sopenharmony_ci dev->inquiry_scan_capability & INQ_CAP_DISABLE_CAL ? "DisCal " : "", 705141cc406Sopenharmony_ci dev->inquiry_scan_capability & INQ_CAP_SPEEDS, 706141cc406Sopenharmony_ci dev->inquiry_scan_capability); 707141cc406Sopenharmony_ci 708141cc406Sopenharmony_ci DBG (DBG_inquiry, "Optional Devices..............: %s%s%s%s (%02x)\n", 709141cc406Sopenharmony_ci dev->inquiry_optional_devices & INQ_OPT_DEV_MPCL ? "MultiPageLoad " : 710141cc406Sopenharmony_ci "", 711141cc406Sopenharmony_ci dev->inquiry_optional_devices & INQ_OPT_DEV_TP1 ? "TransModule1 " : "", 712141cc406Sopenharmony_ci dev->inquiry_optional_devices & INQ_OPT_DEV_TP ? "TransModule " : "", 713141cc406Sopenharmony_ci dev->inquiry_optional_devices & INQ_OPT_DEV_ADF ? "ADF " : "", 714141cc406Sopenharmony_ci dev->inquiry_optional_devices); 715141cc406Sopenharmony_ci 716141cc406Sopenharmony_ci DBG (DBG_inquiry, "Enhancement...................: %02x\n", 717141cc406Sopenharmony_ci dev->inquiry_enhancements); 718141cc406Sopenharmony_ci DBG (DBG_inquiry, "Gamma bits....................: %d\n", 719141cc406Sopenharmony_ci dev->inquiry_gamma_bits); 720141cc406Sopenharmony_ci 721141cc406Sopenharmony_ci DBG (DBG_inquiry, "Fast Preview Resolution.......: %d\n", 722141cc406Sopenharmony_ci dev->inquiry_fast_preview_res); 723141cc406Sopenharmony_ci DBG (DBG_inquiry, "Min Highlight.................: %d\n", 724141cc406Sopenharmony_ci dev->inquiry_min_highlight); 725141cc406Sopenharmony_ci DBG (DBG_inquiry, "Max Shadow....................: %d\n", 726141cc406Sopenharmony_ci dev->inquiry_max_shadow); 727141cc406Sopenharmony_ci DBG (DBG_inquiry, "Cal Eqn.......................: %d\n", 728141cc406Sopenharmony_ci dev->inquiry_cal_eqn); 729141cc406Sopenharmony_ci DBG (DBG_inquiry, "Min Exposure..................: %d\n", 730141cc406Sopenharmony_ci dev->inquiry_min_exp); 731141cc406Sopenharmony_ci DBG (DBG_inquiry, "Max Exposure..................: %d\n", 732141cc406Sopenharmony_ci dev->inquiry_max_exp); 733141cc406Sopenharmony_ci} 734141cc406Sopenharmony_ci 735141cc406Sopenharmony_ci 736141cc406Sopenharmony_ci/* ------------------------------ PIE GET INQUIRY VALUES -------------------- */ 737141cc406Sopenharmony_ci 738141cc406Sopenharmony_ci 739141cc406Sopenharmony_cistatic void 740141cc406Sopenharmony_cipie_get_inquiry_values (Pie_Device * dev, unsigned char *buffer) 741141cc406Sopenharmony_ci{ 742141cc406Sopenharmony_ci DBG (DBG_proc, "get_inquiry_values\n"); 743141cc406Sopenharmony_ci 744141cc406Sopenharmony_ci dev->inquiry_len = get_inquiry_additional_length (buffer) + 5; 745141cc406Sopenharmony_ci 746141cc406Sopenharmony_ci get_inquiry_vendor ((char *) buffer, dev->vendor); 747141cc406Sopenharmony_ci get_inquiry_product ((char *) buffer, dev->product); 748141cc406Sopenharmony_ci get_inquiry_version ((char *) buffer, dev->version); 749141cc406Sopenharmony_ci 750141cc406Sopenharmony_ci dev->inquiry_x_res = get_inquiry_max_x_res (buffer); 751141cc406Sopenharmony_ci dev->inquiry_y_res = get_inquiry_max_y_res (buffer); 752141cc406Sopenharmony_ci 753141cc406Sopenharmony_ci if (dev->inquiry_y_res < 256) 754141cc406Sopenharmony_ci { 755141cc406Sopenharmony_ci /* y res is a multiplier */ 756141cc406Sopenharmony_ci dev->inquiry_pixel_resolution = dev->inquiry_x_res; 757141cc406Sopenharmony_ci dev->inquiry_x_res *= dev->inquiry_y_res; 758141cc406Sopenharmony_ci dev->inquiry_y_res = dev->inquiry_x_res; 759141cc406Sopenharmony_ci } 760141cc406Sopenharmony_ci else 761141cc406Sopenharmony_ci { 762141cc406Sopenharmony_ci /* y res really is resolution */ 763141cc406Sopenharmony_ci dev->inquiry_pixel_resolution = 764141cc406Sopenharmony_ci min (dev->inquiry_x_res, dev->inquiry_y_res); 765141cc406Sopenharmony_ci } 766141cc406Sopenharmony_ci 767141cc406Sopenharmony_ci dev->inquiry_fb_width = 768141cc406Sopenharmony_ci (double) get_inquiry_fb_max_scan_width (buffer) / 769141cc406Sopenharmony_ci dev->inquiry_pixel_resolution; 770141cc406Sopenharmony_ci dev->inquiry_fb_length = 771141cc406Sopenharmony_ci (double) get_inquiry_fb_max_scan_length (buffer) / 772141cc406Sopenharmony_ci dev->inquiry_pixel_resolution; 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci dev->inquiry_trans_top_left_x = get_inquiry_trans_x1 (buffer); 775141cc406Sopenharmony_ci dev->inquiry_trans_top_left_y = get_inquiry_trans_y1 (buffer); 776141cc406Sopenharmony_ci 777141cc406Sopenharmony_ci dev->inquiry_trans_width = 778141cc406Sopenharmony_ci (double) (get_inquiry_trans_x2 (buffer) - 779141cc406Sopenharmony_ci get_inquiry_trans_x1 (buffer)) / dev->inquiry_pixel_resolution; 780141cc406Sopenharmony_ci dev->inquiry_trans_length = 781141cc406Sopenharmony_ci (double) (get_inquiry_trans_y2 (buffer) - 782141cc406Sopenharmony_ci get_inquiry_trans_y1 (buffer)) / dev->inquiry_pixel_resolution; 783141cc406Sopenharmony_ci 784141cc406Sopenharmony_ci dev->inquiry_halftones = get_inquiry_halftones (buffer) & 0x0f; 785141cc406Sopenharmony_ci 786141cc406Sopenharmony_ci dev->inquiry_filters = get_inquiry_filters (buffer); 787141cc406Sopenharmony_ci dev->inquiry_color_depths = get_inquiry_color_depths (buffer); 788141cc406Sopenharmony_ci dev->inquiry_color_format = get_inquiry_color_format (buffer); 789141cc406Sopenharmony_ci dev->inquiry_image_format = get_inquiry_image_format (buffer); 790141cc406Sopenharmony_ci 791141cc406Sopenharmony_ci dev->inquiry_scan_capability = get_inquiry_scan_capability (buffer); 792141cc406Sopenharmony_ci dev->inquiry_optional_devices = get_inquiry_optional_devices (buffer); 793141cc406Sopenharmony_ci dev->inquiry_enhancements = get_inquiry_enhancements (buffer); 794141cc406Sopenharmony_ci dev->inquiry_gamma_bits = get_inquiry_gamma_bits (buffer); 795141cc406Sopenharmony_ci dev->inquiry_fast_preview_res = get_inquiry_fast_preview_res (buffer); 796141cc406Sopenharmony_ci dev->inquiry_min_highlight = get_inquiry_min_highlight (buffer); 797141cc406Sopenharmony_ci dev->inquiry_max_shadow = get_inquiry_max_shadow (buffer); 798141cc406Sopenharmony_ci dev->inquiry_cal_eqn = get_inquiry_cal_eqn (buffer); 799141cc406Sopenharmony_ci dev->inquiry_min_exp = get_inquiry_min_exp (buffer); 800141cc406Sopenharmony_ci dev->inquiry_max_exp = get_inquiry_max_exp (buffer); 801141cc406Sopenharmony_ci 802141cc406Sopenharmony_ci pie_print_inquiry (dev); 803141cc406Sopenharmony_ci 804141cc406Sopenharmony_ci return; 805141cc406Sopenharmony_ci} 806141cc406Sopenharmony_ci 807141cc406Sopenharmony_ci/* ----------------------------- PIE DO INQUIRY ---------------------------- */ 808141cc406Sopenharmony_ci 809141cc406Sopenharmony_ci 810141cc406Sopenharmony_cistatic void 811141cc406Sopenharmony_cipie_do_inquiry (int sfd, unsigned char *buffer) 812141cc406Sopenharmony_ci{ 813141cc406Sopenharmony_ci size_t size; 814141cc406Sopenharmony_ci SANE_Status status; 815141cc406Sopenharmony_ci 816141cc406Sopenharmony_ci DBG (DBG_proc, "do_inquiry\n"); 817141cc406Sopenharmony_ci memset (buffer, '\0', 256); /* clear buffer */ 818141cc406Sopenharmony_ci 819141cc406Sopenharmony_ci size = 5; 820141cc406Sopenharmony_ci 821141cc406Sopenharmony_ci set_inquiry_return_size (inquiry.cmd, size); /* first get only 5 bytes to get size of inquiry_return_block */ 822141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); 823141cc406Sopenharmony_ci if (status) 824141cc406Sopenharmony_ci { 825141cc406Sopenharmony_ci DBG (DBG_error, "pie_do_inquiry: command returned status %s\n", 826141cc406Sopenharmony_ci sane_strstatus (status)); 827141cc406Sopenharmony_ci } 828141cc406Sopenharmony_ci 829141cc406Sopenharmony_ci size = get_inquiry_additional_length (buffer) + 5; 830141cc406Sopenharmony_ci 831141cc406Sopenharmony_ci set_inquiry_return_size (inquiry.cmd, size); /* then get inquiry with actual size */ 832141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size); 833141cc406Sopenharmony_ci if (status) 834141cc406Sopenharmony_ci { 835141cc406Sopenharmony_ci DBG (DBG_error, "pie_do_inquiry: command returned status %s\n", 836141cc406Sopenharmony_ci sane_strstatus (status)); 837141cc406Sopenharmony_ci } 838141cc406Sopenharmony_ci} 839141cc406Sopenharmony_ci 840141cc406Sopenharmony_ci/* ---------------------- PIE IDENTIFY SCANNER ---------------------- */ 841141cc406Sopenharmony_ci 842141cc406Sopenharmony_ci 843141cc406Sopenharmony_cistatic int 844141cc406Sopenharmony_cipie_identify_scanner (Pie_Device * dev, int sfd) 845141cc406Sopenharmony_ci{ 846141cc406Sopenharmony_ci char vendor[9]; 847141cc406Sopenharmony_ci char product[0x11]; 848141cc406Sopenharmony_ci char version[5]; 849141cc406Sopenharmony_ci char *pp; 850141cc406Sopenharmony_ci int i = 0; 851141cc406Sopenharmony_ci unsigned char inquiry_block[256]; 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci DBG (DBG_proc, "identify_scanner\n"); 854141cc406Sopenharmony_ci 855141cc406Sopenharmony_ci pie_do_inquiry (sfd, inquiry_block); /* get inquiry */ 856141cc406Sopenharmony_ci 857141cc406Sopenharmony_ci if (get_inquiry_periph_devtype (inquiry_block) != IN_periph_devtype_scanner) 858141cc406Sopenharmony_ci { 859141cc406Sopenharmony_ci return 1; 860141cc406Sopenharmony_ci } /* no scanner */ 861141cc406Sopenharmony_ci 862141cc406Sopenharmony_ci get_inquiry_vendor ((char *) inquiry_block, vendor); 863141cc406Sopenharmony_ci get_inquiry_product ((char *) inquiry_block, product); 864141cc406Sopenharmony_ci get_inquiry_version ((char *) inquiry_block, version); 865141cc406Sopenharmony_ci 866141cc406Sopenharmony_ci pp = &vendor[8]; 867141cc406Sopenharmony_ci vendor[8] = ' '; 868141cc406Sopenharmony_ci while (*pp == ' ') 869141cc406Sopenharmony_ci { 870141cc406Sopenharmony_ci *pp-- = '\0'; 871141cc406Sopenharmony_ci } 872141cc406Sopenharmony_ci 873141cc406Sopenharmony_ci pp = &product[0x10]; 874141cc406Sopenharmony_ci product[0x10] = ' '; 875141cc406Sopenharmony_ci while (*pp == ' ') 876141cc406Sopenharmony_ci { 877141cc406Sopenharmony_ci *pp-- = '\0'; 878141cc406Sopenharmony_ci } 879141cc406Sopenharmony_ci 880141cc406Sopenharmony_ci pp = &version[4]; 881141cc406Sopenharmony_ci 882141cc406Sopenharmony_ci version[4] = ' '; 883141cc406Sopenharmony_ci while (*pp == ' ') 884141cc406Sopenharmony_ci { 885141cc406Sopenharmony_ci *pp-- = '\0'; 886141cc406Sopenharmony_ci } 887141cc406Sopenharmony_ci 888141cc406Sopenharmony_ci DBG (DBG_info, "Found %s scanner %s version %s on device %s\n", vendor, 889141cc406Sopenharmony_ci product, version, dev->devicename); 890141cc406Sopenharmony_ci 891141cc406Sopenharmony_ci while (strncmp ("END_OF_LIST", scanner_str[2 * i], 11) != 0) /* Now identify full supported scanners */ 892141cc406Sopenharmony_ci { 893141cc406Sopenharmony_ci if (!strncmp (vendor, scanner_str[2 * i], strlen (scanner_str[2 * i]))) 894141cc406Sopenharmony_ci { 895141cc406Sopenharmony_ci if (!strncmp 896141cc406Sopenharmony_ci (product, scanner_str[2 * i + 1], 897141cc406Sopenharmony_ci strlen (scanner_str[2 * i + 1]))) 898141cc406Sopenharmony_ci { 899141cc406Sopenharmony_ci DBG (DBG_info, "found supported scanner\n"); 900141cc406Sopenharmony_ci 901141cc406Sopenharmony_ci pie_get_inquiry_values (dev, inquiry_block); 902141cc406Sopenharmony_ci return 0; 903141cc406Sopenharmony_ci } 904141cc406Sopenharmony_ci } 905141cc406Sopenharmony_ci i++; 906141cc406Sopenharmony_ci } 907141cc406Sopenharmony_ci 908141cc406Sopenharmony_ci return 1; /* NO SUPPORTED SCANNER: short inquiry-block and unknown scanner */ 909141cc406Sopenharmony_ci} 910141cc406Sopenharmony_ci 911141cc406Sopenharmony_ci 912141cc406Sopenharmony_ci/* ------------------------------- GET SPEEDS ----------------------------- */ 913141cc406Sopenharmony_ci 914141cc406Sopenharmony_cistatic void 915141cc406Sopenharmony_cipie_get_speeds (Pie_Device * dev) 916141cc406Sopenharmony_ci{ 917141cc406Sopenharmony_ci int speeds = dev->inquiry_scan_capability & INQ_CAP_SPEEDS; 918141cc406Sopenharmony_ci 919141cc406Sopenharmony_ci DBG (DBG_proc, "get_speeds\n"); 920141cc406Sopenharmony_ci 921141cc406Sopenharmony_ci if (speeds == 3) 922141cc406Sopenharmony_ci { 923141cc406Sopenharmony_ci dev->speed_list[0] = strdup ("Normal"); 924141cc406Sopenharmony_ci dev->speed_list[1] = strdup ("Fine"); 925141cc406Sopenharmony_ci dev->speed_list[2] = strdup ("Pro"); 926141cc406Sopenharmony_ci dev->speed_list[3] = NULL; 927141cc406Sopenharmony_ci } 928141cc406Sopenharmony_ci else 929141cc406Sopenharmony_ci { 930141cc406Sopenharmony_ci int i; 931141cc406Sopenharmony_ci char buf[2]; 932141cc406Sopenharmony_ci 933141cc406Sopenharmony_ci buf[1] = '\0'; 934141cc406Sopenharmony_ci 935141cc406Sopenharmony_ci for (i = 0; i < speeds; i++) 936141cc406Sopenharmony_ci { 937141cc406Sopenharmony_ci buf[0] = '1' + i; 938141cc406Sopenharmony_ci dev->speed_list[i] = strdup (buf); 939141cc406Sopenharmony_ci } 940141cc406Sopenharmony_ci 941141cc406Sopenharmony_ci dev->speed_list[i] = NULL; 942141cc406Sopenharmony_ci } 943141cc406Sopenharmony_ci} 944141cc406Sopenharmony_ci 945141cc406Sopenharmony_ci/* ------------------------------- GET HALFTONES ----------------------------- */ 946141cc406Sopenharmony_ci 947141cc406Sopenharmony_cistatic void 948141cc406Sopenharmony_cipie_get_halftones (Pie_Device * dev, int sfd) 949141cc406Sopenharmony_ci{ 950141cc406Sopenharmony_ci int i; 951141cc406Sopenharmony_ci size_t size; 952141cc406Sopenharmony_ci SANE_Status status; 953141cc406Sopenharmony_ci unsigned char *data; 954141cc406Sopenharmony_ci unsigned char buffer[128]; 955141cc406Sopenharmony_ci 956141cc406Sopenharmony_ci DBG (DBG_proc, "get_halftones\n"); 957141cc406Sopenharmony_ci 958141cc406Sopenharmony_ci for (i = 0; i < dev->inquiry_halftones; i++) 959141cc406Sopenharmony_ci { 960141cc406Sopenharmony_ci size = 6; 961141cc406Sopenharmony_ci 962141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 963141cc406Sopenharmony_ci 964141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 965141cc406Sopenharmony_ci 966141cc406Sopenharmony_ci data = buffer + swrite.size; 967141cc406Sopenharmony_ci memset (data, 0, size); 968141cc406Sopenharmony_ci 969141cc406Sopenharmony_ci set_command (data, READ_HALFTONE); 970141cc406Sopenharmony_ci set_data_length (data, 2); 971141cc406Sopenharmony_ci data[4] = i; 972141cc406Sopenharmony_ci 973141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL); 974141cc406Sopenharmony_ci if (status) 975141cc406Sopenharmony_ci { 976141cc406Sopenharmony_ci DBG (DBG_error, 977141cc406Sopenharmony_ci "pie_get_halftones: write command returned status %s\n", 978141cc406Sopenharmony_ci sane_strstatus (status)); 979141cc406Sopenharmony_ci } 980141cc406Sopenharmony_ci else 981141cc406Sopenharmony_ci { 982141cc406Sopenharmony_ci /* now read the halftone data */ 983141cc406Sopenharmony_ci memset (buffer, '\0', sizeof buffer); /* clear buffer */ 984141cc406Sopenharmony_ci 985141cc406Sopenharmony_ci size = 128; 986141cc406Sopenharmony_ci set_read_length (sread.cmd, size); 987141cc406Sopenharmony_ci 988141cc406Sopenharmony_ci DBG (DBG_info, "doing read\n"); 989141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size); 990141cc406Sopenharmony_ci if (status) 991141cc406Sopenharmony_ci { 992141cc406Sopenharmony_ci DBG (DBG_error, 993141cc406Sopenharmony_ci "pie_get_halftones: read command returned status %s\n", 994141cc406Sopenharmony_ci sane_strstatus (status)); 995141cc406Sopenharmony_ci } 996141cc406Sopenharmony_ci else 997141cc406Sopenharmony_ci { 998141cc406Sopenharmony_ci unsigned char *s; 999141cc406Sopenharmony_ci 1000141cc406Sopenharmony_ci s = buffer + 8 + buffer[6] * buffer[7]; 1001141cc406Sopenharmony_ci 1002141cc406Sopenharmony_ci DBG (DBG_info, "halftone %d: %s\n", i, s); 1003141cc406Sopenharmony_ci 1004141cc406Sopenharmony_ci dev->halftone_list[i] = strdup ((char *)s); 1005141cc406Sopenharmony_ci } 1006141cc406Sopenharmony_ci } 1007141cc406Sopenharmony_ci } 1008141cc406Sopenharmony_ci dev->halftone_list[i] = NULL; 1009141cc406Sopenharmony_ci} 1010141cc406Sopenharmony_ci 1011141cc406Sopenharmony_ci/* ------------------------------- GET CAL DATA ----------------------------- */ 1012141cc406Sopenharmony_ci 1013141cc406Sopenharmony_cistatic void 1014141cc406Sopenharmony_cipie_get_cal_info (Pie_Device * dev, int sfd) 1015141cc406Sopenharmony_ci{ 1016141cc406Sopenharmony_ci size_t size; 1017141cc406Sopenharmony_ci SANE_Status status; 1018141cc406Sopenharmony_ci unsigned char *data; 1019141cc406Sopenharmony_ci unsigned char buffer[280]; 1020141cc406Sopenharmony_ci 1021141cc406Sopenharmony_ci DBG (DBG_proc, "get_cal_info\n"); 1022141cc406Sopenharmony_ci 1023141cc406Sopenharmony_ci if (!(dev->inquiry_scan_capability & INQ_CAP_EXT_CAL)) 1024141cc406Sopenharmony_ci return; 1025141cc406Sopenharmony_ci 1026141cc406Sopenharmony_ci size = 6; 1027141cc406Sopenharmony_ci 1028141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 1029141cc406Sopenharmony_ci 1030141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 1031141cc406Sopenharmony_ci 1032141cc406Sopenharmony_ci data = buffer + swrite.size; 1033141cc406Sopenharmony_ci memset (data, 0, size); 1034141cc406Sopenharmony_ci 1035141cc406Sopenharmony_ci set_command (data, READ_CAL_INFO); 1036141cc406Sopenharmony_ci 1037141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL); 1038141cc406Sopenharmony_ci if (status) 1039141cc406Sopenharmony_ci { 1040141cc406Sopenharmony_ci DBG (DBG_error, "pie_get_cal_info: write command returned status %s\n", 1041141cc406Sopenharmony_ci sane_strstatus (status)); 1042141cc406Sopenharmony_ci } 1043141cc406Sopenharmony_ci else 1044141cc406Sopenharmony_ci { 1045141cc406Sopenharmony_ci /* now read the cal data */ 1046141cc406Sopenharmony_ci memset (buffer, '\0', sizeof buffer); /* clear buffer */ 1047141cc406Sopenharmony_ci 1048141cc406Sopenharmony_ci size = 128; 1049141cc406Sopenharmony_ci set_read_length (sread.cmd, size); 1050141cc406Sopenharmony_ci 1051141cc406Sopenharmony_ci DBG (DBG_info, "doing read\n"); 1052141cc406Sopenharmony_ci status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size); 1053141cc406Sopenharmony_ci if (status) 1054141cc406Sopenharmony_ci { 1055141cc406Sopenharmony_ci DBG (DBG_error, 1056141cc406Sopenharmony_ci "pie_get_cal_info: read command returned status %s\n", 1057141cc406Sopenharmony_ci sane_strstatus (status)); 1058141cc406Sopenharmony_ci } 1059141cc406Sopenharmony_ci else 1060141cc406Sopenharmony_ci { 1061141cc406Sopenharmony_ci int i; 1062141cc406Sopenharmony_ci 1063141cc406Sopenharmony_ci dev->cal_info_count = buffer[4]; 1064141cc406Sopenharmony_ci dev->cal_info = 1065141cc406Sopenharmony_ci malloc (sizeof (struct Pie_cal_info) * dev->cal_info_count); 1066141cc406Sopenharmony_ci 1067141cc406Sopenharmony_ci for (i = 0; i < dev->cal_info_count; i++) 1068141cc406Sopenharmony_ci { 1069141cc406Sopenharmony_ci dev->cal_info[i].cal_type = buffer[8 + i * buffer[5]]; 1070141cc406Sopenharmony_ci dev->cal_info[i].send_bits = buffer[9 + i * buffer[5]]; 1071141cc406Sopenharmony_ci dev->cal_info[i].receive_bits = buffer[10 + i * buffer[5]]; 1072141cc406Sopenharmony_ci dev->cal_info[i].num_lines = buffer[11 + i * buffer[5]]; 1073141cc406Sopenharmony_ci dev->cal_info[i].pixels_per_line = 1074141cc406Sopenharmony_ci (buffer[13 + i * buffer[5]] << 8) + buffer[12 + 1075141cc406Sopenharmony_ci i * buffer[5]]; 1076141cc406Sopenharmony_ci 1077141cc406Sopenharmony_ci DBG (DBG_info2, "%02x %2d %2d %2d %d\n", 1078141cc406Sopenharmony_ci dev->cal_info[i].cal_type, dev->cal_info[i].send_bits, 1079141cc406Sopenharmony_ci dev->cal_info[i].receive_bits, dev->cal_info[i].num_lines, 1080141cc406Sopenharmony_ci dev->cal_info[i].pixels_per_line); 1081141cc406Sopenharmony_ci } 1082141cc406Sopenharmony_ci } 1083141cc406Sopenharmony_ci } 1084141cc406Sopenharmony_ci} 1085141cc406Sopenharmony_ci 1086141cc406Sopenharmony_ci/* ------------------------------- ATTACH SCANNER ----------------------------- */ 1087141cc406Sopenharmony_ci 1088141cc406Sopenharmony_cistatic SANE_Status 1089141cc406Sopenharmony_ciattach_scanner (const char *devicename, Pie_Device ** devp) 1090141cc406Sopenharmony_ci{ 1091141cc406Sopenharmony_ci Pie_Device *dev; 1092141cc406Sopenharmony_ci int sfd; 1093141cc406Sopenharmony_ci int bufsize; 1094141cc406Sopenharmony_ci 1095141cc406Sopenharmony_ci DBG (DBG_sane_proc, "attach_scanner: %s\n", devicename); 1096141cc406Sopenharmony_ci 1097141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 1098141cc406Sopenharmony_ci { 1099141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devicename) == 0) 1100141cc406Sopenharmony_ci { 1101141cc406Sopenharmony_ci if (devp) 1102141cc406Sopenharmony_ci { 1103141cc406Sopenharmony_ci *devp = dev; 1104141cc406Sopenharmony_ci } 1105141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1106141cc406Sopenharmony_ci } 1107141cc406Sopenharmony_ci } 1108141cc406Sopenharmony_ci 1109141cc406Sopenharmony_ci dev = malloc (sizeof (*dev)); 1110141cc406Sopenharmony_ci if (!dev) 1111141cc406Sopenharmony_ci { 1112141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1113141cc406Sopenharmony_ci } 1114141cc406Sopenharmony_ci 1115141cc406Sopenharmony_ci DBG (DBG_info, "attach_scanner: opening %s\n", devicename); 1116141cc406Sopenharmony_ci 1117141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 1118141cc406Sopenharmony_ci bufsize = 16384; /* 16KB */ 1119141cc406Sopenharmony_ci 1120141cc406Sopenharmony_ci if (sanei_scsi_open_extended 1121141cc406Sopenharmony_ci (devicename, &sfd, sense_handler, dev, &bufsize) != 0) 1122141cc406Sopenharmony_ci { 1123141cc406Sopenharmony_ci DBG (DBG_error, "attach_scanner: open failed\n"); 1124141cc406Sopenharmony_ci free (dev); 1125141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1126141cc406Sopenharmony_ci } 1127141cc406Sopenharmony_ci 1128141cc406Sopenharmony_ci if (bufsize < 4096) /* < 4KB */ 1129141cc406Sopenharmony_ci { 1130141cc406Sopenharmony_ci DBG (DBG_error, 1131141cc406Sopenharmony_ci "attach_scanner: sanei_scsi_open_extended returned too small scsi buffer (%d)\n", 1132141cc406Sopenharmony_ci bufsize); 1133141cc406Sopenharmony_ci sanei_scsi_close (sfd); 1134141cc406Sopenharmony_ci free (dev); 1135141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1136141cc406Sopenharmony_ci } 1137141cc406Sopenharmony_ci 1138141cc406Sopenharmony_ci DBG (DBG_info, 1139141cc406Sopenharmony_ci "attach_scanner: sanei_scsi_open_extended returned scsi buffer size = %d\n", 1140141cc406Sopenharmony_ci bufsize); 1141141cc406Sopenharmony_ci#else 1142141cc406Sopenharmony_ci bufsize = sanei_scsi_max_request_size; 1143141cc406Sopenharmony_ci 1144141cc406Sopenharmony_ci if (sanei_scsi_open (devicename, &sfd, sense_handler, dev) != 0) 1145141cc406Sopenharmony_ci { 1146141cc406Sopenharmony_ci DBG (DBG_error, "attach_scanner: open failed\n"); 1147141cc406Sopenharmony_ci free (dev); 1148141cc406Sopenharmony_ci 1149141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1150141cc406Sopenharmony_ci 1151141cc406Sopenharmony_ci } 1152141cc406Sopenharmony_ci#endif 1153141cc406Sopenharmony_ci 1154141cc406Sopenharmony_ci pie_init (dev); /* preset values in structure dev */ 1155141cc406Sopenharmony_ci 1156141cc406Sopenharmony_ci dev->devicename = strdup (devicename); 1157141cc406Sopenharmony_ci 1158141cc406Sopenharmony_ci if (pie_identify_scanner (dev, sfd) != 0) 1159141cc406Sopenharmony_ci { 1160141cc406Sopenharmony_ci DBG (DBG_error, "attach_scanner: scanner-identification failed\n"); 1161141cc406Sopenharmony_ci sanei_scsi_close (sfd); 1162141cc406Sopenharmony_ci free (dev); 1163141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1164141cc406Sopenharmony_ci } 1165141cc406Sopenharmony_ci 1166141cc406Sopenharmony_ci pie_get_halftones (dev, sfd); 1167141cc406Sopenharmony_ci pie_get_cal_info (dev, sfd); 1168141cc406Sopenharmony_ci pie_get_speeds (dev); 1169141cc406Sopenharmony_ci 1170141cc406Sopenharmony_ci dev->scan_mode_list[0] = COLOR_STR; 1171141cc406Sopenharmony_ci dev->scan_mode_list[1] = GRAY_STR; 1172141cc406Sopenharmony_ci dev->scan_mode_list[2] = LINEART_STR; 1173141cc406Sopenharmony_ci dev->scan_mode_list[3] = HALFTONE_STR; 1174141cc406Sopenharmony_ci dev->scan_mode_list[4] = 0; 1175141cc406Sopenharmony_ci 1176141cc406Sopenharmony_ci sanei_scsi_close (sfd); 1177141cc406Sopenharmony_ci 1178141cc406Sopenharmony_ci dev->sane.name = dev->devicename; 1179141cc406Sopenharmony_ci dev->sane.vendor = dev->vendor; 1180141cc406Sopenharmony_ci dev->sane.model = dev->product; 1181141cc406Sopenharmony_ci dev->sane.type = "flatbed scanner"; 1182141cc406Sopenharmony_ci 1183141cc406Sopenharmony_ci dev->x_range.min = SANE_FIX (0); 1184141cc406Sopenharmony_ci dev->x_range.quant = SANE_FIX (0); 1185141cc406Sopenharmony_ci dev->x_range.max = SANE_FIX (dev->inquiry_fb_width * MM_PER_INCH); 1186141cc406Sopenharmony_ci 1187141cc406Sopenharmony_ci dev->y_range.min = SANE_FIX (0); 1188141cc406Sopenharmony_ci dev->y_range.quant = SANE_FIX (0); 1189141cc406Sopenharmony_ci dev->y_range.max = SANE_FIX (dev->inquiry_fb_length * MM_PER_INCH); 1190141cc406Sopenharmony_ci 1191141cc406Sopenharmony_ci dev->dpi_range.min = SANE_FIX (25); 1192141cc406Sopenharmony_ci dev->dpi_range.quant = SANE_FIX (1); 1193141cc406Sopenharmony_ci dev->dpi_range.max = 1194141cc406Sopenharmony_ci SANE_FIX (max (dev->inquiry_x_res, dev->inquiry_y_res)); 1195141cc406Sopenharmony_ci 1196141cc406Sopenharmony_ci dev->shadow_range.min = SANE_FIX (0); 1197141cc406Sopenharmony_ci dev->shadow_range.quant = SANE_FIX (1); 1198141cc406Sopenharmony_ci dev->shadow_range.max = SANE_FIX (dev->inquiry_max_shadow); 1199141cc406Sopenharmony_ci 1200141cc406Sopenharmony_ci dev->highlight_range.min = SANE_FIX (dev->inquiry_min_highlight); 1201141cc406Sopenharmony_ci dev->highlight_range.quant = SANE_FIX (1); 1202141cc406Sopenharmony_ci dev->highlight_range.max = SANE_FIX (100); 1203141cc406Sopenharmony_ci 1204141cc406Sopenharmony_ci dev->exposure_range.min = SANE_FIX (dev->inquiry_min_exp); 1205141cc406Sopenharmony_ci dev->exposure_range.quant = SANE_FIX (1); 1206141cc406Sopenharmony_ci dev->exposure_range.max = SANE_FIX (dev->inquiry_max_exp); 1207141cc406Sopenharmony_ci 1208141cc406Sopenharmony_ci#if 0 1209141cc406Sopenharmony_ci dev->analog_gamma_range.min = SANE_FIX (1.0); 1210141cc406Sopenharmony_ci dev->analog_gamma_range.quant = SANE_FIX (0.01); 1211141cc406Sopenharmony_ci dev->analog_gamma_range.max = SANE_FIX (2.0); 1212141cc406Sopenharmony_ci 1213141cc406Sopenharmony_ci#endif 1214141cc406Sopenharmony_ci 1215141cc406Sopenharmony_ci dev->next = first_dev; 1216141cc406Sopenharmony_ci first_dev = dev; 1217141cc406Sopenharmony_ci 1218141cc406Sopenharmony_ci if (devp) 1219141cc406Sopenharmony_ci { 1220141cc406Sopenharmony_ci *devp = dev; 1221141cc406Sopenharmony_ci } 1222141cc406Sopenharmony_ci 1223141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1224141cc406Sopenharmony_ci} 1225141cc406Sopenharmony_ci 1226141cc406Sopenharmony_ci/* --------------------------- MAX STRING SIZE ---------------------------- */ 1227141cc406Sopenharmony_ci 1228141cc406Sopenharmony_ci 1229141cc406Sopenharmony_cistatic size_t 1230141cc406Sopenharmony_cimax_string_size (SANE_String_Const strings[]) 1231141cc406Sopenharmony_ci{ 1232141cc406Sopenharmony_ci size_t size, max_size = 0; 1233141cc406Sopenharmony_ci int i; 1234141cc406Sopenharmony_ci 1235141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 1236141cc406Sopenharmony_ci { 1237141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 1238141cc406Sopenharmony_ci if (size > max_size) 1239141cc406Sopenharmony_ci { 1240141cc406Sopenharmony_ci max_size = size; 1241141cc406Sopenharmony_ci } 1242141cc406Sopenharmony_ci } 1243141cc406Sopenharmony_ci 1244141cc406Sopenharmony_ci return max_size; 1245141cc406Sopenharmony_ci} 1246141cc406Sopenharmony_ci 1247141cc406Sopenharmony_ci 1248141cc406Sopenharmony_ci/* --------------------------- INIT OPTIONS ------------------------------- */ 1249141cc406Sopenharmony_ci 1250141cc406Sopenharmony_ci 1251141cc406Sopenharmony_cistatic SANE_Status 1252141cc406Sopenharmony_ciinit_options (Pie_Scanner * scanner) 1253141cc406Sopenharmony_ci{ 1254141cc406Sopenharmony_ci int i; 1255141cc406Sopenharmony_ci 1256141cc406Sopenharmony_ci DBG (DBG_sane_proc, "init_options\n"); 1257141cc406Sopenharmony_ci 1258141cc406Sopenharmony_ci memset (scanner->opt, 0, sizeof (scanner->opt)); 1259141cc406Sopenharmony_ci memset (scanner->val, 0, sizeof (scanner->val)); 1260141cc406Sopenharmony_ci 1261141cc406Sopenharmony_ci for (i = 0; i < NUM_OPTIONS; ++i) 1262141cc406Sopenharmony_ci { 1263141cc406Sopenharmony_ci scanner->opt[i].size = sizeof (SANE_Word); 1264141cc406Sopenharmony_ci scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 1265141cc406Sopenharmony_ci } 1266141cc406Sopenharmony_ci 1267141cc406Sopenharmony_ci scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 1268141cc406Sopenharmony_ci scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 1269141cc406Sopenharmony_ci scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 1270141cc406Sopenharmony_ci scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 1271141cc406Sopenharmony_ci scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 1272141cc406Sopenharmony_ci 1273141cc406Sopenharmony_ci /* "Mode" group: */ 1274141cc406Sopenharmony_ci scanner->opt[OPT_MODE_GROUP].title = "Scan Mode"; 1275141cc406Sopenharmony_ci scanner->opt[OPT_MODE_GROUP].desc = ""; 1276141cc406Sopenharmony_ci scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 1277141cc406Sopenharmony_ci scanner->opt[OPT_MODE_GROUP].cap = 0; 1278141cc406Sopenharmony_ci scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1279141cc406Sopenharmony_ci 1280141cc406Sopenharmony_ci /* scan mode */ 1281141cc406Sopenharmony_ci scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 1282141cc406Sopenharmony_ci scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 1283141cc406Sopenharmony_ci scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 1284141cc406Sopenharmony_ci scanner->opt[OPT_MODE].type = SANE_TYPE_STRING; 1285141cc406Sopenharmony_ci scanner->opt[OPT_MODE].size = 1286141cc406Sopenharmony_ci max_string_size ((SANE_String_Const *) scanner->device->scan_mode_list); 1287141cc406Sopenharmony_ci scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1288141cc406Sopenharmony_ci scanner->opt[OPT_MODE].constraint.string_list = 1289141cc406Sopenharmony_ci (SANE_String_Const *) scanner->device->scan_mode_list; 1290141cc406Sopenharmony_ci scanner->val[OPT_MODE].s = 1291141cc406Sopenharmony_ci (SANE_Char *) strdup (scanner->device->scan_mode_list[0]); 1292141cc406Sopenharmony_ci 1293141cc406Sopenharmony_ci /* x-resolution */ 1294141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 1295141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; 1296141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 1297141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED; 1298141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 1299141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 1300141cc406Sopenharmony_ci scanner->opt[OPT_RESOLUTION].constraint.range = &scanner->device->dpi_range; 1301141cc406Sopenharmony_ci scanner->val[OPT_RESOLUTION].w = 100 << SANE_FIXED_SCALE_SHIFT; 1302141cc406Sopenharmony_ci 1303141cc406Sopenharmony_ci /* "Geometry" group: */ 1304141cc406Sopenharmony_ci 1305141cc406Sopenharmony_ci scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 1306141cc406Sopenharmony_ci scanner->opt[OPT_GEOMETRY_GROUP].desc = ""; 1307141cc406Sopenharmony_ci scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 1308141cc406Sopenharmony_ci scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 1309141cc406Sopenharmony_ci scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1310141cc406Sopenharmony_ci 1311141cc406Sopenharmony_ci /* top-left x */ 1312141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 1313141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 1314141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 1315141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 1316141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM; 1317141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 1318141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range); 1319141cc406Sopenharmony_ci scanner->val[OPT_TL_X].w = 0; 1320141cc406Sopenharmony_ci 1321141cc406Sopenharmony_ci /* top-left y */ 1322141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 1323141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 1324141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 1325141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 1326141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 1327141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1328141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range); 1329141cc406Sopenharmony_ci scanner->val[OPT_TL_Y].w = 0; 1330141cc406Sopenharmony_ci 1331141cc406Sopenharmony_ci /* bottom-right x */ 1332141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 1333141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 1334141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 1335141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 1336141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM; 1337141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 1338141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range); 1339141cc406Sopenharmony_ci scanner->val[OPT_BR_X].w = scanner->device->x_range.max; 1340141cc406Sopenharmony_ci 1341141cc406Sopenharmony_ci /* bottom-right y */ 1342141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 1343141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 1344141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 1345141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 1346141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 1347141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1348141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range); 1349141cc406Sopenharmony_ci scanner->val[OPT_BR_Y].w = scanner->device->y_range.max; 1350141cc406Sopenharmony_ci 1351141cc406Sopenharmony_ci /* "enhancement" group: */ 1352141cc406Sopenharmony_ci 1353141cc406Sopenharmony_ci scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 1354141cc406Sopenharmony_ci scanner->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 1355141cc406Sopenharmony_ci scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 1356141cc406Sopenharmony_ci scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 1357141cc406Sopenharmony_ci scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1358141cc406Sopenharmony_ci 1359141cc406Sopenharmony_ci /* grayscale gamma vector */ 1360141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR; 1361141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR; 1362141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR; 1363141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT; 1364141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE; 1365141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE; 1366141cc406Sopenharmony_ci scanner->val[OPT_GAMMA_VECTOR].wa = scanner->gamma_table[0]; 1367141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &scanner->gamma_range; 1368141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].size = 1369141cc406Sopenharmony_ci scanner->gamma_length * sizeof (SANE_Word); 1370141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 1371141cc406Sopenharmony_ci 1372141cc406Sopenharmony_ci /* red gamma vector */ 1373141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R; 1374141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R; 1375141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R; 1376141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT; 1377141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE; 1378141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE; 1379141cc406Sopenharmony_ci scanner->val[OPT_GAMMA_VECTOR_R].wa = scanner->gamma_table[1]; 1380141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range); 1381141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].size = 1382141cc406Sopenharmony_ci scanner->gamma_length * sizeof (SANE_Word); 1383141cc406Sopenharmony_ci 1384141cc406Sopenharmony_ci /* green gamma vector */ 1385141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G; 1386141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G; 1387141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G; 1388141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT; 1389141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE; 1390141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE; 1391141cc406Sopenharmony_ci scanner->val[OPT_GAMMA_VECTOR_G].wa = scanner->gamma_table[2]; 1392141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range); 1393141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].size = 1394141cc406Sopenharmony_ci scanner->gamma_length * sizeof (SANE_Word); 1395141cc406Sopenharmony_ci 1396141cc406Sopenharmony_ci 1397141cc406Sopenharmony_ci /* blue gamma vector */ 1398141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B; 1399141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B; 1400141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B; 1401141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT; 1402141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE; 1403141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE; 1404141cc406Sopenharmony_ci scanner->val[OPT_GAMMA_VECTOR_B].wa = scanner->gamma_table[3]; 1405141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range); 1406141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].size = 1407141cc406Sopenharmony_ci scanner->gamma_length * sizeof (SANE_Word); 1408141cc406Sopenharmony_ci 1409141cc406Sopenharmony_ci /* halftone pattern */ 1410141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN; 1411141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN; 1412141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN; 1413141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING; 1414141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].size = 1415141cc406Sopenharmony_ci max_string_size ((SANE_String_Const *) scanner->device->halftone_list); 1416141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].constraint_type = 1417141cc406Sopenharmony_ci SANE_CONSTRAINT_STRING_LIST; 1418141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].constraint.string_list = 1419141cc406Sopenharmony_ci (SANE_String_Const *) scanner->device->halftone_list; 1420141cc406Sopenharmony_ci scanner->val[OPT_HALFTONE_PATTERN].s = 1421141cc406Sopenharmony_ci (SANE_Char *) strdup (scanner->device->halftone_list[0]); 1422141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; 1423141cc406Sopenharmony_ci 1424141cc406Sopenharmony_ci /* speed */ 1425141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED; 1426141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED; 1427141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED; 1428141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].type = SANE_TYPE_STRING; 1429141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].size = 1430141cc406Sopenharmony_ci max_string_size ((SANE_String_Const *) scanner->device->speed_list); 1431141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1432141cc406Sopenharmony_ci scanner->opt[OPT_SPEED].constraint.string_list = 1433141cc406Sopenharmony_ci (SANE_String_Const *) scanner->device->speed_list; 1434141cc406Sopenharmony_ci scanner->val[OPT_SPEED].s = 1435141cc406Sopenharmony_ci (SANE_Char *) strdup (scanner->device->speed_list[0]); 1436141cc406Sopenharmony_ci 1437141cc406Sopenharmony_ci /* lineart threshold */ 1438141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 1439141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 1440141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 1441141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED; 1442141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT; 1443141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 1444141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100; 1445141cc406Sopenharmony_ci scanner->val[OPT_THRESHOLD].w = SANE_FIX (50); 1446141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 1447141cc406Sopenharmony_ci 1448141cc406Sopenharmony_ci /* "advanced" group: */ 1449141cc406Sopenharmony_ci 1450141cc406Sopenharmony_ci scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced"; 1451141cc406Sopenharmony_ci scanner->opt[OPT_ADVANCED_GROUP].desc = ""; 1452141cc406Sopenharmony_ci scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP; 1453141cc406Sopenharmony_ci scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED; 1454141cc406Sopenharmony_ci scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1455141cc406Sopenharmony_ci 1456141cc406Sopenharmony_ci /* preview */ 1457141cc406Sopenharmony_ci scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; 1458141cc406Sopenharmony_ci scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; 1459141cc406Sopenharmony_ci scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; 1460141cc406Sopenharmony_ci scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; 1461141cc406Sopenharmony_ci scanner->val[OPT_PREVIEW].w = SANE_FALSE; 1462141cc406Sopenharmony_ci 1463141cc406Sopenharmony_ci 1464141cc406Sopenharmony_ci 1465141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1466141cc406Sopenharmony_ci} 1467141cc406Sopenharmony_ci 1468141cc406Sopenharmony_ci 1469141cc406Sopenharmony_ci/*------------------------- PIE POWER SAVE -----------------------------*/ 1470141cc406Sopenharmony_ci 1471141cc406Sopenharmony_cistatic SANE_Status 1472141cc406Sopenharmony_cipie_power_save (Pie_Scanner * scanner, int time) 1473141cc406Sopenharmony_ci{ 1474141cc406Sopenharmony_ci unsigned char buffer[128]; 1475141cc406Sopenharmony_ci size_t size; 1476141cc406Sopenharmony_ci SANE_Status status; 1477141cc406Sopenharmony_ci unsigned char *data; 1478141cc406Sopenharmony_ci 1479141cc406Sopenharmony_ci DBG (DBG_proc, "pie_power_save: %d min\n", time); 1480141cc406Sopenharmony_ci 1481141cc406Sopenharmony_ci size = 6; 1482141cc406Sopenharmony_ci 1483141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 1484141cc406Sopenharmony_ci 1485141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 1486141cc406Sopenharmony_ci 1487141cc406Sopenharmony_ci data = buffer + swrite.size; 1488141cc406Sopenharmony_ci memset (data, 0, size); 1489141cc406Sopenharmony_ci 1490141cc406Sopenharmony_ci set_command (data, SET_POWER_SAVE_CONTROL); 1491141cc406Sopenharmony_ci set_data_length (data, size - 4); 1492141cc406Sopenharmony_ci data[4] = time & 0x7f; 1493141cc406Sopenharmony_ci 1494141cc406Sopenharmony_ci status = 1495141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 1496141cc406Sopenharmony_ci if (status) 1497141cc406Sopenharmony_ci { 1498141cc406Sopenharmony_ci DBG (DBG_error, "pie_power_save: write command returned status %s\n", 1499141cc406Sopenharmony_ci sane_strstatus (status)); 1500141cc406Sopenharmony_ci } 1501141cc406Sopenharmony_ci 1502141cc406Sopenharmony_ci return status; 1503141cc406Sopenharmony_ci} 1504141cc406Sopenharmony_ci 1505141cc406Sopenharmony_ci/*------------------------- PIE SEND EXPOSURE ONE -----------------------------*/ 1506141cc406Sopenharmony_ci 1507141cc406Sopenharmony_ci 1508141cc406Sopenharmony_cistatic SANE_Status 1509141cc406Sopenharmony_cipie_send_exposure_one (Pie_Scanner * scanner, int filter, int value) 1510141cc406Sopenharmony_ci{ 1511141cc406Sopenharmony_ci unsigned char buffer[128]; 1512141cc406Sopenharmony_ci size_t size; 1513141cc406Sopenharmony_ci SANE_Status status; 1514141cc406Sopenharmony_ci unsigned char *data; 1515141cc406Sopenharmony_ci 1516141cc406Sopenharmony_ci DBG (DBG_proc, "pie_send_exposure_one\n"); 1517141cc406Sopenharmony_ci 1518141cc406Sopenharmony_ci size = 8; 1519141cc406Sopenharmony_ci 1520141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 1521141cc406Sopenharmony_ci 1522141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 1523141cc406Sopenharmony_ci 1524141cc406Sopenharmony_ci data = buffer + swrite.size; 1525141cc406Sopenharmony_ci memset (data, 0, size); 1526141cc406Sopenharmony_ci 1527141cc406Sopenharmony_ci set_command (data, SET_EXP_TIME); 1528141cc406Sopenharmony_ci set_data_length (data, size - 4); 1529141cc406Sopenharmony_ci 1530141cc406Sopenharmony_ci data[4] = filter; 1531141cc406Sopenharmony_ci 1532141cc406Sopenharmony_ci set_data (data, 6, (int) value, 2); 1533141cc406Sopenharmony_ci 1534141cc406Sopenharmony_ci status = 1535141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 1536141cc406Sopenharmony_ci if (status) 1537141cc406Sopenharmony_ci { 1538141cc406Sopenharmony_ci DBG (DBG_error, 1539141cc406Sopenharmony_ci "pie_send_exposure_one: write command returned status %s\n", 1540141cc406Sopenharmony_ci sane_strstatus (status)); 1541141cc406Sopenharmony_ci } 1542141cc406Sopenharmony_ci 1543141cc406Sopenharmony_ci return status; 1544141cc406Sopenharmony_ci} 1545141cc406Sopenharmony_ci 1546141cc406Sopenharmony_ci/*------------------------- PIE SEND EXPOSURE -----------------------------*/ 1547141cc406Sopenharmony_ci 1548141cc406Sopenharmony_cistatic SANE_Status 1549141cc406Sopenharmony_cipie_send_exposure (Pie_Scanner * scanner) 1550141cc406Sopenharmony_ci{ 1551141cc406Sopenharmony_ci SANE_Status status; 1552141cc406Sopenharmony_ci 1553141cc406Sopenharmony_ci DBG (DBG_proc, "pie_send_exposure\n"); 1554141cc406Sopenharmony_ci 1555141cc406Sopenharmony_ci status = pie_send_exposure_one (scanner, FILTER_RED, 100); 1556141cc406Sopenharmony_ci if (status) 1557141cc406Sopenharmony_ci return status; 1558141cc406Sopenharmony_ci 1559141cc406Sopenharmony_ci status = pie_send_exposure_one (scanner, FILTER_GREEN, 100); 1560141cc406Sopenharmony_ci if (status) 1561141cc406Sopenharmony_ci return status; 1562141cc406Sopenharmony_ci 1563141cc406Sopenharmony_ci status = pie_send_exposure_one (scanner, FILTER_BLUE, 100); 1564141cc406Sopenharmony_ci if (status) 1565141cc406Sopenharmony_ci return status; 1566141cc406Sopenharmony_ci 1567141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1568141cc406Sopenharmony_ci} 1569141cc406Sopenharmony_ci 1570141cc406Sopenharmony_ci 1571141cc406Sopenharmony_ci/*------------------------- PIE SEND HIGHLIGHT/SHADOW ONE -----------------------------*/ 1572141cc406Sopenharmony_ci 1573141cc406Sopenharmony_cistatic SANE_Status 1574141cc406Sopenharmony_cipie_send_highlight_shadow_one (Pie_Scanner * scanner, int filter, 1575141cc406Sopenharmony_ci int highlight, int shadow) 1576141cc406Sopenharmony_ci{ 1577141cc406Sopenharmony_ci unsigned char buffer[128]; 1578141cc406Sopenharmony_ci size_t size; 1579141cc406Sopenharmony_ci SANE_Status status; 1580141cc406Sopenharmony_ci unsigned char *data; 1581141cc406Sopenharmony_ci 1582141cc406Sopenharmony_ci DBG (DBG_proc, "pie_send_highlight_shadow_one\n"); 1583141cc406Sopenharmony_ci 1584141cc406Sopenharmony_ci size = 8; 1585141cc406Sopenharmony_ci 1586141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 1587141cc406Sopenharmony_ci 1588141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 1589141cc406Sopenharmony_ci 1590141cc406Sopenharmony_ci data = buffer + swrite.size; 1591141cc406Sopenharmony_ci memset (data, 0, size); 1592141cc406Sopenharmony_ci 1593141cc406Sopenharmony_ci set_command (data, SET_EXP_TIME); 1594141cc406Sopenharmony_ci set_data_length (data, size - 4); 1595141cc406Sopenharmony_ci 1596141cc406Sopenharmony_ci data[4] = filter; 1597141cc406Sopenharmony_ci 1598141cc406Sopenharmony_ci data[6] = highlight; 1599141cc406Sopenharmony_ci data[7] = shadow; 1600141cc406Sopenharmony_ci 1601141cc406Sopenharmony_ci status = 1602141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 1603141cc406Sopenharmony_ci if (status) 1604141cc406Sopenharmony_ci { 1605141cc406Sopenharmony_ci DBG (DBG_error, 1606141cc406Sopenharmony_ci "pie_send_highlight_shadow_one: write command returned status %s\n", 1607141cc406Sopenharmony_ci sane_strstatus (status)); 1608141cc406Sopenharmony_ci } 1609141cc406Sopenharmony_ci 1610141cc406Sopenharmony_ci return status; 1611141cc406Sopenharmony_ci} 1612141cc406Sopenharmony_ci 1613141cc406Sopenharmony_ci/*------------------------- PIE SEND HIGHLIGHT/SHADOW -----------------------------*/ 1614141cc406Sopenharmony_ci 1615141cc406Sopenharmony_cistatic SANE_Status 1616141cc406Sopenharmony_cipie_send_highlight_shadow (Pie_Scanner * scanner) 1617141cc406Sopenharmony_ci{ 1618141cc406Sopenharmony_ci SANE_Status status; 1619141cc406Sopenharmony_ci 1620141cc406Sopenharmony_ci DBG (DBG_proc, "pie_send_highlight_shadow\n"); 1621141cc406Sopenharmony_ci 1622141cc406Sopenharmony_ci status = pie_send_highlight_shadow_one (scanner, FILTER_RED, 100, 0); 1623141cc406Sopenharmony_ci if (status) 1624141cc406Sopenharmony_ci return status; 1625141cc406Sopenharmony_ci 1626141cc406Sopenharmony_ci status = pie_send_highlight_shadow_one (scanner, FILTER_GREEN, 100, 0); 1627141cc406Sopenharmony_ci if (status) 1628141cc406Sopenharmony_ci return status; 1629141cc406Sopenharmony_ci 1630141cc406Sopenharmony_ci status = pie_send_highlight_shadow_one (scanner, FILTER_BLUE, 100, 0); 1631141cc406Sopenharmony_ci if (status) 1632141cc406Sopenharmony_ci return status; 1633141cc406Sopenharmony_ci 1634141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1635141cc406Sopenharmony_ci} 1636141cc406Sopenharmony_ci 1637141cc406Sopenharmony_ci/*------------------------- PIE PERFORM CAL ----------------------------*/ 1638141cc406Sopenharmony_ci 1639141cc406Sopenharmony_cistatic SANE_Status 1640141cc406Sopenharmony_cipie_perform_cal (Pie_Scanner * scanner, int cal_index) 1641141cc406Sopenharmony_ci{ 1642141cc406Sopenharmony_ci long *red_result; 1643141cc406Sopenharmony_ci long *green_result; 1644141cc406Sopenharmony_ci long *blue_result; 1645141cc406Sopenharmony_ci long *neutral_result; 1646141cc406Sopenharmony_ci long *result = NULL; 1647141cc406Sopenharmony_ci int rcv_length, send_length; 1648141cc406Sopenharmony_ci int rcv_lines, rcv_bits, send_bits; 1649141cc406Sopenharmony_ci int pixels_per_line; 1650141cc406Sopenharmony_ci int i; 1651141cc406Sopenharmony_ci unsigned char *rcv_buffer, *rcv_ptr; 1652141cc406Sopenharmony_ci unsigned char *send_buffer, *send_ptr; 1653141cc406Sopenharmony_ci size_t size; 1654141cc406Sopenharmony_ci int fullscale; 1655141cc406Sopenharmony_ci int cal_limit; 1656141cc406Sopenharmony_ci int k; 1657141cc406Sopenharmony_ci int filter; 1658141cc406Sopenharmony_ci SANE_Status status; 1659141cc406Sopenharmony_ci 1660141cc406Sopenharmony_ci DBG (DBG_proc, "pie_perform_cal\n"); 1661141cc406Sopenharmony_ci 1662141cc406Sopenharmony_ci pixels_per_line = scanner->device->cal_info[cal_index].pixels_per_line; 1663141cc406Sopenharmony_ci rcv_length = pixels_per_line; 1664141cc406Sopenharmony_ci send_length = pixels_per_line; 1665141cc406Sopenharmony_ci 1666141cc406Sopenharmony_ci rcv_bits = scanner->device->cal_info[cal_index].receive_bits; 1667141cc406Sopenharmony_ci if (rcv_bits > 8) 1668141cc406Sopenharmony_ci rcv_length *= 2; /* 2 bytes / sample */ 1669141cc406Sopenharmony_ci 1670141cc406Sopenharmony_ci send_bits = scanner->device->cal_info[cal_index].send_bits; 1671141cc406Sopenharmony_ci if (send_bits > 8) 1672141cc406Sopenharmony_ci send_length *= 2; /* 2 bytes / sample */ 1673141cc406Sopenharmony_ci 1674141cc406Sopenharmony_ci rcv_lines = scanner->device->cal_info[cal_index].num_lines; 1675141cc406Sopenharmony_ci 1676141cc406Sopenharmony_ci send_length += 2; /* space for filter at start */ 1677141cc406Sopenharmony_ci 1678141cc406Sopenharmony_ci if (scanner->colormode == RGB) 1679141cc406Sopenharmony_ci { 1680141cc406Sopenharmony_ci rcv_lines *= 3; 1681141cc406Sopenharmony_ci send_length *= 3; 1682141cc406Sopenharmony_ci rcv_length += 2; /* 2 bytes for index at front of data (only in RGB??) */ 1683141cc406Sopenharmony_ci } 1684141cc406Sopenharmony_ci 1685141cc406Sopenharmony_ci send_length += 4; /* space for header at start of data */ 1686141cc406Sopenharmony_ci 1687141cc406Sopenharmony_ci /* allocate buffers for the receive data, the result buffers, and for the send data */ 1688141cc406Sopenharmony_ci rcv_buffer = (unsigned char *) malloc (rcv_length); 1689141cc406Sopenharmony_ci 1690141cc406Sopenharmony_ci red_result = (long *) calloc (pixels_per_line, sizeof (long)); 1691141cc406Sopenharmony_ci green_result = (long *) calloc (pixels_per_line, sizeof (long)); 1692141cc406Sopenharmony_ci blue_result = (long *) calloc (pixels_per_line, sizeof (long)); 1693141cc406Sopenharmony_ci neutral_result = (long *) calloc (pixels_per_line, sizeof (long)); 1694141cc406Sopenharmony_ci 1695141cc406Sopenharmony_ci if (!rcv_buffer || !red_result || !green_result || !blue_result 1696141cc406Sopenharmony_ci || !neutral_result) 1697141cc406Sopenharmony_ci { 1698141cc406Sopenharmony_ci /* at least one malloc failed, so free all buffers (free accepts NULL) */ 1699141cc406Sopenharmony_ci free (rcv_buffer); 1700141cc406Sopenharmony_ci free (red_result); 1701141cc406Sopenharmony_ci free (green_result); 1702141cc406Sopenharmony_ci free (blue_result); 1703141cc406Sopenharmony_ci free (neutral_result); 1704141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1705141cc406Sopenharmony_ci } 1706141cc406Sopenharmony_ci 1707141cc406Sopenharmony_ci /* read the cal data a line at a time, and accumulate into the result arrays */ 1708141cc406Sopenharmony_ci while (rcv_lines--) 1709141cc406Sopenharmony_ci { 1710141cc406Sopenharmony_ci /* TUR */ 1711141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 1712141cc406Sopenharmony_ci if (status) 1713141cc406Sopenharmony_ci { 1714141cc406Sopenharmony_ci free (rcv_buffer); 1715141cc406Sopenharmony_ci free (red_result); 1716141cc406Sopenharmony_ci free (green_result); 1717141cc406Sopenharmony_ci free (blue_result); 1718141cc406Sopenharmony_ci free (neutral_result); 1719141cc406Sopenharmony_ci return status; 1720141cc406Sopenharmony_ci } 1721141cc406Sopenharmony_ci 1722141cc406Sopenharmony_ci set_read_length (sread.cmd, 1); 1723141cc406Sopenharmony_ci size = rcv_length; 1724141cc406Sopenharmony_ci 1725141cc406Sopenharmony_ci DBG (DBG_info, "pie_perform_cal: reading 1 line (%lu bytes)\n", (u_long) size); 1726141cc406Sopenharmony_ci 1727141cc406Sopenharmony_ci status = 1728141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, rcv_buffer, 1729141cc406Sopenharmony_ci &size); 1730141cc406Sopenharmony_ci 1731141cc406Sopenharmony_ci if (status) 1732141cc406Sopenharmony_ci { 1733141cc406Sopenharmony_ci DBG (DBG_error, 1734141cc406Sopenharmony_ci "pie_perform_cal: read command returned status %s\n", 1735141cc406Sopenharmony_ci sane_strstatus (status)); 1736141cc406Sopenharmony_ci free (rcv_buffer); 1737141cc406Sopenharmony_ci free (red_result); 1738141cc406Sopenharmony_ci free (green_result); 1739141cc406Sopenharmony_ci free (blue_result); 1740141cc406Sopenharmony_ci free (neutral_result); 1741141cc406Sopenharmony_ci return status; 1742141cc406Sopenharmony_ci } 1743141cc406Sopenharmony_ci 1744141cc406Sopenharmony_ci DBG_DUMP (DBG_dump, rcv_buffer, 32); 1745141cc406Sopenharmony_ci 1746141cc406Sopenharmony_ci /* which result buffer does this line belong to? */ 1747141cc406Sopenharmony_ci if (scanner->colormode == RGB) 1748141cc406Sopenharmony_ci { 1749141cc406Sopenharmony_ci if (*rcv_buffer == 'R') 1750141cc406Sopenharmony_ci result = red_result; 1751141cc406Sopenharmony_ci else if (*rcv_buffer == 'G') 1752141cc406Sopenharmony_ci result = green_result; 1753141cc406Sopenharmony_ci else if (*rcv_buffer == 'B') 1754141cc406Sopenharmony_ci result = blue_result; 1755141cc406Sopenharmony_ci else if (*rcv_buffer == 'N') 1756141cc406Sopenharmony_ci result = neutral_result; 1757141cc406Sopenharmony_ci else 1758141cc406Sopenharmony_ci { 1759141cc406Sopenharmony_ci DBG (DBG_error, "pie_perform_cal: invalid index byte (%02x)\n", 1760141cc406Sopenharmony_ci *rcv_buffer); 1761141cc406Sopenharmony_ci DBG_DUMP (DBG_error, rcv_buffer, 32); 1762141cc406Sopenharmony_ci free (rcv_buffer); 1763141cc406Sopenharmony_ci free (red_result); 1764141cc406Sopenharmony_ci free (green_result); 1765141cc406Sopenharmony_ci free (blue_result); 1766141cc406Sopenharmony_ci free (neutral_result); 1767141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1768141cc406Sopenharmony_ci } 1769141cc406Sopenharmony_ci rcv_ptr = rcv_buffer + 2; 1770141cc406Sopenharmony_ci } 1771141cc406Sopenharmony_ci else 1772141cc406Sopenharmony_ci { 1773141cc406Sopenharmony_ci /* monochrome - no bytes indicating filter here */ 1774141cc406Sopenharmony_ci result = neutral_result; 1775141cc406Sopenharmony_ci rcv_ptr = rcv_buffer; 1776141cc406Sopenharmony_ci } 1777141cc406Sopenharmony_ci 1778141cc406Sopenharmony_ci /* now add the values in this line to the result array */ 1779141cc406Sopenharmony_ci for (i = 0; i < pixels_per_line; i++) 1780141cc406Sopenharmony_ci { 1781141cc406Sopenharmony_ci result[i] += *rcv_ptr++; 1782141cc406Sopenharmony_ci if (rcv_bits > 8) 1783141cc406Sopenharmony_ci { 1784141cc406Sopenharmony_ci result[i] += (*rcv_ptr++) << 8; 1785141cc406Sopenharmony_ci } 1786141cc406Sopenharmony_ci } 1787141cc406Sopenharmony_ci } 1788141cc406Sopenharmony_ci 1789141cc406Sopenharmony_ci /* got all the cal data, now process it ready to send back */ 1790141cc406Sopenharmony_ci free (rcv_buffer); 1791141cc406Sopenharmony_ci send_buffer = (unsigned char *) malloc (send_length + swrite.size); 1792141cc406Sopenharmony_ci 1793141cc406Sopenharmony_ci if (!send_buffer) 1794141cc406Sopenharmony_ci { 1795141cc406Sopenharmony_ci free (red_result); 1796141cc406Sopenharmony_ci free (green_result); 1797141cc406Sopenharmony_ci free (blue_result); 1798141cc406Sopenharmony_ci free (neutral_result); 1799141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1800141cc406Sopenharmony_ci } 1801141cc406Sopenharmony_ci 1802141cc406Sopenharmony_ci rcv_lines = scanner->device->cal_info[cal_index].num_lines; 1803141cc406Sopenharmony_ci fullscale = (1 << rcv_bits) - 1; 1804141cc406Sopenharmony_ci cal_limit = fullscale / (1 << scanner->device->inquiry_cal_eqn); 1805141cc406Sopenharmony_ci k = (1 << scanner->device->inquiry_cal_eqn) - 1; 1806141cc406Sopenharmony_ci 1807141cc406Sopenharmony_ci /* set up scsi command and data */ 1808141cc406Sopenharmony_ci size = send_length; 1809141cc406Sopenharmony_ci 1810141cc406Sopenharmony_ci memcpy (send_buffer, swrite.cmd, swrite.size); 1811141cc406Sopenharmony_ci set_write_length (send_buffer, size); 1812141cc406Sopenharmony_ci 1813141cc406Sopenharmony_ci set_command (send_buffer + swrite.size, SEND_CAL_DATA); 1814141cc406Sopenharmony_ci set_data_length (send_buffer + swrite.size, size - 4); 1815141cc406Sopenharmony_ci 1816141cc406Sopenharmony_ci send_ptr = send_buffer + swrite.size + 4; 1817141cc406Sopenharmony_ci 1818141cc406Sopenharmony_ci for (filter = FILTER_NEUTRAL; filter <= FILTER_BLUE; filter <<= 1) 1819141cc406Sopenharmony_ci { 1820141cc406Sopenharmony_ci 1821141cc406Sopenharmony_ci /* only send data for filter we expect to send */ 1822141cc406Sopenharmony_ci if (!(filter & scanner->cal_filter)) 1823141cc406Sopenharmony_ci continue; 1824141cc406Sopenharmony_ci 1825141cc406Sopenharmony_ci set_data (send_ptr, 0, filter, 2); 1826141cc406Sopenharmony_ci send_ptr += 2; 1827141cc406Sopenharmony_ci 1828141cc406Sopenharmony_ci if (scanner->colormode == RGB) 1829141cc406Sopenharmony_ci { 1830141cc406Sopenharmony_ci switch (filter) 1831141cc406Sopenharmony_ci { 1832141cc406Sopenharmony_ci case FILTER_RED: 1833141cc406Sopenharmony_ci result = red_result; 1834141cc406Sopenharmony_ci break; 1835141cc406Sopenharmony_ci 1836141cc406Sopenharmony_ci case FILTER_GREEN: 1837141cc406Sopenharmony_ci result = green_result; 1838141cc406Sopenharmony_ci break; 1839141cc406Sopenharmony_ci 1840141cc406Sopenharmony_ci case FILTER_BLUE: 1841141cc406Sopenharmony_ci result = blue_result; 1842141cc406Sopenharmony_ci break; 1843141cc406Sopenharmony_ci 1844141cc406Sopenharmony_ci case FILTER_NEUTRAL: 1845141cc406Sopenharmony_ci result = neutral_result; 1846141cc406Sopenharmony_ci break; 1847141cc406Sopenharmony_ci } 1848141cc406Sopenharmony_ci } 1849141cc406Sopenharmony_ci else 1850141cc406Sopenharmony_ci result = neutral_result; 1851141cc406Sopenharmony_ci 1852141cc406Sopenharmony_ci /* for each pixel */ 1853141cc406Sopenharmony_ci for (i = 0; i < pixels_per_line; i++) 1854141cc406Sopenharmony_ci { 1855141cc406Sopenharmony_ci long x; 1856141cc406Sopenharmony_ci 1857141cc406Sopenharmony_ci /* make average */ 1858141cc406Sopenharmony_ci x = result[i] / rcv_lines; 1859141cc406Sopenharmony_ci 1860141cc406Sopenharmony_ci /* ensure not overflowed */ 1861141cc406Sopenharmony_ci if (x > fullscale) 1862141cc406Sopenharmony_ci x = fullscale; 1863141cc406Sopenharmony_ci 1864141cc406Sopenharmony_ci /* process according to required calibration equation */ 1865141cc406Sopenharmony_ci if (scanner->device->inquiry_cal_eqn) 1866141cc406Sopenharmony_ci { 1867141cc406Sopenharmony_ci if (x <= cal_limit) 1868141cc406Sopenharmony_ci x = fullscale; 1869141cc406Sopenharmony_ci else 1870141cc406Sopenharmony_ci x = ((fullscale - x) * fullscale) / (x * k); 1871141cc406Sopenharmony_ci } 1872141cc406Sopenharmony_ci 1873141cc406Sopenharmony_ci if (rcv_bits > send_bits) 1874141cc406Sopenharmony_ci x >>= (rcv_bits - send_bits); 1875141cc406Sopenharmony_ci else if (send_bits > rcv_bits) 1876141cc406Sopenharmony_ci x <<= (send_bits - rcv_bits); 1877141cc406Sopenharmony_ci 1878141cc406Sopenharmony_ci /* put result into send buffer */ 1879141cc406Sopenharmony_ci *send_ptr++ = x; 1880141cc406Sopenharmony_ci if (send_bits > 8) 1881141cc406Sopenharmony_ci *send_ptr++ = x >> 8; 1882141cc406Sopenharmony_ci } 1883141cc406Sopenharmony_ci } 1884141cc406Sopenharmony_ci 1885141cc406Sopenharmony_ci /* now send the data back to scanner */ 1886141cc406Sopenharmony_ci 1887141cc406Sopenharmony_ci /* TUR */ 1888141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 1889141cc406Sopenharmony_ci if (status) 1890141cc406Sopenharmony_ci { 1891141cc406Sopenharmony_ci free (red_result); 1892141cc406Sopenharmony_ci free (green_result); 1893141cc406Sopenharmony_ci free (blue_result); 1894141cc406Sopenharmony_ci free (neutral_result); 1895141cc406Sopenharmony_ci free (send_buffer); 1896141cc406Sopenharmony_ci return status; 1897141cc406Sopenharmony_ci } 1898141cc406Sopenharmony_ci 1899141cc406Sopenharmony_ci DBG (DBG_info, "pie_perform_cal: sending cal data (%lu bytes)\n", (u_long) size); 1900141cc406Sopenharmony_ci DBG_DUMP (DBG_dump, send_buffer, 64); 1901141cc406Sopenharmony_ci 1902141cc406Sopenharmony_ci status = 1903141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, send_buffer, swrite.size + size, NULL, 1904141cc406Sopenharmony_ci NULL); 1905141cc406Sopenharmony_ci if (status) 1906141cc406Sopenharmony_ci { 1907141cc406Sopenharmony_ci DBG (DBG_error, "pie_perform_cal: write command returned status %s\n", 1908141cc406Sopenharmony_ci sane_strstatus (status)); 1909141cc406Sopenharmony_ci free (red_result); 1910141cc406Sopenharmony_ci free (green_result); 1911141cc406Sopenharmony_ci free (blue_result); 1912141cc406Sopenharmony_ci free (neutral_result); 1913141cc406Sopenharmony_ci free (send_buffer); 1914141cc406Sopenharmony_ci return status; 1915141cc406Sopenharmony_ci } 1916141cc406Sopenharmony_ci 1917141cc406Sopenharmony_ci free (red_result); 1918141cc406Sopenharmony_ci free (green_result); 1919141cc406Sopenharmony_ci free (blue_result); 1920141cc406Sopenharmony_ci free (neutral_result); 1921141cc406Sopenharmony_ci free (send_buffer); 1922141cc406Sopenharmony_ci 1923141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1924141cc406Sopenharmony_ci} 1925141cc406Sopenharmony_ci 1926141cc406Sopenharmony_ci/*------------------------- PIE DO CAL -----------------------------*/ 1927141cc406Sopenharmony_ci 1928141cc406Sopenharmony_cistatic SANE_Status 1929141cc406Sopenharmony_cipie_do_cal (Pie_Scanner * scanner) 1930141cc406Sopenharmony_ci{ 1931141cc406Sopenharmony_ci SANE_Status status; 1932141cc406Sopenharmony_ci int cal_index; 1933141cc406Sopenharmony_ci 1934141cc406Sopenharmony_ci DBG (DBG_proc, "pie_do_cal\n"); 1935141cc406Sopenharmony_ci 1936141cc406Sopenharmony_ci if (scanner->device->inquiry_scan_capability & INQ_CAP_EXT_CAL) 1937141cc406Sopenharmony_ci { 1938141cc406Sopenharmony_ci for (cal_index = 0; cal_index < scanner->device->cal_info_count; 1939141cc406Sopenharmony_ci cal_index++) 1940141cc406Sopenharmony_ci if (scanner->device->cal_info[cal_index].cal_type == 1941141cc406Sopenharmony_ci scanner->cal_mode) 1942141cc406Sopenharmony_ci { 1943141cc406Sopenharmony_ci status = pie_perform_cal (scanner, cal_index); 1944141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1945141cc406Sopenharmony_ci return status; 1946141cc406Sopenharmony_ci } 1947141cc406Sopenharmony_ci } 1948141cc406Sopenharmony_ci 1949141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1950141cc406Sopenharmony_ci} 1951141cc406Sopenharmony_ci 1952141cc406Sopenharmony_ci/*------------------------- PIE DWNLD GAMMA ONE -----------------------------*/ 1953141cc406Sopenharmony_ci 1954141cc406Sopenharmony_cistatic SANE_Status 1955141cc406Sopenharmony_cipie_dwnld_gamma_one (Pie_Scanner * scanner, int filter, SANE_Int * table) 1956141cc406Sopenharmony_ci{ 1957141cc406Sopenharmony_ci unsigned char *buffer; 1958141cc406Sopenharmony_ci size_t size; 1959141cc406Sopenharmony_ci SANE_Status status; 1960141cc406Sopenharmony_ci unsigned char *data; 1961141cc406Sopenharmony_ci int i; 1962141cc406Sopenharmony_ci 1963141cc406Sopenharmony_ci DBG (DBG_proc, "pie_dwnld_gamma_one\n"); 1964141cc406Sopenharmony_ci 1965141cc406Sopenharmony_ci /* TUR */ 1966141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 1967141cc406Sopenharmony_ci if (status) 1968141cc406Sopenharmony_ci { 1969141cc406Sopenharmony_ci return status; 1970141cc406Sopenharmony_ci } 1971141cc406Sopenharmony_ci 1972141cc406Sopenharmony_ci if (scanner->device->inquiry_gamma_bits > 8) 1973141cc406Sopenharmony_ci size = scanner->gamma_length * 2 + 6; 1974141cc406Sopenharmony_ci else 1975141cc406Sopenharmony_ci size = scanner->gamma_length + 6; 1976141cc406Sopenharmony_ci 1977141cc406Sopenharmony_ci buffer = malloc (size + swrite.size); 1978141cc406Sopenharmony_ci if (!buffer) 1979141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1980141cc406Sopenharmony_ci 1981141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 1982141cc406Sopenharmony_ci 1983141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 1984141cc406Sopenharmony_ci 1985141cc406Sopenharmony_ci data = buffer + swrite.size; 1986141cc406Sopenharmony_ci memset (data, 0, size); 1987141cc406Sopenharmony_ci 1988141cc406Sopenharmony_ci set_command (data, DWNLD_GAMMA_TABLE); 1989141cc406Sopenharmony_ci set_data_length (data, size - 4); 1990141cc406Sopenharmony_ci 1991141cc406Sopenharmony_ci data[4] = filter; 1992141cc406Sopenharmony_ci 1993141cc406Sopenharmony_ci for (i = 0; i < scanner->gamma_length; i++) 1994141cc406Sopenharmony_ci { 1995141cc406Sopenharmony_ci if (scanner->device->inquiry_gamma_bits > 8) 1996141cc406Sopenharmony_ci { 1997141cc406Sopenharmony_ci set_data (data, 6 + 2 * i, table ? table[i] : i, 2); 1998141cc406Sopenharmony_ci } 1999141cc406Sopenharmony_ci else 2000141cc406Sopenharmony_ci { 2001141cc406Sopenharmony_ci set_data (data, 6 + i, table ? table[i] : i, 1); 2002141cc406Sopenharmony_ci } 2003141cc406Sopenharmony_ci } 2004141cc406Sopenharmony_ci 2005141cc406Sopenharmony_ci DBG_DUMP (DBG_dump, data, 128); 2006141cc406Sopenharmony_ci 2007141cc406Sopenharmony_ci status = 2008141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 2009141cc406Sopenharmony_ci if (status) 2010141cc406Sopenharmony_ci { 2011141cc406Sopenharmony_ci DBG (DBG_error, 2012141cc406Sopenharmony_ci "pie_dwnld_gamma_one: write command returned status %s\n", 2013141cc406Sopenharmony_ci sane_strstatus (status)); 2014141cc406Sopenharmony_ci } 2015141cc406Sopenharmony_ci 2016141cc406Sopenharmony_ci free (buffer); 2017141cc406Sopenharmony_ci 2018141cc406Sopenharmony_ci return status; 2019141cc406Sopenharmony_ci} 2020141cc406Sopenharmony_ci 2021141cc406Sopenharmony_ci/*------------------------- PIE DWNLD GAMMA -----------------------------*/ 2022141cc406Sopenharmony_ci 2023141cc406Sopenharmony_cistatic SANE_Status 2024141cc406Sopenharmony_cipie_dwnld_gamma (Pie_Scanner * scanner) 2025141cc406Sopenharmony_ci{ 2026141cc406Sopenharmony_ci SANE_Status status; 2027141cc406Sopenharmony_ci 2028141cc406Sopenharmony_ci DBG (DBG_proc, "pie_dwnld_gamma\n"); 2029141cc406Sopenharmony_ci 2030141cc406Sopenharmony_ci if (scanner->colormode == RGB) 2031141cc406Sopenharmony_ci { 2032141cc406Sopenharmony_ci status = 2033141cc406Sopenharmony_ci pie_dwnld_gamma_one (scanner, FILTER_RED, scanner->gamma_table[1]); 2034141cc406Sopenharmony_ci if (status) 2035141cc406Sopenharmony_ci return status; 2036141cc406Sopenharmony_ci 2037141cc406Sopenharmony_ci 2038141cc406Sopenharmony_ci status = 2039141cc406Sopenharmony_ci pie_dwnld_gamma_one (scanner, FILTER_GREEN, scanner->gamma_table[2]); 2040141cc406Sopenharmony_ci if (status) 2041141cc406Sopenharmony_ci return status; 2042141cc406Sopenharmony_ci 2043141cc406Sopenharmony_ci status = 2044141cc406Sopenharmony_ci pie_dwnld_gamma_one (scanner, FILTER_BLUE, scanner->gamma_table[3]); 2045141cc406Sopenharmony_ci if (status) 2046141cc406Sopenharmony_ci return status; 2047141cc406Sopenharmony_ci } 2048141cc406Sopenharmony_ci else 2049141cc406Sopenharmony_ci { 2050141cc406Sopenharmony_ci SANE_Int *table; 2051141cc406Sopenharmony_ci 2052141cc406Sopenharmony_ci /* if lineart or half tone, force gamma to be one to one by passing NULL */ 2053141cc406Sopenharmony_ci if (scanner->colormode == GRAYSCALE) 2054141cc406Sopenharmony_ci table = scanner->gamma_table[0]; 2055141cc406Sopenharmony_ci else 2056141cc406Sopenharmony_ci table = NULL; 2057141cc406Sopenharmony_ci 2058141cc406Sopenharmony_ci status = pie_dwnld_gamma_one (scanner, FILTER_GREEN, table); 2059141cc406Sopenharmony_ci if (status) 2060141cc406Sopenharmony_ci return status; 2061141cc406Sopenharmony_ci } 2062141cc406Sopenharmony_ci 2063141cc406Sopenharmony_ci usleep (DOWNLOAD_GAMMA_WAIT_TIME); 2064141cc406Sopenharmony_ci 2065141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2066141cc406Sopenharmony_ci} 2067141cc406Sopenharmony_ci 2068141cc406Sopenharmony_ci/*------------------------- PIE SET WINDOW -----------------------------*/ 2069141cc406Sopenharmony_ci 2070141cc406Sopenharmony_cistatic SANE_Status 2071141cc406Sopenharmony_cipie_set_window (Pie_Scanner * scanner) 2072141cc406Sopenharmony_ci{ 2073141cc406Sopenharmony_ci unsigned char buffer[128]; 2074141cc406Sopenharmony_ci size_t size; 2075141cc406Sopenharmony_ci SANE_Status status; 2076141cc406Sopenharmony_ci unsigned char *data; 2077141cc406Sopenharmony_ci double x, dpmm; 2078141cc406Sopenharmony_ci 2079141cc406Sopenharmony_ci DBG (DBG_proc, "pie_set_window\n"); 2080141cc406Sopenharmony_ci 2081141cc406Sopenharmony_ci size = 14; 2082141cc406Sopenharmony_ci 2083141cc406Sopenharmony_ci set_write_length (swrite.cmd, size); 2084141cc406Sopenharmony_ci 2085141cc406Sopenharmony_ci memcpy (buffer, swrite.cmd, swrite.size); 2086141cc406Sopenharmony_ci 2087141cc406Sopenharmony_ci data = buffer + swrite.size; 2088141cc406Sopenharmony_ci memset (data, 0, size); 2089141cc406Sopenharmony_ci 2090141cc406Sopenharmony_ci set_command (data, SET_SCAN_FRAME); 2091141cc406Sopenharmony_ci set_data_length (data, size - 4); 2092141cc406Sopenharmony_ci 2093141cc406Sopenharmony_ci data[4] = 0x80; 2094141cc406Sopenharmony_ci if (scanner->colormode == HALFTONE) 2095141cc406Sopenharmony_ci data[4] |= 0x40; 2096141cc406Sopenharmony_ci 2097141cc406Sopenharmony_ci dpmm = (double) scanner->device->inquiry_pixel_resolution / MM_PER_INCH; 2098141cc406Sopenharmony_ci 2099141cc406Sopenharmony_ci x = SANE_UNFIX (scanner->val[OPT_TL_X].w) * dpmm; 2100141cc406Sopenharmony_ci set_data (data, 6, (int) x, 2); 2101141cc406Sopenharmony_ci DBG (DBG_info, "TL_X: %d\n", (int) x); 2102141cc406Sopenharmony_ci 2103141cc406Sopenharmony_ci x = SANE_UNFIX (scanner->val[OPT_TL_Y].w) * dpmm; 2104141cc406Sopenharmony_ci set_data (data, 8, (int) x, 2); 2105141cc406Sopenharmony_ci DBG (DBG_info, "TL_Y: %d\n", (int) x); 2106141cc406Sopenharmony_ci 2107141cc406Sopenharmony_ci x = SANE_UNFIX (scanner->val[OPT_BR_X].w) * dpmm; 2108141cc406Sopenharmony_ci set_data (data, 10, (int) x, 2); 2109141cc406Sopenharmony_ci DBG (DBG_info, "BR_X: %d\n", (int) x); 2110141cc406Sopenharmony_ci 2111141cc406Sopenharmony_ci x = SANE_UNFIX (scanner->val[OPT_BR_Y].w) * dpmm; 2112141cc406Sopenharmony_ci set_data (data, 12, (int) x, 2); 2113141cc406Sopenharmony_ci DBG (DBG_info, "BR_Y: %d\n", (int) x); 2114141cc406Sopenharmony_ci 2115141cc406Sopenharmony_ci status = 2116141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 2117141cc406Sopenharmony_ci if (status) 2118141cc406Sopenharmony_ci { 2119141cc406Sopenharmony_ci DBG (DBG_error, "pie_set_window: write command returned status %s\n", 2120141cc406Sopenharmony_ci sane_strstatus (status)); 2121141cc406Sopenharmony_ci } 2122141cc406Sopenharmony_ci 2123141cc406Sopenharmony_ci return status; 2124141cc406Sopenharmony_ci} 2125141cc406Sopenharmony_ci 2126141cc406Sopenharmony_ci 2127141cc406Sopenharmony_ci/*------------------------- PIE MODE SELECT -----------------------------*/ 2128141cc406Sopenharmony_ci 2129141cc406Sopenharmony_cistatic SANE_Status 2130141cc406Sopenharmony_cipie_mode_select (Pie_Scanner * scanner) 2131141cc406Sopenharmony_ci{ 2132141cc406Sopenharmony_ci 2133141cc406Sopenharmony_ci SANE_Status status; 2134141cc406Sopenharmony_ci unsigned char buffer[128]; 2135141cc406Sopenharmony_ci size_t size; 2136141cc406Sopenharmony_ci unsigned char *data; 2137141cc406Sopenharmony_ci int i; 2138141cc406Sopenharmony_ci 2139141cc406Sopenharmony_ci DBG (DBG_proc, "pie_mode_select\n"); 2140141cc406Sopenharmony_ci 2141141cc406Sopenharmony_ci size = 14; 2142141cc406Sopenharmony_ci 2143141cc406Sopenharmony_ci set_mode_length (smode.cmd, size); 2144141cc406Sopenharmony_ci 2145141cc406Sopenharmony_ci memcpy (buffer, smode.cmd, smode.size); 2146141cc406Sopenharmony_ci 2147141cc406Sopenharmony_ci data = buffer + smode.size; 2148141cc406Sopenharmony_ci memset (data, 0, size); 2149141cc406Sopenharmony_ci 2150141cc406Sopenharmony_ci /* size of data */ 2151141cc406Sopenharmony_ci data[1] = size - 2; 2152141cc406Sopenharmony_ci 2153141cc406Sopenharmony_ci /* set resolution required */ 2154141cc406Sopenharmony_ci set_data (data, 2, scanner->resolution, 2); 2155141cc406Sopenharmony_ci 2156141cc406Sopenharmony_ci /* set color filter and color depth */ 2157141cc406Sopenharmony_ci switch (scanner->colormode) 2158141cc406Sopenharmony_ci { 2159141cc406Sopenharmony_ci case RGB: 2160141cc406Sopenharmony_ci if (scanner->device->inquiry_filters & INQ_ONE_PASS_COLOR) 2161141cc406Sopenharmony_ci { 2162141cc406Sopenharmony_ci data[4] = INQ_ONE_PASS_COLOR; 2163141cc406Sopenharmony_ci scanner->cal_filter = FILTER_RED | FILTER_GREEN | FILTER_BLUE; 2164141cc406Sopenharmony_ci } 2165141cc406Sopenharmony_ci else 2166141cc406Sopenharmony_ci { 2167141cc406Sopenharmony_ci DBG (DBG_error, 2168141cc406Sopenharmony_ci "pie_mode_select: support for multipass color not yet implemented\n"); 2169141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2170141cc406Sopenharmony_ci } 2171141cc406Sopenharmony_ci data[5] = INQ_COLOR_DEPTH_8; 2172141cc406Sopenharmony_ci break; 2173141cc406Sopenharmony_ci 2174141cc406Sopenharmony_ci case GRAYSCALE: 2175141cc406Sopenharmony_ci case LINEART: 2176141cc406Sopenharmony_ci case HALFTONE: 2177141cc406Sopenharmony_ci /* choose which filter to use for monochrome mode */ 2178141cc406Sopenharmony_ci if (scanner->device->inquiry_filters & INQ_FILTER_NEUTRAL) 2179141cc406Sopenharmony_ci { 2180141cc406Sopenharmony_ci data[4] = FILTER_NEUTRAL; 2181141cc406Sopenharmony_ci scanner->cal_filter = FILTER_NEUTRAL; 2182141cc406Sopenharmony_ci } 2183141cc406Sopenharmony_ci else if (scanner->device->inquiry_filters & INQ_FILTER_GREEN) 2184141cc406Sopenharmony_ci { 2185141cc406Sopenharmony_ci data[4] = FILTER_GREEN; 2186141cc406Sopenharmony_ci scanner->cal_filter = FILTER_GREEN; 2187141cc406Sopenharmony_ci } 2188141cc406Sopenharmony_ci else if (scanner->device->inquiry_filters & INQ_FILTER_RED) 2189141cc406Sopenharmony_ci { 2190141cc406Sopenharmony_ci data[4] = FILTER_RED; 2191141cc406Sopenharmony_ci scanner->cal_filter = FILTER_RED; 2192141cc406Sopenharmony_ci } 2193141cc406Sopenharmony_ci else if (scanner->device->inquiry_filters & INQ_FILTER_BLUE) 2194141cc406Sopenharmony_ci { 2195141cc406Sopenharmony_ci data[4] = FILTER_BLUE; 2196141cc406Sopenharmony_ci scanner->cal_filter = FILTER_BLUE; 2197141cc406Sopenharmony_ci } 2198141cc406Sopenharmony_ci else 2199141cc406Sopenharmony_ci { 2200141cc406Sopenharmony_ci DBG (DBG_error, 2201141cc406Sopenharmony_ci "pie_mode_select: scanner doesn't appear to support monochrome\n"); 2202141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2203141cc406Sopenharmony_ci } 2204141cc406Sopenharmony_ci 2205141cc406Sopenharmony_ci if (scanner->colormode == GRAYSCALE) 2206141cc406Sopenharmony_ci data[5] = INQ_COLOR_DEPTH_8; 2207141cc406Sopenharmony_ci else 2208141cc406Sopenharmony_ci data[5] = INQ_COLOR_DEPTH_1; 2209141cc406Sopenharmony_ci break; 2210141cc406Sopenharmony_ci } 2211141cc406Sopenharmony_ci 2212141cc406Sopenharmony_ci /* choose color packing method */ 2213141cc406Sopenharmony_ci if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE) 2214141cc406Sopenharmony_ci data[6] = INQ_COLOR_FORMAT_LINE; 2215141cc406Sopenharmony_ci else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 2216141cc406Sopenharmony_ci data[6] = INQ_COLOR_FORMAT_INDEX; 2217141cc406Sopenharmony_ci else 2218141cc406Sopenharmony_ci { 2219141cc406Sopenharmony_ci DBG (DBG_error, 2220141cc406Sopenharmony_ci "pie_mode_select: support for pixel packing not yet implemented\n"); 2221141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2222141cc406Sopenharmony_ci } 2223141cc406Sopenharmony_ci 2224141cc406Sopenharmony_ci /* choose data format */ 2225141cc406Sopenharmony_ci if (scanner->device->inquiry_image_format & INQ_IMG_FMT_INTEL) 2226141cc406Sopenharmony_ci data[8] = INQ_IMG_FMT_INTEL; 2227141cc406Sopenharmony_ci else 2228141cc406Sopenharmony_ci { 2229141cc406Sopenharmony_ci DBG (DBG_error, 2230141cc406Sopenharmony_ci "pie_mode_select: support for Motorola format not yet implemented\n"); 2231141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2232141cc406Sopenharmony_ci } 2233141cc406Sopenharmony_ci 2234141cc406Sopenharmony_ci /* set required speed */ 2235141cc406Sopenharmony_ci i = 0; 2236141cc406Sopenharmony_ci while (scanner->device->speed_list[i] != NULL) 2237141cc406Sopenharmony_ci { 2238141cc406Sopenharmony_ci if (strcmp (scanner->device->speed_list[i], scanner->val[OPT_SPEED].s) 2239141cc406Sopenharmony_ci == 0) 2240141cc406Sopenharmony_ci break; 2241141cc406Sopenharmony_ci i++; 2242141cc406Sopenharmony_ci } 2243141cc406Sopenharmony_ci 2244141cc406Sopenharmony_ci if (scanner->device->speed_list[i] == NULL) 2245141cc406Sopenharmony_ci data[9] = 0; 2246141cc406Sopenharmony_ci else 2247141cc406Sopenharmony_ci data[9] = i; 2248141cc406Sopenharmony_ci 2249141cc406Sopenharmony_ci scanner->cal_mode = CAL_MODE_FLATBED; 2250141cc406Sopenharmony_ci 2251141cc406Sopenharmony_ci /* if preview supported, ask for preview, limit resolution to max for fast preview */ 2252141cc406Sopenharmony_ci if (scanner->val[OPT_PREVIEW].w 2253141cc406Sopenharmony_ci && (scanner->device->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW)) 2254141cc406Sopenharmony_ci { 2255141cc406Sopenharmony_ci DBG (DBG_info, "pie_mode_select: setting preview\n"); 2256141cc406Sopenharmony_ci scanner->cal_mode |= CAL_MODE_PREVIEW; 2257141cc406Sopenharmony_ci data[9] |= INQ_CAP_FAST_PREVIEW; 2258141cc406Sopenharmony_ci data[9] &= ~INQ_CAP_SPEEDS; 2259141cc406Sopenharmony_ci if (scanner->resolution > scanner->device->inquiry_fast_preview_res) 2260141cc406Sopenharmony_ci set_data (data, 2, scanner->device->inquiry_fast_preview_res, 2); 2261141cc406Sopenharmony_ci } 2262141cc406Sopenharmony_ci 2263141cc406Sopenharmony_ci 2264141cc406Sopenharmony_ci /* set required halftone pattern */ 2265141cc406Sopenharmony_ci i = 0; 2266141cc406Sopenharmony_ci while (scanner->device->halftone_list[i] != NULL) 2267141cc406Sopenharmony_ci { 2268141cc406Sopenharmony_ci if (strcmp 2269141cc406Sopenharmony_ci (scanner->device->halftone_list[i], 2270141cc406Sopenharmony_ci scanner->val[OPT_HALFTONE_PATTERN].s) == 0) 2271141cc406Sopenharmony_ci break; 2272141cc406Sopenharmony_ci i++; 2273141cc406Sopenharmony_ci } 2274141cc406Sopenharmony_ci 2275141cc406Sopenharmony_ci if (scanner->device->halftone_list[i] == NULL) 2276141cc406Sopenharmony_ci data[12] = 0; /* halftone pattern */ 2277141cc406Sopenharmony_ci else 2278141cc406Sopenharmony_ci data[12] = i; 2279141cc406Sopenharmony_ci 2280141cc406Sopenharmony_ci data[13] = SANE_UNFIX (scanner->val[OPT_THRESHOLD].w) * 255 / 100; /* lineart threshold */ 2281141cc406Sopenharmony_ci 2282141cc406Sopenharmony_ci DBG (DBG_info, "pie_mode_select: speed %02x\n", data[9]); 2283141cc406Sopenharmony_ci DBG (DBG_info, "pie_mode_select: halftone %d\n", data[12]); 2284141cc406Sopenharmony_ci DBG (DBG_info, "pie_mode_select: threshold %02x\n", data[13]); 2285141cc406Sopenharmony_ci 2286141cc406Sopenharmony_ci status = 2287141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, buffer, smode.size + size, NULL, NULL); 2288141cc406Sopenharmony_ci if (status) 2289141cc406Sopenharmony_ci { 2290141cc406Sopenharmony_ci DBG (DBG_error, "pie_mode_select: write command returned status %s\n", 2291141cc406Sopenharmony_ci sane_strstatus (status)); 2292141cc406Sopenharmony_ci } 2293141cc406Sopenharmony_ci 2294141cc406Sopenharmony_ci return status; 2295141cc406Sopenharmony_ci} 2296141cc406Sopenharmony_ci 2297141cc406Sopenharmony_ci 2298141cc406Sopenharmony_ci/*------------------------- PIE SCAN -----------------------------*/ 2299141cc406Sopenharmony_ci 2300141cc406Sopenharmony_cistatic SANE_Status 2301141cc406Sopenharmony_cipie_scan (Pie_Scanner * scanner, int start) 2302141cc406Sopenharmony_ci{ 2303141cc406Sopenharmony_ci SANE_Status status; 2304141cc406Sopenharmony_ci 2305141cc406Sopenharmony_ci DBG (DBG_proc, "pie_scan\n"); 2306141cc406Sopenharmony_ci 2307141cc406Sopenharmony_ci /* TUR */ 2308141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 2309141cc406Sopenharmony_ci if (status) 2310141cc406Sopenharmony_ci { 2311141cc406Sopenharmony_ci return status; 2312141cc406Sopenharmony_ci } 2313141cc406Sopenharmony_ci 2314141cc406Sopenharmony_ci set_scan_cmd (scan.cmd, start); 2315141cc406Sopenharmony_ci 2316141cc406Sopenharmony_ci do 2317141cc406Sopenharmony_ci { 2318141cc406Sopenharmony_ci status = sanei_scsi_cmd (scanner->sfd, scan.cmd, scan.size, NULL, NULL); 2319141cc406Sopenharmony_ci if (status) 2320141cc406Sopenharmony_ci { 2321141cc406Sopenharmony_ci DBG (DBG_error, "pie_scan: write command returned status %s\n", 2322141cc406Sopenharmony_ci sane_strstatus (status)); 2323141cc406Sopenharmony_ci usleep (SCAN_WARMUP_WAIT_TIME); 2324141cc406Sopenharmony_ci } 2325141cc406Sopenharmony_ci } 2326141cc406Sopenharmony_ci while (start && status); 2327141cc406Sopenharmony_ci 2328141cc406Sopenharmony_ci usleep (SCAN_WAIT_TIME); 2329141cc406Sopenharmony_ci 2330141cc406Sopenharmony_ci return status; 2331141cc406Sopenharmony_ci} 2332141cc406Sopenharmony_ci 2333141cc406Sopenharmony_ci 2334141cc406Sopenharmony_ci/* --------------------------------------- PIE WAIT SCANNER -------------------------- */ 2335141cc406Sopenharmony_ci 2336141cc406Sopenharmony_ci 2337141cc406Sopenharmony_cistatic SANE_Status 2338141cc406Sopenharmony_cipie_wait_scanner (Pie_Scanner * scanner) 2339141cc406Sopenharmony_ci{ 2340141cc406Sopenharmony_ci SANE_Status status; 2341141cc406Sopenharmony_ci int cnt = 0; 2342141cc406Sopenharmony_ci 2343141cc406Sopenharmony_ci DBG (DBG_proc, "wait_scanner\n"); 2344141cc406Sopenharmony_ci 2345141cc406Sopenharmony_ci do 2346141cc406Sopenharmony_ci { 2347141cc406Sopenharmony_ci if (cnt > 100) /* maximal 100 * 0.5 sec = 50 sec */ 2348141cc406Sopenharmony_ci { 2349141cc406Sopenharmony_ci DBG (DBG_warning, "scanner does not get ready\n"); 2350141cc406Sopenharmony_ci return -1; 2351141cc406Sopenharmony_ci } 2352141cc406Sopenharmony_ci /* test unit ready */ 2353141cc406Sopenharmony_ci status = 2354141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, test_unit_ready.cmd, 2355141cc406Sopenharmony_ci test_unit_ready.size, NULL, NULL); 2356141cc406Sopenharmony_ci cnt++; 2357141cc406Sopenharmony_ci 2358141cc406Sopenharmony_ci if (status) 2359141cc406Sopenharmony_ci { 2360141cc406Sopenharmony_ci if (cnt == 1) 2361141cc406Sopenharmony_ci { 2362141cc406Sopenharmony_ci DBG (DBG_info2, "scanner reports %s, waiting ...\n", 2363141cc406Sopenharmony_ci sane_strstatus (status)); 2364141cc406Sopenharmony_ci } 2365141cc406Sopenharmony_ci 2366141cc406Sopenharmony_ci usleep (TUR_WAIT_TIME); 2367141cc406Sopenharmony_ci } 2368141cc406Sopenharmony_ci } 2369141cc406Sopenharmony_ci while (status != SANE_STATUS_GOOD); 2370141cc406Sopenharmony_ci 2371141cc406Sopenharmony_ci DBG (DBG_info, "scanner ready\n"); 2372141cc406Sopenharmony_ci 2373141cc406Sopenharmony_ci 2374141cc406Sopenharmony_ci return status; 2375141cc406Sopenharmony_ci} 2376141cc406Sopenharmony_ci 2377141cc406Sopenharmony_ci 2378141cc406Sopenharmony_ci/* -------------------------------------- PIE GET PARAMS -------------------------- */ 2379141cc406Sopenharmony_ci 2380141cc406Sopenharmony_ci 2381141cc406Sopenharmony_cistatic SANE_Status 2382141cc406Sopenharmony_cipie_get_params (Pie_Scanner * scanner) 2383141cc406Sopenharmony_ci{ 2384141cc406Sopenharmony_ci SANE_Status status; 2385141cc406Sopenharmony_ci size_t size; 2386141cc406Sopenharmony_ci unsigned char buffer[128]; 2387141cc406Sopenharmony_ci 2388141cc406Sopenharmony_ci DBG (DBG_proc, "pie_get_params\n"); 2389141cc406Sopenharmony_ci 2390141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 2391141cc406Sopenharmony_ci if (status) 2392141cc406Sopenharmony_ci return status; 2393141cc406Sopenharmony_ci 2394141cc406Sopenharmony_ci if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE) 2395141cc406Sopenharmony_ci size = 16; 2396141cc406Sopenharmony_ci else 2397141cc406Sopenharmony_ci 2398141cc406Sopenharmony_ci size = 14; 2399141cc406Sopenharmony_ci 2400141cc406Sopenharmony_ci set_param_length (param.cmd, size); 2401141cc406Sopenharmony_ci 2402141cc406Sopenharmony_ci status = 2403141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, param.cmd, param.size, buffer, &size); 2404141cc406Sopenharmony_ci 2405141cc406Sopenharmony_ci if (status) 2406141cc406Sopenharmony_ci { 2407141cc406Sopenharmony_ci DBG (DBG_error, "pie_get_params: command returned status %s\n", 2408141cc406Sopenharmony_ci sane_strstatus (status)); 2409141cc406Sopenharmony_ci } 2410141cc406Sopenharmony_ci else 2411141cc406Sopenharmony_ci { 2412141cc406Sopenharmony_ci DBG (DBG_info, "Scan Width: %d\n", get_param_scan_width (buffer)); 2413141cc406Sopenharmony_ci DBG (DBG_info, "Scan Lines: %d\n", get_param_scan_lines (buffer)); 2414141cc406Sopenharmony_ci DBG (DBG_info, "Scan bytes: %d\n", get_param_scan_bytes (buffer)); 2415141cc406Sopenharmony_ci 2416141cc406Sopenharmony_ci DBG (DBG_info, "Offset 1: %d\n", 2417141cc406Sopenharmony_ci get_param_scan_filter_offset1 (buffer)); 2418141cc406Sopenharmony_ci DBG (DBG_info, "Offset 2: %d\n", 2419141cc406Sopenharmony_ci get_param_scan_filter_offset2 (buffer)); 2420141cc406Sopenharmony_ci DBG (DBG_info, "Scan period: %d\n", get_param_scan_period (buffer)); 2421141cc406Sopenharmony_ci DBG (DBG_info, "Xfer rate: %d\n", get_param_scsi_xfer_rate (buffer)); 2422141cc406Sopenharmony_ci if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE) 2423141cc406Sopenharmony_ci DBG (DBG_info, "Avail lines: %d\n", 2424141cc406Sopenharmony_ci get_param_scan_available_lines (buffer)); 2425141cc406Sopenharmony_ci 2426141cc406Sopenharmony_ci scanner->filter_offset1 = get_param_scan_filter_offset1 (buffer); 2427141cc406Sopenharmony_ci scanner->filter_offset2 = get_param_scan_filter_offset2 (buffer); 2428141cc406Sopenharmony_ci scanner->bytes_per_line = get_param_scan_bytes (buffer); 2429141cc406Sopenharmony_ci 2430141cc406Sopenharmony_ci scanner->params.pixels_per_line = get_param_scan_width (buffer); 2431141cc406Sopenharmony_ci scanner->params.lines = get_param_scan_lines (buffer); 2432141cc406Sopenharmony_ci 2433141cc406Sopenharmony_ci switch (scanner->colormode) 2434141cc406Sopenharmony_ci { 2435141cc406Sopenharmony_ci case RGB: 2436141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_RGB; 2437141cc406Sopenharmony_ci scanner->params.depth = 8; 2438141cc406Sopenharmony_ci scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer); 2439141cc406Sopenharmony_ci break; 2440141cc406Sopenharmony_ci 2441141cc406Sopenharmony_ci case GRAYSCALE: 2442141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_GRAY; 2443141cc406Sopenharmony_ci scanner->params.depth = 8; 2444141cc406Sopenharmony_ci scanner->params.bytes_per_line = get_param_scan_bytes (buffer); 2445141cc406Sopenharmony_ci break; 2446141cc406Sopenharmony_ci 2447141cc406Sopenharmony_ci case HALFTONE: 2448141cc406Sopenharmony_ci case LINEART: 2449141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_GRAY; 2450141cc406Sopenharmony_ci scanner->params.depth = 1; 2451141cc406Sopenharmony_ci scanner->params.bytes_per_line = get_param_scan_bytes (buffer); 2452141cc406Sopenharmony_ci break; 2453141cc406Sopenharmony_ci } 2454141cc406Sopenharmony_ci 2455141cc406Sopenharmony_ci scanner->params.last_frame = 0; 2456141cc406Sopenharmony_ci } 2457141cc406Sopenharmony_ci 2458141cc406Sopenharmony_ci return status; 2459141cc406Sopenharmony_ci} 2460141cc406Sopenharmony_ci 2461141cc406Sopenharmony_ci 2462141cc406Sopenharmony_ci/* -------------------------------------- PIE GRAB SCANNER -------------------------- */ 2463141cc406Sopenharmony_ci 2464141cc406Sopenharmony_ci 2465141cc406Sopenharmony_cistatic SANE_Status 2466141cc406Sopenharmony_cipie_grab_scanner (Pie_Scanner * scanner) 2467141cc406Sopenharmony_ci{ 2468141cc406Sopenharmony_ci SANE_Status status; 2469141cc406Sopenharmony_ci 2470141cc406Sopenharmony_ci DBG (DBG_proc, "grab_scanner\n"); 2471141cc406Sopenharmony_ci 2472141cc406Sopenharmony_ci 2473141cc406Sopenharmony_ci status = pie_wait_scanner (scanner); 2474141cc406Sopenharmony_ci if (status) 2475141cc406Sopenharmony_ci return status; 2476141cc406Sopenharmony_ci 2477141cc406Sopenharmony_ci status = 2478141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, reserve_unit.cmd, reserve_unit.size, NULL, 2479141cc406Sopenharmony_ci NULL); 2480141cc406Sopenharmony_ci 2481141cc406Sopenharmony_ci 2482141cc406Sopenharmony_ci if (status) 2483141cc406Sopenharmony_ci { 2484141cc406Sopenharmony_ci DBG (DBG_error, "pie_grab_scanner: command returned status %s\n", 2485141cc406Sopenharmony_ci sane_strstatus (status)); 2486141cc406Sopenharmony_ci } 2487141cc406Sopenharmony_ci else 2488141cc406Sopenharmony_ci { 2489141cc406Sopenharmony_ci DBG (DBG_info, "scanner reserved\n"); 2490141cc406Sopenharmony_ci } 2491141cc406Sopenharmony_ci 2492141cc406Sopenharmony_ci return status; 2493141cc406Sopenharmony_ci} 2494141cc406Sopenharmony_ci 2495141cc406Sopenharmony_ci 2496141cc406Sopenharmony_ci/* ------------------------------------ PIE GIVE SCANNER -------------------------- */ 2497141cc406Sopenharmony_ci 2498141cc406Sopenharmony_ci 2499141cc406Sopenharmony_cistatic SANE_Status 2500141cc406Sopenharmony_cipie_give_scanner (Pie_Scanner * scanner) 2501141cc406Sopenharmony_ci{ 2502141cc406Sopenharmony_ci SANE_Status status; 2503141cc406Sopenharmony_ci 2504141cc406Sopenharmony_ci DBG (DBG_info2, "trying to release scanner ...\n"); 2505141cc406Sopenharmony_ci 2506141cc406Sopenharmony_ci status = 2507141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, release_unit.cmd, release_unit.size, NULL, 2508141cc406Sopenharmony_ci NULL); 2509141cc406Sopenharmony_ci if (status) 2510141cc406Sopenharmony_ci { 2511141cc406Sopenharmony_ci DBG (DBG_error, "pie_give_scanner: command returned status %s\n", 2512141cc406Sopenharmony_ci sane_strstatus (status)); 2513141cc406Sopenharmony_ci } 2514141cc406Sopenharmony_ci else 2515141cc406Sopenharmony_ci { 2516141cc406Sopenharmony_ci DBG (DBG_info, "scanner released\n"); 2517141cc406Sopenharmony_ci } 2518141cc406Sopenharmony_ci return status; 2519141cc406Sopenharmony_ci} 2520141cc406Sopenharmony_ci 2521141cc406Sopenharmony_ci 2522141cc406Sopenharmony_ci/* ------------------- PIE READER PROCESS INDEXED ------------------- */ 2523141cc406Sopenharmony_ci 2524141cc406Sopenharmony_cistatic int 2525141cc406Sopenharmony_cipie_reader_process_indexed (Pie_Scanner * scanner, FILE * fp) 2526141cc406Sopenharmony_ci{ 2527141cc406Sopenharmony_ci int status; 2528141cc406Sopenharmony_ci int lines; 2529141cc406Sopenharmony_ci unsigned char *buffer, *reorder = NULL; 2530141cc406Sopenharmony_ci unsigned char *red_buffer = NULL, *green_buffer = NULL; 2531141cc406Sopenharmony_ci unsigned char *red_in = NULL, *red_out = NULL; 2532141cc406Sopenharmony_ci unsigned char *green_in = NULL, *green_out = NULL; 2533141cc406Sopenharmony_ci int red_size = 0, green_size = 0; 2534141cc406Sopenharmony_ci int bytes_per_line; 2535141cc406Sopenharmony_ci int red_count = 0, green_count = 0; 2536141cc406Sopenharmony_ci 2537141cc406Sopenharmony_ci size_t size; 2538141cc406Sopenharmony_ci 2539141cc406Sopenharmony_ci DBG (DBG_read, "reading %d lines of %d bytes/line (indexed)\n", 2540141cc406Sopenharmony_ci scanner->params.lines, scanner->params.bytes_per_line); 2541141cc406Sopenharmony_ci 2542141cc406Sopenharmony_ci lines = scanner->params.lines; 2543141cc406Sopenharmony_ci bytes_per_line = scanner->bytes_per_line; 2544141cc406Sopenharmony_ci 2545141cc406Sopenharmony_ci /* allocate receive buffer */ 2546141cc406Sopenharmony_ci buffer = malloc (bytes_per_line + 2); 2547141cc406Sopenharmony_ci if (!buffer) 2548141cc406Sopenharmony_ci { 2549141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2550141cc406Sopenharmony_ci } 2551141cc406Sopenharmony_ci 2552141cc406Sopenharmony_ci /* allocate deskew buffers for RGB mode */ 2553141cc406Sopenharmony_ci if (scanner->colormode == RGB) 2554141cc406Sopenharmony_ci { 2555141cc406Sopenharmony_ci lines *= 3; 2556141cc406Sopenharmony_ci 2557141cc406Sopenharmony_ci red_size = bytes_per_line * (scanner->filter_offset1 + 2558141cc406Sopenharmony_ci scanner->filter_offset2 + 2); 2559141cc406Sopenharmony_ci green_size = bytes_per_line * (scanner->filter_offset2 + 2); 2560141cc406Sopenharmony_ci 2561141cc406Sopenharmony_ci DBG (DBG_info2, 2562141cc406Sopenharmony_ci "pie_reader_process_indexed: alloc %d lines (%d bytes) for red buffer\n", 2563141cc406Sopenharmony_ci red_size / bytes_per_line, red_size); 2564141cc406Sopenharmony_ci DBG (DBG_info2, 2565141cc406Sopenharmony_ci "pie_reader_process_indexed: alloc %d lines (%d bytes) for green buffer\n", 2566141cc406Sopenharmony_ci green_size / bytes_per_line, green_size); 2567141cc406Sopenharmony_ci 2568141cc406Sopenharmony_ci reorder = malloc (scanner->params.bytes_per_line); 2569141cc406Sopenharmony_ci red_buffer = malloc (red_size); 2570141cc406Sopenharmony_ci green_buffer = malloc (green_size); 2571141cc406Sopenharmony_ci 2572141cc406Sopenharmony_ci if (!reorder || !red_buffer || !green_buffer) 2573141cc406Sopenharmony_ci { 2574141cc406Sopenharmony_ci free (buffer); 2575141cc406Sopenharmony_ci free (reorder); 2576141cc406Sopenharmony_ci free (red_buffer); 2577141cc406Sopenharmony_ci free (green_buffer); 2578141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2579141cc406Sopenharmony_ci } 2580141cc406Sopenharmony_ci 2581141cc406Sopenharmony_ci red_in = red_out = red_buffer; 2582141cc406Sopenharmony_ci green_in = green_out = green_buffer; 2583141cc406Sopenharmony_ci } 2584141cc406Sopenharmony_ci 2585141cc406Sopenharmony_ci while (lines--) 2586141cc406Sopenharmony_ci { 2587141cc406Sopenharmony_ci set_read_length (sread.cmd, 1); 2588141cc406Sopenharmony_ci size = bytes_per_line + 2; 2589141cc406Sopenharmony_ci 2590141cc406Sopenharmony_ci do 2591141cc406Sopenharmony_ci { 2592141cc406Sopenharmony_ci status = 2593141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer, 2594141cc406Sopenharmony_ci &size); 2595141cc406Sopenharmony_ci } 2596141cc406Sopenharmony_ci while (status); 2597141cc406Sopenharmony_ci 2598141cc406Sopenharmony_ci DBG_DUMP (DBG_dump, buffer, 64); 2599141cc406Sopenharmony_ci 2600141cc406Sopenharmony_ci if (scanner->colormode == RGB) 2601141cc406Sopenharmony_ci { 2602141cc406Sopenharmony_ci /* we're assuming that we get red before green before blue here */ 2603141cc406Sopenharmony_ci switch (*buffer) 2604141cc406Sopenharmony_ci { 2605141cc406Sopenharmony_ci case 'R': 2606141cc406Sopenharmony_ci /* copy to red buffer */ 2607141cc406Sopenharmony_ci memcpy (red_in, buffer + 2, bytes_per_line); 2608141cc406Sopenharmony_ci 2609141cc406Sopenharmony_ci /* advance in pointer, and check for wrap */ 2610141cc406Sopenharmony_ci red_in += bytes_per_line; 2611141cc406Sopenharmony_ci if (red_in >= (red_buffer + red_size)) 2612141cc406Sopenharmony_ci red_in = red_buffer; 2613141cc406Sopenharmony_ci 2614141cc406Sopenharmony_ci /* increment red line count */ 2615141cc406Sopenharmony_ci red_count++; 2616141cc406Sopenharmony_ci DBG (DBG_info2, 2617141cc406Sopenharmony_ci "pie_reader_process_indexed: got a red line (%d)\n", 2618141cc406Sopenharmony_ci red_count); 2619141cc406Sopenharmony_ci break; 2620141cc406Sopenharmony_ci 2621141cc406Sopenharmony_ci case 'G': 2622141cc406Sopenharmony_ci /* copy to green buffer */ 2623141cc406Sopenharmony_ci memcpy (green_in, buffer + 2, bytes_per_line); 2624141cc406Sopenharmony_ci 2625141cc406Sopenharmony_ci /* advance in pointer, and check for wrap */ 2626141cc406Sopenharmony_ci green_in += bytes_per_line; 2627141cc406Sopenharmony_ci if (green_in >= (green_buffer + green_size)) 2628141cc406Sopenharmony_ci green_in = green_buffer; 2629141cc406Sopenharmony_ci 2630141cc406Sopenharmony_ci /* increment green line count */ 2631141cc406Sopenharmony_ci green_count++; 2632141cc406Sopenharmony_ci DBG (DBG_info2, 2633141cc406Sopenharmony_ci "pie_reader_process_indexed: got a green line (%d)\n", 2634141cc406Sopenharmony_ci green_count); 2635141cc406Sopenharmony_ci break; 2636141cc406Sopenharmony_ci 2637141cc406Sopenharmony_ci case 'B': 2638141cc406Sopenharmony_ci /* check we actually have red and green data available */ 2639141cc406Sopenharmony_ci if (!red_count || !green_count) 2640141cc406Sopenharmony_ci { 2641141cc406Sopenharmony_ci DBG (DBG_error, 2642141cc406Sopenharmony_ci "pie_reader_process_indexed: deskew buffer empty (%d %d)\n", 2643141cc406Sopenharmony_ci red_count, green_count); 2644141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2645141cc406Sopenharmony_ci } 2646141cc406Sopenharmony_ci red_count--; 2647141cc406Sopenharmony_ci green_count--; 2648141cc406Sopenharmony_ci 2649141cc406Sopenharmony_ci DBG (DBG_info2, 2650141cc406Sopenharmony_ci "pie_reader_process_indexed: got a blue line\n"); 2651141cc406Sopenharmony_ci 2652141cc406Sopenharmony_ci { 2653141cc406Sopenharmony_ci int i; 2654141cc406Sopenharmony_ci unsigned char *red, *green, *blue, *dest; 2655141cc406Sopenharmony_ci 2656141cc406Sopenharmony_ci /* now pack the pixels lines into RGB format */ 2657141cc406Sopenharmony_ci dest = reorder; 2658141cc406Sopenharmony_ci red = red_out; 2659141cc406Sopenharmony_ci green = green_out; 2660141cc406Sopenharmony_ci blue = buffer + 2; 2661141cc406Sopenharmony_ci 2662141cc406Sopenharmony_ci for (i = bytes_per_line; i > 0; i--) 2663141cc406Sopenharmony_ci { 2664141cc406Sopenharmony_ci *dest++ = *red++; 2665141cc406Sopenharmony_ci *dest++ = *green++; 2666141cc406Sopenharmony_ci *dest++ = *blue++; 2667141cc406Sopenharmony_ci } 2668141cc406Sopenharmony_ci fwrite (reorder, 1, scanner->params.bytes_per_line, fp); 2669141cc406Sopenharmony_ci 2670141cc406Sopenharmony_ci /* advance out pointers, and check for wrap */ 2671141cc406Sopenharmony_ci red_out += bytes_per_line; 2672141cc406Sopenharmony_ci if (red_out >= (red_buffer + red_size)) 2673141cc406Sopenharmony_ci red_out = red_buffer; 2674141cc406Sopenharmony_ci green_out += bytes_per_line; 2675141cc406Sopenharmony_ci if (green_out >= (green_buffer + green_size)) 2676141cc406Sopenharmony_ci green_out = green_buffer; 2677141cc406Sopenharmony_ci } 2678141cc406Sopenharmony_ci break; 2679141cc406Sopenharmony_ci 2680141cc406Sopenharmony_ci default: 2681141cc406Sopenharmony_ci DBG (DBG_error, 2682141cc406Sopenharmony_ci "pie_reader_process_indexed: bad filter index\n"); 2683141cc406Sopenharmony_ci } 2684141cc406Sopenharmony_ci } 2685141cc406Sopenharmony_ci else 2686141cc406Sopenharmony_ci { 2687141cc406Sopenharmony_ci DBG (DBG_info2, 2688141cc406Sopenharmony_ci "pie_reader_process_indexed: got a line (%lu bytes)\n", (u_long) size); 2689141cc406Sopenharmony_ci 2690141cc406Sopenharmony_ci /* just send the data on, assume filter bytes not present as per calibration case */ 2691141cc406Sopenharmony_ci fwrite (buffer, 1, scanner->params.bytes_per_line, fp); 2692141cc406Sopenharmony_ci } 2693141cc406Sopenharmony_ci } 2694141cc406Sopenharmony_ci 2695141cc406Sopenharmony_ci free (buffer); 2696141cc406Sopenharmony_ci free (reorder); 2697141cc406Sopenharmony_ci free (red_buffer); 2698141cc406Sopenharmony_ci free (green_buffer); 2699141cc406Sopenharmony_ci return 0; 2700141cc406Sopenharmony_ci} 2701141cc406Sopenharmony_ci 2702141cc406Sopenharmony_ci/* --------------------------------- PIE READER PROCESS ------------------------ */ 2703141cc406Sopenharmony_ci 2704141cc406Sopenharmony_cistatic int 2705141cc406Sopenharmony_cipie_reader_process (Pie_Scanner * scanner, FILE * fp) 2706141cc406Sopenharmony_ci{ 2707141cc406Sopenharmony_ci int status; 2708141cc406Sopenharmony_ci int lines; 2709141cc406Sopenharmony_ci unsigned char *buffer, *reorder; 2710141cc406Sopenharmony_ci size_t size; 2711141cc406Sopenharmony_ci 2712141cc406Sopenharmony_ci DBG (DBG_read, "reading %d lines of %d bytes/line\n", scanner->params.lines, 2713141cc406Sopenharmony_ci scanner->params.bytes_per_line); 2714141cc406Sopenharmony_ci 2715141cc406Sopenharmony_ci buffer = malloc (scanner->params.bytes_per_line); 2716141cc406Sopenharmony_ci reorder = malloc (scanner->params.bytes_per_line); 2717141cc406Sopenharmony_ci if (!buffer || !reorder) 2718141cc406Sopenharmony_ci { 2719141cc406Sopenharmony_ci free (buffer); 2720141cc406Sopenharmony_ci free (reorder); 2721141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2722141cc406Sopenharmony_ci } 2723141cc406Sopenharmony_ci 2724141cc406Sopenharmony_ci lines = scanner->params.lines; 2725141cc406Sopenharmony_ci 2726141cc406Sopenharmony_ci while (lines--) 2727141cc406Sopenharmony_ci { 2728141cc406Sopenharmony_ci set_read_length (sread.cmd, 1); 2729141cc406Sopenharmony_ci size = scanner->params.bytes_per_line; 2730141cc406Sopenharmony_ci 2731141cc406Sopenharmony_ci do 2732141cc406Sopenharmony_ci { 2733141cc406Sopenharmony_ci status = 2734141cc406Sopenharmony_ci sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer, 2735141cc406Sopenharmony_ci &size); 2736141cc406Sopenharmony_ci } 2737141cc406Sopenharmony_ci while (status); 2738141cc406Sopenharmony_ci 2739141cc406Sopenharmony_ci DBG_DUMP (DBG_dump, buffer, 64); 2740141cc406Sopenharmony_ci 2741141cc406Sopenharmony_ci if (scanner->colormode == RGB) 2742141cc406Sopenharmony_ci { 2743141cc406Sopenharmony_ci int i; 2744141cc406Sopenharmony_ci unsigned char *src, *dest; 2745141cc406Sopenharmony_ci int offset; 2746141cc406Sopenharmony_ci 2747141cc406Sopenharmony_ci dest = reorder; 2748141cc406Sopenharmony_ci src = buffer; 2749141cc406Sopenharmony_ci offset = scanner->params.pixels_per_line; 2750141cc406Sopenharmony_ci 2751141cc406Sopenharmony_ci for (i = scanner->params.pixels_per_line; i > 0; i--) 2752141cc406Sopenharmony_ci { 2753141cc406Sopenharmony_ci *dest++ = *src; 2754141cc406Sopenharmony_ci *dest++ = *(src + offset); 2755141cc406Sopenharmony_ci *dest++ = *(src + 2 * offset); 2756141cc406Sopenharmony_ci src++; 2757141cc406Sopenharmony_ci } 2758141cc406Sopenharmony_ci fwrite (reorder, 1, scanner->params.bytes_per_line, fp); 2759141cc406Sopenharmony_ci } 2760141cc406Sopenharmony_ci else 2761141cc406Sopenharmony_ci { 2762141cc406Sopenharmony_ci fwrite (buffer, 1, scanner->params.bytes_per_line, fp); 2763141cc406Sopenharmony_ci } 2764141cc406Sopenharmony_ci 2765141cc406Sopenharmony_ci fflush (fp); 2766141cc406Sopenharmony_ci } 2767141cc406Sopenharmony_ci 2768141cc406Sopenharmony_ci free (buffer); 2769141cc406Sopenharmony_ci free (reorder); 2770141cc406Sopenharmony_ci 2771141cc406Sopenharmony_ci return 0; 2772141cc406Sopenharmony_ci} 2773141cc406Sopenharmony_ci 2774141cc406Sopenharmony_ci 2775141cc406Sopenharmony_ci 2776141cc406Sopenharmony_ci/* --------------------------------- READER PROCESS SIGTERM HANDLER ------------ */ 2777141cc406Sopenharmony_ci 2778141cc406Sopenharmony_ci 2779141cc406Sopenharmony_cistatic void 2780141cc406Sopenharmony_cireader_process_sigterm_handler (int signal) 2781141cc406Sopenharmony_ci{ 2782141cc406Sopenharmony_ci DBG (DBG_sane_info, "reader_process: terminated by signal %d\n", signal); 2783141cc406Sopenharmony_ci 2784141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 2785141cc406Sopenharmony_ci sanei_scsi_req_flush_all (); /* flush SCSI queue */ 2786141cc406Sopenharmony_ci#else 2787141cc406Sopenharmony_ci sanei_scsi_req_flush_all (); /* flush SCSI queue */ 2788141cc406Sopenharmony_ci#endif 2789141cc406Sopenharmony_ci 2790141cc406Sopenharmony_ci _exit (SANE_STATUS_GOOD); 2791141cc406Sopenharmony_ci} 2792141cc406Sopenharmony_ci 2793141cc406Sopenharmony_ci 2794141cc406Sopenharmony_ci 2795141cc406Sopenharmony_ci/* ------------------------------ READER PROCESS ----------------------------- */ 2796141cc406Sopenharmony_ci 2797141cc406Sopenharmony_ci 2798141cc406Sopenharmony_cistatic int 2799141cc406Sopenharmony_cireader_process ( void *data ) /* executed as a child process */ 2800141cc406Sopenharmony_ci{ 2801141cc406Sopenharmony_ci int status; 2802141cc406Sopenharmony_ci FILE *fp; 2803141cc406Sopenharmony_ci Pie_Scanner * scanner; 2804141cc406Sopenharmony_ci sigset_t ignore_set; 2805141cc406Sopenharmony_ci struct SIGACTION act; 2806141cc406Sopenharmony_ci 2807141cc406Sopenharmony_ci scanner = (Pie_Scanner *)data; 2808141cc406Sopenharmony_ci 2809141cc406Sopenharmony_ci if (sanei_thread_is_forked ()) { 2810141cc406Sopenharmony_ci 2811141cc406Sopenharmony_ci close ( scanner->pipe ); 2812141cc406Sopenharmony_ci 2813141cc406Sopenharmony_ci sigfillset (&ignore_set); 2814141cc406Sopenharmony_ci sigdelset (&ignore_set, SIGTERM); 2815141cc406Sopenharmony_ci#if defined (__APPLE__) && defined (__MACH__) 2816141cc406Sopenharmony_ci sigdelset (&ignore_set, SIGUSR2); 2817141cc406Sopenharmony_ci#endif 2818141cc406Sopenharmony_ci sigprocmask (SIG_SETMASK, &ignore_set, 0); 2819141cc406Sopenharmony_ci 2820141cc406Sopenharmony_ci memset (&act, 0, sizeof (act)); 2821141cc406Sopenharmony_ci sigaction (SIGTERM, &act, 0); 2822141cc406Sopenharmony_ci } 2823141cc406Sopenharmony_ci 2824141cc406Sopenharmony_ci DBG (DBG_sane_proc, "reader_process started\n"); 2825141cc406Sopenharmony_ci 2826141cc406Sopenharmony_ci memset (&act, 0, sizeof (act)); /* define SIGTERM-handler */ 2827141cc406Sopenharmony_ci act.sa_handler = reader_process_sigterm_handler; 2828141cc406Sopenharmony_ci sigaction (SIGTERM, &act, 0); 2829141cc406Sopenharmony_ci 2830141cc406Sopenharmony_ci fp = fdopen (scanner->reader_fds, "w"); 2831141cc406Sopenharmony_ci if (!fp) 2832141cc406Sopenharmony_ci { 2833141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 2834141cc406Sopenharmony_ci } 2835141cc406Sopenharmony_ci 2836141cc406Sopenharmony_ci DBG (DBG_sane_info, "reader_process: starting to READ data\n"); 2837141cc406Sopenharmony_ci 2838141cc406Sopenharmony_ci if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE) 2839141cc406Sopenharmony_ci status = pie_reader_process (scanner, fp); 2840141cc406Sopenharmony_ci else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 2841141cc406Sopenharmony_ci status = pie_reader_process_indexed (scanner, fp); 2842141cc406Sopenharmony_ci else 2843141cc406Sopenharmony_ci status = SANE_STATUS_UNSUPPORTED; 2844141cc406Sopenharmony_ci 2845141cc406Sopenharmony_ci fclose (fp); 2846141cc406Sopenharmony_ci 2847141cc406Sopenharmony_ci DBG (DBG_sane_info, "reader_process: finished reading data\n"); 2848141cc406Sopenharmony_ci 2849141cc406Sopenharmony_ci return status; 2850141cc406Sopenharmony_ci} 2851141cc406Sopenharmony_ci 2852141cc406Sopenharmony_ci 2853141cc406Sopenharmony_ci/* -------------------------------- ATTACH_ONE ---------------------------------- */ 2854141cc406Sopenharmony_ci 2855141cc406Sopenharmony_ci 2856141cc406Sopenharmony_ci/* callback function for sanei_config_attach_matching_devices(dev_name, attach_one) */ 2857141cc406Sopenharmony_cistatic SANE_Status 2858141cc406Sopenharmony_ciattach_one (const char *name) 2859141cc406Sopenharmony_ci{ 2860141cc406Sopenharmony_ci attach_scanner (name, 0); 2861141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2862141cc406Sopenharmony_ci} 2863141cc406Sopenharmony_ci 2864141cc406Sopenharmony_ci 2865141cc406Sopenharmony_ci/* ----------------------------- CLOSE PIPE ---------------------------------- */ 2866141cc406Sopenharmony_ci 2867141cc406Sopenharmony_ci 2868141cc406Sopenharmony_cistatic SANE_Status 2869141cc406Sopenharmony_ciclose_pipe (Pie_Scanner * scanner) 2870141cc406Sopenharmony_ci{ 2871141cc406Sopenharmony_ci DBG (DBG_sane_proc, "close_pipe\n"); 2872141cc406Sopenharmony_ci 2873141cc406Sopenharmony_ci if (scanner->pipe >= 0) 2874141cc406Sopenharmony_ci { 2875141cc406Sopenharmony_ci close (scanner->pipe); 2876141cc406Sopenharmony_ci scanner->pipe = -1; 2877141cc406Sopenharmony_ci } 2878141cc406Sopenharmony_ci 2879141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2880141cc406Sopenharmony_ci} 2881141cc406Sopenharmony_ci 2882141cc406Sopenharmony_ci 2883141cc406Sopenharmony_ci 2884141cc406Sopenharmony_ci/* ---------------------------- DO CANCEL ---------------------------------- */ 2885141cc406Sopenharmony_ci 2886141cc406Sopenharmony_ci 2887141cc406Sopenharmony_cistatic SANE_Status 2888141cc406Sopenharmony_cido_cancel (Pie_Scanner * scanner) 2889141cc406Sopenharmony_ci{ 2890141cc406Sopenharmony_ci DBG (DBG_sane_proc, "do_cancel\n"); 2891141cc406Sopenharmony_ci 2892141cc406Sopenharmony_ci scanner->scanning = SANE_FALSE; 2893141cc406Sopenharmony_ci 2894141cc406Sopenharmony_ci if (sanei_thread_is_valid (scanner->reader_pid)) 2895141cc406Sopenharmony_ci { 2896141cc406Sopenharmony_ci DBG (DBG_sane_info, "killing reader_process\n"); 2897141cc406Sopenharmony_ci sanei_thread_kill (scanner->reader_pid); 2898141cc406Sopenharmony_ci sanei_thread_waitpid (scanner->reader_pid, 0); 2899141cc406Sopenharmony_ci sanei_thread_invalidate (scanner->reader_pid); 2900141cc406Sopenharmony_ci DBG (DBG_sane_info, "reader_process killed\n"); 2901141cc406Sopenharmony_ci } 2902141cc406Sopenharmony_ci 2903141cc406Sopenharmony_ci if (scanner->sfd >= 0) 2904141cc406Sopenharmony_ci { 2905141cc406Sopenharmony_ci pie_scan (scanner, 0); 2906141cc406Sopenharmony_ci 2907141cc406Sopenharmony_ci pie_power_save (scanner, 15); 2908141cc406Sopenharmony_ci 2909141cc406Sopenharmony_ci pie_give_scanner (scanner); /* reposition and release scanner */ 2910141cc406Sopenharmony_ci 2911141cc406Sopenharmony_ci DBG (DBG_sane_info, "closing scannerdevice filedescriptor\n"); 2912141cc406Sopenharmony_ci sanei_scsi_close (scanner->sfd); 2913141cc406Sopenharmony_ci scanner->sfd = -1; 2914141cc406Sopenharmony_ci } 2915141cc406Sopenharmony_ci 2916141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 2917141cc406Sopenharmony_ci} 2918141cc406Sopenharmony_ci 2919141cc406Sopenharmony_ci 2920141cc406Sopenharmony_ci 2921141cc406Sopenharmony_ci/* --------------------------------------- SANE INIT ---------------------------------- */ 2922141cc406Sopenharmony_ci 2923141cc406Sopenharmony_ci 2924141cc406Sopenharmony_ciSANE_Status 2925141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize) 2926141cc406Sopenharmony_ci{ 2927141cc406Sopenharmony_ci char dev_name[PATH_MAX]; 2928141cc406Sopenharmony_ci size_t len; 2929141cc406Sopenharmony_ci FILE *fp; 2930141cc406Sopenharmony_ci 2931141cc406Sopenharmony_ci DBG_INIT (); 2932141cc406Sopenharmony_ci 2933141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_init() build %d\n", BUILD); 2934141cc406Sopenharmony_ci 2935141cc406Sopenharmony_ci if (version_code) 2936141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 2937141cc406Sopenharmony_ci 2938141cc406Sopenharmony_ci fp = sanei_config_open (PIE_CONFIG_FILE); 2939141cc406Sopenharmony_ci if (!fp) 2940141cc406Sopenharmony_ci { 2941141cc406Sopenharmony_ci attach_scanner ("/dev/scanner", 0); /* no config-file: /dev/scanner */ 2942141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2943141cc406Sopenharmony_ci } 2944141cc406Sopenharmony_ci 2945141cc406Sopenharmony_ci while (sanei_config_read (dev_name, sizeof (dev_name), fp)) 2946141cc406Sopenharmony_ci { 2947141cc406Sopenharmony_ci if (dev_name[0] == '#') 2948141cc406Sopenharmony_ci { 2949141cc406Sopenharmony_ci continue; 2950141cc406Sopenharmony_ci } /* ignore line comments */ 2951141cc406Sopenharmony_ci 2952141cc406Sopenharmony_ci len = strlen (dev_name); 2953141cc406Sopenharmony_ci 2954141cc406Sopenharmony_ci if (!len) /* ignore empty lines */ 2955141cc406Sopenharmony_ci { 2956141cc406Sopenharmony_ci continue; 2957141cc406Sopenharmony_ci } 2958141cc406Sopenharmony_ci 2959141cc406Sopenharmony_ci sanei_config_attach_matching_devices (dev_name, attach_one); 2960141cc406Sopenharmony_ci } 2961141cc406Sopenharmony_ci 2962141cc406Sopenharmony_ci fclose (fp); 2963141cc406Sopenharmony_ci 2964141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2965141cc406Sopenharmony_ci} 2966141cc406Sopenharmony_ci 2967141cc406Sopenharmony_ci 2968141cc406Sopenharmony_ci/* ----------------------------------------- SANE EXIT ---------------------------------- */ 2969141cc406Sopenharmony_ci 2970141cc406Sopenharmony_ci 2971141cc406Sopenharmony_civoid 2972141cc406Sopenharmony_cisane_exit (void) 2973141cc406Sopenharmony_ci{ 2974141cc406Sopenharmony_ci Pie_Device *dev, *next; 2975141cc406Sopenharmony_ci int i; 2976141cc406Sopenharmony_ci 2977141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_exit()\n"); 2978141cc406Sopenharmony_ci 2979141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = next) 2980141cc406Sopenharmony_ci { 2981141cc406Sopenharmony_ci next = dev->next; 2982141cc406Sopenharmony_ci free (dev->devicename); 2983141cc406Sopenharmony_ci free (dev->cal_info); 2984141cc406Sopenharmony_ci i = 0; 2985141cc406Sopenharmony_ci while (dev->halftone_list[i] != NULL) 2986141cc406Sopenharmony_ci free (dev->halftone_list[i++]); 2987141cc406Sopenharmony_ci i = 0; 2988141cc406Sopenharmony_ci while (dev->speed_list[i] != NULL) 2989141cc406Sopenharmony_ci free (dev->speed_list[i++]); 2990141cc406Sopenharmony_ci 2991141cc406Sopenharmony_ci free (dev); 2992141cc406Sopenharmony_ci } 2993141cc406Sopenharmony_ci 2994141cc406Sopenharmony_ci first_dev = NULL; 2995141cc406Sopenharmony_ci 2996141cc406Sopenharmony_ci if (devlist) 2997141cc406Sopenharmony_ci { 2998141cc406Sopenharmony_ci free (devlist); 2999141cc406Sopenharmony_ci devlist = NULL; 3000141cc406Sopenharmony_ci } 3001141cc406Sopenharmony_ci} 3002141cc406Sopenharmony_ci 3003141cc406Sopenharmony_ci 3004141cc406Sopenharmony_ci/* ------------------------------------------ SANE GET DEVICES --------------------------- */ 3005141cc406Sopenharmony_ci 3006141cc406Sopenharmony_ci 3007141cc406Sopenharmony_ciSANE_Status 3008141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only) 3009141cc406Sopenharmony_ci{ 3010141cc406Sopenharmony_ci Pie_Device *dev; 3011141cc406Sopenharmony_ci int i; 3012141cc406Sopenharmony_ci 3013141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_get_devices\n"); 3014141cc406Sopenharmony_ci 3015141cc406Sopenharmony_ci i = 0; 3016141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 3017141cc406Sopenharmony_ci i++; 3018141cc406Sopenharmony_ci 3019141cc406Sopenharmony_ci if (devlist) 3020141cc406Sopenharmony_ci { 3021141cc406Sopenharmony_ci free (devlist); 3022141cc406Sopenharmony_ci } 3023141cc406Sopenharmony_ci 3024141cc406Sopenharmony_ci devlist = malloc ((i + 1) * sizeof (devlist[0])); 3025141cc406Sopenharmony_ci if (!devlist) 3026141cc406Sopenharmony_ci { 3027141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 3028141cc406Sopenharmony_ci } 3029141cc406Sopenharmony_ci 3030141cc406Sopenharmony_ci i = 0; 3031141cc406Sopenharmony_ci 3032141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 3033141cc406Sopenharmony_ci { 3034141cc406Sopenharmony_ci devlist[i++] = &dev->sane; 3035141cc406Sopenharmony_ci } 3036141cc406Sopenharmony_ci 3037141cc406Sopenharmony_ci devlist[i] = NULL; 3038141cc406Sopenharmony_ci 3039141cc406Sopenharmony_ci *device_list = devlist; 3040141cc406Sopenharmony_ci 3041141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3042141cc406Sopenharmony_ci} 3043141cc406Sopenharmony_ci 3044141cc406Sopenharmony_ci 3045141cc406Sopenharmony_ci/* --------------------------------------- SANE OPEN ---------------------------------- */ 3046141cc406Sopenharmony_ci 3047141cc406Sopenharmony_ciSANE_Status 3048141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle * handle) 3049141cc406Sopenharmony_ci{ 3050141cc406Sopenharmony_ci Pie_Device *dev; 3051141cc406Sopenharmony_ci SANE_Status status; 3052141cc406Sopenharmony_ci Pie_Scanner *scanner; 3053141cc406Sopenharmony_ci int i, j; 3054141cc406Sopenharmony_ci 3055141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_open(%s)\n", devicename); 3056141cc406Sopenharmony_ci 3057141cc406Sopenharmony_ci if (devicename[0]) /* search for devicename */ 3058141cc406Sopenharmony_ci { 3059141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 3060141cc406Sopenharmony_ci { 3061141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devicename) == 0) 3062141cc406Sopenharmony_ci { 3063141cc406Sopenharmony_ci break; 3064141cc406Sopenharmony_ci } 3065141cc406Sopenharmony_ci } 3066141cc406Sopenharmony_ci 3067141cc406Sopenharmony_ci if (!dev) 3068141cc406Sopenharmony_ci { 3069141cc406Sopenharmony_ci status = attach_scanner (devicename, &dev); 3070141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3071141cc406Sopenharmony_ci { 3072141cc406Sopenharmony_ci return status; 3073141cc406Sopenharmony_ci } 3074141cc406Sopenharmony_ci } 3075141cc406Sopenharmony_ci } 3076141cc406Sopenharmony_ci else 3077141cc406Sopenharmony_ci { 3078141cc406Sopenharmony_ci dev = first_dev; /* empty devicename -> use first device */ 3079141cc406Sopenharmony_ci } 3080141cc406Sopenharmony_ci 3081141cc406Sopenharmony_ci 3082141cc406Sopenharmony_ci if (!dev) 3083141cc406Sopenharmony_ci { 3084141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3085141cc406Sopenharmony_ci } 3086141cc406Sopenharmony_ci 3087141cc406Sopenharmony_ci scanner = malloc (sizeof (*scanner)); 3088141cc406Sopenharmony_ci if (!scanner) 3089141cc406Sopenharmony_ci 3090141cc406Sopenharmony_ci { 3091141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 3092141cc406Sopenharmony_ci } 3093141cc406Sopenharmony_ci 3094141cc406Sopenharmony_ci memset (scanner, 0, sizeof (*scanner)); 3095141cc406Sopenharmony_ci 3096141cc406Sopenharmony_ci scanner->device = dev; 3097141cc406Sopenharmony_ci scanner->sfd = -1; 3098141cc406Sopenharmony_ci scanner->pipe = -1; 3099141cc406Sopenharmony_ci 3100141cc406Sopenharmony_ci scanner->gamma_length = 1 << (scanner->device->inquiry_gamma_bits); 3101141cc406Sopenharmony_ci 3102141cc406Sopenharmony_ci DBG (DBG_sane_info, "Using %d bits for gamma input\n", 3103141cc406Sopenharmony_ci scanner->device->inquiry_gamma_bits); 3104141cc406Sopenharmony_ci 3105141cc406Sopenharmony_ci scanner->gamma_range.min = 0; 3106141cc406Sopenharmony_ci scanner->gamma_range.max = scanner->gamma_length - 1; 3107141cc406Sopenharmony_ci scanner->gamma_range.quant = 0; 3108141cc406Sopenharmony_ci 3109141cc406Sopenharmony_ci scanner->gamma_table[0] = 3110141cc406Sopenharmony_ci (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 3111141cc406Sopenharmony_ci scanner->gamma_table[1] = 3112141cc406Sopenharmony_ci (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 3113141cc406Sopenharmony_ci scanner->gamma_table[2] = 3114141cc406Sopenharmony_ci (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 3115141cc406Sopenharmony_ci scanner->gamma_table[3] = 3116141cc406Sopenharmony_ci (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 3117141cc406Sopenharmony_ci 3118141cc406Sopenharmony_ci for (i = 0; i < 4; ++i) /* gamma_table[0,1,2,3] */ 3119141cc406Sopenharmony_ci { 3120141cc406Sopenharmony_ci for (j = 0; j < scanner->gamma_length; ++j) 3121141cc406Sopenharmony_ci { 3122141cc406Sopenharmony_ci scanner->gamma_table[i][j] = j; 3123141cc406Sopenharmony_ci } 3124141cc406Sopenharmony_ci } 3125141cc406Sopenharmony_ci 3126141cc406Sopenharmony_ci init_options (scanner); 3127141cc406Sopenharmony_ci 3128141cc406Sopenharmony_ci scanner->next = first_handle; /* insert newly opened handle into list of open handles: */ 3129141cc406Sopenharmony_ci first_handle = scanner; 3130141cc406Sopenharmony_ci 3131141cc406Sopenharmony_ci *handle = scanner; 3132141cc406Sopenharmony_ci 3133141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3134141cc406Sopenharmony_ci} 3135141cc406Sopenharmony_ci 3136141cc406Sopenharmony_ci 3137141cc406Sopenharmony_ci/* ------------------------------------ SANE CLOSE --------------------------------- */ 3138141cc406Sopenharmony_ci 3139141cc406Sopenharmony_ci 3140141cc406Sopenharmony_civoid 3141141cc406Sopenharmony_cisane_close (SANE_Handle handle) 3142141cc406Sopenharmony_ci{ 3143141cc406Sopenharmony_ci Pie_Scanner *prev, *scanner; 3144141cc406Sopenharmony_ci 3145141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_close\n"); 3146141cc406Sopenharmony_ci 3147141cc406Sopenharmony_ci /* remove handle from list of open handles: */ 3148141cc406Sopenharmony_ci prev = 0; 3149141cc406Sopenharmony_ci 3150141cc406Sopenharmony_ci for (scanner = first_handle; scanner; scanner = scanner->next) 3151141cc406Sopenharmony_ci { 3152141cc406Sopenharmony_ci if (scanner == handle) 3153141cc406Sopenharmony_ci { 3154141cc406Sopenharmony_ci break; 3155141cc406Sopenharmony_ci } 3156141cc406Sopenharmony_ci 3157141cc406Sopenharmony_ci prev = scanner; 3158141cc406Sopenharmony_ci } 3159141cc406Sopenharmony_ci 3160141cc406Sopenharmony_ci if (!scanner) 3161141cc406Sopenharmony_ci { 3162141cc406Sopenharmony_ci DBG (DBG_error, "close: invalid handle %p\n", handle); 3163141cc406Sopenharmony_ci return; /* oops, not a handle we know about */ 3164141cc406Sopenharmony_ci } 3165141cc406Sopenharmony_ci 3166141cc406Sopenharmony_ci if (scanner->scanning) /* stop scan if still scanning */ 3167141cc406Sopenharmony_ci { 3168141cc406Sopenharmony_ci do_cancel (handle); 3169141cc406Sopenharmony_ci } 3170141cc406Sopenharmony_ci 3171141cc406Sopenharmony_ci if (prev) 3172141cc406Sopenharmony_ci { 3173141cc406Sopenharmony_ci prev->next = scanner->next; 3174141cc406Sopenharmony_ci } 3175141cc406Sopenharmony_ci else 3176141cc406Sopenharmony_ci { 3177141cc406Sopenharmony_ci first_handle = scanner->next; 3178141cc406Sopenharmony_ci } 3179141cc406Sopenharmony_ci 3180141cc406Sopenharmony_ci free (scanner->gamma_table[0]); /* free custom gamma tables */ 3181141cc406Sopenharmony_ci free (scanner->gamma_table[1]); 3182141cc406Sopenharmony_ci free (scanner->gamma_table[2]); 3183141cc406Sopenharmony_ci free (scanner->gamma_table[3]); 3184141cc406Sopenharmony_ci free (scanner->val[OPT_MODE].s); 3185141cc406Sopenharmony_ci free (scanner->val[OPT_SPEED].s); 3186141cc406Sopenharmony_ci free (scanner->val[OPT_HALFTONE_PATTERN].s); 3187141cc406Sopenharmony_ci 3188141cc406Sopenharmony_ci scanner->bufsize = 0; 3189141cc406Sopenharmony_ci 3190141cc406Sopenharmony_ci free (scanner); /* free scanner */ 3191141cc406Sopenharmony_ci} 3192141cc406Sopenharmony_ci 3193141cc406Sopenharmony_ci 3194141cc406Sopenharmony_ci/* ---------------------------------- SANE GET OPTION DESCRIPTOR ----------------- */ 3195141cc406Sopenharmony_ci 3196141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 3197141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 3198141cc406Sopenharmony_ci{ 3199141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3200141cc406Sopenharmony_ci 3201141cc406Sopenharmony_ci DBG (DBG_sane_option, "sane_get_option_descriptor %d\n", option); 3202141cc406Sopenharmony_ci 3203141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 3204141cc406Sopenharmony_ci { 3205141cc406Sopenharmony_ci return 0; 3206141cc406Sopenharmony_ci } 3207141cc406Sopenharmony_ci 3208141cc406Sopenharmony_ci return scanner->opt + option; 3209141cc406Sopenharmony_ci} 3210141cc406Sopenharmony_ci 3211141cc406Sopenharmony_ci 3212141cc406Sopenharmony_ci/* ---------------------------------- SANE CONTROL OPTION ------------------------ */ 3213141cc406Sopenharmony_ci 3214141cc406Sopenharmony_ci 3215141cc406Sopenharmony_ciSANE_Status 3216141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action, 3217141cc406Sopenharmony_ci void *val, SANE_Int * info) 3218141cc406Sopenharmony_ci{ 3219141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3220141cc406Sopenharmony_ci SANE_Status status; 3221141cc406Sopenharmony_ci SANE_Word cap; 3222141cc406Sopenharmony_ci SANE_String_Const name; 3223141cc406Sopenharmony_ci 3224141cc406Sopenharmony_ci if (info) 3225141cc406Sopenharmony_ci { 3226141cc406Sopenharmony_ci *info = 0; 3227141cc406Sopenharmony_ci } 3228141cc406Sopenharmony_ci 3229141cc406Sopenharmony_ci if (scanner->scanning) 3230141cc406Sopenharmony_ci { 3231141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 3232141cc406Sopenharmony_ci } 3233141cc406Sopenharmony_ci 3234141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 3235141cc406Sopenharmony_ci { 3236141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3237141cc406Sopenharmony_ci } 3238141cc406Sopenharmony_ci 3239141cc406Sopenharmony_ci cap = scanner->opt[option].cap; 3240141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 3241141cc406Sopenharmony_ci { 3242141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3243141cc406Sopenharmony_ci } 3244141cc406Sopenharmony_ci 3245141cc406Sopenharmony_ci name = scanner->opt[option].name; 3246141cc406Sopenharmony_ci if (!name) 3247141cc406Sopenharmony_ci { 3248141cc406Sopenharmony_ci name = "(no name)"; 3249141cc406Sopenharmony_ci } 3250141cc406Sopenharmony_ci 3251141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 3252141cc406Sopenharmony_ci { 3253141cc406Sopenharmony_ci 3254141cc406Sopenharmony_ci DBG (DBG_sane_option, "get %s [#%d]\n", name, option); 3255141cc406Sopenharmony_ci 3256141cc406Sopenharmony_ci switch (option) 3257141cc406Sopenharmony_ci { 3258141cc406Sopenharmony_ci /* word options: */ 3259141cc406Sopenharmony_ci case OPT_NUM_OPTS: 3260141cc406Sopenharmony_ci case OPT_RESOLUTION: 3261141cc406Sopenharmony_ci case OPT_TL_X: 3262141cc406Sopenharmony_ci case OPT_TL_Y: 3263141cc406Sopenharmony_ci case OPT_BR_X: 3264141cc406Sopenharmony_ci case OPT_BR_Y: 3265141cc406Sopenharmony_ci case OPT_PREVIEW: 3266141cc406Sopenharmony_ci case OPT_THRESHOLD: 3267141cc406Sopenharmony_ci *(SANE_Word *) val = scanner->val[option].w; 3268141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3269141cc406Sopenharmony_ci 3270141cc406Sopenharmony_ci /* word-array options: */ 3271141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR: 3272141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 3273141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 3274141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 3275141cc406Sopenharmony_ci memcpy (val, scanner->val[option].wa, scanner->opt[option].size); 3276141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3277141cc406Sopenharmony_ci 3278141cc406Sopenharmony_ci#if 0 3279141cc406Sopenharmony_ci /* string options: */ 3280141cc406Sopenharmony_ci case OPT_SOURCE: 3281141cc406Sopenharmony_ci#endif 3282141cc406Sopenharmony_ci case OPT_MODE: 3283141cc406Sopenharmony_ci case OPT_HALFTONE_PATTERN: 3284141cc406Sopenharmony_ci case OPT_SPEED: 3285141cc406Sopenharmony_ci strcpy (val, scanner->val[option].s); 3286141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3287141cc406Sopenharmony_ci } 3288141cc406Sopenharmony_ci } 3289141cc406Sopenharmony_ci else if (action == SANE_ACTION_SET_VALUE) 3290141cc406Sopenharmony_ci { 3291141cc406Sopenharmony_ci switch (scanner->opt[option].type) 3292141cc406Sopenharmony_ci { 3293141cc406Sopenharmony_ci case SANE_TYPE_INT: 3294141cc406Sopenharmony_ci DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 3295141cc406Sopenharmony_ci *(SANE_Word *) val); 3296141cc406Sopenharmony_ci break; 3297141cc406Sopenharmony_ci 3298141cc406Sopenharmony_ci case SANE_TYPE_FIXED: 3299141cc406Sopenharmony_ci DBG (DBG_sane_option, "set %s [#%d] to %f\n", name, option, 3300141cc406Sopenharmony_ci SANE_UNFIX (*(SANE_Word *) val)); 3301141cc406Sopenharmony_ci break; 3302141cc406Sopenharmony_ci 3303141cc406Sopenharmony_ci case SANE_TYPE_STRING: 3304141cc406Sopenharmony_ci DBG (DBG_sane_option, "set %s [#%d] to %s\n", name, option, 3305141cc406Sopenharmony_ci (char *) val); 3306141cc406Sopenharmony_ci break; 3307141cc406Sopenharmony_ci 3308141cc406Sopenharmony_ci case SANE_TYPE_BOOL: 3309141cc406Sopenharmony_ci DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 3310141cc406Sopenharmony_ci *(SANE_Word *) val); 3311141cc406Sopenharmony_ci break; 3312141cc406Sopenharmony_ci 3313141cc406Sopenharmony_ci default: 3314141cc406Sopenharmony_ci DBG (DBG_sane_option, "set %s [#%d]\n", name, option); 3315141cc406Sopenharmony_ci } 3316141cc406Sopenharmony_ci 3317141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 3318141cc406Sopenharmony_ci { 3319141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3320141cc406Sopenharmony_ci } 3321141cc406Sopenharmony_ci 3322141cc406Sopenharmony_ci status = sanei_constrain_value (scanner->opt + option, val, info); 3323141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3324141cc406Sopenharmony_ci { 3325141cc406Sopenharmony_ci return status; 3326141cc406Sopenharmony_ci } 3327141cc406Sopenharmony_ci 3328141cc406Sopenharmony_ci switch (option) 3329141cc406Sopenharmony_ci { 3330141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 3331141cc406Sopenharmony_ci case OPT_RESOLUTION: 3332141cc406Sopenharmony_ci case OPT_TL_X: 3333141cc406Sopenharmony_ci case OPT_TL_Y: 3334141cc406Sopenharmony_ci case OPT_BR_X: 3335141cc406Sopenharmony_ci case OPT_BR_Y: 3336141cc406Sopenharmony_ci if (info) 3337141cc406Sopenharmony_ci { 3338141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 3339141cc406Sopenharmony_ci } 3340141cc406Sopenharmony_ci /* fall through */ 3341141cc406Sopenharmony_ci case OPT_NUM_OPTS: 3342141cc406Sopenharmony_ci case OPT_PREVIEW: 3343141cc406Sopenharmony_ci case OPT_THRESHOLD: 3344141cc406Sopenharmony_ci scanner->val[option].w = *(SANE_Word *) val; 3345141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3346141cc406Sopenharmony_ci 3347141cc406Sopenharmony_ci /* side-effect-free word-array options: */ 3348141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR: 3349141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 3350141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 3351141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 3352141cc406Sopenharmony_ci memcpy (scanner->val[option].wa, val, scanner->opt[option].size); 3353141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3354141cc406Sopenharmony_ci 3355141cc406Sopenharmony_ci /* options with side-effects: */ 3356141cc406Sopenharmony_ci 3357141cc406Sopenharmony_ci case OPT_MODE: 3358141cc406Sopenharmony_ci { 3359141cc406Sopenharmony_ci int halftoning; 3360141cc406Sopenharmony_ci 3361141cc406Sopenharmony_ci if (scanner->val[option].s) 3362141cc406Sopenharmony_ci { 3363141cc406Sopenharmony_ci free (scanner->val[option].s); 3364141cc406Sopenharmony_ci } 3365141cc406Sopenharmony_ci 3366141cc406Sopenharmony_ci scanner->val[option].s = (SANE_Char *) strdup (val); 3367141cc406Sopenharmony_ci 3368141cc406Sopenharmony_ci if (info) 3369141cc406Sopenharmony_ci { 3370141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 3371141cc406Sopenharmony_ci } 3372141cc406Sopenharmony_ci 3373141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; 3374141cc406Sopenharmony_ci 3375141cc406Sopenharmony_ci 3376141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 3377141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 3378141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 3379141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 3380141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 3381141cc406Sopenharmony_ci 3382141cc406Sopenharmony_ci halftoning = (strcmp (val, HALFTONE_STR) == 0); 3383141cc406Sopenharmony_ci 3384141cc406Sopenharmony_ci if (halftoning || strcmp (val, LINEART_STR) == 0) 3385141cc406Sopenharmony_ci { /* one bit modes */ 3386141cc406Sopenharmony_ci if (halftoning) 3387141cc406Sopenharmony_ci { /* halftoning modes */ 3388141cc406Sopenharmony_ci scanner->opt[OPT_HALFTONE_PATTERN].cap &= 3389141cc406Sopenharmony_ci ~SANE_CAP_INACTIVE; 3390141cc406Sopenharmony_ci } 3391141cc406Sopenharmony_ci else 3392141cc406Sopenharmony_ci { /* lineart modes */ 3393141cc406Sopenharmony_ci } 3394141cc406Sopenharmony_ci scanner->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE; 3395141cc406Sopenharmony_ci } 3396141cc406Sopenharmony_ci else 3397141cc406Sopenharmony_ci { /* multi-bit modes(gray or color) */ 3398141cc406Sopenharmony_ci } 3399141cc406Sopenharmony_ci 3400141cc406Sopenharmony_ci if ((strcmp (val, LINEART_STR) == 0) 3401141cc406Sopenharmony_ci || (strcmp (val, HALFTONE_STR) == 0) 3402141cc406Sopenharmony_ci || (strcmp (val, GRAY_STR) == 0)) 3403141cc406Sopenharmony_ci { 3404141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; 3405141cc406Sopenharmony_ci } 3406141cc406Sopenharmony_ci else if (strcmp (val, COLOR_STR) == 0) 3407141cc406Sopenharmony_ci { 3408141cc406Sopenharmony_ci /* scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; */ 3409141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE; 3410141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE; 3411141cc406Sopenharmony_ci scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE; 3412141cc406Sopenharmony_ci } 3413141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3414141cc406Sopenharmony_ci } 3415141cc406Sopenharmony_ci 3416141cc406Sopenharmony_ci case OPT_SPEED: 3417141cc406Sopenharmony_ci case OPT_HALFTONE_PATTERN: 3418141cc406Sopenharmony_ci { 3419141cc406Sopenharmony_ci if (scanner->val[option].s) 3420141cc406Sopenharmony_ci { 3421141cc406Sopenharmony_ci free (scanner->val[option].s); 3422141cc406Sopenharmony_ci } 3423141cc406Sopenharmony_ci 3424141cc406Sopenharmony_ci scanner->val[option].s = (SANE_Char *) strdup (val); 3425141cc406Sopenharmony_ci 3426141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3427141cc406Sopenharmony_ci } 3428141cc406Sopenharmony_ci } 3429141cc406Sopenharmony_ci } /* else */ 3430141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3431141cc406Sopenharmony_ci} 3432141cc406Sopenharmony_ci 3433141cc406Sopenharmony_ci 3434141cc406Sopenharmony_ci/* ------------------------------------ SANE GET PARAMETERS ------------------------ */ 3435141cc406Sopenharmony_ci 3436141cc406Sopenharmony_ci 3437141cc406Sopenharmony_ciSANE_Status 3438141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 3439141cc406Sopenharmony_ci{ 3440141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3441141cc406Sopenharmony_ci const char *mode; 3442141cc406Sopenharmony_ci 3443141cc406Sopenharmony_ci DBG (DBG_sane_info, "sane_get_parameters\n"); 3444141cc406Sopenharmony_ci 3445141cc406Sopenharmony_ci if (!scanner->scanning) 3446141cc406Sopenharmony_ci { /* not scanning, so lets use recent values */ 3447141cc406Sopenharmony_ci double width, length, x_dpi, y_dpi; 3448141cc406Sopenharmony_ci 3449141cc406Sopenharmony_ci memset (&scanner->params, 0, sizeof (scanner->params)); 3450141cc406Sopenharmony_ci 3451141cc406Sopenharmony_ci width = 3452141cc406Sopenharmony_ci SANE_UNFIX (scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w); 3453141cc406Sopenharmony_ci length = 3454141cc406Sopenharmony_ci SANE_UNFIX (scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w); 3455141cc406Sopenharmony_ci x_dpi = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w); 3456141cc406Sopenharmony_ci y_dpi = x_dpi; 3457141cc406Sopenharmony_ci 3458141cc406Sopenharmony_ci#if 0 3459141cc406Sopenharmony_ci if ((scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE) 3460141cc406Sopenharmony_ci || (scanner->val[OPT_PREVIEW].w == SANE_TRUE)) 3461141cc406Sopenharmony_ci { 3462141cc406Sopenharmony_ci y_dpi = x_dpi; 3463141cc406Sopenharmony_ci } 3464141cc406Sopenharmony_ci#endif 3465141cc406Sopenharmony_ci if (x_dpi > 0.0 && y_dpi > 0.0 && width > 0.0 && length > 0.0) 3466141cc406Sopenharmony_ci { 3467141cc406Sopenharmony_ci double x_dots_per_mm = x_dpi / MM_PER_INCH; 3468141cc406Sopenharmony_ci double y_dots_per_mm = y_dpi / MM_PER_INCH; 3469141cc406Sopenharmony_ci 3470141cc406Sopenharmony_ci scanner->params.pixels_per_line = width * x_dots_per_mm; 3471141cc406Sopenharmony_ci scanner->params.lines = length * y_dots_per_mm; 3472141cc406Sopenharmony_ci } 3473141cc406Sopenharmony_ci } 3474141cc406Sopenharmony_ci 3475141cc406Sopenharmony_ci mode = scanner->val[OPT_MODE].s; 3476141cc406Sopenharmony_ci 3477141cc406Sopenharmony_ci if (strcmp (mode, LINEART_STR) == 0 || strcmp (mode, HALFTONE_STR) == 0) 3478141cc406Sopenharmony_ci { 3479141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_GRAY; 3480141cc406Sopenharmony_ci scanner->params.bytes_per_line = 3481141cc406Sopenharmony_ci (scanner->params.pixels_per_line + 7) / 8; 3482141cc406Sopenharmony_ci scanner->params.depth = 1; 3483141cc406Sopenharmony_ci } 3484141cc406Sopenharmony_ci else if (strcmp (mode, GRAY_STR) == 0) 3485141cc406Sopenharmony_ci { 3486141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_GRAY; 3487141cc406Sopenharmony_ci scanner->params.bytes_per_line = scanner->params.pixels_per_line; 3488141cc406Sopenharmony_ci scanner->params.depth = 8; 3489141cc406Sopenharmony_ci } 3490141cc406Sopenharmony_ci else /* RGB */ 3491141cc406Sopenharmony_ci { 3492141cc406Sopenharmony_ci scanner->params.format = SANE_FRAME_RGB; 3493141cc406Sopenharmony_ci scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line; 3494141cc406Sopenharmony_ci scanner->params.depth = 8; 3495141cc406Sopenharmony_ci } 3496141cc406Sopenharmony_ci 3497141cc406Sopenharmony_ci scanner->params.last_frame = (scanner->params.format != SANE_FRAME_RED 3498141cc406Sopenharmony_ci && scanner->params.format != 3499141cc406Sopenharmony_ci SANE_FRAME_GREEN); 3500141cc406Sopenharmony_ci 3501141cc406Sopenharmony_ci if (params) 3502141cc406Sopenharmony_ci { 3503141cc406Sopenharmony_ci *params = scanner->params; 3504141cc406Sopenharmony_ci } 3505141cc406Sopenharmony_ci 3506141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3507141cc406Sopenharmony_ci} 3508141cc406Sopenharmony_ci 3509141cc406Sopenharmony_ci 3510141cc406Sopenharmony_ci/* ----------------------------------------- SANE START --------------------------------- */ 3511141cc406Sopenharmony_ci 3512141cc406Sopenharmony_ci 3513141cc406Sopenharmony_ciSANE_Status 3514141cc406Sopenharmony_cisane_start (SANE_Handle handle) 3515141cc406Sopenharmony_ci{ 3516141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3517141cc406Sopenharmony_ci int fds[2]; 3518141cc406Sopenharmony_ci const char *mode; 3519141cc406Sopenharmony_ci int status; 3520141cc406Sopenharmony_ci 3521141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_start\n"); 3522141cc406Sopenharmony_ci 3523141cc406Sopenharmony_ci /* Check for inconsistencies */ 3524141cc406Sopenharmony_ci 3525141cc406Sopenharmony_ci if (scanner->val[OPT_TL_X].w > scanner->val[OPT_BR_X].w) 3526141cc406Sopenharmony_ci { 3527141cc406Sopenharmony_ci DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) " 3528141cc406Sopenharmony_ci "-- aborting\n", 3529141cc406Sopenharmony_ci scanner->opt[OPT_TL_X].title, SANE_UNFIX (scanner->val[OPT_TL_X].w), 3530141cc406Sopenharmony_ci scanner->opt[OPT_BR_X].title, SANE_UNFIX (scanner->val[OPT_BR_X].w)); 3531141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3532141cc406Sopenharmony_ci } 3533141cc406Sopenharmony_ci if (scanner->val[OPT_TL_Y].w > scanner->val[OPT_BR_Y].w) 3534141cc406Sopenharmony_ci { 3535141cc406Sopenharmony_ci DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) " 3536141cc406Sopenharmony_ci "-- aborting\n", 3537141cc406Sopenharmony_ci scanner->opt[OPT_TL_Y].title, SANE_UNFIX (scanner->val[OPT_TL_Y].w), 3538141cc406Sopenharmony_ci scanner->opt[OPT_BR_Y].title, SANE_UNFIX (scanner->val[OPT_BR_Y].w)); 3539141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3540141cc406Sopenharmony_ci } 3541141cc406Sopenharmony_ci 3542141cc406Sopenharmony_ci mode = scanner->val[OPT_MODE].s; 3543141cc406Sopenharmony_ci 3544141cc406Sopenharmony_ci if (scanner->sfd < 0) /* first call, don`t run this routine again on multi frame or multi image scan */ 3545141cc406Sopenharmony_ci { 3546141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 3547141cc406Sopenharmony_ci int scsi_bufsize = 131072; /* 128KB */ 3548141cc406Sopenharmony_ci 3549141cc406Sopenharmony_ci if (sanei_scsi_open_extended 3550141cc406Sopenharmony_ci (scanner->device->sane.name, &(scanner->sfd), sense_handler, 3551141cc406Sopenharmony_ci scanner->device, &scsi_bufsize) != 0) 3552141cc406Sopenharmony_ci 3553141cc406Sopenharmony_ci { 3554141cc406Sopenharmony_ci DBG (DBG_error, "sane_start: open failed\n"); 3555141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3556141cc406Sopenharmony_ci } 3557141cc406Sopenharmony_ci 3558141cc406Sopenharmony_ci if (scsi_bufsize < 32768) /* < 32KB */ 3559141cc406Sopenharmony_ci { 3560141cc406Sopenharmony_ci DBG (DBG_error, 3561141cc406Sopenharmony_ci "sane_start: sanei_scsi_open_extended returned too small scsi buffer (%d)\n", 3562141cc406Sopenharmony_ci scsi_bufsize); 3563141cc406Sopenharmony_ci sanei_scsi_close ((scanner->sfd)); 3564141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 3565141cc406Sopenharmony_ci } 3566141cc406Sopenharmony_ci DBG (DBG_info, 3567141cc406Sopenharmony_ci "sane_start: sanei_scsi_open_extended returned scsi buffer size = %d\n", 3568141cc406Sopenharmony_ci scsi_bufsize); 3569141cc406Sopenharmony_ci 3570141cc406Sopenharmony_ci 3571141cc406Sopenharmony_ci scanner->bufsize = scsi_bufsize; 3572141cc406Sopenharmony_ci#else 3573141cc406Sopenharmony_ci if (sanei_scsi_open 3574141cc406Sopenharmony_ci (scanner->device->sane.name, &(scanner->sfd), sense_handler, 3575141cc406Sopenharmony_ci scanner->device) != SANE_STATUS_GOOD) 3576141cc406Sopenharmony_ci { 3577141cc406Sopenharmony_ci DBG (DBG_error, "sane_start: open of %s failed:\n", 3578141cc406Sopenharmony_ci scanner->device->sane.name); 3579141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3580141cc406Sopenharmony_ci } 3581141cc406Sopenharmony_ci 3582141cc406Sopenharmony_ci /* there is no need to reallocate the buffer because the size is fixed */ 3583141cc406Sopenharmony_ci#endif 3584141cc406Sopenharmony_ci 3585141cc406Sopenharmony_ci#if 0 3586141cc406Sopenharmony_ci if (pie_check_values (scanner->device) != 0) 3587141cc406Sopenharmony_ci { 3588141cc406Sopenharmony_ci DBG (DBG_error, "ERROR: invalid scan-values\n"); 3589141cc406Sopenharmony_ci scanner->scanning = SANE_FALSE; 3590141cc406Sopenharmony_ci pie_give_scanner (scanner); /* reposition and release scanner */ 3591141cc406Sopenharmony_ci sanei_scsi_close (scanner->sfd); 3592141cc406Sopenharmony_ci scanner->sfd = -1; 3593141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3594141cc406Sopenharmony_ci } 3595141cc406Sopenharmony_ci#endif 3596141cc406Sopenharmony_ci#if 0 3597141cc406Sopenharmony_ci scanner->params.bytes_per_line = scanner->device->row_len; 3598141cc406Sopenharmony_ci scanner->params.pixels_per_line = scanner->device->width_in_pixels; 3599141cc406Sopenharmony_ci scanner->params.lines = scanner->device->length_in_pixels; 3600141cc406Sopenharmony_ci 3601141cc406Sopenharmony_ci sane_get_parameters (scanner, 0); 3602141cc406Sopenharmony_ci 3603141cc406Sopenharmony_ci DBG (DBG_sane_info, "x_resolution (dpi) = %u\n", 3604141cc406Sopenharmony_ci scanner->device->x_resolution); 3605141cc406Sopenharmony_ci DBG (DBG_sane_info, "y_resolution (dpi) = %u\n", 3606141cc406Sopenharmony_ci scanner->device->y_resolution); 3607141cc406Sopenharmony_ci DBG (DBG_sane_info, "x_coordinate_base (dpi) = %u\n", 3608141cc406Sopenharmony_ci scanner->device->x_coordinate_base); 3609141cc406Sopenharmony_ci DBG (DBG_sane_info, "y_coordinate_base (dpi) = %u\n", 3610141cc406Sopenharmony_ci scanner->device->y_coordinate_base); 3611141cc406Sopenharmony_ci DBG (DBG_sane_info, "upper_left_x (xbase) = %d\n", 3612141cc406Sopenharmony_ci scanner->device->upper_left_x); 3613141cc406Sopenharmony_ci DBG (DBG_sane_info, "upper_left_y (ybase) = %d\n", 3614141cc406Sopenharmony_ci scanner->device->upper_left_y); 3615141cc406Sopenharmony_ci DBG (DBG_sane_info, "scanwidth (xbase) = %u\n", 3616141cc406Sopenharmony_ci scanner->device->scanwidth); 3617141cc406Sopenharmony_ci DBG (DBG_sane_info, "scanlength (ybase) = %u\n", 3618141cc406Sopenharmony_ci scanner->device->scanlength); 3619141cc406Sopenharmony_ci DBG (DBG_sane_info, "width in pixels = %u\n", 3620141cc406Sopenharmony_ci scanner->device->width_in_pixels); 3621141cc406Sopenharmony_ci DBG (DBG_sane_info, "length in pixels = %u\n", 3622141cc406Sopenharmony_ci scanner->device->length_in_pixels); 3623141cc406Sopenharmony_ci DBG (DBG_sane_info, "bits per pixel/color = %u\n", 3624141cc406Sopenharmony_ci scanner->device->bits_per_pixel); 3625141cc406Sopenharmony_ci DBG (DBG_sane_info, "bytes per line = %d\n", 3626141cc406Sopenharmony_ci scanner->params.bytes_per_line); 3627141cc406Sopenharmony_ci DBG (DBG_sane_info, "pixels_per_line = %d\n", 3628141cc406Sopenharmony_ci scanner->params.pixels_per_line); 3629141cc406Sopenharmony_ci DBG (DBG_sane_info, "lines = %d\n", 3630141cc406Sopenharmony_ci scanner->params.lines); 3631141cc406Sopenharmony_ci#endif 3632141cc406Sopenharmony_ci 3633141cc406Sopenharmony_ci /* grab scanner */ 3634141cc406Sopenharmony_ci if (pie_grab_scanner (scanner)) 3635141cc406Sopenharmony_ci { 3636141cc406Sopenharmony_ci sanei_scsi_close (scanner->sfd); 3637141cc406Sopenharmony_ci scanner->sfd = -1; 3638141cc406Sopenharmony_ci DBG (DBG_warning, 3639141cc406Sopenharmony_ci "WARNING: unable to reserve scanner: device busy\n"); 3640141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 3641141cc406Sopenharmony_ci } 3642141cc406Sopenharmony_ci 3643141cc406Sopenharmony_ci scanner->scanning = SANE_TRUE; 3644141cc406Sopenharmony_ci 3645141cc406Sopenharmony_ci pie_power_save (scanner, 0); 3646141cc406Sopenharmony_ci } /* ------------ end of first call -------------- */ 3647141cc406Sopenharmony_ci 3648141cc406Sopenharmony_ci 3649141cc406Sopenharmony_ci if (strcmp (mode, LINEART_STR) == 0) 3650141cc406Sopenharmony_ci { 3651141cc406Sopenharmony_ci scanner->colormode = LINEART; 3652141cc406Sopenharmony_ci } 3653141cc406Sopenharmony_ci else if (strcmp (mode, HALFTONE_STR) == 0) 3654141cc406Sopenharmony_ci { 3655141cc406Sopenharmony_ci scanner->colormode = HALFTONE; 3656141cc406Sopenharmony_ci } 3657141cc406Sopenharmony_ci else if (strcmp (mode, GRAY_STR) == 0) 3658141cc406Sopenharmony_ci { 3659141cc406Sopenharmony_ci scanner->colormode = GRAYSCALE; 3660141cc406Sopenharmony_ci } 3661141cc406Sopenharmony_ci else if (strcmp (mode, COLOR_STR) == 0) 3662141cc406Sopenharmony_ci { 3663141cc406Sopenharmony_ci scanner->colormode = RGB; 3664141cc406Sopenharmony_ci } 3665141cc406Sopenharmony_ci 3666141cc406Sopenharmony_ci /* get and set geometric values for scanning */ 3667141cc406Sopenharmony_ci scanner->resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w); 3668141cc406Sopenharmony_ci 3669141cc406Sopenharmony_ci pie_set_window (scanner); 3670141cc406Sopenharmony_ci pie_send_exposure (scanner); 3671141cc406Sopenharmony_ci pie_mode_select (scanner); 3672141cc406Sopenharmony_ci pie_send_highlight_shadow (scanner); 3673141cc406Sopenharmony_ci 3674141cc406Sopenharmony_ci pie_scan (scanner, 1); 3675141cc406Sopenharmony_ci 3676141cc406Sopenharmony_ci status = pie_do_cal (scanner); 3677141cc406Sopenharmony_ci if (status) 3678141cc406Sopenharmony_ci return status; 3679141cc406Sopenharmony_ci 3680141cc406Sopenharmony_ci /* send gammacurves */ 3681141cc406Sopenharmony_ci 3682141cc406Sopenharmony_ci pie_dwnld_gamma (scanner); 3683141cc406Sopenharmony_ci 3684141cc406Sopenharmony_ci pie_get_params (scanner); 3685141cc406Sopenharmony_ci 3686141cc406Sopenharmony_ci if (pipe (fds) < 0) /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */ 3687141cc406Sopenharmony_ci { 3688141cc406Sopenharmony_ci DBG (DBG_error, "ERROR: could not create pipe\n"); 3689141cc406Sopenharmony_ci scanner->scanning = SANE_FALSE; 3690141cc406Sopenharmony_ci pie_scan (scanner, 0); 3691141cc406Sopenharmony_ci pie_give_scanner (scanner); /* reposition and release scanner */ 3692141cc406Sopenharmony_ci sanei_scsi_close (scanner->sfd); 3693141cc406Sopenharmony_ci scanner->sfd = -1; 3694141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 3695141cc406Sopenharmony_ci } 3696141cc406Sopenharmony_ci 3697141cc406Sopenharmony_ci scanner->pipe = fds[0]; 3698141cc406Sopenharmony_ci scanner->reader_fds = fds[1]; 3699141cc406Sopenharmony_ci scanner->reader_pid = sanei_thread_begin( reader_process, (void*)scanner ); 3700141cc406Sopenharmony_ci 3701141cc406Sopenharmony_ci if (!sanei_thread_is_valid (scanner->reader_pid)) 3702141cc406Sopenharmony_ci { 3703141cc406Sopenharmony_ci DBG (1, "sane_start: sanei_thread_begin failed (%s)\n", 3704141cc406Sopenharmony_ci strerror (errno)); 3705141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 3706141cc406Sopenharmony_ci } 3707141cc406Sopenharmony_ci 3708141cc406Sopenharmony_ci if (sanei_thread_is_forked ()) 3709141cc406Sopenharmony_ci { 3710141cc406Sopenharmony_ci close (scanner->reader_fds); 3711141cc406Sopenharmony_ci scanner->reader_fds = -1; 3712141cc406Sopenharmony_ci } 3713141cc406Sopenharmony_ci 3714141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3715141cc406Sopenharmony_ci} 3716141cc406Sopenharmony_ci 3717141cc406Sopenharmony_ci 3718141cc406Sopenharmony_ci/* -------------------------------------- SANE READ ---------------------------------- */ 3719141cc406Sopenharmony_ci 3720141cc406Sopenharmony_ci 3721141cc406Sopenharmony_ciSANE_Status 3722141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 3723141cc406Sopenharmony_ci SANE_Int * len) 3724141cc406Sopenharmony_ci{ 3725141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3726141cc406Sopenharmony_ci ssize_t nread; 3727141cc406Sopenharmony_ci 3728141cc406Sopenharmony_ci *len = 0; 3729141cc406Sopenharmony_ci 3730141cc406Sopenharmony_ci nread = read (scanner->pipe, buf, max_len); 3731141cc406Sopenharmony_ci DBG (DBG_sane_info, "sane_read: read %ld bytes\n", (long) nread); 3732141cc406Sopenharmony_ci 3733141cc406Sopenharmony_ci if (!(scanner->scanning)) /* OOPS, not scanning */ 3734141cc406Sopenharmony_ci { 3735141cc406Sopenharmony_ci return do_cancel (scanner); 3736141cc406Sopenharmony_ci } 3737141cc406Sopenharmony_ci 3738141cc406Sopenharmony_ci if (nread < 0) 3739141cc406Sopenharmony_ci { 3740141cc406Sopenharmony_ci if (errno == EAGAIN) 3741141cc406Sopenharmony_ci { 3742141cc406Sopenharmony_ci DBG (DBG_sane_info, "sane_read: EAGAIN\n"); 3743141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3744141cc406Sopenharmony_ci } 3745141cc406Sopenharmony_ci else 3746141cc406Sopenharmony_ci { 3747141cc406Sopenharmony_ci do_cancel (scanner); /* we had an error, stop scanner */ 3748141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 3749141cc406Sopenharmony_ci } 3750141cc406Sopenharmony_ci } 3751141cc406Sopenharmony_ci 3752141cc406Sopenharmony_ci *len = nread; 3753141cc406Sopenharmony_ci 3754141cc406Sopenharmony_ci if (nread == 0) /* EOF */ 3755141cc406Sopenharmony_ci { 3756141cc406Sopenharmony_ci do_cancel (scanner); 3757141cc406Sopenharmony_ci 3758141cc406Sopenharmony_ci return close_pipe (scanner); /* close pipe */ 3759141cc406Sopenharmony_ci } 3760141cc406Sopenharmony_ci 3761141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3762141cc406Sopenharmony_ci} 3763141cc406Sopenharmony_ci 3764141cc406Sopenharmony_ci 3765141cc406Sopenharmony_ci/* ------------------------------------- SANE CANCEL -------------------------------- */ 3766141cc406Sopenharmony_ci 3767141cc406Sopenharmony_ci 3768141cc406Sopenharmony_civoid 3769141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 3770141cc406Sopenharmony_ci{ 3771141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3772141cc406Sopenharmony_ci 3773141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_cancel\n"); 3774141cc406Sopenharmony_ci 3775141cc406Sopenharmony_ci if (scanner->scanning) 3776141cc406Sopenharmony_ci { 3777141cc406Sopenharmony_ci do_cancel (scanner); 3778141cc406Sopenharmony_ci } 3779141cc406Sopenharmony_ci} 3780141cc406Sopenharmony_ci 3781141cc406Sopenharmony_ci 3782141cc406Sopenharmony_ci/* -------------------------------------- SANE SET IO MODE --------------------------- */ 3783141cc406Sopenharmony_ci 3784141cc406Sopenharmony_ci 3785141cc406Sopenharmony_ciSANE_Status 3786141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 3787141cc406Sopenharmony_ci{ 3788141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3789141cc406Sopenharmony_ci 3790141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_set_io_mode: non_blocking=%d\n", non_blocking); 3791141cc406Sopenharmony_ci 3792141cc406Sopenharmony_ci if (!scanner->scanning) 3793141cc406Sopenharmony_ci { 3794141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3795141cc406Sopenharmony_ci } 3796141cc406Sopenharmony_ci 3797141cc406Sopenharmony_ci if (fcntl (scanner->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0) 3798141cc406Sopenharmony_ci { 3799141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 3800141cc406Sopenharmony_ci } 3801141cc406Sopenharmony_ci 3802141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3803141cc406Sopenharmony_ci} 3804141cc406Sopenharmony_ci 3805141cc406Sopenharmony_ci 3806141cc406Sopenharmony_ci/* --------------------------------------- SANE GET SELECT FD ------------------------- */ 3807141cc406Sopenharmony_ci 3808141cc406Sopenharmony_ci 3809141cc406Sopenharmony_ciSANE_Status 3810141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 3811141cc406Sopenharmony_ci{ 3812141cc406Sopenharmony_ci Pie_Scanner *scanner = handle; 3813141cc406Sopenharmony_ci 3814141cc406Sopenharmony_ci DBG (DBG_sane_init, "sane_get_select_fd\n"); 3815141cc406Sopenharmony_ci 3816141cc406Sopenharmony_ci if (!scanner->scanning) 3817141cc406Sopenharmony_ci { 3818141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3819141cc406Sopenharmony_ci } 3820141cc406Sopenharmony_ci *fd = scanner->pipe; 3821141cc406Sopenharmony_ci 3822141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3823141cc406Sopenharmony_ci} 3824