piuspatch
v0.1
USB addition to PIE backend
|
00001 /* sane - Scanner Access Now Easy. */ 00002 00097 #include "../include/sane/config.h" 00098 00099 #include <errno.h> 00100 #include <fcntl.h> 00101 #include <limits.h> 00102 #include <signal.h> 00103 #include <stdio.h> 00104 #include <stdlib.h> 00105 #include <string.h> 00106 #include <sys/types.h> 00107 #include <sys/wait.h> 00108 #include <sys/time.h> 00109 #include <unistd.h> 00110 #include <stdint.h> 00111 #include <math.h> 00112 #include <limits.h> 00113 00114 #include "../include/byteorder.h" /* TODO portable ? */ 00115 #include "../include/sane/sane.h" 00116 #include "../include/sane/sanei.h" 00117 #include "../include/sane/saneopts.h" 00118 #include "../include/sane/sanei_scsi.h" 00119 #include "../include/sane/sanei_usb.h" 00120 #include "../include/sane/sanei_debug.h" 00121 00122 #define BACKEND_NAME pie 00123 00124 #include "../include/sane/sanei_backend.h" 00125 #include "../include/sane/sanei_config.h" 00126 00127 #include "../include/sane/sanei_thread.h" 00128 #include "../include/sane/sanei_ir.h" 00129 #include "../include/sane/sanei_magic.h" 00130 00131 /* 00132 * @@ Definitions and static allocation 00133 */ 00134 00135 #include "pie-scsidef.h" 00136 #include "pie_usb.h" 00137 00138 #define DBG_error0 0 00139 #define DBG_error 1 00140 #define DBG_sense 2 00141 #define DBG_warning 3 00142 #define DBG_inquiry 4 00143 00144 #define DBG_info 5 00145 #define DBG_info2 6 00146 #define DBG_proc 7 00147 #define DBG_read 8 00148 #define DBG_sane_init 10 00149 #define DBG_sane_proc 11 00150 #define DBG_sane_info 12 00151 #define DBG_sane_option 13 00152 #define DBG_dump 14 00153 #define DBG_image 15 00154 #define DBG_poke 16 00155 00156 #define BUILD 10 00157 00158 #define PIE_CONFIG_FILE "pie.conf" 00159 00160 /* Option string defines */ 00161 00162 #define LINEART_STR SANE_VALUE_SCAN_MODE_LINEART 00163 #define HALFTONE_STR SANE_VALUE_SCAN_MODE_HALFTONE 00164 #define GRAY_STR SANE_VALUE_SCAN_MODE_GRAY 00165 #define COLOR_STR SANE_VALUE_SCAN_MODE_COLOR 00166 #define COLOR_IR_STR "RGBI" 00167 00168 #define IR_NAME_STR "swired" 00169 #define IR_TITLE_STR "Infrared processing" 00170 #define IR_DESC_STR "What to do with infrared plane"; 00171 #define IR_SPECT_STR "Reduce red overlap" 00172 #define IR_CLEAN_STR "Remove dirt" 00173 00174 #define THE_NONE_STR "None" 00175 00176 #define CROP_NAME_STR "swcrop" 00177 #define CROP_TITLE_STR "Cropping" 00178 #define CROP_DESC_STR "How to crop the image"; 00179 #define CROP_OUTER_STR "Outside" 00180 #define CROP_INNER_STR "Inside" 00181 00182 /* Color modes the scanner is operated in */ 00183 00184 #define LINEART 1 00185 #define HALFTONE 2 00186 #define GRAYSCALE 3 00187 #define RGB 4 00188 /* USB film scanners: infrared modus */ 00189 #define RGBI 8 00190 00191 /* USB film scanners: post scan processing */ 00192 00193 #define POST_SW_COLORS (1 << 0) /* gain, negatives, ..., can be done at any time */ 00194 #define POST_SW_IRED (1 << 1) /* remove spectral overlap, needs complete scan */ 00195 #define POST_SW_DIRT (1 << 2) /* our digital lavabo, needs complete scan */ 00196 #define POST_SW_GRAIN (1 << 3) /* smoothen a bit */ 00197 #define POST_SW_CROP (1 << 4) /* trim whole image in sane_start 00198 before sane_get_parameters() is answered */ 00199 #define POST_SW_IRED_MASK (POST_SW_IRED | POST_SW_DIRT) 00200 #define POST_SW_ACCUM_MASK (POST_SW_IRED_MASK | POST_SW_GRAIN | POST_SW_CROP) 00201 00202 /* SCSI scanners: calibration modes */ 00203 00204 #define CAL_MODE_PREVIEW (INQ_CAP_FAST_PREVIEW) 00205 #define CAL_MODE_FLATBED 0x00 00206 #define CAL_MODE_ADF (INQ_OPT_DEV_ADF) 00207 #define CAL_MODE_TRANPSARENCY (INQ_OPT_DEV_TP) 00208 #define CAL_MODE_TRANPSARENCY1 (INQ_OPT_DEV_TP1) 00209 00210 #define min(a,b) (((a)<(b))?(a):(b)) 00211 #define max(a,b) (((a)>(b))?(a):(b)) 00212 00213 /* names of scanners that are supported because */ 00214 /* the inquiry_return_block is ok and driver is tested, 00215 * for USB film scanners a first rough identification 00216 */ 00217 static char *scanner_str[] = { 00218 "DEVCOM", "9636PRO", 00219 "DEVCOM", "9636S", 00220 "DEVCOM", "9630S", 00221 "PIE", "ScanAce 1236S", 00222 "PIE", "ScanAce 1230S", 00223 "PIE", "ScanAce II", 00224 "PIE", "ScanAce III", 00225 "PIE", "ScanAce Plus", 00226 "PIE", "ScanAce II Plus", 00227 "PIE", "ScanAce III Plus", 00228 "PIE", "ScanAce V", 00229 "PIE", "ScanMedia", 00230 "PIE", "ScanMedia II", 00231 "PIE", "ScanAce 630S", 00232 "PIE", "ScanAce 636S", 00233 "AdLib", "JetScan 630", 00234 "AdLib", "JetScan 636PRO", 00235 /* USB film scanners */ 00236 "PIE", "SF Scanner", 00237 "END_OF_LIST" 00238 }; 00239 00240 /* times (in us) to delay after certain commands. Scanner seems to lock up if it returns busy 00241 * status and commands are repeatedly reissued (by kernel error handler) */ 00242 00243 #define DOWNLOAD_GAMMA_WAIT_TIME (1000000) 00244 #define SCAN_WAIT_TIME (1000000) 00245 #define SCAN_WARMUP_WAIT_TIME (500000) 00246 #define TUR_WAIT_TIME (500000) 00247 00248 /* otherwise lots of warnings when compiled with pthread enabled */ 00249 #if defined USE_PTHREAD 00250 #define NO_PID (pthread_t) -1 00251 #else 00252 #define NO_PID -1 00253 #endif 00254 00260 enum Pie_Option 00261 { 00262 OPT_NUM_OPTS = 0, 00263 00264 /* ------------------------------------------- */ 00265 OPT_MODE_GROUP, 00266 OPT_MODE, 00267 OPT_BIT_DEPTH, 00268 OPT_RESOLUTION, 00269 00270 00271 /* ------------------------------------------- */ 00272 00273 OPT_GEOMETRY_GROUP, 00274 OPT_TL_X, /* top-left x */ 00275 OPT_TL_Y, /* top-left y */ 00276 OPT_BR_X, /* bottom-right x */ 00277 OPT_BR_Y, /* bottom-right y */ 00278 00279 /* ------------------------------------------- */ 00280 00281 OPT_ENHANCEMENT_GROUP, 00282 00283 OPT_HALFTONE_PATTERN, /* SCSI only */ 00284 OPT_SPEED, 00285 OPT_THRESHOLD, /* SCSI only */ 00286 00287 OPT_SW_CROP, /* USB only */ 00288 OPT_SW_IRED, /* USB only */ 00289 OPT_SW_GRAIN, /* USB only */ 00290 OPT_SW_SRGB, /* USB only */ 00291 OPT_SW_NEGA, /* USB only */ 00292 00293 OPT_GAMMA_VECTOR, /* SCSI only */ 00294 OPT_GAMMA_VECTOR_R, /* SCSI only */ 00295 OPT_GAMMA_VECTOR_G, /* SCSI only */ 00296 OPT_GAMMA_VECTOR_B, /* SCSI only */ 00297 00298 /* ------------------------------------------- */ 00299 00300 OPT_ADVANCED_GROUP, 00301 OPT_PREVIEW, 00302 00303 /* must come last: */ 00304 NUM_OPTIONS 00305 }; 00306 00307 00312 struct Pie_cal_info 00313 { 00314 int cal_type; 00315 int receive_bits; 00316 int send_bits; 00317 int num_lines; 00318 int pixels_per_line; 00319 }; 00320 00324 typedef struct Pie_Device 00325 { 00326 struct Pie_Device *next; 00327 00328 char *devicename; 00330 char *vendor; 00331 char *product; 00332 char *version; 00334 PIE_USB_Model *model; 00335 SANE_Device sane; 00336 SANE_Range dpi_range; 00337 SANE_Range x_range; 00338 SANE_Range y_range; 00339 00340 SANE_Range exposure_range; 00341 SANE_Range shadow_range; 00342 SANE_Range highlight_range; 00343 00344 int inquiry_len; 00346 int inquiry_x_res; 00347 int inquiry_y_res; 00348 int inquiry_pixel_resolution; 00349 double inquiry_fb_width; 00350 double inquiry_fb_length; 00352 int inquiry_trans_top_left_x; 00353 int inquiry_trans_top_left_y; 00354 double inquiry_trans_width; 00355 double inquiry_trans_length; 00357 int inquiry_halftones; 00358 int inquiry_filters; 00359 int inquiry_color_depths; 00360 int inquiry_color_format; 00361 int inquiry_image_format; 00362 int inquiry_scan_capability; 00363 int inquiry_optional_devices; 00364 int inquiry_enhancements; 00365 int inquiry_gamma_bits; 00366 int inquiry_fast_preview_res; 00367 int inquiry_min_highlight; 00368 int inquiry_max_shadow; 00369 int inquiry_cal_eqn; 00370 int inquiry_min_exp; 00371 int inquiry_max_exp; 00373 SANE_String scan_mode_list[7]; 00374 SANE_String ir_sw_list[4]; 00375 SANE_String crop_sw_list[4]; 00377 SANE_Word bpp_list[4]; 00378 SANE_Word grain_sw_list[6]; 00380 SANE_String halftone_list[17]; 00382 SANE_String speed_list[9]; 00384 int cal_info_count; 00385 struct Pie_cal_info *cal_info; 00387 SANE_Status (*scsi_cmd) (int fd, const void *src, size_t src_size, 00388 void *dst, size_t * dst_size); 00389 } 00390 Pie_Device; 00391 00395 typedef struct Pie_Scanner 00396 { 00397 struct Pie_Scanner *next; 00398 Pie_Device *device; 00400 int sfd; 00401 int bufsize; 00403 SANE_Option_Descriptor opt[NUM_OPTIONS]; 00404 Option_Value val[NUM_OPTIONS]; 00405 SANE_Int *gamma_table[4]; 00406 SANE_Range gamma_range; 00407 int gamma_length; 00409 uint16_t *gamma_lut8; 00410 uint16_t *gamma_lut16; 00411 double *ln_lut; 00413 int scanning; 00414 SANE_Parameters params; 00415 00416 SANE_Pid parking_pid; 00417 SANE_Pid reader_pid; 00418 int pipe; 00419 int reader_fds; 00420 00421 int colormode; 00422 int processing; 00423 int resolution; 00424 int cal_mode; 00426 int cal_filter; 00427 PIE_USB_Calibration *cal_data; 00429 int filter_offset1; 00430 int filter_offset2; 00431 00432 int bytes_per_line; 00434 SANEI_IR_bufptr img_buffer; 00435 int total_bytes_stored; 00436 int total_bytes_read; 00437 } 00438 Pie_Scanner; 00439 00440 /* forward declarations */ 00441 00442 static SANE_Status pie_usb_read_status (int dn, unsigned char *buf); 00443 SANE_Status 00444 pie_usb_scsi_wrapper (int fd, const void *src, size_t src_size, void *dst, 00445 size_t * dst_size); 00446 static SANE_Status 00447 pie_sense_handler (int scsi_fd, unsigned char *result, void *arg); 00448 static SANE_Status pie_wait_scanner (Pie_Scanner * scanner); 00449 static SANE_Status pie_send_exposure (Pie_Scanner * scanner); 00450 static SANE_Status pie_send_highlight_shadow (Pie_Scanner * scanner); 00451 static SANE_Status pie_power_save (Pie_Scanner * scanner, int time); 00452 static SANE_Status pie_attach_one (const char *name); 00453 00454 00455 /* USB scanners can not be "killed" by a cancel 00456 * but have to complete their current USB transaction, 00457 * used to gracefully cancel the child thread / process */ 00458 static volatile sig_atomic_t cancel_requ; 00459 00460 static const SANE_Range percentage_range_100 = { 00461 0 << SANE_FIXED_SCALE_SHIFT, /* minimum */ 00462 100 << SANE_FIXED_SCALE_SHIFT, /* maximum */ 00463 0 << SANE_FIXED_SCALE_SHIFT /* quantization */ 00464 }; 00465 00466 static Pie_Device *first_dev = NULL; 00467 static Pie_Scanner *first_handle = NULL; 00468 static const SANE_Device **devlist = NULL; 00469 00470 #define DBG_DUMP(level, buf, n) { if (DBG_LEVEL >= (level)) pie_dump_buffer(level,buf,n); } 00471 00472 00473 /* USB film scanners we support 00474 */ 00475 static PIE_USB_Model crystalscan_7200_model = { 00476 "PIE/Reflecta", /* Device vendor string */ 00477 "CrystalScan 7200", /* Device model name */ 00478 0x30, /* Model ID */ 00479 PIE_USB_FLAG_MIRROR_IMAGE | /* flags */ 00480 PIE_USB_FLAG_XRES_FAKE, 00481 /* operation mode values for preview, skip calibration and quality */ 00482 {0x00, 0x08, 0x0a}, 00483 75000, /* default brightness */ 00484 /* R, G, B gain constant */ 00485 {4.19682524E-04, 3.92060196E-04, 3.89647803E-04}, 00486 /* R, G, B normal mode offset factor */ 00487 {1.05, 1.05, 1.05}, 00488 16, /* minimal gain */ 00489 42, /* maximal gain in quality mode */ 00490 0x0f00, /* normal mode maximal exposure time */ 00491 10, /* gain calibration part */ 00492 {{0x16e6, 0x0ff2, 0x0ff2}, /* RGB texp and gain, first calibration if quality mode */ 00493 0x16e6, {0x21, 0x21, 0x19}}, 00494 {{0x0be2, 0x0bcf, 0x0b88}, /* RGB texp and gain, first calibration if normal mode */ 00495 0x0be2, {0x35, 0x2c, 0x27}} 00496 }; 00497 00498 static PIE_USB_Model proscan_7200_model = { 00499 "PIE/Reflecta", /* Device vendor string */ 00500 "ProScan 7200", /* Device model name */ 00501 0x36, /* Model ID */ 00502 PIE_USB_FLAG_MIRROR_IMAGE, /* flags */ 00503 /* operation mode values for preview, skip calibration and quality */ 00504 {0x00, 0x08, 0x02}, 00505 75000, /* default brightness */ 00506 /* R, G, B gain constant */ 00507 {4.19682524E-04, 3.92060196E-04, 3.89647803E-04}, 00508 /* R, G, B normal mode offset factor */ 00509 {1.2229896394, 1.0447735936, 0.9805181615}, 00510 16, /* minimal gain */ 00511 42, /* maximal gain in quality mode */ 00512 0x0f00, /* normal mode maximal exposure time */ 00513 10, /* gain calibration part */ 00514 {{0x2c89, 0x1eb7, 0x17ca}, /* RGB texp and gain, first calibration if quality mode */ 00515 0x2c89, {0x25, 0x25, 0x28}}, 00516 {{0x0e79, 0x0bff, 0x0c6c}, /* RGB texp and gain, first calibration if normal mode */ 00517 0x0e79, {0x3f, 0x3d, 0x39}} 00518 }; 00519 00520 /* list of USB descriptors, do not mind different models with the same USB id 00521 */ 00522 static PIE_USB_Device_Entry pie_usb_device_list[] = { 00523 {0x05e3, 0x0145, &crystalscan_7200_model}, /* Reflecta CrystalScan 7200, id 0x30 */ 00524 {0x05e3, 0x0145, &proscan_7200_model}, /* Reflecta ProScan 7200, id 0x36 */ 00525 {0, 0, 0} 00526 }; 00527 00528 /* 00529 * @@ Utility functions mostly for USB code 00530 */ 00531 00532 /* ---------------------------------- PIE DUMP_BUFFER ---------------------------------- */ 00540 static void 00541 pie_dump_buffer (int level, unsigned char *buf, int n) 00542 { 00543 char s[80], *p = s; 00544 int a = 0; 00545 00546 while (n--) 00547 { 00548 if ((a % 16) == 0) 00549 p += sprintf (p, " %04X ", a); 00550 00551 p += sprintf (p, "%02X ", *buf++); 00552 00553 if ((n == 0) || (a % 16) == 15) 00554 { 00555 DBG (level, "%s\n", s); 00556 p = s; 00557 } 00558 a++; 00559 } 00560 } 00561 00562 /* --------------------------------- PIE_USB_POKE_INTS --------------------------------- */ 00577 static SANE_Status 00578 pie_usb_poke_ints (char *filename, int *nums, int *len) 00579 { 00580 FILE *afile; 00581 char buffer[1024]; 00582 char *fres, *nptr; 00583 char *eptr = NULL; 00584 long int lnum; 00585 int i; 00586 00587 afile = fopen (filename, "r"); 00588 if (afile == NULL) 00589 { 00590 DBG (DBG_error, "pie_usb_poke_ints: file %s does not exist\n", 00591 filename); 00592 return SANE_STATUS_INVAL; 00593 } 00594 00595 i = 0; 00596 do 00597 { 00598 fres = fgets (buffer, sizeof (buffer), afile); 00599 if (fres != NULL) 00600 { 00601 nptr = buffer; 00602 errno = 0; 00603 lnum = strtol (nptr, &eptr, 10); 00604 while ((errno == 0) && (nptr != eptr) && (i < *len)) 00605 { 00606 nums[i] = lnum; 00607 i++; 00608 nptr = eptr; 00609 00610 errno = 0; 00611 lnum = strtol (nptr, &eptr, 10); 00612 } 00613 } 00614 } 00615 while (fres != NULL); 00616 *len = i; 00617 00618 fclose (afile); 00619 00620 return SANE_STATUS_GOOD; 00621 } 00622 00623 /* -------------------------------- PIE_USB_POKE_BYTES --------------------------------- */ 00637 static SANE_Status 00638 pie_usb_poke_bytes (char *filename, unsigned char *nums, int *len) 00639 { 00640 FILE *afile; 00641 char buffer[1024]; 00642 char *fres, *nptr; 00643 char *eptr = NULL; 00644 long int lnum; 00645 int i; 00646 00647 afile = fopen (filename, "r"); 00648 if (afile == NULL) 00649 { 00650 DBG (DBG_error, "pie_usb_poke_bytes: file %s does not exist\n", 00651 filename); 00652 return SANE_STATUS_INVAL; 00653 } 00654 00655 i = 0; 00656 do 00657 { 00658 fres = fgets (buffer, sizeof (buffer), afile); 00659 if (fres != NULL) 00660 { 00661 nptr = buffer; 00662 errno = 0; 00663 lnum = strtol (nptr, &eptr, 16); 00664 while ((errno == 0) && (nptr != eptr) && (i < *len)) 00665 { 00666 nums[i] = lnum & 0xff; 00667 i++; 00668 nptr = eptr; 00669 00670 errno = 0; 00671 lnum = strtol (nptr, &eptr, 16); 00672 } 00673 } 00674 } 00675 while (fres != NULL); 00676 *len = i; 00677 00678 fclose (afile); 00679 00680 return SANE_STATUS_GOOD; 00681 } 00682 00683 00684 /* ------------------------------ PIE_USB_WRITE_PNM_FILE ------------------------------- */ 00698 static SANE_Status 00699 pie_usb_write_pnm_file (char *filename, uint8_t * data, int depth, 00700 int channels, int pixels_per_line, int lines) 00701 { 00702 FILE *out; 00703 int count; 00704 00705 DBG (DBG_proc, 00706 "pie_usb_write_pnm_file: depth=%d, channels=%d, ppl=%d, lines=%d\n", 00707 depth, channels, pixels_per_line, lines); 00708 00709 out = fopen (filename, "w"); 00710 if (!out) 00711 { 00712 DBG (DBG_error, 00713 "pie_usb_write_pnm_file: could nor open %s for writing: %s\n", 00714 filename, strerror (errno)); 00715 return SANE_STATUS_INVAL; 00716 } 00717 if (depth == 1) 00718 { 00719 fprintf (out, "P4\n%d\n%d\n", pixels_per_line, lines); 00720 } 00721 else 00722 { 00723 fprintf (out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6', 00724 pixels_per_line, lines, (int) pow (2, depth) - 1); 00725 } 00726 if (channels == 3) 00727 { 00728 for (count = 0; count < (pixels_per_line * lines * 3); count++) 00729 { 00730 if (depth == 16) 00731 fputc (*(data + 1), out); 00732 fputc (*(data++), out); 00733 if (depth == 16) 00734 data++; 00735 } 00736 } 00737 else 00738 { 00739 if (depth == 1) 00740 { 00741 pixels_per_line /= 8; 00742 } 00743 for (count = 0; count < (pixels_per_line * lines); count++) 00744 { 00745 switch (depth) 00746 { 00747 case 8: 00748 fputc (*(data + count), out); 00749 break; 00750 case 16: 00751 fputc (*(data + 1), out); 00752 fputc (*(data), out); 00753 data += 2; 00754 break; 00755 default: 00756 fputc (data[count], out); 00757 break; 00758 } 00759 } 00760 } 00761 fclose (out); 00762 00763 DBG (DBG_info, "pie_usb_write_pnm_file: finished\n"); 00764 return SANE_STATUS_GOOD; 00765 } 00766 00767 /* ------------------------------ PIE_USB_SHADES_TO_PNM -------------------------------- */ 00780 static SANE_Status 00781 pie_usb_shades_to_pnm (Pie_Scanner * scanner, char *name, int lines) 00782 { 00783 char plane[4][12] = { "-red.pnm", "-green.pnm", "-blue.pnm", "-ired.pnm" }; 00784 char filename[256]; 00785 unsigned char *buffer, *dest; 00786 int *shade[4]; 00787 int pixels_per_line; 00788 int snd_length, bits; 00789 int i, j, k, val; 00790 SANE_Int status; 00791 00792 DBG (DBG_proc, "pie_usb_shades_to_pnm\n"); 00793 00794 pixels_per_line = scanner->device->cal_info[0].pixels_per_line; 00795 snd_length = pixels_per_line; 00796 bits = scanner->device->cal_info[0].receive_bits; 00797 if (bits > 8) 00798 snd_length *= 2; 00799 00800 buffer = malloc (snd_length * lines); 00801 if (!buffer) 00802 return SANE_STATUS_NO_MEM; 00803 for (k = 0; k < 4; k++) 00804 { 00805 shade[k] = scanner->cal_data->shades + k * pixels_per_line; 00806 } 00807 00808 for (j = 0; j < 4; j++) 00809 { 00810 dest = buffer; 00811 if (bits > 8) 00812 for (i = 0; i < pixels_per_line; i++) 00813 { 00814 val = shade[j][i]; 00815 *dest++ = val & 0xff; 00816 *dest++ = (val >> 8) & 0xff; 00817 } 00818 else 00819 for (i = 0; i < pixels_per_line; i++) 00820 *dest++ = shade[j][i] & 0xff; 00821 for (i = 1; i < lines; i++) 00822 { 00823 memcpy (dest, buffer, snd_length); 00824 dest += snd_length; 00825 } 00826 00827 strncpy (filename, name, 240); 00828 strncat (filename, plane[j], 255); 00829 status = pie_usb_write_pnm_file (filename, buffer, bits, 00830 1, pixels_per_line, lines); 00831 if (status != SANE_STATUS_GOOD) 00832 return status; 00833 } 00834 00835 free (buffer); 00836 return SANE_STATUS_GOOD; 00837 } 00838 00839 /* 00840 * @@ SCSI over USB and related functions 00841 */ 00842 00843 /* ----------------------- PIE_USB_WRITE_CONTROL_SEQUENCE ------------------------ */ 00856 static SANE_Status 00857 pie_usb_write_control_sequence (SANE_Int dn, PIE_USB_Value_Data sequ[]) 00858 { 00859 SANE_Int status = SANE_STATUS_GOOD; 00860 int i; 00861 00862 DBG (DBG_proc, "pie_usb_write_control_sequence writing\n"); 00863 00864 for (i = 0; (status == SANE_STATUS_GOOD) && (sequ[i].bValue != 0); i++) 00865 { 00866 status = 00867 sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, 00868 sequ[i].bValue, INDEX, 1, &(sequ[i].bData)); 00869 if (status != SANE_STATUS_GOOD) 00870 { 00871 DBG (DBG_error, "pie_usb_write_control_sequence failed\n"); 00872 return status; 00873 } 00874 } 00875 return SANE_STATUS_GOOD; 00876 } 00877 00878 /* ---------------------------- PIE_USB_READY_STATE ------------------------------ */ 00894 static SANE_Status 00895 pie_usb_ready_state (SANE_Int dn) 00896 { 00897 SANE_Status status; 00898 SANE_Byte val; 00899 00900 status = 00901 sanei_usb_control_msg (dn, REQUEST_TYPE_IN, REQUEST_REGISTER, 00902 VALUE_READ_REGISTER, INDEX, 1, &val); 00903 if (status != SANE_STATUS_GOOD) 00904 { 00905 DBG (DBG_error, "pie_usb_ready_state failed at 1st read\n"); 00906 return status; 00907 } 00908 DBG (DBG_info, "pie_usb_ready_state got 0x%02x at 1st read\n", val); 00909 00910 if (val <= 1) 00911 return SANE_STATUS_GOOD; 00912 if (val != 3) 00913 { 00914 DBG (DBG_error, "pie_usb_ready_state failed\n"); 00915 return SANE_STATUS_INVAL; 00916 } 00917 00918 status = 00919 sanei_usb_control_msg (dn, REQUEST_TYPE_IN, REQUEST_REGISTER, 00920 VALUE_READ_REGISTER, INDEX, 1, &val); 00921 if (status != SANE_STATUS_GOOD) 00922 { 00923 DBG (DBG_error, "pie_usb_ready_state failed at 2nd read\n"); 00924 return status; 00925 } 00926 DBG (DBG_info, "pie_usb_ready_state got 0x%02x at 2nd read\n", val); 00927 00928 if (val == 0) 00929 return SANE_STATUS_GOOD; 00930 else if (val == 8) 00931 return SANE_STATUS_DEVICE_BUSY; 00932 else if (val == 2) 00933 return SANE_STATUS_IO_ERROR; 00934 else 00935 return SANE_STATUS_INVAL; 00936 } 00937 00938 /* --------------------------- PIE_USB_WRITE_SCSI_CMD ---------------------------- */ 00951 static SANE_Status 00952 pie_usb_write_scsi_cmd (SANE_Int dn, const SANE_Byte cmnd[6]) 00953 { 00954 SANE_Status status; 00955 SANE_Byte mnd; 00956 int i; 00957 00958 DBG (DBG_proc, "pie_usb_write_scsi_cmd writing 6 bytes\n"); 00959 00960 for (i = 0; i < 6; i++) 00961 { 00962 mnd = cmnd[i]; 00963 status = 00964 sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, 00965 VALUE_WRITE_REGISTER, INDEX, 1, &mnd); 00966 if (status != SANE_STATUS_GOOD) 00967 { 00968 DBG (DBG_error, "pie_usb_write_scsi_cmd failed at byte %d\n", i); 00969 return status; 00970 } 00971 } 00972 return SANE_STATUS_GOOD; 00973 } 00974 00975 /* ----------------------------- PIE_USB_BULK_READ ------------------------------- */ 00989 static SANE_Status 00990 pie_usb_bulk_read (SANE_Int dn, SANE_Byte * data, size_t len) 00991 { 00992 SANE_Status status; 00993 size_t size; 00994 SANE_Byte outdata[8]; 00995 00996 DBG (DBG_proc, "pie_usb_bulk_read requesting %lu bytes\n", (u_long) len); 00997 00998 if (len == 0) 00999 01000 return SANE_STATUS_GOOD; 01001 01002 memset (outdata, '\0', sizeof (outdata)); 01003 01004 while (len) 01005 { 01006 if (len > BULKIN_MAXSIZE) 01007 size = BULKIN_MAXSIZE; 01008 else 01009 size = len; 01010 01011 outdata[4] = (size & 0xff); 01012 outdata[5] = ((size >> 8) & 0xff); 01013 outdata[6] = ((size >> 16) & 0xff); 01014 outdata[7] = ((size >> 24) & 0xff); 01015 01016 status = 01017 sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_BUFFER, 01018 VALUE_BUFFER, INDEX, sizeof (outdata), 01019 outdata); 01020 if (status != SANE_STATUS_GOOD) 01021 { 01022 DBG (DBG_error, 01023 "pie_usb_bulk_read failed while writing command: %s\n", 01024 sane_strstatus (status)); 01025 return status; 01026 } 01027 01028 DBG (DBG_info, 01029 "pie_usb_bulk_read trying to read %lu bytes of data\n", 01030 (u_long) size); 01031 status = sanei_usb_read_bulk (dn, data, &size); 01032 if (status != SANE_STATUS_GOOD) 01033 { 01034 DBG (DBG_error, 01035 "pie_usb_bulk_read failed while reading bulk data: %s\n", 01036 sane_strstatus (status)); 01037 return status; 01038 } 01039 01040 DBG (DBG_info, 01041 "pie_usb_bulk_read read %lu bytes, %lu remaining\n", 01042 (u_long) size, (u_long) (len - size)); 01043 len -= size; 01044 data += size; 01045 } 01046 01047 DBG (DBG_info, "pie_usb_bulk_read completed\n"); 01048 return SANE_STATUS_GOOD; 01049 } 01050 01051 /* ------------------------------- PIE_USB_READ ---------------------------------- */ 01073 static SANE_Status 01074 pie_usb_read (int dn, const SANE_Byte * cmnd, void *buf, size_t * buf_len) 01075 { 01076 SANE_Status status; 01077 size_t length = *buf_len; 01078 01079 DBG (DBG_proc, "pie_usb_read\n"); 01080 01081 status = pie_usb_write_scsi_cmd (dn, cmnd); 01082 if (status != SANE_STATUS_GOOD) 01083 return status; 01084 status = pie_usb_ready_state (dn); 01085 if (status != SANE_STATUS_GOOD) 01086 return status; 01087 01088 status = pie_usb_bulk_read (dn, buf, length); 01089 if (status != SANE_STATUS_GOOD) 01090 return status; 01091 01092 return pie_usb_ready_state (dn); 01093 } 01094 01095 /* ------------------------------- PIE_USB_WRITE --------------------------------- */ 01114 static SANE_Status 01115 pie_usb_write (int dn, const SANE_Byte * cmnd, size_t length) 01116 { 01117 SANE_Status status; 01118 SANE_Byte mnd; 01119 size_t i; 01120 01121 DBG (DBG_proc, "pie_usb_write\n"); 01122 if (length <= 6) 01123 return SANE_STATUS_GOOD; 01124 01125 status = pie_usb_write_scsi_cmd (dn, cmnd); 01126 if (status != SANE_STATUS_GOOD) 01127 return status; 01128 status = pie_usb_ready_state (dn); 01129 if (status != SANE_STATUS_GOOD) 01130 return status; 01131 01132 DBG (DBG_info, "pie_usb_write: now writing %lu bytes\n", 01133 (u_long) length - 6); 01134 for (i = 6; i < length; i++) 01135 { 01136 mnd = cmnd[i]; 01137 status = 01138 sanei_usb_control_msg (dn, REQUEST_TYPE_OUT, REQUEST_REGISTER, 01139 VALUE_WRITE_REGISTER, INDEX, 1, &mnd); 01140 if (status != SANE_STATUS_GOOD) 01141 { 01142 DBG (DBG_error, "pie_usb_write failed at byte %lu\n", 01143 (unsigned long) length); 01144 return status; 01145 } 01146 } 01147 01148 return pie_usb_ready_state (dn); 01149 } 01150 01151 /* ------------------------------ PIE_USB_COMMAND -------------------------------- */ 01165 static SANE_Status 01166 pie_usb_command (int dn, const SANE_Byte * cmnd) 01167 { 01168 SANE_Status status; 01169 01170 DBG (DBG_proc, "pie_usb_command\n"); 01171 01172 status = pie_usb_write_scsi_cmd (dn, cmnd); 01173 if (status != SANE_STATUS_GOOD) 01174 return status; 01175 01176 return pie_usb_ready_state (dn); 01177 } 01178 01179 /* ---------------------------- PIE_USB_SCSI_WRAPPER ----------------------------- */ 01199 SANE_Status 01200 pie_usb_scsi_wrapper (int fd, const void *src, size_t src_size, void *dst, 01201 size_t * dst_size) 01202 { 01203 /* values for some stereotype USB control write sequences */ 01204 static PIE_USB_Value_Data PIE_USB_Init_Sequence_1[] = { 01205 {VALUE_INIT_1, 0x04}, 01206 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0xaa}, {VALUE_INIT_2, 0x55}, 01207 {VALUE_INIT_2, 0x00}, 01208 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0x87}, {VALUE_INIT_2, 0x78}, 01209 {VALUE_INIT_2, 0x30}, 01210 {VALUE_INIT_1, 0x05}, {VALUE_INIT_1, 0x04}, 01211 {VALUE_INIT_2, 0xff}, 01212 {0x0, 0x0} 01213 }; 01214 static PIE_USB_Value_Data PIE_USB_Init_Sequence_2[] = { 01215 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0xaa}, {VALUE_INIT_2, 0x55}, 01216 {VALUE_INIT_2, 0x00}, 01217 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0x87}, {VALUE_INIT_2, 0x78}, 01218 {VALUE_INIT_2, 0x00}, 01219 {VALUE_INIT_1, 0x05}, {VALUE_INIT_1, 0x04}, 01220 {VALUE_INIT_2, 0xff}, 01221 {0x0, 0x0} 01222 }; 01223 static PIE_USB_Value_Data PIE_USB_Setup_SCSI_Sequence[] = { 01224 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0xaa}, {VALUE_INIT_2, 0x55}, 01225 {VALUE_INIT_2, 0x00}, 01226 {VALUE_INIT_2, 0xff}, {VALUE_INIT_2, 0x87}, {VALUE_INIT_2, 0x78}, 01227 {VALUE_INIT_2, 0xe0}, 01228 {VALUE_INIT_1, 0x05}, {VALUE_INIT_1, 0x04}, 01229 {VALUE_INIT_2, 0xff}, 01230 {0x0, 0x0} 01231 }; 01232 01233 SANE_Status status = SANE_STATUS_GOOD; 01234 const SANE_Byte *cmnd = src; 01235 01236 if (cmnd[0] == INQUIRY) 01237 { 01238 status = pie_usb_write_control_sequence (fd, PIE_USB_Init_Sequence_1); 01239 if (status != SANE_STATUS_GOOD) 01240 return status; 01241 status = pie_usb_write_control_sequence (fd, PIE_USB_Init_Sequence_2); 01242 if (status != SANE_STATUS_GOOD) 01243 return status; 01244 } 01245 status = pie_usb_write_control_sequence (fd, PIE_USB_Setup_SCSI_Sequence); 01246 if (status != SANE_STATUS_GOOD) 01247 return status; 01248 01249 switch (cmnd[0]) 01250 { 01251 case TEST_UNIT_READY: 01252 DBG (DBG_proc, "pie_usb_scsi_wrapper doing TEST_UNIT_READY\n"); 01253 status = pie_usb_command (fd, cmnd); 01254 break; 01255 case REQUEST_SENSE: 01256 DBG (DBG_proc, "pie_usb_scsi_wrapper doing REQUEST_SENSE\n"); 01257 status = pie_usb_read (fd, cmnd, dst, dst_size); 01258 break; 01259 case READ: 01260 DBG (DBG_proc, "pie_usb_scsi_wrapper doing READ\n"); 01261 status = pie_usb_read (fd, cmnd, dst, dst_size); 01262 break; 01263 case WRITE: 01264 DBG (DBG_proc, "pie_usb_scsi_wrapper doing WRITE\n"); 01265 status = pie_usb_write (fd, cmnd, src_size); 01266 break; 01267 case INQUIRY: 01268 DBG (DBG_proc, "pie_usb_scsi_wrapper doing INQUIRY\n"); 01269 status = pie_usb_read (fd, cmnd, dst, dst_size); 01270 break; 01271 case PARAM: 01272 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PARAM\n"); 01273 status = pie_usb_read (fd, cmnd, dst, dst_size); 01274 break; 01275 case MODE: 01276 DBG (DBG_proc, "pie_usb_scsi_wrapper doing MODE\n"); 01277 status = pie_usb_write (fd, cmnd, src_size); 01278 break; 01279 case RESERVE_UNIT: 01280 DBG (DBG_proc, "pie_usb_scsi_wrapper doing RESERVE_UNIT\n"); 01281 status = pie_usb_command (fd, cmnd); 01282 break; 01283 case RELEASE_UNIT: 01284 DBG (DBG_proc, "pie_usb_scsi_wrapper doing RELEASE_UNIT\n"); 01285 status = pie_usb_command (fd, cmnd); 01286 break; 01287 case PIE_COPY: 01288 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PIE_COPY\n"); 01289 status = pie_usb_read (fd, cmnd, dst, dst_size); 01290 break; 01291 case SCAN: 01292 DBG (DBG_proc, "pie_usb_scsi_wrapper doing SCAN\n"); 01293 status = pie_usb_command (fd, cmnd); 01294 break; 01295 case PIE_RELEASE_SCANNER: 01296 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PIE_RELEASE_SCANNER\n"); 01297 status = pie_usb_write (fd, cmnd, src_size); 01298 break; 01299 case PIE_READ_CALIBRATION: 01300 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PIE_READ_CALIBRATION\n"); 01301 status = pie_usb_read (fd, cmnd, dst, dst_size); 01302 break; 01303 case PIE_WRITE_CALIBRATION: 01304 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PIE_WRITE_CALIBRATION\n"); 01305 status = pie_usb_write (fd, cmnd, src_size); 01306 break; 01307 case PIE_READ_STATUS: 01308 DBG (DBG_proc, "pie_usb_scsi_wrapper doing PIE_READ_STATUS\n"); 01309 status = pie_usb_read (fd, cmnd, dst, dst_size); 01310 break; 01311 default: 01312 DBG (DBG_proc, "pie_usb_scsi_wrapper failed for command 0x%02x\n", 01313 cmnd[0]); 01314 status = SANE_STATUS_INVAL; 01315 break; 01316 } 01317 01318 return status; 01319 } 01320 01321 /* ---------------------------- PIE_USB_REQUEST_SENSE ---------------------------- */ 01341 static SANE_Status 01342 pie_usb_request_sense (int dn, uint32_t * kascq) 01343 { 01344 unsigned char buffer[16]; /* for PIE's sense */ 01345 size_t size; 01346 SANE_Status status; 01347 01348 DBG (DBG_proc, "pie_usb_request_sense\n"); 01349 01350 size = 14; 01351 set_RS_allocation_length (request_senseC, size); 01352 01353 status = 01354 pie_usb_scsi_wrapper (dn, request_senseC, sizeof (request_senseC), buffer, 01355 &size); 01356 if (status != SANE_STATUS_GOOD) 01357 { 01358 DBG (DBG_error, "pie_usb_request_sense failed\n"); 01359 return status; 01360 } 01361 *kascq = ((int) get_RS_sense_key (buffer) << 16) + 01362 ((int) get_RS_ASC (buffer) << 8) + (int) get_RS_ASCQ (buffer); 01363 pie_sense_handler (dn, buffer, NULL); 01364 01365 return SANE_STATUS_GOOD; 01366 } 01367 01368 01369 /* -------------------------- PIE_SENSE_HANDLER ---------------------------- */ 01382 static SANE_Status 01383 pie_sense_handler (__sane_unused__ int scsi_fd, unsigned char *result, 01384 __sane_unused__ void *arg) 01385 { 01386 unsigned char asc, ascq, sensekey; 01387 int asc_ascq, len; 01388 /* Pie_Device *dev = arg; */ 01389 01390 DBG (DBG_proc, "check condition sense handler\n"); 01391 01392 sensekey = get_RS_sense_key (result); 01393 asc = get_RS_ASC (result); 01394 ascq = get_RS_ASCQ (result); 01395 asc_ascq = (int) (256 * asc + ascq); 01396 len = 7 + get_RS_additional_length (result); 01397 01398 if (get_RS_error_code (result) != 0x70) 01399 { 01400 DBG (DBG_proc, "invalid sense key => handled as DEVICE BUSY!\n"); 01401 return SANE_STATUS_DEVICE_BUSY; /* sense key invalid */ 01402 } 01403 01404 DBG (DBG_sense, "check condition sense: %s\n", sense_str[sensekey]); 01405 01406 if (get_RS_ILI (result) != 0) 01407 { 01408 DBG (DBG_sense, 01409 "-> ILI-ERROR: requested data length is larger than actual length\n"); 01410 } 01411 01412 switch (sensekey) 01413 { 01414 case 0x00: /* no sense, could have been busy */ 01415 return SANE_STATUS_IO_ERROR; 01416 break; 01417 01418 case 0x02: 01419 if (asc_ascq == 0x0401) 01420 DBG (DBG_sense, "-> Not Ready - Warming Up\n"); 01421 else if (asc_ascq == 0x0483) 01422 DBG (DBG_sense, "-> Not Ready - Need manual service\n"); 01423 else if (asc_ascq == 0x0881) 01424 DBG (DBG_sense, "-> Not Ready - Communication time out\n"); 01425 else 01426 DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc, 01427 ascq); 01428 break; 01429 01430 case 0x03: /* medium error */ 01431 if (asc_ascq == 0x5300) 01432 DBG (DBG_sense, "-> Media load or eject failure\n"); 01433 else if (asc_ascq == 0x3a00) 01434 DBG (DBG_sense, "-> Media not present\n"); 01435 else if (asc_ascq == 0x3b05) 01436 DBG (DBG_sense, "-> Paper jam\n"); 01437 else if (asc_ascq == 0x3a80) 01438 DBG (DBG_sense, "-> ADF paper out\n"); 01439 else 01440 DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc, 01441 ascq); 01442 break; 01443 01444 01445 case 0x04: /* hardware error */ 01446 if (asc_ascq == 0x4081) 01447 DBG (DBG_sense, "-> CPU RAM failure\n"); 01448 else if (asc_ascq == 0x4082) 01449 DBG (DBG_sense, "-> Scanning system RAM failure\n"); 01450 else if (asc_ascq == 0x4083) 01451 DBG (DBG_sense, "-> Image buffer failure\n"); 01452 else if (asc_ascq == 0x0403) 01453 DBG (DBG_sense, "-> Manual intervention required\n"); 01454 else if (asc_ascq == 0x6200) 01455 DBG (DBG_sense, "-> Scan head position error\n"); 01456 else if (asc_ascq == 0x6000) 01457 DBG (DBG_sense, "-> Lamp or CCD failure\n"); 01458 else if (asc_ascq == 0x6081) 01459 DBG (DBG_sense, "-> Transparency lamp failure\n"); 01460 else if (asc_ascq == 0x8180) 01461 DBG (DBG_sense, "-> DC offset or black level calibration failure\n"); 01462 else if (asc_ascq == 0x8181) 01463 DBG (DBG_sense, 01464 "-> Integration time adjustment failure (too light)\n"); 01465 else if (asc_ascq == 0x8182) 01466 DBG (DBG_sense, 01467 "-> Integration time adjustment failure (too dark)\n"); 01468 else if (asc_ascq == 0x8183) 01469 DBG (DBG_sense, "-> Shading curve adjustment failure\n"); 01470 else if (asc_ascq == 0x8184) 01471 DBG (DBG_sense, "-> Gain adjustment failure\n"); 01472 else if (asc_ascq == 0x8185) 01473 DBG (DBG_sense, "-> Optical alignment failure\n"); 01474 else if (asc_ascq == 0x8186) 01475 DBG (DBG_sense, "-> Optical locating failure\n"); 01476 else if (asc_ascq == 0x8187) 01477 DBG (DBG_sense, "-> Scan pixel map less than 5100 pixels!\n"); 01478 else if (asc_ascq == 0x4700) 01479 DBG (DBG_sense, "-> Parity error on SCSI bus\n"); 01480 else if (asc_ascq == 0x4b00) 01481 DBG (DBG_sense, "-> Data phase error\n"); 01482 else 01483 DBG (DBG_sense, "-> unknown hardware error: asc=%d, ascq=%d\n", asc, 01484 ascq); 01485 return SANE_STATUS_IO_ERROR; 01486 break; 01487 01488 01489 case 0x05: /* illegal request */ 01490 if (asc_ascq == 0x1a00) 01491 DBG (DBG_sense, "-> Parameter list length error\n"); 01492 else if (asc_ascq == 0x2c01) 01493 DBG (DBG_sense, "-> Too many windows specified\n"); 01494 else if (asc_ascq == 0x2c02) 01495 DBG (DBG_sense, "-> Invalid combination of windows\n"); 01496 else if (asc_ascq == 0x2c81) 01497 DBG (DBG_sense, "-> Illegal scanning frame\n"); 01498 else if (asc_ascq == 0x2400) 01499 DBG (DBG_sense, "-> Invalid field in CDB\n"); 01500 else if (asc_ascq == 0x2481) 01501 DBG (DBG_sense, "-> Request too many lines of data\n"); 01502 else if (asc_ascq == 0x2000) 01503 DBG (DBG_sense, "-> Invalid command OP code\n"); 01504 else if (asc_ascq == 0x2501) 01505 DBG (DBG_sense, "-> LUN not supported\n"); 01506 else if (asc_ascq == 0x2601) 01507 DBG (DBG_sense, "-> Parameter not supported\n"); 01508 else if (asc_ascq == 0x2602) 01509 DBG (DBG_sense, 01510 "-> Parameter value invalid - Parameter not specified\n"); 01511 else if (asc_ascq == 0x2603) 01512 DBG (DBG_sense, "-> Parameter value invalid - Invalid threshold\n"); 01513 else if (asc_ascq == 0x2680) 01514 DBG (DBG_sense, 01515 "-> Parameter value invalid - Control command sequence error\n"); 01516 else if (asc_ascq == 0x2681) 01517 DBG (DBG_sense, 01518 "-> Parameter value invalid - Grain setting (halftone pattern\n"); 01519 else if (asc_ascq == 0x2682) 01520 DBG (DBG_sense, 01521 "-> Parameter value invalid - Illegal resolution setting\n"); 01522 else if (asc_ascq == 0x2683) 01523 DBG (DBG_sense, 01524 "-> Parameter value invalid - Invalid filter assignment\n"); 01525 else if (asc_ascq == 0x2684) 01526 DBG (DBG_sense, 01527 "-> Parameter value invalid - Illegal gamma adjustment setting (look-up table)\n"); 01528 else if (asc_ascq == 0x2685) 01529 DBG (DBG_sense, 01530 "-> Parameter value invalid - Illegal offset setting (digital brightness)\n"); 01531 else if (asc_ascq == 0x2686) 01532 DBG (DBG_sense, 01533 "-> Parameter value invalid - Illegal bits per pixel setting\n"); 01534 else if (asc_ascq == 0x2687) 01535 DBG (DBG_sense, 01536 "-> Parameter value invalid - Illegal contrast setting\n"); 01537 else if (asc_ascq == 0x2688) 01538 DBG (DBG_sense, 01539 "-> Parameter value invalid - Illegal paper length setting\n"); 01540 else if (asc_ascq == 0x2689) 01541 DBG (DBG_sense, 01542 "-> Parameter value invalid - Illegal highlight/shadow setting\n"); 01543 else if (asc_ascq == 0x268a) 01544 DBG (DBG_sense, 01545 "-> Parameter value invalid - Illegal exposure time setting (analog brightness)\n"); 01546 else if (asc_ascq == 0x268b) 01547 DBG (DBG_sense, 01548 "-> Parameter value invalid - Invalid device select or device not exist\n"); 01549 else if (asc_ascq == 0x268c) 01550 DBG (DBG_sense, 01551 "-> Parameter value invalid - Illegal color packing\n"); 01552 else if (asc_ascq == 0x3d00) 01553 DBG (DBG_sense, "-> Invalid bits in identify field\n"); 01554 01555 01556 01557 else if (asc_ascq == 0x4900) 01558 DBG (DBG_sense, "-> Invalid message\n"); 01559 else if (asc_ascq == 0x8101) 01560 DBG (DBG_sense, "-> Not enough memory for color packing\n"); 01561 01562 if (len >= 0x11) 01563 { 01564 if (get_RS_SKSV (result) != 0) 01565 { 01566 if (get_RS_CD (result) == 0) 01567 { 01568 01569 DBG (DBG_sense, "-> illegal parameter in CDB\n"); 01570 } 01571 else 01572 { 01573 DBG (DBG_sense, 01574 "-> illegal parameter is in the data parameters sent during data out phase\n"); 01575 } 01576 01577 DBG (DBG_sense, "-> error detected in byte %d\n", 01578 get_RS_field_pointer (result)); 01579 } 01580 } 01581 return SANE_STATUS_IO_ERROR; 01582 break; 01583 01584 01585 case 0x06: /* unit attention */ 01586 if (asc_ascq == 0x2900) 01587 DBG (DBG_sense, "-> power on, reset or bus device reset\n"); 01588 if (asc_ascq == 0x8200) 01589 DBG (DBG_sense, 01590 "-> unit attention - calibration disable not granted\n"); 01591 if (asc_ascq == 0x8300) 01592 DBG (DBG_sense, "-> unit attention - calibration will be ignored\n"); 01593 else 01594 DBG (DBG_sense, "-> unit attention: asc=%d, ascq=%d\n", asc, ascq); 01595 break; 01596 01597 01598 case 0x09: /* vendor specific */ 01599 DBG (DBG_sense, "-> vendor specific sense-code: asc=%d, ascq=%d\n", asc, 01600 ascq); 01601 break; 01602 01603 case 0x0b: 01604 if (asc_ascq == 0x0006) 01605 DBG (DBG_sense, "-> Received ABORT message from initiator\n"); 01606 if (asc_ascq == 0x4800) 01607 DBG (DBG_sense, "-> Initiator detected error message received\n"); 01608 if (asc_ascq == 0x4300) 01609 DBG (DBG_sense, "-> Message error\n"); 01610 if (asc_ascq == 0x4500) 01611 DBG (DBG_sense, "-> Select or re-select error\n"); 01612 else 01613 DBG (DBG_sense, "-> aborted command: asc=%d, ascq=%d\n", asc, ascq); 01614 break; 01615 01616 } 01617 01618 return SANE_STATUS_IO_ERROR; 01619 } 01620 01621 /* --------------------------- PIE_USB_READ_STATUS ---------------------------- */ 01636 static SANE_Status 01637 pie_usb_read_status (int dn, unsigned char *buf) 01638 { 01639 SANE_Status status; 01640 size_t size; 01641 01642 DBG (DBG_proc, "pie_usb_read_status\n"); 01643 01644 size = 11; 01645 01646 status = 01647 pie_usb_scsi_wrapper (dn, read_statusC, sizeof (read_statusC), buf, 01648 &size); 01649 return status; 01650 } 01651 01652 01653 /* 01654 * @@ Initialization is rather similar for SCSI and USB scanners 01655 */ 01656 01657 /* ---------------------------------- PIE INIT ---------------------------------- */ 01658 01659 static void 01660 pie_init (Pie_Device * dev, SANE_Int is_USB) /* pie_init is called once while driver-initialization */ 01661 { 01662 DBG (DBG_proc, "init\n"); 01663 01664 dev->cal_info_count = 0; 01665 dev->cal_info = NULL; 01666 dev->halftone_list[0] = NULL; 01667 dev->speed_list[0] = NULL; 01668 01669 dev->devicename = NULL; 01670 dev->inquiry_len = 0; 01671 dev->model = NULL; 01672 01673 if (is_USB == 0) 01674 { 01675 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 01676 DBG (DBG_info, 01677 "variable scsi buffer size (usage of sanei_scsi_open_extended)\n"); 01678 #else 01679 DBG (DBG_info, "fixed scsi buffer size = %d bytes\n", 01680 sanei_scsi_max_request_size); 01681 #endif 01682 dev->scsi_cmd = sanei_scsi_cmd; 01683 } 01684 else 01685 { 01686 dev->scsi_cmd = pie_usb_scsi_wrapper; 01687 } 01688 } 01689 01690 /* -------------------------------- PIE PRINT INQUIRY ------------------------- */ 01691 01692 static void 01693 pie_print_inquiry (Pie_Device * dev) 01694 { 01695 DBG (DBG_inquiry, "INQUIRY:\n"); 01696 DBG (DBG_inquiry, "========\n"); 01697 DBG (DBG_inquiry, "\n"); 01698 DBG (DBG_inquiry, "vendor........................: '%s'\n", dev->vendor); 01699 DBG (DBG_inquiry, "product.......................: '%s'\n", dev->product); 01700 DBG (DBG_inquiry, "version.......................: '%s'\n", dev->version); 01701 01702 DBG (DBG_inquiry, "X resolution..................: %d dpi\n", 01703 dev->inquiry_x_res); 01704 DBG (DBG_inquiry, "Y resolution..................: %d dpi\n", 01705 dev->inquiry_y_res); 01706 DBG (DBG_inquiry, "pixel resolution..............: %d dpi\n", 01707 dev->inquiry_pixel_resolution); 01708 DBG (DBG_inquiry, "fb width......................: %f in\n", 01709 dev->inquiry_fb_width); 01710 DBG (DBG_inquiry, "fb length.....................: %f in\n", 01711 dev->inquiry_fb_length); 01712 01713 DBG (DBG_inquiry, "transparency width............: %f in\n", 01714 dev->inquiry_trans_width); 01715 DBG (DBG_inquiry, "transparency length...........: %f in\n", 01716 dev->inquiry_trans_length); 01717 DBG (DBG_inquiry, "transparency offset...........: %d,%d\n", 01718 dev->inquiry_trans_top_left_x, dev->inquiry_trans_top_left_y); 01719 01720 DBG (DBG_inquiry, "# of halftones................: %d\n", 01721 dev->inquiry_halftones); 01722 01723 DBG (DBG_inquiry, "One pass color................: %s\n", 01724 dev->inquiry_filters & INQ_ONE_PASS_COLOR ? "yes" : "no"); 01725 01726 DBG (DBG_inquiry, "Filters.......................: %s%s%s%s (%02x)\n", 01727 dev->inquiry_filters & INQ_FILTER_RED ? "Red " : "", 01728 dev->inquiry_filters & INQ_FILTER_GREEN ? "Green " : "", 01729 dev->inquiry_filters & INQ_FILTER_BLUE ? "Blue " : "", 01730 dev->inquiry_filters & INQ_FILTER_NEUTRAL ? "Neutral " : "", 01731 dev->inquiry_filters); 01732 01733 DBG (DBG_inquiry, "Color depths..................: %s%s%s%s%s%s (%02x)\n", 01734 dev->inquiry_color_depths & INQ_COLOR_DEPTH_16 ? "16 bit " : "", 01735 dev->inquiry_color_depths & INQ_COLOR_DEPTH_12 ? "12 bit " : "", 01736 dev->inquiry_color_depths & INQ_COLOR_DEPTH_10 ? "10 bit " : "", 01737 dev->inquiry_color_depths & INQ_COLOR_DEPTH_8 ? "8 bit " : "", 01738 dev->inquiry_color_depths & INQ_COLOR_DEPTH_4 ? "4 bit " : "", 01739 dev->inquiry_color_depths & INQ_COLOR_DEPTH_1 ? "1 bit " : "", 01740 dev->inquiry_color_depths); 01741 01742 DBG (DBG_inquiry, "Color Format..................: %s%s%s (%02x)\n", 01743 dev->inquiry_color_format & INQ_COLOR_FORMAT_INDEX ? "Indexed " : "", 01744 dev->inquiry_color_format & INQ_COLOR_FORMAT_LINE ? "Line " : "", 01745 dev->inquiry_color_format & INQ_COLOR_FORMAT_PIXEL ? "Pixel " : "", 01746 dev->inquiry_color_format); 01747 01748 DBG (DBG_inquiry, "Image Format..................: %s%s%s%s (%02x)\n", 01749 dev->inquiry_image_format & INQ_IMG_FMT_OKLINE ? "OKLine " : "", 01750 dev->inquiry_image_format & INQ_IMG_FMT_BLK_ONE ? "BlackOne " : "", 01751 dev->inquiry_image_format & INQ_IMG_FMT_MOTOROLA ? "Motorola " : "", 01752 dev->inquiry_image_format & INQ_IMG_FMT_INTEL ? "Intel" : "", 01753 dev->inquiry_image_format); 01754 01755 DBG (DBG_inquiry, 01756 "Scan Capability...............: %s%s%s%s%d speeds (%02x)\n", 01757 dev->inquiry_scan_capability & INQ_CAP_PWRSAV ? "PowerSave " : "", 01758 dev->inquiry_scan_capability & INQ_CAP_EXT_CAL ? "ExtCal " : "", 01759 dev->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW ? "FastPreview" : 01760 "", 01761 dev->inquiry_scan_capability & INQ_CAP_DISABLE_CAL ? "DisCal " : "", 01762 dev->inquiry_scan_capability & INQ_CAP_SPEEDS, 01763 dev->inquiry_scan_capability); 01764 01765 DBG (DBG_inquiry, "Optional Devices..............: %s%s%s%s (%02x)\n", 01766 dev->inquiry_optional_devices & INQ_OPT_DEV_MPCL ? "MultiPageLoad " : 01767 "", 01768 dev->inquiry_optional_devices & INQ_OPT_DEV_TP1 ? "TransModule1 " : "", 01769 dev->inquiry_optional_devices & INQ_OPT_DEV_TP ? "TransModule " : "", 01770 dev->inquiry_optional_devices & INQ_OPT_DEV_ADF ? "ADF " : "", 01771 dev->inquiry_optional_devices); 01772 01773 DBG (DBG_inquiry, "Enhancement...................: %02x\n", 01774 dev->inquiry_enhancements); 01775 DBG (DBG_inquiry, "Gamma bits....................: %d\n", 01776 dev->inquiry_gamma_bits); 01777 01778 DBG (DBG_inquiry, "Fast Preview Resolution.......: %d\n", 01779 dev->inquiry_fast_preview_res); 01780 DBG (DBG_inquiry, "Min Highlight.................: %d\n", 01781 dev->inquiry_min_highlight); 01782 DBG (DBG_inquiry, "Max Shadow....................: %d\n", 01783 dev->inquiry_max_shadow); 01784 DBG (DBG_inquiry, "Cal Eqn.......................: %d\n", 01785 dev->inquiry_cal_eqn); 01786 DBG (DBG_inquiry, "Min Exposure..................: %d\n", 01787 dev->inquiry_min_exp); 01788 DBG (DBG_inquiry, "Max Exposure..................: %d\n", 01789 dev->inquiry_max_exp); 01790 } 01791 01792 01793 /* ------------------------------ PIE GET INQUIRY VALUES -------------------- */ 01794 01795 01796 static void 01797 pie_get_inquiry_values (Pie_Device * dev, unsigned char *buffer) 01798 { 01799 DBG (DBG_proc, "get_inquiry_values\n"); 01800 01801 dev->inquiry_len = get_inquiry_additional_length (buffer) + 5; 01802 01803 dev->inquiry_x_res = get_inquiry_max_x_res (buffer); 01804 dev->inquiry_y_res = get_inquiry_max_y_res (buffer); 01805 01806 if (dev->inquiry_y_res < 256) 01807 { 01808 /* y res is a multiplier */ 01809 dev->inquiry_pixel_resolution = dev->inquiry_x_res; 01810 dev->inquiry_x_res *= dev->inquiry_y_res; 01811 dev->inquiry_y_res = dev->inquiry_x_res; 01812 } 01813 else 01814 { 01815 /* y res really is resolution */ 01816 dev->inquiry_pixel_resolution = 01817 min (dev->inquiry_x_res, dev->inquiry_y_res); 01818 } 01819 01820 dev->inquiry_fb_width = 01821 (double) get_inquiry_fb_max_scan_width (buffer) / 01822 dev->inquiry_pixel_resolution; 01823 dev->inquiry_fb_length = 01824 (double) get_inquiry_fb_max_scan_length (buffer) / 01825 dev->inquiry_pixel_resolution; 01826 01827 dev->inquiry_trans_top_left_x = get_inquiry_trans_x1 (buffer); 01828 dev->inquiry_trans_top_left_y = get_inquiry_trans_y1 (buffer); 01829 01830 dev->inquiry_trans_width = 01831 (double) (get_inquiry_trans_x2 (buffer) - 01832 get_inquiry_trans_x1 (buffer)) / dev->inquiry_pixel_resolution; 01833 dev->inquiry_trans_length = 01834 (double) (get_inquiry_trans_y2 (buffer) - 01835 get_inquiry_trans_y1 (buffer)) / dev->inquiry_pixel_resolution; 01836 01837 dev->inquiry_halftones = get_inquiry_halftones (buffer) & 0x0f; 01838 01839 dev->inquiry_filters = get_inquiry_filters (buffer); 01840 dev->inquiry_color_depths = get_inquiry_color_depths (buffer); 01841 dev->inquiry_color_format = get_inquiry_color_format (buffer); 01842 dev->inquiry_image_format = get_inquiry_image_format (buffer); 01843 01844 dev->inquiry_scan_capability = get_inquiry_scan_capability (buffer); 01845 dev->inquiry_optional_devices = get_inquiry_optional_devices (buffer); 01846 dev->inquiry_enhancements = get_inquiry_enhancements (buffer); 01847 dev->inquiry_gamma_bits = get_inquiry_gamma_bits (buffer); 01848 dev->inquiry_fast_preview_res = get_inquiry_fast_preview_res (buffer); 01849 dev->inquiry_min_highlight = get_inquiry_min_highlight (buffer); 01850 dev->inquiry_max_shadow = get_inquiry_max_shadow (buffer); 01851 dev->inquiry_cal_eqn = get_inquiry_cal_eqn (buffer); 01852 dev->inquiry_min_exp = get_inquiry_min_exp (buffer); 01853 dev->inquiry_max_exp = get_inquiry_max_exp (buffer); 01854 01855 pie_print_inquiry (dev); 01856 01857 return; 01858 } 01859 01860 /* ----------------------------- PIE DO INQUIRY ---------------------------- */ 01861 01862 01863 static void 01864 pie_do_inquiry (Pie_Device * dev, int sfd, unsigned char *buffer) 01865 { 01866 size_t size; 01867 SANE_Status status; 01868 01869 DBG (DBG_proc, "do_inquiry\n"); 01870 memset (buffer, '\0', 256); /* clear buffer */ 01871 01872 size = 5; 01873 01874 set_inquiry_return_size (inquiry.cmd, size); /* first get only 5 bytes to get size of inquiry_return_block */ 01875 status = (*dev->scsi_cmd) (sfd, inquiry.cmd, inquiry.size, buffer, &size); 01876 if (status) 01877 { 01878 DBG (DBG_error, "pie_do_inquiry: command returned status %s\n", 01879 sane_strstatus (status)); 01880 } 01881 01882 size = get_inquiry_additional_length (buffer) + 5; 01883 01884 set_inquiry_return_size (inquiry.cmd, size); /* then get inquiry with actual size */ 01885 status = (*dev->scsi_cmd) (sfd, inquiry.cmd, inquiry.size, buffer, &size); 01886 if (status) 01887 { 01888 DBG (DBG_error, "pie_do_inquiry: command returned status %s\n", 01889 sane_strstatus (status)); 01890 } 01891 } 01892 01893 /* ---------------------- PIE IDENTIFY SCANNER ---------------------- */ 01894 01895 01896 static int 01897 pie_identify_scanner (Pie_Device * dev, int sfd, int is_USB) 01898 { 01899 char *vendor, *product, *version; 01900 char *pp; 01901 int j, i = 0; 01902 SANE_Byte usb_model_id = 0; 01903 unsigned char inquiry_block[256]; 01904 01905 DBG (DBG_proc, "identify_scanner\n"); 01906 01907 pie_do_inquiry (dev, sfd, inquiry_block); /* get inquiry */ 01908 01909 if (get_inquiry_periph_devtype (inquiry_block) != IN_periph_devtype_scanner) 01910 { 01911 return 1; 01912 } /* no scanner */ 01913 01914 vendor = dup_inquiry_vendor ((char *) inquiry_block); 01915 product = dup_inquiry_product ((char *) inquiry_block); 01916 version = dup_inquiry_version ((char *) inquiry_block); 01917 01918 pp = &vendor[8]; 01919 vendor[8] = ' '; 01920 while (*pp == ' ') 01921 { 01922 *pp-- = '\0'; 01923 } 01924 01925 pp = &product[0x10]; 01926 product[0x10] = ' '; 01927 while (*pp == ' ') 01928 { 01929 *pp-- = '\0'; 01930 } 01931 01932 pp = &version[4]; 01933 01934 version[4] = ' '; 01935 while (*pp == ' ') 01936 { 01937 *pp-- = '\0'; 01938 } 01939 01940 DBG (DBG_info, "Found %s scanner %s version %s on device %s\n", vendor, 01941 product, version, dev->devicename); 01942 01943 while (strncmp ("END_OF_LIST", scanner_str[2 * i], 11) != 0) /* Now identify full supported scanners */ 01944 { 01945 if (!strncmp (vendor, scanner_str[2 * i], strlen (scanner_str[2 * i]))) 01946 { 01947 if (!strncmp 01948 (product, scanner_str[2 * i + 1], 01949 strlen (scanner_str[2 * i + 1]))) 01950 { 01951 /* different types of PIE USB scanners use the same USB id and inquiry name 01952 so we need to do some subtyping here */ 01953 if (is_USB) 01954 { 01955 for (j = 0; pie_usb_device_list[j].model != 0; j++) 01956 { 01957 usb_model_id = get_inquiry_model (inquiry_block); 01958 if (pie_usb_device_list[j].model->model_id == usb_model_id) 01959 dev->model = pie_usb_device_list[j].model; 01960 } 01961 if (dev->model == NULL) 01962 continue; 01963 } 01964 01965 DBG (DBG_info, "found supported scanner\n"); 01966 01967 if (dev->model == NULL) 01968 { 01969 dev->vendor = vendor; 01970 dev->product = product; 01971 } 01972 else 01973 { 01974 free (vendor); 01975 free (product); 01976 dev->vendor = dev->model->vendor; 01977 dev->product = dev->model->model; 01978 } 01979 dev->version = version; 01980 pie_get_inquiry_values (dev, inquiry_block); 01981 return 0; 01982 } 01983 } 01984 i++; 01985 } 01986 01987 /* A new USB model was recognized, we wish to know about it */ 01988 if (usb_model_id) 01989 { 01990 DBG (DBG_info, "You have a scanner which is recognized but not yet\n"); 01991 DBG (DBG_info, "supported by this backend. The model id is %d\n", usb_model_id); 01992 if (DBG_LEVEL == 197) 01993 { 01994 DBG (DBG_info, "You are now working at your own risk!!!\n"); 01995 dev->model = pie_usb_device_list[0].model; 01996 free (vendor); 01997 free (product); 01998 dev->vendor = dev->model->vendor; 01999 dev->product = dev->model->model; 02000 } 02001 else 02002 { 02003 DBG (DBG_info, "Please post this output at the sane-devel list.\n"); 02004 dev->vendor = vendor; 02005 dev->product = product; 02006 } 02007 dev->version = version; 02008 pie_get_inquiry_values (dev, inquiry_block); 02009 if (DBG_LEVEL == 197) 02010 return 0; 02011 } 02012 return 1; /* NO SUPPORTED SCANNER: short inquiry-block and unknown scanner */ 02013 } 02014 02015 02016 /* ------------------------------- GET SPEEDS ----------------------------- */ 02017 02018 static void 02019 pie_get_speeds (Pie_Device * dev) 02020 { 02021 int speeds = dev->inquiry_scan_capability & INQ_CAP_SPEEDS; 02022 02023 DBG (DBG_proc, "get_speeds\n"); 02024 02025 if (speeds == 3) 02026 { 02027 dev->speed_list[0] = strdup ("Normal"); 02028 dev->speed_list[1] = strdup ("Fine"); 02029 dev->speed_list[2] = strdup ("Pro"); 02030 dev->speed_list[3] = NULL; 02031 } 02032 else 02033 { 02034 int i; 02035 char buf[2]; 02036 02037 buf[1] = '\0'; 02038 02039 for (i = 0; i < speeds; i++) 02040 { 02041 buf[0] = '1' + i; 02042 dev->speed_list[i] = strdup (buf); 02043 } 02044 02045 dev->speed_list[i] = NULL; 02046 } 02047 } 02048 02049 /* ------------------------------- GET HALFTONES ----------------------------- */ 02050 02051 static void 02052 pie_get_halftones (Pie_Device * dev, int sfd) 02053 { 02054 int i; 02055 size_t size; 02056 SANE_Status status; 02057 unsigned char *data; 02058 unsigned char buffer[128]; 02059 02060 DBG (DBG_proc, "get_halftones\n"); 02061 02062 for (i = 0; i < dev->inquiry_halftones; i++) 02063 { 02064 size = 6; 02065 02066 set_write_length (swrite.cmd, size); 02067 02068 memcpy (buffer, swrite.cmd, swrite.size); 02069 02070 data = buffer + swrite.size; 02071 memset (data, 0, size); 02072 02073 set_command (data, READ_HALFTONE); 02074 set_data_length (data, 2); 02075 data[4] = i; 02076 02077 status = (*dev->scsi_cmd) (sfd, buffer, swrite.size + size, NULL, NULL); 02078 if (status) 02079 { 02080 DBG (DBG_error, 02081 "pie_get_halftones: write command returned status %s\n", 02082 sane_strstatus (status)); 02083 } 02084 else 02085 { 02086 /* now read the halftone data */ 02087 memset (buffer, '\0', sizeof buffer); /* clear buffer */ 02088 02089 size = 128; 02090 set_read_length (sread.cmd, size); 02091 02092 DBG (DBG_info, "doing read\n"); 02093 status = 02094 (*dev->scsi_cmd) (sfd, sread.cmd, sread.size, buffer, &size); 02095 if (status) 02096 { 02097 DBG (DBG_error, 02098 "pie_get_halftones: read command returned status %s\n", 02099 sane_strstatus (status)); 02100 } 02101 else 02102 { 02103 unsigned char *s; 02104 02105 s = buffer + 8 + buffer[6] * buffer[7]; 02106 02107 DBG (DBG_info, "halftone %d: %s\n", i, s); 02108 02109 dev->halftone_list[i] = strdup ((char *) s); 02110 } 02111 } 02112 } 02113 dev->halftone_list[i] = NULL; 02114 } 02115 02116 /* ------------------------------- GET CAL DATA ----------------------------- */ 02117 02118 static void 02119 pie_get_cal_info (Pie_Device * dev, int sfd) 02120 { 02121 size_t size; 02122 SANE_Status status; 02123 unsigned char *data; 02124 unsigned char buffer[280]; 02125 02126 DBG (DBG_proc, "get_cal_info\n"); 02127 02128 if (!(dev->inquiry_scan_capability & INQ_CAP_EXT_CAL)) 02129 return; 02130 02131 size = 6; 02132 02133 set_write_length (swrite.cmd, size); 02134 02135 memcpy (buffer, swrite.cmd, swrite.size); 02136 02137 data = buffer + swrite.size; 02138 memset (data, 0, size); 02139 02140 set_command (data, READ_CAL_INFO); 02141 02142 status = (*dev->scsi_cmd) (sfd, buffer, swrite.size + size, NULL, NULL); 02143 if (status) 02144 { 02145 DBG (DBG_error, "pie_get_cal_info: write command returned status %s\n", 02146 sane_strstatus (status)); 02147 } 02148 else 02149 { 02150 /* now read the cal data */ 02151 memset (buffer, '\0', sizeof buffer); /* clear buffer */ 02152 02153 size = 128; 02154 set_read_length (sread.cmd, size); 02155 02156 DBG (DBG_info, "doing read\n"); 02157 status = (*dev->scsi_cmd) (sfd, sread.cmd, sread.size, buffer, &size); 02158 if (status) 02159 { 02160 DBG (DBG_error, 02161 "pie_get_cal_info: read command returned status %s\n", 02162 sane_strstatus (status)); 02163 } 02164 else 02165 { 02166 int i; 02167 02168 dev->cal_info_count = buffer[4]; 02169 dev->cal_info = 02170 malloc (sizeof (struct Pie_cal_info) * dev->cal_info_count); 02171 02172 for (i = 0; i < dev->cal_info_count; i++) 02173 { 02174 dev->cal_info[i].cal_type = buffer[8 + i * buffer[5]]; 02175 dev->cal_info[i].send_bits = buffer[9 + i * buffer[5]]; 02176 dev->cal_info[i].receive_bits = buffer[10 + i * buffer[5]]; 02177 dev->cal_info[i].num_lines = buffer[11 + i * buffer[5]]; 02178 dev->cal_info[i].pixels_per_line = 02179 (buffer[13 + i * buffer[5]] << 8) + buffer[12 + 02180 i * buffer[5]]; 02181 02182 DBG (DBG_info2, "%02x %2d %2d %2d %d\n", 02183 dev->cal_info[i].cal_type, dev->cal_info[i].send_bits, 02184 dev->cal_info[i].receive_bits, dev->cal_info[i].num_lines, 02185 dev->cal_info[i].pixels_per_line); 02186 } 02187 } 02188 } 02189 } 02190 02191 02192 /* ----------------------------- PIE_USB_ATTACH_OPEN ----------------------------- */ 02205 static SANE_Status 02206 pie_usb_attach_open (SANE_String_Const devname, SANE_Int * dn) 02207 { 02208 SANE_Status status; 02209 SANE_Int vendor, product; 02210 SANE_Int model = 0; 02211 int i; 02212 02213 DBG (DBG_proc, "pie_usb_attach_open: opening `%s'\n", devname); 02214 status = sanei_usb_open (devname, dn); 02215 if (status != SANE_STATUS_GOOD) 02216 { 02217 DBG (DBG_error, "pie_usb_attach_open: sanei_usb_open failed\n"); 02218 return status; 02219 } 02220 DBG (DBG_info, "pie_usb_attach_open: USB device `%s' successfully opened\n", 02221 devname); 02222 02223 status = sanei_usb_get_vendor_product (*dn, &vendor, &product); 02224 if (status != SANE_STATUS_GOOD) 02225 { 02226 DBG (DBG_error, 02227 "pie_usb_attach_open: couldn't get vendor and product ids of device `%s': %s\n", 02228 devname, sane_strstatus (status)); 02229 return status; 02230 } 02231 02232 for (i = 0; pie_usb_device_list[i].model != 0; i++) 02233 { 02234 if (vendor == pie_usb_device_list[i].vendor && 02235 product == pie_usb_device_list[i].product) 02236 { 02237 model++; 02238 break; 02239 } 02240 } 02241 if (model == 0) 02242 { 02243 DBG (DBG_error, 02244 "pie_usb_attach_open: vendor 0x%04x product 0x%04x is not supported by this backend\n", 02245 vendor, product); 02246 status = SANE_STATUS_INVAL; 02247 } 02248 02249 return status; 02250 } 02251 02252 02253 /* ----------------------------- PIE_USB_TRY_ATTACH ----------------------------- */ 02262 static SANE_Status 02263 pie_usb_try_attach (const char *name) 02264 { 02265 sanei_usb_attach_matching_devices (name, pie_attach_one); 02266 return SANE_STATUS_GOOD; 02267 } 02268 02269 02270 /* ------------------------------- ATTACH SCANNER ----------------------------- */ 02271 02272 static SANE_Status 02273 pie_attach_scanner (const char *devicename, Pie_Device ** devp) 02274 { 02275 SANE_Status status; 02276 SANE_Int USB_model = 1; /* assume USB scanner */ 02277 Pie_Device *dev; 02278 int sfd; 02279 int bufsize; 02280 02281 DBG (DBG_sane_proc, "pie_attach_scanner: %s\n", devicename); 02282 02283 for (dev = first_dev; dev; dev = dev->next) 02284 { 02285 if (strcmp (dev->sane.name, devicename) == 0) 02286 { 02287 if (devp) 02288 { 02289 *devp = dev; 02290 } 02291 return SANE_STATUS_GOOD; 02292 } 02293 } 02294 02295 dev = malloc (sizeof (*dev)); 02296 if (!dev) 02297 { 02298 return SANE_STATUS_NO_MEM; 02299 } 02300 02301 status = pie_usb_attach_open (devicename, &sfd); /* try USB scanners first */ 02302 if (status != SANE_STATUS_GOOD) 02303 { 02304 USB_model = 0; /* if failed try SCSI */ 02305 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 02306 bufsize = 16384; /* 16KB */ 02307 02308 if (sanei_scsi_open_extended 02309 (devicename, &sfd, pie_sense_handler, dev, &bufsize) != 0) 02310 { 02311 DBG (DBG_error, "pie_attach_scanner: open failed\n"); 02312 free (dev); 02313 return SANE_STATUS_INVAL; 02314 } 02315 02316 if (bufsize < 4096) /* < 4KB */ 02317 { 02318 DBG (DBG_error, 02319 "pie_attach_scanner: sanei_scsi_open_extended returned too small scsi buffer (%d)\n", 02320 bufsize); 02321 sanei_scsi_close (sfd); 02322 free (dev); 02323 return SANE_STATUS_NO_MEM; 02324 } 02325 DBG (DBG_info, 02326 "pie_attach_scanner: sanei_scsi_open_extended returned scsi buffer size = %d\n", 02327 bufsize); 02328 #else 02329 bufsize = sanei_scsi_max_request_size; 02330 02331 if (sanei_scsi_open (devicename, &sfd, pie_sense_handler, dev) != 0) 02332 { 02333 DBG (DBG_error, "pie_attach_scanner: open failed\n"); 02334 free (dev); 02335 02336 return SANE_STATUS_INVAL; 02337 } 02338 #endif 02339 } 02340 02341 pie_init (dev, USB_model); /* preset values in structure dev */ 02342 02343 dev->devicename = strdup (devicename); 02344 02345 if (pie_identify_scanner (dev, sfd, USB_model) != 0) 02346 { 02347 DBG (DBG_error, "pie_attach_scanner: scanner-identification failed\n"); 02348 if (USB_model == 0) 02349 sanei_scsi_close (sfd); 02350 else 02351 sanei_usb_close (sfd); 02352 free (dev); 02353 return SANE_STATUS_INVAL; 02354 } 02355 02356 if (USB_model == 0) 02357 { 02358 pie_get_halftones (dev, sfd); 02359 pie_get_cal_info (dev, sfd); 02360 pie_get_speeds (dev); 02361 02362 dev->scan_mode_list[0] = COLOR_STR; 02363 dev->scan_mode_list[1] = GRAY_STR; 02364 dev->scan_mode_list[2] = LINEART_STR; 02365 dev->scan_mode_list[3] = HALFTONE_STR; 02366 dev->scan_mode_list[4] = 0; 02367 02368 dev->bpp_list[0] = 1; 02369 dev->bpp_list[1] = 8; 02370 dev->bpp_list[2] = 0; 02371 02372 dev->sane.type = "flatbed scanner"; 02373 02374 sanei_scsi_close (sfd); 02375 } 02376 else 02377 { 02378 dev->scan_mode_list[0] = COLOR_STR; 02379 dev->scan_mode_list[1] = COLOR_IR_STR; 02380 dev->scan_mode_list[2] = 0; 02381 02382 dev->sane.type = "film scanner"; 02383 02384 dev->bpp_list[0] = 2; 02385 dev->bpp_list[1] = 16; 02386 dev->bpp_list[2] = 8; 02387 dev->bpp_list[3] = 0; 02388 02389 sanei_usb_close (sfd); 02390 } 02391 02392 dev->ir_sw_list[0] = THE_NONE_STR; 02393 dev->ir_sw_list[1] = IR_SPECT_STR; 02394 dev->ir_sw_list[2] = IR_CLEAN_STR; 02395 dev->ir_sw_list[3] = 0; 02396 02397 dev->grain_sw_list[0] = 4; 02398 dev->grain_sw_list[1] = 0; 02399 dev->grain_sw_list[2] = 1; 02400 dev->grain_sw_list[3] = 2; 02401 dev->grain_sw_list[4] = 3; 02402 dev->grain_sw_list[5] = 0; 02403 02404 dev->crop_sw_list[0] = THE_NONE_STR; 02405 dev->crop_sw_list[1] = CROP_OUTER_STR; 02406 dev->crop_sw_list[2] = CROP_INNER_STR; 02407 dev->crop_sw_list[3] = 0; 02408 02409 dev->sane.name = dev->devicename; 02410 dev->sane.vendor = dev->vendor; 02411 dev->sane.model = dev->product; 02412 02413 dev->x_range.min = SANE_FIX (0); 02414 dev->x_range.quant = SANE_FIX (0); 02415 dev->x_range.max = SANE_FIX (dev->inquiry_fb_width * MM_PER_INCH); 02416 02417 dev->y_range.min = SANE_FIX (0); 02418 dev->y_range.quant = SANE_FIX (0); 02419 dev->y_range.max = SANE_FIX (dev->inquiry_fb_length * MM_PER_INCH); 02420 02421 dev->dpi_range.min = SANE_FIX (25); 02422 dev->dpi_range.quant = SANE_FIX (1); 02423 dev->dpi_range.max = 02424 SANE_FIX (max (dev->inquiry_x_res, dev->inquiry_y_res)); 02425 02426 dev->shadow_range.min = SANE_FIX (0); 02427 dev->shadow_range.quant = SANE_FIX (1); 02428 dev->shadow_range.max = SANE_FIX (dev->inquiry_max_shadow); 02429 02430 dev->highlight_range.min = SANE_FIX (dev->inquiry_min_highlight); 02431 dev->highlight_range.quant = SANE_FIX (1); 02432 dev->highlight_range.max = SANE_FIX (100); 02433 02434 dev->exposure_range.min = SANE_FIX (dev->inquiry_min_exp); 02435 dev->exposure_range.quant = SANE_FIX (1); 02436 dev->exposure_range.max = SANE_FIX (dev->inquiry_max_exp); 02437 02438 #if 0 02439 dev->analog_gamma_range.min = SANE_FIX (1.0); 02440 dev->analog_gamma_range.quant = SANE_FIX (0.01); 02441 dev->analog_gamma_range.max = SANE_FIX (2.0); 02442 02443 #endif 02444 02445 dev->next = first_dev; 02446 first_dev = dev; 02447 02448 if (devp) 02449 { 02450 *devp = dev; 02451 } 02452 02453 return SANE_STATUS_GOOD; 02454 } 02455 02456 /* --------------------------- MAX STRING SIZE ---------------------------- */ 02457 02458 02459 static size_t 02460 max_string_size (SANE_String_Const strings[]) 02461 { 02462 size_t size, max_size = 0; 02463 int i; 02464 02465 for (i = 0; strings[i]; ++i) 02466 { 02467 size = strlen (strings[i]) + 1; 02468 if (size > max_size) 02469 { 02470 max_size = size; 02471 } 02472 } 02473 02474 return max_size; 02475 } 02476 02477 02478 /* --------------------------- INIT OPTIONS ------------------------------- */ 02479 02480 02481 static SANE_Status 02482 pie_init_options (Pie_Scanner * scanner) 02483 { 02484 int i; 02485 02486 DBG (DBG_sane_proc, "pie_init_options\n"); 02487 02488 memset (scanner->opt, 0, sizeof (scanner->opt)); 02489 memset (scanner->val, 0, sizeof (scanner->val)); 02490 02491 for (i = 0; i < NUM_OPTIONS; ++i) 02492 { 02493 scanner->opt[i].size = sizeof (SANE_Word); 02494 scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 02495 } 02496 02497 scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 02498 scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 02499 scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 02500 scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 02501 scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 02502 02503 /* "Mode" group: */ 02504 scanner->opt[OPT_MODE_GROUP].title = "Scan Mode"; 02505 scanner->opt[OPT_MODE_GROUP].desc = ""; 02506 scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 02507 scanner->opt[OPT_MODE_GROUP].cap = 0; 02508 scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 02509 02510 /* scan mode */ 02511 scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 02512 scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 02513 scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 02514 scanner->opt[OPT_MODE].type = SANE_TYPE_STRING; 02515 scanner->opt[OPT_MODE].size = 02516 max_string_size ((SANE_String_Const *)(void*) scanner->device->scan_mode_list); 02517 scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 02518 scanner->opt[OPT_MODE].constraint.string_list = 02519 (SANE_String_Const *)(void*) scanner->device->scan_mode_list; 02520 scanner->val[OPT_MODE].s = 02521 (SANE_Char *) strdup (scanner->device->scan_mode_list[1]); 02522 02523 /* bit depth */ 02524 scanner->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH; 02525 scanner->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH; 02526 scanner->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH; 02527 scanner->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT; 02528 scanner->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; 02529 scanner->opt[OPT_BIT_DEPTH].size = sizeof (SANE_Word); 02530 scanner->opt[OPT_BIT_DEPTH].constraint.word_list = 02531 scanner->device->bpp_list; 02532 scanner->val[OPT_BIT_DEPTH].w = scanner->device->bpp_list[1]; 02533 if (scanner->opt[OPT_BIT_DEPTH].constraint.word_list[0] < 2) 02534 scanner->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE; 02535 02536 /* x-resolution */ 02537 scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 02538 scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; 02539 scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 02540 scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED; 02541 scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 02542 scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 02543 scanner->opt[OPT_RESOLUTION].constraint.range = &scanner->device->dpi_range; 02544 scanner->val[OPT_RESOLUTION].w = 1200 << SANE_FIXED_SCALE_SHIFT; 02545 02546 /* "Geometry" group: */ 02547 02548 scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 02549 scanner->opt[OPT_GEOMETRY_GROUP].desc = ""; 02550 scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 02551 scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 02552 scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 02553 02554 /* top-left x */ 02555 scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 02556 scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 02557 scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 02558 scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 02559 scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM; 02560 scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 02561 scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range); 02562 scanner->val[OPT_TL_X].w = 0; 02563 02564 /* top-left y */ 02565 scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 02566 scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 02567 scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 02568 scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 02569 scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 02570 scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 02571 scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range); 02572 scanner->val[OPT_TL_Y].w = 0; 02573 02574 /* bottom-right x */ 02575 scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 02576 scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 02577 scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 02578 scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 02579 scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM; 02580 scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 02581 scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range); 02582 scanner->val[OPT_BR_X].w = scanner->device->x_range.max; 02583 02584 /* bottom-right y */ 02585 scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 02586 scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 02587 scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 02588 scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 02589 scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 02590 scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 02591 scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range); 02592 scanner->val[OPT_BR_Y].w = scanner->device->y_range.max; 02593 02594 /* "enhancement" group: */ 02595 02596 scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 02597 scanner->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 02598 scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 02599 scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 02600 scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 02601 02602 /* reduce spectal overlap from infrared plane */ 02603 scanner->opt[OPT_SW_IRED].name = IR_NAME_STR; 02604 scanner->opt[OPT_SW_IRED].title = IR_TITLE_STR; 02605 scanner->opt[OPT_SW_IRED].desc = IR_DESC_STR; 02606 scanner->opt[OPT_SW_IRED].type = SANE_TYPE_STRING; 02607 scanner->opt[OPT_SW_IRED].size = 02608 max_string_size ((SANE_String_Const *)(void*) scanner->device->ir_sw_list); 02609 scanner->opt[OPT_SW_IRED].constraint_type = SANE_CONSTRAINT_STRING_LIST; 02610 scanner->opt[OPT_SW_IRED].constraint.string_list = 02611 (SANE_String_Const *)(void*) scanner->device->ir_sw_list; 02612 scanner->val[OPT_SW_IRED].s = 02613 (SANE_Char *) strdup (scanner->device->ir_sw_list[2]); 02614 02615 /* strength of grain filtering */ 02616 scanner->opt[OPT_SW_GRAIN].name = "swgrain"; 02617 scanner->opt[OPT_SW_GRAIN].title = "Attenuate film grain"; 02618 scanner->opt[OPT_SW_GRAIN].desc = "Amount of smothening"; 02619 scanner->opt[OPT_SW_GRAIN].type = SANE_TYPE_INT; 02620 scanner->opt[OPT_SW_GRAIN].constraint_type = SANE_CONSTRAINT_WORD_LIST; 02621 scanner->opt[OPT_SW_GRAIN].size = sizeof (SANE_Word); 02622 scanner->opt[OPT_SW_GRAIN].constraint.word_list = 02623 scanner->device->grain_sw_list; 02624 scanner->val[OPT_SW_GRAIN].w = scanner->device->grain_sw_list[1]; 02625 if (scanner->opt[OPT_SW_GRAIN].constraint.word_list[0] < 2) 02626 scanner->opt[OPT_SW_GRAIN].cap |= SANE_CAP_INACTIVE; 02627 02628 /* gamma correction, to make image sRGB like */ 02629 scanner->opt[OPT_SW_SRGB].name = "swsrgb"; 02630 scanner->opt[OPT_SW_SRGB].title = "sRGB colors"; 02631 scanner->opt[OPT_SW_SRGB].desc = "Transform image to approximate sRGB color space"; 02632 scanner->opt[OPT_SW_SRGB].type = SANE_TYPE_BOOL; 02633 scanner->opt[OPT_SW_SRGB].unit = SANE_UNIT_NONE; 02634 scanner->val[OPT_SW_SRGB].w = SANE_TRUE; 02635 02636 /* color correction for generic negative film */ 02637 scanner->opt[OPT_SW_NEGA].name = "swnega"; 02638 scanner->opt[OPT_SW_NEGA].title = "Invert colors"; 02639 scanner->opt[OPT_SW_NEGA].desc = "Correct for generic negative film"; 02640 scanner->opt[OPT_SW_NEGA].type = SANE_TYPE_BOOL; 02641 scanner->opt[OPT_SW_NEGA].unit = SANE_UNIT_NONE; 02642 02643 /* crop image */ 02644 scanner->opt[OPT_SW_CROP].name = CROP_NAME_STR; 02645 scanner->opt[OPT_SW_CROP].title = CROP_TITLE_STR; 02646 scanner->opt[OPT_SW_CROP].desc = CROP_DESC_STR; 02647 scanner->opt[OPT_SW_CROP].type = SANE_TYPE_STRING; 02648 scanner->opt[OPT_SW_CROP].size = 02649 max_string_size ((SANE_String_Const *)(void*) scanner->device->crop_sw_list); 02650 scanner->opt[OPT_SW_CROP].constraint_type = SANE_CONSTRAINT_STRING_LIST; 02651 scanner->opt[OPT_SW_CROP].constraint.string_list = 02652 (SANE_String_Const *)(void*) scanner->device->crop_sw_list; 02653 scanner->val[OPT_SW_CROP].s = 02654 (SANE_Char *) strdup (scanner->device->crop_sw_list[2]); 02655 02656 /* grayscale gamma vector */ 02657 scanner->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR; 02658 scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR; 02659 scanner->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR; 02660 scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT; 02661 scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE; 02662 scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE; 02663 scanner->val[OPT_GAMMA_VECTOR].wa = scanner->gamma_table[0]; 02664 scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &scanner->gamma_range; 02665 scanner->opt[OPT_GAMMA_VECTOR].size = 02666 scanner->gamma_length * sizeof (SANE_Word); 02667 scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 02668 02669 /* red gamma vector */ 02670 scanner->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R; 02671 scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R; 02672 scanner->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R; 02673 scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT; 02674 scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE; 02675 scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE; 02676 scanner->val[OPT_GAMMA_VECTOR_R].wa = scanner->gamma_table[1]; 02677 scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range); 02678 scanner->opt[OPT_GAMMA_VECTOR_R].size = 02679 scanner->gamma_length * sizeof (SANE_Word); 02680 02681 /* green gamma vector */ 02682 scanner->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G; 02683 scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G; 02684 scanner->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G; 02685 scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT; 02686 scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE; 02687 scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE; 02688 scanner->val[OPT_GAMMA_VECTOR_G].wa = scanner->gamma_table[2]; 02689 scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range); 02690 scanner->opt[OPT_GAMMA_VECTOR_G].size = 02691 scanner->gamma_length * sizeof (SANE_Word); 02692 02693 02694 /* blue gamma vector */ 02695 scanner->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B; 02696 scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B; 02697 scanner->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B; 02698 scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT; 02699 scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE; 02700 scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE; 02701 scanner->val[OPT_GAMMA_VECTOR_B].wa = scanner->gamma_table[3]; 02702 scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range); 02703 scanner->opt[OPT_GAMMA_VECTOR_B].size = 02704 scanner->gamma_length * sizeof (SANE_Word); 02705 02706 if (scanner->device->model != NULL) 02707 { 02708 scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 02709 scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 02710 scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 02711 scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 02712 } 02713 else 02714 { 02715 scanner->opt[OPT_SW_SRGB].cap |= SANE_CAP_INACTIVE; 02716 scanner->opt[OPT_SW_NEGA].cap |= SANE_CAP_INACTIVE; 02717 scanner->opt[OPT_SW_IRED].cap |= SANE_CAP_INACTIVE; 02718 scanner->opt[OPT_SW_CROP].cap |= SANE_CAP_INACTIVE; 02719 scanner->opt[OPT_SW_GRAIN].cap |= SANE_CAP_INACTIVE; 02720 } 02721 02722 /* halftone pattern */ 02723 scanner->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN; 02724 scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN; 02725 scanner->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN; 02726 scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING; 02727 scanner->opt[OPT_HALFTONE_PATTERN].size = 02728 max_string_size ((SANE_String_Const *)(void*) scanner->device->halftone_list); 02729 scanner->opt[OPT_HALFTONE_PATTERN].constraint_type = 02730 SANE_CONSTRAINT_STRING_LIST; 02731 scanner->opt[OPT_HALFTONE_PATTERN].constraint.string_list = 02732 (SANE_String_Const *)(void*) scanner->device->halftone_list; 02733 scanner->val[OPT_HALFTONE_PATTERN].s = 02734 (SANE_Char *) strdup (scanner->device->halftone_list[0]); 02735 scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; 02736 02737 /* speed */ 02738 scanner->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED; 02739 scanner->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED; 02740 scanner->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED; 02741 scanner->opt[OPT_SPEED].type = SANE_TYPE_STRING; 02742 scanner->opt[OPT_SPEED].size = 02743 max_string_size ((SANE_String_Const *)(void*) scanner->device->speed_list); 02744 scanner->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST; 02745 scanner->opt[OPT_SPEED].constraint.string_list = 02746 (SANE_String_Const *)(void*) scanner->device->speed_list; 02747 scanner->val[OPT_SPEED].s = 02748 (SANE_Char *) strdup (scanner->device->speed_list[1]); 02749 02750 /* lineart threshold */ 02751 scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 02752 scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 02753 scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 02754 scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED; 02755 scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT; 02756 scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 02757 scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100; 02758 scanner->val[OPT_THRESHOLD].w = SANE_FIX (50); 02759 scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 02760 02761 /* "advanced" group: */ 02762 02763 scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced"; 02764 scanner->opt[OPT_ADVANCED_GROUP].desc = ""; 02765 scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP; 02766 scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED; 02767 scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 02768 02769 /* preview */ 02770 scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; 02771 scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; 02772 scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; 02773 scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; 02774 scanner->val[OPT_PREVIEW].w = SANE_FALSE; 02775 02776 02777 02778 return SANE_STATUS_GOOD; 02779 } 02780 02781 /* 02782 * @@ Mid level USB functions 02783 */ 02784 02785 /* ---------------------------- PIE_USB_WAIT_SCANNER ----------------------------- */ 02799 static SANE_Status 02800 pie_usb_wait_scanner (Pie_Scanner * scanner, int secs) 02801 { 02802 SANE_Status status; 02803 int cnt = secs * 16; 02804 02805 DBG (DBG_proc, "pie_usb_wait_scanner\n"); 02806 02807 do 02808 { 02809 status = pie_usb_scsi_wrapper (scanner->sfd, test_unit_ready.cmd, 02810 test_unit_ready.size, NULL, NULL); 02811 if (status == SANE_STATUS_GOOD) 02812 return status; 02813 if (cnt == 0) 02814 { 02815 DBG (DBG_warning, "pie_usb_wait_scanner timed out\n"); 02816 return status; 02817 } 02818 usleep (62500); 02819 cnt--; 02820 02821 } 02822 while (status == SANE_STATUS_DEVICE_BUSY); 02823 02824 DBG (DBG_error, 02825 "pie_usb_wait_scanner failed: %s\n", sane_strstatus (status)); 02826 return status; 02827 } 02828 02829 02830 /* -------------------------- PIE_USB_RELEASE_SCANNER ---------------------------- */ 02851 static int 02852 pie_usb_release_scanner (void * passed) 02853 { 02854 unsigned char buffer[16]; 02855 unsigned char *data; 02856 SANE_Status status; 02857 size_t size = release_scanC[4]; 02858 Pie_Scanner * scanner; 02859 int cnt = 0; 02860 02861 DBG (DBG_proc, "pie_usb_release_scanner\n"); 02862 02863 scanner = (Pie_Scanner *) passed; 02864 02865 /* wait upto 15 secs */ 02866 status = pie_usb_wait_scanner (scanner, 15); 02867 if (status != SANE_STATUS_GOOD) 02868 return status; 02869 02870 /* prepare to issue vendor specific 0xd2 command */ 02871 memcpy (buffer, release_scanC, sizeof (release_scanC)); 02872 data = buffer + sizeof (release_scanC); 02873 memset (data, 0, size); 02874 data[0] = 2; 02875 size += sizeof (release_scanC); 02876 02877 /* try command for maximally 20 * 0.5 = 10 sec */ 02878 do 02879 { 02880 status = pie_usb_scsi_wrapper (scanner->sfd, buffer, size, NULL, NULL); 02881 02882 if (status != SANE_STATUS_DEVICE_BUSY) 02883 break; 02884 02885 if (cnt == 1) 02886 DBG (DBG_info2, 02887 "pie_usb_release_scanner: scanner reports %s, waiting ...\n", 02888 sane_strstatus (status)); 02889 02890 usleep (TUR_WAIT_TIME); 02891 cnt++; 02892 } 02893 while (cnt < 20); 02894 02895 if (status != SANE_STATUS_GOOD) 02896 return status; 02897 02898 pie_power_save (scanner, 15); 02899 02900 return status; 02901 } 02902 02903 /* ---------------------- PIE_USB_IS_SCANNER_RELEASED ------------------------- */ 02913 static SANE_Status 02914 pie_usb_is_scanner_released (Pie_Scanner * scanner) 02915 { 02916 SANE_Status status = SANE_STATUS_DEVICE_BUSY; 02917 int cnt = 0; 02918 02919 DBG (DBG_proc, "pie_usb_is_scanner_released: pid %d\n", 02920 (int) scanner->parking_pid); 02921 02922 if (scanner->parking_pid == NO_PID) 02923 return SANE_STATUS_GOOD; 02924 else 02925 do 02926 { 02927 status = sanei_thread_get_status (scanner->parking_pid); 02928 if (status == SANE_STATUS_GOOD) 02929 break; 02930 02931 if (cnt == 1) 02932 DBG (DBG_info2, "pie_usb_is_scanner_released: waiting ...\n"); 02933 02934 cnt++; 02935 usleep (TUR_WAIT_TIME); 02936 } 02937 while (cnt < 20); 02938 02939 if (status == SANE_STATUS_GOOD) 02940 { 02941 scanner->parking_pid = NO_PID; 02942 DBG (DBG_proc, "pie_usb_is_scanner_released: success\n"); 02943 return status; 02944 } 02945 else 02946 return SANE_STATUS_IO_ERROR; 02947 } 02948 02949 02950 /* --------------------- PIE_USB_IS_SCANNER_INITIALZED ----------------------- */ 02968 static SANE_Status 02969 pie_usb_is_scanner_initialized (int dn) 02970 { 02971 unsigned char buffer[16]; 02972 SANE_Status status, state; 02973 uint32_t sense_kascq; 02974 int wait_cnt = 240; /* 240 * 0.5 = 120 seconds */ 02975 DBG (DBG_proc, "pie_usb_is_scanner_initialized\n"); 02976 do 02977 { 02978 status = 02979 pie_usb_scsi_wrapper (dn, test_unit_ready.cmd, 02980 test_unit_ready.size, NULL, NULL); 02981 if (status == SANE_STATUS_IO_ERROR) /* Not Ready - Warming Up ? */ 02982 { 02983 state = pie_usb_request_sense (dn, &sense_kascq); 02984 if (state != SANE_STATUS_GOOD) 02985 return state; 02986 if (sense_kascq != 0x020401) 02987 return status; 02988 else 02989 status = SANE_STATUS_DEVICE_BUSY; 02990 } 02991 02992 if (status == SANE_STATUS_DEVICE_BUSY) 02993 { 02994 usleep (TUR_WAIT_TIME); 02995 wait_cnt--; 02996 } 02997 02998 memset (buffer, 0, 11); 02999 status = pie_usb_read_status (dn, buffer); 03000 if (status == SANE_STATUS_IO_ERROR) /* Not Ready - Warming Up ? */ 03001 { 03002 state = pie_usb_request_sense (dn, &sense_kascq); 03003 if (state != SANE_STATUS_GOOD) 03004 return state; 03005 if (sense_kascq != 0x020401) 03006 return status; 03007 else 03008 status = SANE_STATUS_DEVICE_BUSY; 03009 } 03010 03011 if (status == SANE_STATUS_GOOD) 03012 { 03013 DBG_DUMP (DBG_info, buffer, 11); 03014 /* if ((buffer[5] != 0) || (buffer[9] != 0) || (buffer[10] != 0))*/ 03015 if (buffer[5] != 0) 03016 status = SANE_STATUS_DEVICE_BUSY; 03017 } 03018 03019 if (status == SANE_STATUS_DEVICE_BUSY) 03020 { 03021 usleep (TUR_WAIT_TIME); 03022 wait_cnt--; 03023 } 03024 } 03025 while ((status == SANE_STATUS_DEVICE_BUSY) && (wait_cnt > 0)); 03026 return status; 03027 } 03028 03029 03030 /* -------------------------- PIE_USB_COPY_SENSORS ---------------------------- */ 03049 static SANE_Status 03050 pie_usb_copy_sensors (Pie_Scanner * scanner) 03051 { 03052 size_t size_read; 03053 int cnt = 0; 03054 SANE_Status status; 03055 03056 DBG (DBG_proc, "pie_usb_copy_sensors\n"); 03057 03058 do 03059 { 03060 size_read = scanner->device->cal_info[0].pixels_per_line; 03061 status = 03062 pie_usb_scsi_wrapper (scanner->sfd, pie_copyC, sizeof (pie_copyC), 03063 scanner->cal_data->sensors, &size_read); 03064 if (status == SANE_STATUS_GOOD) 03065 return status; 03066 03067 if (cnt == 1) 03068 DBG (DBG_info2, 03069 "pie_usb_copy_sensors: scanner reports %s, waiting ...\n", 03070 sane_strstatus (status)); 03071 03072 usleep (TUR_WAIT_TIME); 03073 cnt++; 03074 } 03075 while (cnt < 10); /* maximally 10 * 0.5 = 5 sec */ 03076 03077 return status; 03078 } 03079 03080 /* ------------------------------ PIE_USB_SCAN -------------------------------- */ 03097 static SANE_Status 03098 pie_usb_scan (Pie_Scanner * scanner, int start) 03099 { 03100 SANE_Status status, state; 03101 uint32_t sense_kascq; 03102 03103 DBG (DBG_proc, "pie_usb_scan: %d\n", start); 03104 03105 set_scan_cmd (scan.cmd, start); 03106 if (start) 03107 { 03108 /* wait upto X seconds until returned to start position */ 03109 status = pie_usb_wait_scanner (scanner, 15); 03110 if (status != SANE_STATUS_GOOD) 03111 return status; 03112 do 03113 { 03114 status = 03115 pie_usb_scsi_wrapper (scanner->sfd, scan.cmd, scan.size, 03116 NULL, NULL); 03117 if (status) 03118 { 03119 DBG (DBG_error, "pie_usb_scan: received %s\n", 03120 sane_strstatus (status)); 03121 if (status == SANE_STATUS_IO_ERROR) 03122 { 03123 state = pie_usb_request_sense (scanner->sfd, &sense_kascq); 03124 if (state != SANE_STATUS_GOOD) 03125 return state; 03126 if (sense_kascq == 0x020401) /* Not Ready - Warming Up */ 03127 status = SANE_STATUS_DEVICE_BUSY; 03128 else if (sense_kascq == 0x068200) /* calibration disable not granted */ 03129 status = SANE_STATUS_GOOD; 03130 } 03131 if (status == SANE_STATUS_DEVICE_BUSY) 03132 usleep (SCAN_WARMUP_WAIT_TIME); 03133 } 03134 } 03135 while (status == SANE_STATUS_DEVICE_BUSY); 03136 return status; 03137 } 03138 else 03139 { 03140 status = 03141 pie_usb_scsi_wrapper (scanner->sfd, scan.cmd, scan.size, NULL, NULL); 03142 if (status == SANE_STATUS_IO_ERROR) 03143 { 03144 state = pie_usb_request_sense (scanner->sfd, &sense_kascq); 03145 if (state != SANE_STATUS_GOOD) 03146 return state; 03147 if (sense_kascq != 0x0b0006) /* ABORT message from initiator */ 03148 return status; 03149 } 03150 return SANE_STATUS_GOOD; 03151 } 03152 } 03153 03154 03155 /*----------------------- PIE_USB_SET_WINDOW --------------------------- */ 03169 static SANE_Status 03170 pie_usb_set_window (Pie_Scanner * scanner) 03171 { 03172 unsigned char buffer[128]; 03173 size_t size; 03174 SANE_Status status; 03175 unsigned char *data; 03176 double x, dpmm; 03177 03178 DBG (DBG_proc, "pie_usb_set_window\n"); 03179 03180 size = 14; 03181 set_write_length (swrite.cmd, size); 03182 memcpy (buffer, swrite.cmd, swrite.size); 03183 data = buffer + swrite.size; 03184 memset (data, 0, size); 03185 set_command (data, SET_SCAN_FRAME); 03186 set_data_length (data, size - 4); 03187 03188 data[4] = 0x80; 03189 03190 dpmm = (double) scanner->device->inquiry_pixel_resolution / MM_PER_INCH; 03191 03192 if (scanner->device->model->flags & PIE_USB_FLAG_MIRROR_IMAGE) 03193 { 03194 x = 03195 SANE_UNFIX (scanner->device->x_range.max - 03196 scanner->val[OPT_BR_X].w) * dpmm; 03197 set_data (data, 6, (int) x, 2); 03198 DBG (DBG_info, "TL_X: %d\n", (int) x); 03199 03200 x = 03201 SANE_UNFIX (scanner->device->x_range.max - 03202 scanner->val[OPT_TL_X].w) * dpmm; 03203 set_data (data, 10, (int) x, 2); 03204 DBG (DBG_info, "BR_X: %d\n", (int) x); 03205 } 03206 else 03207 { 03208 x = SANE_UNFIX (scanner->val[OPT_TL_X].w) * dpmm; 03209 set_data (data, 6, (int) x, 2); 03210 DBG (DBG_info, "TL_X: %d\n", (int) x); 03211 03212 x = SANE_UNFIX (scanner->val[OPT_BR_X].w) * dpmm; 03213 set_data (data, 10, (int) x, 2); 03214 DBG (DBG_info, "BR_X: %d\n", (int) x); 03215 } 03216 x = SANE_UNFIX (scanner->val[OPT_TL_Y].w) * dpmm; 03217 set_data (data, 8, (int) x, 2); 03218 DBG (DBG_info, "TL_Y: %d\n", (int) x); 03219 03220 x = SANE_UNFIX (scanner->val[OPT_BR_Y].w) * dpmm; 03221 set_data (data, 12, (int) x, 2); 03222 DBG (DBG_info, "BR_Y: %d\n", (int) x); 03223 03224 status = 03225 pie_usb_scsi_wrapper (scanner->sfd, buffer, swrite.size + size, NULL, 03226 NULL); 03227 if (status) 03228 { 03229 DBG (DBG_error, 03230 "pie_usb_set_window: write command returned status %s\n", 03231 sane_strstatus (status)); 03232 } 03233 03234 return status; 03235 } 03236 03237 03238 /*-------------------------- PIE_USB_MODE_SELECT ------------------------------- */ 03255 static SANE_Status 03256 pie_usb_mode_select (Pie_Scanner * scanner) 03257 { 03258 PIE_USB_Model *model = scanner->device->model; 03259 SANE_Status status; 03260 unsigned char buffer[128]; 03261 size_t size; 03262 unsigned char *data; 03263 int i, cal; 03264 03265 DBG (DBG_proc, "pie_usb_mode_select\n"); 03266 03267 size = 16; 03268 set_mode_length (smode.cmd, size); 03269 memcpy (buffer, smode.cmd, smode.size); 03270 data = buffer + smode.size; 03271 memset (data, 0, size); 03272 /* size of data */ 03273 data[1] = size - 2; 03274 /* set resolution required */ 03275 set_data (data, 2, scanner->resolution, 2); 03276 /* set color filter and color depth */ 03277 data[4] = 0; 03278 scanner->cal_filter = 0; 03279 switch (scanner->colormode) 03280 { 03281 case RGBI: 03282 data[4] = INQ_FILTER_IRED; 03283 scanner->cal_filter = INQ_FILTER_IRED; /* fall through */ 03284 case RGB: 03285 if (scanner->device->inquiry_filters & INQ_ONE_PASS_COLOR) 03286 { 03287 data[4] |= INQ_ONE_PASS_COLOR; 03288 scanner->cal_filter |= FILTER_RED | FILTER_GREEN | FILTER_BLUE; 03289 } 03290 else 03291 { 03292 DBG (DBG_error, 03293 "pie_usb_mode_select: support for multipass color not yet implemented\n"); 03294 return SANE_STATUS_UNSUPPORTED; 03295 } 03296 if (scanner->val[OPT_BIT_DEPTH].w == 16) 03297 data[5] = INQ_COLOR_DEPTH_16; 03298 else 03299 data[5] = INQ_COLOR_DEPTH_8; 03300 break; 03301 default: 03302 DBG (DBG_error, "pie_usb_mode_select: wrong colour format!\n"); 03303 return SANE_STATUS_UNSUPPORTED; 03304 } 03305 03306 /* choose color packing method */ 03307 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 03308 data[6] = INQ_COLOR_FORMAT_INDEX; 03309 #if 0 03310 /* possible TODO: The scanner can do INQ_COLOR_FORMAT_LINE but our 03311 * reader routine for it has been neglected */ 03312 else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE) 03313 data[6] = INQ_COLOR_FORMAT_LINE; 03314 #endif 03315 else 03316 { 03317 DBG (DBG_error, 03318 "pie_usb_mode_select: support for pixel packing not yet implemented\n"); 03319 return SANE_STATUS_UNSUPPORTED; 03320 } 03321 03322 /* choose data format */ 03323 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_INTEL) 03324 data[8] = INQ_IMG_FMT_INTEL; 03325 else 03326 { 03327 DBG (DBG_error, 03328 "pie_usb_mode_select: support for Motorola format not yet implemented\n"); 03329 return SANE_STATUS_UNSUPPORTED; 03330 } 03331 03332 /* set required calibration and quality */ 03333 i = 0; 03334 while (scanner->device->speed_list[i] != NULL) 03335 { 03336 if (strcmp 03337 (scanner->device->speed_list[i], scanner->val[OPT_SPEED].s) == 0) 03338 break; 03339 i++; 03340 } 03341 03342 if (scanner->device->speed_list[i] == NULL) 03343 i = 0; /* neither should happen */ 03344 if (i > 2) 03345 i = 2; 03346 cal = i; 03347 if (cal == 1) 03348 { 03349 if (scanner->val[OPT_PREVIEW].w == SANE_TRUE) 03350 cal = model->op_mode[OPM_PREVIEW]; /*CAL_MODE_FILM_NORMAL; */ 03351 else 03352 cal = model->op_mode[OPM_QUALITY]; /*CAL_MODE_FILM_HIQUAL; */ 03353 } 03354 /* skip calibration if no quality in this or last scan */ 03355 if ((cal != model->op_mode[OPM_QUALITY]) && 03356 (scanner->cal_mode != model->op_mode[OPM_QUALITY])) 03357 cal = model->op_mode[OPM_SKIPCAL]; 03358 data[9] = cal; 03359 scanner->cal_mode = cal; 03360 03361 /* unsupported for USB film scanners: halftone, threshold */ 03362 /* 12: halftone pattern 0 */ 03363 data[13] = 0x80; /* lineart threshold */ 03364 data[14] = 0x10; /* ?? */ 03365 03366 DBG (DBG_info, "pie_usb_mode_select: speed %02x\n", data[9]); 03367 DBG (DBG_info, "pie_usb_mode_select sending:\n"); 03368 DBG_DUMP (DBG_info, data, size); 03369 status = 03370 pie_usb_scsi_wrapper (scanner->sfd, buffer, smode.size + size, 03371 NULL, NULL); 03372 if (status) 03373 { 03374 DBG (DBG_error, 03375 "pie_usb_mode_select: write command returned status %s\n", 03376 sane_strstatus (status)); 03377 } 03378 03379 return status; 03380 } 03381 03382 03383 /* ------------------------------------ PIE_USB_GET_PARAMS ------------------------ */ 03400 static SANE_Status 03401 pie_usb_get_params (Pie_Scanner * scanner) 03402 { 03403 unsigned char buffer[128]; 03404 SANE_Status status; 03405 size_t size = 18; 03406 03407 DBG (DBG_proc, "pie_usb_get_params\n"); 03408 03409 status = pie_usb_wait_scanner (scanner, 5); 03410 if (status) 03411 return status; 03412 03413 set_param_length (param.cmd, size); 03414 03415 status = 03416 pie_usb_scsi_wrapper (scanner->sfd, param.cmd, param.size, buffer, &size); 03417 if (status) 03418 { 03419 DBG (DBG_error, "pie_usb_get_params: command returned status %s\n", 03420 sane_strstatus (status)); 03421 } 03422 else 03423 { 03424 DBG (DBG_info, "Scan Width: %d\n", get_param_scan_width (buffer)); 03425 DBG (DBG_info, "Scan Lines: %d\n", get_param_scan_lines (buffer)); 03426 DBG (DBG_info, "Scan bytes: %d\n", get_param_scan_bytes (buffer)); 03427 03428 DBG (DBG_info, "Offset 1: %d\n", 03429 get_param_scan_filter_offset1 (buffer)); 03430 DBG (DBG_info, "Offset 2: %d\n", 03431 get_param_scan_filter_offset2 (buffer)); 03432 DBG (DBG_info, "Scan period: %d\n", get_param_scan_period (buffer)); 03433 DBG (DBG_info, "Xfer rate: %d\n", get_param_scsi_xfer_rate (buffer)); 03434 DBG (DBG_info, "Avail lines: %d\n", 03435 get_param_scan_available_lines (buffer)); 03436 03437 scanner->filter_offset1 = get_param_scan_filter_offset1 (buffer); 03438 scanner->filter_offset2 = get_param_scan_filter_offset2 (buffer); 03439 scanner->bytes_per_line = get_param_scan_bytes (buffer); 03440 03441 scanner->params.pixels_per_line = get_param_scan_width (buffer); 03442 scanner->params.lines = get_param_scan_lines (buffer); 03443 03444 if (scanner->colormode == RGBI) 03445 { 03446 #ifdef SANE_FRAME_RGBI 03447 scanner->params.format = SANE_FRAME_RGBI; 03448 scanner->params.bytes_per_line = 4 * get_param_scan_bytes (buffer); 03449 #else 03450 scanner->params.format = SANE_FRAME_RGB; 03451 scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer); 03452 #endif 03453 scanner->params.depth = scanner->val[OPT_BIT_DEPTH].w; 03454 } 03455 else if ((scanner->colormode == RGB) || (scanner->processing & POST_SW_DIRT)) 03456 { 03457 scanner->params.format = SANE_FRAME_RGB; 03458 scanner->params.depth = scanner->val[OPT_BIT_DEPTH].w; 03459 scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer); 03460 } 03461 else 03462 { 03463 DBG (DBG_error, "pie_usb_get_params: wrong colour format!\n"); 03464 return SANE_STATUS_UNSUPPORTED; 03465 } 03466 scanner->params.last_frame = 0; 03467 } 03468 return status; 03469 } 03470 03471 /* 03472 * @@ USB calibration functions 03473 */ 03474 03475 /* ------------------------ PIE_USB_CALICALC_HIQUAL ---------------------------- */ 03491 static void 03492 pie_usb_calicalc_hiqual (Pie_Scanner * scanner, 03493 PIE_USB_Calibration_Read * d7cal) 03494 { 03495 PIE_USB_Model *model = scanner->device->model; 03496 PIE_USB_Calibration *caldat = scanner->cal_data; 03497 double fact, dgain; 03498 int i, tg, tt, tmax; 03499 03500 SANE_Status status; 03501 int brightnesses[3]; 03502 int pokebuf[4]; 03503 int pokesiz = 3; 03504 03505 DBG (DBG_proc, "pie_usb_calicalc_hiqual\n"); 03506 03507 for (i = 0; i < 3; i++) 03508 brightnesses[i] = caldat->brightness[i]; 03509 status = pie_usb_poke_ints ("/tmp/bright.txt", pokebuf, &pokesiz); 03510 if (status == SANE_STATUS_GOOD && pokesiz) 03511 { 03512 for (i = 0; i < 3; i++) 03513 brightnesses[i] = pokebuf[i]; 03514 DBG (DBG_info, 03515 "pie_usb_calicalc_hiqual poked brightness %d, %d, %d\n", 03516 brightnesses[0], brightnesses[1], brightnesses[2]); 03517 } 03518 03519 tmax = 0; 03520 for (i = 0; i < 3; i++) 03521 { 03522 /* overall illumination correction factor 03523 fact = I / I0 = exp (c * (g^2 - g0^2)) * t / t0 */ 03524 fact = (double) brightnesses[i] / (double) caldat->mean_shade[i]; 03525 /* calculate gain from f^(1/p) = exp (c * (g^2 - g0^2)), the part done by gain */ 03526 dgain = 03527 log (fact) / (model->gain_const[i] * 03528 (double) model->gain_hiqual_part) + 03529 (double) d7cal->gain[i] * (double) d7cal->gain[i]; 03530 if (dgain < 0) 03531 tg = model->gain_min; 03532 else 03533 { 03534 tg = sqrt (dgain) + 0.5; 03535 if (tg < model->gain_min) 03536 tg = model->gain_min; 03537 if (tg > model->gain_hiqual_max) 03538 tg = model->gain_hiqual_max; 03539 } 03540 caldat->cal_hiqual.gain[i] = tg; 03541 DBG (DBG_info, 03542 "pie_usb_calicalc_hiqual gain[%d] = 0x%02x = %d\n", i, tg, tg); 03543 03544 /* the rest has to be done by exposure time */ 03545 dgain = fact; 03546 if (tg != d7cal->gain[i]) 03547 dgain *= 03548 exp (model->gain_const[i] * 03549 ((double) d7cal->gain[i] * (double) d7cal->gain[i] - 03550 (double) tg * (double) tg)); 03551 tt = dgain * (double) d7cal->texp[i] + 0.5; 03552 03553 /* if exposure time is too short try to redo the gain, 03554 should not happen very often as "fact" is usually > 1 */ 03555 if (tt < d7cal->t_min) 03556 { 03557 tt = d7cal->t_min; 03558 fact *= (double) tt / (double) d7cal->texp[i]; 03559 dgain = 03560 log (fact) / model->gain_const[i] + 03561 (double) d7cal->gain[i] * (double) d7cal->gain[i]; 03562 if (dgain < 0) 03563 tg = model->gain_min; 03564 else 03565 { 03566 tg = sqrt (dgain) + 0.5; 03567 if (tg < model->gain_min) 03568 tg = model->gain_min; 03569 } 03570 caldat->cal_hiqual.gain[i] = tg; 03571 DBG (DBG_info, 03572 "pie_usb_calicalc_hiqual regain[%d] = 0x%02x = %d\n", 03573 i, tg, tg); 03574 } 03575 caldat->cal_hiqual.texp[i] = tt; 03576 if (tt > tmax) 03577 tmax = tt; 03578 DBG (DBG_info, 03579 "pie_usb_calicalc_hiqual texp[%d] = 0x%02x = %d\n", i, tt, tt); 03580 } 03581 caldat->cal_hiqual.texp_max = tmax; 03582 } 03583 03584 /* ------------------------ PIE_USB_CALICALC_NORMAL ---------------------------- 03585 * 03586 * @brief Calculate gain and exposure for normal mode 03587 * 03588 * @param[in] scanner points to structure of opened scanner 03589 * @param[in] d7cal points to calibration data read by a PIE_READ_CALIBRATION command 03590 * 03591 * @note 03592 * In normal mode we have to fight nasty offsets with some types of scanners and 03593 * a rather narrow window for exposure time. Here for a color (j) the illumination 03594 * (Ij) reached with certain gain (gj) and exposure time (tj) settings can be described 03595 * by (II) I = n * aj * exp(c * gj^2) * tj - (n - 1) * 65536 . The gain constant c, offset 03596 * factor n and desired brightness have to be provided. Gain may be really maximal here, 03597 * i.e. 0x3f, the exposure time has to be larger than t_min. 03598 * The result of this routine is stored in scanner->cal_data. 03599 */ 03600 static void 03601 pie_usb_calicalc_normal (Pie_Scanner * scanner, 03602 PIE_USB_Calibration_Read * d7cal) 03603 { 03604 PIE_USB_Model *model = scanner->device->model; 03605 PIE_USB_Calibration *caldat = scanner->cal_data; 03606 int tg, tt, i, tmax; 03607 03608 SANE_Status status; 03609 int brightnesses[3]; 03610 int pokebuf[4]; 03611 int pokesiz = 3; 03612 03613 DBG (DBG_proc, "pie_usb_calicalc_normal\n"); 03614 03615 for (i = 0; i < 3; i++) 03616 brightnesses[i] = caldat->brightness[i]; 03617 status = pie_usb_poke_ints ("/tmp/bright.txt", pokebuf, &pokesiz); 03618 if (status == SANE_STATUS_GOOD && pokesiz) 03619 { 03620 for (i = 0; i < 3; i++) 03621 brightnesses[i] = pokebuf[i]; 03622 DBG (DBG_info, 03623 "pie_usb_calicalc_normal poked brightness %d, %d, %d\n", 03624 brightnesses[0], brightnesses[1], brightnesses[2]); 03625 } 03626 03627 tmax = 0; 03628 for (i = 0; i < 3; i++) 03629 { 03630 /* start calculating gain for default texp rounding down. 03631 Following horrible expression is obtained by setting up equation (II) for the desired 03632 brightness, setting up quality mode equation (I) using the information from the 03633 0xd7 read together with the achieved brightness of read calibration lines and solving 03634 that system for the gain required in normal mode */ 03635 tg = sqrt (log ((((double) brightnesses[i] + 03636 ((model->offs_factor[i] - 03637 1.0) * 65536)) * (double) d7cal->texp[i]) / 03638 (model->offs_factor[i] * 03639 (double) model->default_normal.texp[i] * 03640 (double) caldat->mean_shade[i])) / 03641 model->gain_const[i] + 03642 (double) d7cal->gain[i] * (double) d7cal->gain[i]); 03643 if (tg > 0x3f) 03644 tg = 0x3f; 03645 /* here the gain (tg) is smaller than for what it was calculated, so we need 03646 a longer exposure time. Using the same set of equations as above exposure time is 03647 calculated for the given gain */ 03648 tt = (((double) brightnesses[i] + ((model->offs_factor[i] - 03649 1.0) * 65536.0)) * 03650 (double) d7cal->texp[i]) / (model->offs_factor[i] * 03651 (double) caldat->mean_shade[i]) * 03652 exp (model->gain_const[i] * 03653 ((double) d7cal->gain[i] * (double) d7cal->gain[i] - tg * tg)) + 03654 0.5; 03655 if (tt < d7cal->t_min) 03656 tt = d7cal->t_min; 03657 if (tt > model->texp_normal_max) 03658 tt = model->texp_normal_max; 03659 03660 caldat->cal_normal.gain[i] = tg; 03661 caldat->cal_normal.texp[i] = tt; 03662 if (tt > tmax) 03663 tmax = tt; 03664 DBG (DBG_info, 03665 "pie_usb_calicalc_normal gain[%d] = 0x%02x = %d, texp[%d] = 0x%02x = %d\n", 03666 i, tg, tg, i, tt, tt); 03667 } 03668 caldat->cal_normal.texp_max = tmax; 03669 } 03670 03671 03672 /* ---------------------- PIE_USB_CALICALC_SLOW_DOWN --------------------------- */ 03686 static unsigned char 03687 pie_usb_calicalc_slow_down (Pie_Scanner * scanner) 03688 { 03689 double width, x_dpmm; 03690 int slow_down; 03691 03692 DBG (DBG_proc, "pie_usb_calicalc_slow_down\n"); 03693 03694 slow_down = 0; 03695 width = SANE_UNFIX (scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w); 03696 x_dpmm = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w) / MM_PER_INCH; 03697 if ((width > 0) && (x_dpmm > 0)) 03698 { 03699 width *= 3 * x_dpmm; /* calculate for RGB */ 03700 if (scanner->val[OPT_BIT_DEPTH].w > 8) 03701 width *= 2; /* bytes per line */ 03702 03703 if (width > SLOW_START) 03704 { /* slow down value */ 03705 width = (width - SLOW_START) * SLOW_HEIGHT / SLOW_LENGTH; 03706 if (scanner->cal_mode == /* correct for exposure time */ 03707 scanner->device->model->op_mode[OPM_QUALITY]) 03708 width *= 03709 (double) scanner->device->model->default_hiqual.texp_max / 03710 (double) scanner->cal_data->cal_hiqual.texp_max; 03711 else 03712 width *= 03713 (double) scanner->device->model->default_normal.texp_max / 03714 (double) scanner->cal_data->cal_normal.texp_max; 03715 slow_down = (int) (width + 0.5); 03716 if (scanner->colormode == RGBI) /* correct for infrared */ 03717 slow_down -= 2; 03718 if ((slow_down < 0) || (slow_down >= 16)) 03719 slow_down = 0; 03720 } 03721 } 03722 DBG (DBG_info, "pie_usb_calicalc_slow_down: %d\n", slow_down); 03723 return slow_down; 03724 } 03725 03726 03727 /* ------------------------ PIE_USB_CALIBRATION_SEND -------------------------- */ 03748 static SANE_Status 03749 pie_usb_calibration_send (Pie_Scanner * scanner, int calc_cal) 03750 { 03751 PIE_USB_Calibration_Read calD7in; 03752 PIE_USB_Calibration_Send calDCout; 03753 size_t size_read = 103; 03754 size_t size_write = 23; 03755 SANE_Status status; 03756 unsigned char pokebuf[64]; 03757 int i, pokesiz; 03758 03759 DBG (DBG_proc, "pie_usb_calibration_send\n"); 03760 03761 status = /* 103 bytes */ 03762 pie_usb_scsi_wrapper (scanner->sfd, read_calibrationC, 03763 sizeof (read_calibrationC), &calD7in, &size_read); 03764 if (status != SANE_STATUS_GOOD) 03765 return status; 03766 03767 DBG (DBG_info, "pie_usb_calibration_send received:\n"); 03768 DBG_DUMP (DBG_info, (unsigned char *) &calD7in, 103); 03769 03770 if (calD7in.illumination[0] == 0) /* assume same target as for blue */ 03771 calD7in.illumination[0] = calD7in.illumination[2]; 03772 if (calD7in.illumination[1] == 0) /* assume same target as for blue */ 03773 calD7in.illumination[1] = calD7in.illumination[2]; 03774 for (i = 0; i < 3; i++) 03775 scanner->cal_data->target_shade[i] = calD7in.illumination[i]; 03776 scanner->cal_data->target_shade[3] = calD7in.illumination[2]; /* ired ?? */ 03777 03778 /* now we have all data to calculate calibration */ 03779 if (calc_cal) 03780 { 03781 pie_usb_calicalc_hiqual (scanner, &calD7in); 03782 pie_usb_calicalc_normal (scanner, &calD7in); 03783 } 03784 /* load vector to be sent */ 03785 size_write += 6; 03786 memcpy (&(calDCout.scsi_cmd), write_calibrationC, 6); 03787 /* first with what we have/had calculated */ 03788 if (scanner->cal_mode != scanner->device->model->op_mode[OPM_QUALITY]) /* normal mode */ 03789 { 03790 for (i = 0; i < 3; i++) 03791 calDCout.texp[i] = scanner->cal_data->cal_normal.texp[i]; 03792 for (i = 0; i < 3; i++) 03793 calDCout.gain[i] = scanner->cal_data->cal_normal.gain[i]; 03794 } 03795 else /* quality mode */ 03796 { 03797 for (i = 0; i < 3; i++) 03798 calDCout.texp[i] = scanner->cal_data->cal_hiqual.texp[i]; 03799 for (i = 0; i < 3; i++) 03800 calDCout.gain[i] = scanner->cal_data->cal_hiqual.gain[i]; 03801 } 03802 03803 /* then with values which are usully copied */ 03804 memcpy (calDCout.offset, calD7in.offset, 6); /* offsets, zero_2 */ 03805 03806 calDCout.some_time[0] = calD7in.some_time; 03807 /* slow down at high resolutions */ 03808 if (calc_cal 03809 || (scanner->cal_mode == scanner->device->model->op_mode[OPM_SKIPCAL])) 03810 calDCout.some_time[1] = pie_usb_calicalc_slow_down (scanner); 03811 else 03812 calDCout.some_time[1] = 0; 03813 calDCout.some_time[2] = 0; 03814 03815 memcpy (&calDCout.infrared, &calD7in.infrared, sizeof (PIE_USB_cal_ired)); 03816 pokesiz = 12; 03817 status = pie_usb_poke_bytes ("/tmp/calbytes.txt", pokebuf, &pokesiz); 03818 if (status == SANE_STATUS_GOOD) 03819 { 03820 memcpy (calDCout.texp, &pokebuf[0], 6); 03821 memcpy (calDCout.gain, &pokebuf[6], 6); 03822 } 03823 03824 DBG (DBG_info, "pie_usb_calibration_send sending:\n"); 03825 DBG_DUMP (DBG_info, (unsigned char *) &calDCout, size_write); 03826 status = 03827 pie_usb_scsi_wrapper (scanner->sfd, &calDCout, size_write, NULL, NULL); 03828 return status; 03829 } 03830 03831 03832 /* ---------------------------- PIE_USB_CALIBRATE ----------------------------- */ 03858 static SANE_Status 03859 pie_usb_calibrate (Pie_Scanner * scanner) 03860 { 03861 unsigned int val; 03862 unsigned char *rcv_buffer, *src; 03863 int rcv_length, rcv_lines, rcv_bits; 03864 int pixels_per_line, average_lines; 03865 int i, j, k, l; 03866 int n[4]; 03867 int *dest; 03868 double dval; 03869 size_t size; 03870 SANE_Status status; 03871 03872 DBG (DBG_proc, "pie_usb_calibrate\n"); 03873 03874 rcv_lines = scanner->device->cal_info[0].num_lines; 03875 average_lines = rcv_lines - 1; 03876 if (AVERAGE_CAL_LINES < average_lines) 03877 average_lines = AVERAGE_CAL_LINES; 03878 pixels_per_line = scanner->device->cal_info[0].pixels_per_line; 03879 rcv_length = pixels_per_line; 03880 rcv_bits = scanner->device->cal_info[0].receive_bits; 03881 if (rcv_bits > 8) 03882 rcv_length *= 2; 03883 if ((scanner->colormode == RGB) || (scanner->colormode == RGBI)) 03884 rcv_length = (rcv_length + 2) * 4; 03885 else 03886 return SANE_STATUS_INVAL; 03887 03888 rcv_buffer = (unsigned char *) malloc (rcv_length); 03889 if (!rcv_buffer) 03890 return SANE_STATUS_NO_MEM; 03891 03892 status = pie_usb_wait_scanner (scanner, 6); 03893 if (status != SANE_STATUS_GOOD) 03894 goto freend; 03895 set_read_length (sread.cmd, 4); /* a test line */ 03896 size = rcv_length; 03897 status = 03898 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, sread.size, 03899 rcv_buffer, &size); 03900 if (status != SANE_STATUS_GOOD) /* should not happen */ 03901 { 03902 status = SANE_STATUS_GOOD; /* try to recover */ 03903 goto freend; 03904 } 03905 rcv_lines--; 03906 /* this gets the data */ 03907 memset (scanner->cal_data->shades, 0, pixels_per_line * 4 * sizeof (int)); 03908 scanner->cal_data->shades[0] = 0; 03909 for (i = 0; i < 4; i++) 03910 n[i] = 0; 03911 for (k = 0; k < average_lines; k++) 03912 { 03913 size = rcv_length; 03914 status = 03915 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, sread.size, 03916 rcv_buffer, &size); 03917 if (status != SANE_STATUS_GOOD) 03918 goto freend; 03919 for (i = 0; i < 4; i++) 03920 { 03921 if (rcv_bits > 8) 03922 src = rcv_buffer + i * (pixels_per_line + 1) * 2; 03923 else 03924 src = rcv_buffer + i * (pixels_per_line + 2); 03925 if (*src == 'R') 03926 l = 0; 03927 else if (*src == 'G') 03928 l = 1; 03929 else if (*src == 'B') 03930 l = 2; 03931 else if (*src == 'I') 03932 l = 3; 03933 else 03934 { 03935 DBG (DBG_error, 03936 "pie_usb_calibrate: invalid index byte (%02x)\n", *src); 03937 DBG_DUMP (DBG_error, src, 32); 03938 status = SANE_STATUS_INVAL; 03939 goto freend; 03940 } 03941 src += 2; 03942 dest = scanner->cal_data->shades + l * pixels_per_line; 03943 if (rcv_bits > 8) 03944 { 03945 for (j = 0; j < pixels_per_line; j++) 03946 { 03947 val = *src++; 03948 val += (*src++) << 8; 03949 *dest++ += val; 03950 } 03951 } 03952 else 03953 { 03954 for (j = 0; j < pixels_per_line; j++) 03955 *dest++ += *src++; 03956 } 03957 n[l]++; 03958 } 03959 rcv_lines--; 03960 } 03961 for (l = 0; l < 4; l++) 03962 { 03963 dest = scanner->cal_data->shades + l * pixels_per_line; 03964 dval = 0; 03965 for (j = pixels_per_line; j > 0; j--) 03966 { 03967 dval += *dest; 03968 *dest++ /= n[l]; 03969 } 03970 scanner->cal_data->mean_shade[l] = 03971 dval / (double) (n[l] * pixels_per_line) + 0.5; 03972 DBG (DBG_info, 03973 "pie_usb_calibrate: color %d, mean %d = %04x\n", l, 03974 scanner->cal_data->mean_shade[l], 03975 scanner->cal_data->mean_shade[l]); 03976 } 03977 if (DBG_LEVEL >= DBG_image) 03978 pie_usb_shades_to_pnm (scanner, "/tmp/pieshading", 64); 03979 /* get, calculate and send calibration */ 03980 status = pie_usb_calibration_send (scanner, 1); 03981 if (status != SANE_STATUS_GOOD) 03982 goto freend; 03983 /* we have to read all lines, discard the rest */ 03984 while (rcv_lines > 0) 03985 { 03986 size = rcv_length; 03987 status = 03988 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, sread.size, 03989 rcv_buffer, &size); 03990 if (status != SANE_STATUS_GOOD) 03991 goto freend; 03992 rcv_lines--; 03993 } 03994 03995 freend: /* ugly, but this may be one of the cases ... */ 03996 free (rcv_buffer); 03997 return status; 03998 } 03999 04000 04001 /* ------------------------- PIE_USB_CORRECT_SHADING -------------------------- */ 04017 static void 04018 pie_usb_correct_shading (Pie_Scanner * scanner, 04019 unsigned char *in_buf[4], SANEI_IR_bufptr out_buf[4], 04020 int pixels, int bits, int start_plane, int end_plane) 04021 { 04022 SANEI_IR_bufptr buf[4]; 04023 unsigned char *sensors; 04024 unsigned int val; 04025 int *shade[4]; 04026 int target[4]; 04027 int cal_pixels; 04028 int cal_idx = 0; 04029 int mirror; 04030 int i, j, k; 04031 04032 DBG (DBG_proc, "pie_usb_correct_shading: %d to %d\n", start_plane, 04033 end_plane); 04034 04035 mirror = scanner->device->model->flags & PIE_USB_FLAG_MIRROR_IMAGE; 04036 cal_pixels = scanner->device->cal_info[0].pixels_per_line; 04037 sensors = scanner->cal_data->sensors; 04038 for (k = start_plane; k <= end_plane; k++) 04039 { 04040 shade[k] = scanner->cal_data->shades + k * cal_pixels; 04041 /* we can take means or targets here, 04042 targets may lead to values larger than 16 bit */ 04043 target[k] = scanner->cal_data->mean_shade[k]; 04044 if (mirror == 0) 04045 buf[k] = out_buf[k]; 04046 else if (bits > 8) 04047 buf[k].b16 = out_buf[k].b16 + pixels - 1; 04048 else 04049 buf[k].b8 = out_buf[k].b8 + pixels - 1; 04050 } 04051 04052 j = 0; 04053 for (i = 0; i < pixels; i++) 04054 { 04055 while (sensors[j] != 0 && j < cal_pixels) 04056 j++; 04057 if (j < cal_pixels) 04058 { 04059 cal_idx = j; 04060 j++; 04061 } 04062 if (mirror == 0) 04063 { 04064 if (bits > 8) 04065 for (k = start_plane; k <= end_plane; k++) 04066 { 04067 val = *in_buf[k]++; 04068 val += (*in_buf[k]++) << 8; 04069 if (val > 4096) 04070 { 04071 val = (val * target[k]) / shade[k][cal_idx]; 04072 if (val > 0xffff) 04073 val = 0xffff; 04074 } 04075 *buf[k].b16++ = val; 04076 } 04077 else 04078 for (k = start_plane; k <= end_plane; k++) 04079 { 04080 val = *in_buf[k]++; 04081 if (val > 16) 04082 { 04083 val = (val * target[k]) / shade[k][cal_idx]; 04084 if (val > 0xff) 04085 val = 0xff; 04086 } 04087 *buf[k].b8++ = val; 04088 } 04089 } 04090 else 04091 { 04092 if (bits > 8) 04093 for (k = start_plane; k <= end_plane; k++) 04094 { 04095 val = *in_buf[k]++; 04096 val += (*in_buf[k]++) << 8; 04097 if (val > 4096) 04098 { 04099 val = (val * target[k]) / shade[k][cal_idx]; 04100 if (val > 0xffff) 04101 val = 0xffff; 04102 } 04103 *buf[k].b16-- = val; 04104 } 04105 else 04106 for (k = start_plane; k <= end_plane; k++) 04107 { 04108 val = *in_buf[k]++; 04109 if (val > 16) 04110 { 04111 val = (val * target[k]) / shade[k][cal_idx]; 04112 if (val > 0xff) 04113 val = 0xff; 04114 } 04115 *buf[k].b8-- = val; 04116 } 04117 } 04118 } 04119 } 04120 04121 04122 /* 04123 * @@ USB image reading and processing 04124 */ 04125 04126 /* ------------------------- PIE_USB_READER_REORDER --------------------------- */ 04136 static void 04137 pie_usb_reader_reorder (Pie_Scanner * scanner, SANEI_IR_bufptr * in_img, 04138 SANEI_IR_bufptr out_img, int planes, int pixels) 04139 { 04140 SANEI_IR_bufptr dest; 04141 SANEI_IR_bufptr cptr[4]; 04142 uint16_t *gamma_lut; 04143 int i, k; 04144 04145 DBG (DBG_proc, 04146 "pie_usb_reader_reorder: %d pixels\n", pixels); 04147 04148 for (i = 0; i < planes; i++) 04149 cptr[i] = in_img[i]; 04150 04151 dest = out_img; 04152 if (scanner->processing & POST_SW_COLORS) 04153 { 04154 if (scanner->val[OPT_SW_NEGA].w == SANE_TRUE) 04155 { 04156 if (scanner->params.depth > 8) 04157 { 04158 gamma_lut = scanner->gamma_lut16; 04159 for (i = pixels; i > 0; i--) 04160 for (k = 0; k < planes; k++) 04161 *dest.b16++ = (uint16_t) (65535 - gamma_lut[*cptr[k].b16++]); 04162 } 04163 else 04164 { 04165 gamma_lut = scanner->gamma_lut8; 04166 for (i = pixels; i > 0; i--) 04167 for (k = 0; k < planes; k++) 04168 *dest.b8++ = (uint8_t) (255 - gamma_lut[*cptr[k].b8++]); 04169 } 04170 } 04171 else 04172 { 04173 if (scanner->params.depth > 8) 04174 { 04175 gamma_lut = scanner->gamma_lut16; 04176 for (i = pixels; i > 0; i--) 04177 for (k = 0; k < planes; k++) 04178 *dest.b16++ = (uint16_t) gamma_lut[*cptr[k].b16++]; 04179 } 04180 else 04181 { 04182 gamma_lut = scanner->gamma_lut8; 04183 for (i = pixels; i > 0; i--) 04184 for (k = 0; k < planes; k++) 04185 *dest.b8++ = (uint8_t) gamma_lut[*cptr[k].b8++]; 04186 } 04187 } 04188 } 04189 else 04190 { 04191 if (scanner->params.depth > 8) 04192 { 04193 for (i = pixels; i > 0; i--) 04194 for (k = 0; k < planes; k++) 04195 *dest.b16++ = *cptr[k].b16++; 04196 } 04197 else 04198 { 04199 for (i = pixels; i > 0; i--) 04200 for (k = 0; k < planes; k++) 04201 *dest.b8++ = *cptr[k].b8++; 04202 } 04203 } 04204 } 04205 04206 04207 /* ---------------------------- PIE_USB_SW_STORE ------------------------------ */ 04219 static SANE_Status 04220 pie_usb_sw_store (Pie_Scanner * scanner, 04221 SANEI_IR_bufptr * in_img, int planes) 04222 { 04223 SANE_Status status = SANE_STATUS_GOOD; 04224 size_t size; 04225 04226 DBG (DBG_proc, 04227 "pie_usb_sw_store: %d lines of %d bytes/line\n", 04228 scanner->params.lines, scanner->params.bytes_per_line); 04229 04230 if (scanner->img_buffer.b8) 04231 free (scanner->img_buffer.b8); 04232 size = scanner->params.bytes_per_line * scanner->params.lines; 04233 scanner->img_buffer.b8 = malloc (size); 04234 if (scanner->img_buffer.b8) 04235 { 04236 pie_usb_reader_reorder (scanner, in_img, scanner->img_buffer, planes, 04237 scanner->params.pixels_per_line * scanner->params.lines); 04238 if (DBG_LEVEL >= DBG_image) 04239 { 04240 pie_usb_write_pnm_file ("/tmp/RGBi-img.pnm", scanner->img_buffer.b8, 04241 scanner->params.depth, planes, 04242 scanner->params.pixels_per_line, 04243 scanner->params.lines); 04244 } 04245 } 04246 else 04247 { 04248 DBG (DBG_error, "pie_usb_sw_store: no buffer\n"); 04249 status = SANE_STATUS_NO_MEM; 04250 } 04251 04252 return status; 04253 } 04254 04255 04256 /* -------------------------- PIE_USB_READER_WRITE ---------------------------- */ 04271 static SANE_Status 04272 pie_usb_reader_write (Pie_Scanner * scanner, FILE * fp, 04273 SANEI_IR_bufptr * in_img, int planes, int lines) 04274 { 04275 SANE_Status status = SANE_STATUS_GOOD; 04276 SANEI_IR_bufptr reorder; 04277 size_t size, nwrite; 04278 04279 DBG (DBG_proc, 04280 "pie_usb_reader_write: %d lines of %d bytes/line\n", 04281 lines, scanner->params.bytes_per_line); 04282 04283 size = scanner->params.bytes_per_line * lines; 04284 reorder.b8 = malloc (size); 04285 if (reorder.b8) 04286 { 04287 pie_usb_reader_reorder (scanner, in_img, reorder, planes, 04288 scanner->params.pixels_per_line * lines); 04289 04290 nwrite = fwrite (reorder.b8, 1, size, fp); 04291 if (nwrite < size) /* abort */ 04292 { 04293 DBG (DBG_error, "pie_usb_reader_write: pipe error\n"); 04294 status = SANE_STATUS_IO_ERROR; 04295 } 04296 04297 free (reorder.b8); 04298 } 04299 else 04300 { 04301 DBG (DBG_error, "pie_usb_reader_write: no buffer\n"); 04302 status = SANE_STATUS_NO_MEM; 04303 } 04304 04305 return status; 04306 } 04307 04308 04309 /* -------------------------- PIE_USB_SMOOTHEN RGB ---------------------------- */ 04326 static SANE_Status 04327 pie_usb_smoothen_rgb (const SANE_Parameters * params, 04328 SANEI_IR_bufptr * the_img, int win_size) 04329 { 04330 SANEI_IR_bufptr cplane[3]; /* R, G, B, (I) gray scale planes */ 04331 SANEI_IR_bufptr plane; 04332 int depth, i; 04333 size_t itop; 04334 SANE_Status ret = SANE_STATUS_NO_MEM; 04335 04336 for (i = 0; i < 3; i++) 04337 cplane[i] = the_img[i]; 04338 04339 depth = params->depth; 04340 itop = params->lines * params->pixels_per_line; 04341 if (depth > 8) 04342 plane.b8 = malloc (itop * sizeof (uint16_t)); 04343 else 04344 plane.b8 = malloc (itop * sizeof (uint8_t)); 04345 if (!plane.b8) 04346 DBG (5, "pie_usb_smoothen_rgb: Cannot allocate buffer\n"); 04347 else 04348 { 04349 for (i = 0; i < 3; i++) 04350 { 04351 ret = 04352 sanei_ir_filter_mean (params, cplane[i], plane, win_size, win_size); 04353 if (ret != SANE_STATUS_GOOD) 04354 break; 04355 ret = 04356 sanei_ir_filter_mean (params, plane, cplane[i], win_size, win_size); 04357 if (ret != SANE_STATUS_GOOD) 04358 break; 04359 } 04360 free (plane.b8); 04361 } 04362 return ret; 04363 } 04364 04365 /* ------------------------ PIE_USB_SW_FINAL_CROP ----------------------------- */ 04381 static SANE_Status 04382 pie_usb_sw_crop_planes (SANE_Parameters * parameters, Pie_Scanner * scanner, 04383 SANEI_IR_bufptr * in_img, int top, int bot, int left, int right, int planes) 04384 { 04385 SANEI_IR_bufptr cplane[4]; /* R, G, B, I gray scale planes */ 04386 SANE_Parameters params; 04387 SANE_Status status; 04388 int i; 04389 04390 for (i = 0; i < planes; i++) 04391 cplane[i] = in_img[i]; 04392 04393 for (i = 0; i < planes; i++) 04394 { 04395 memcpy (¶ms, parameters, sizeof (SANE_Parameters)); 04396 status = 04397 sanei_magic_crop(¶ms, cplane[i].b8, top, bot, left, right); 04398 if (status != SANE_STATUS_GOOD) 04399 return status; 04400 } 04401 memcpy (parameters, ¶ms, sizeof (SANE_Parameters)); 04402 scanner->params.bytes_per_line /= scanner->params.pixels_per_line; 04403 scanner->params.pixels_per_line = params.pixels_per_line; 04404 scanner->params.bytes_per_line *= params.pixels_per_line; 04405 scanner->params.lines = params.lines; 04406 04407 return SANE_STATUS_GOOD; 04408 } 04409 04410 04411 /* ------------------------ PIE_USB_SW_FINAL_CROP ----------------------------- */ 04426 static SANE_Status 04427 pie_usb_sw_final_crop (Pie_Scanner * scanner) 04428 { 04429 SANEI_IR_bufptr tmp_img; 04430 SANE_Parameters params; 04431 SANE_Status status; 04432 int resol = scanner->resolution / 16; 04433 int top, bot, left, right; 04434 04435 DBG (DBG_sane_proc, "pie_usb_sw_final_crop\n"); 04436 04437 /* reduce image depth for edge detection */ 04438 status = 04439 sane_ir_to_8bit (&scanner->params, scanner->img_buffer, 04440 ¶ms, &tmp_img); 04441 if (status != SANE_STATUS_GOOD) 04442 return status; 04443 04444 status = sanei_magic_findEdges(¶ms, tmp_img.b8, 04445 resol, resol, &top, &bot, &left, &right); 04446 if (status != SANE_STATUS_GOOD) 04447 return status; 04448 04449 if (strcmp (scanner->val[OPT_SW_CROP].s, CROP_INNER_STR) == 0) 04450 { 04451 int width = scanner->params.pixels_per_line; 04452 int height = scanner->params.lines; 04453 int it = top; 04454 int ib = bot; 04455 int il = left; 04456 int ir = right; 04457 04458 resol = scanner->resolution / 100; 04459 if (it > 2) 04460 it += resol; 04461 if (height - ib > 2) 04462 ib -= resol; 04463 if (il > 2) 04464 il += resol; 04465 if (width - ir > 2) 04466 ir -= resol; 04467 04468 if (ib - it > 0) 04469 { 04470 top = it; 04471 bot = ib; 04472 } 04473 if (ir - il > 0) 04474 { 04475 left = il; 04476 right = ir; 04477 } 04478 DBG (DBG_info, "pie_usb_sw_final_crop: suggested cropping:\n \ 04479 top %d, bot %d, left %d, right %d\n", top, bot, left, right); 04480 } 04481 04482 status = 04483 sanei_magic_crop(&scanner->params, scanner->img_buffer.b8, top, bot, left, right); 04484 04485 free (tmp_img.b8); 04486 return status; 04487 } 04488 04489 04490 /* -------------------------- PIE_USB_SW_POST --------------------------------- */ 04515 static SANE_Status 04516 pie_usb_sw_post (Pie_Scanner * scanner, 04517 SANEI_IR_bufptr * in_img, int planes, int out_planes) 04518 { 04519 SANEI_IR_bufptr cplane[4]; /* R, G, B, I gray scale planes */ 04520 SANE_Parameters parameters; /* describes the image */ 04521 int winsize_smooth; /* for adapting replaced pixels */ 04522 char filename[64]; 04523 SANE_Status status; 04524 int smooth, i; 04525 04526 memcpy (¶meters, &scanner->params, sizeof (SANE_Parameters)); 04527 parameters.format = SANE_FRAME_GRAY; 04528 parameters.bytes_per_line = parameters.pixels_per_line; 04529 if (parameters.depth > 8) 04530 parameters.bytes_per_line *= 2; 04531 parameters.last_frame = 0; 04532 04533 DBG (DBG_info, "pie_usb_sw_post: %d ppl, %d lines, %d bits, %d planes, %d dpi\n", 04534 parameters.pixels_per_line, parameters.lines, 04535 planes, parameters.depth, scanner->resolution); 04536 04537 for (i = 0; i < planes; i++) 04538 cplane[i] = in_img[i]; 04539 04540 /* dirt is rather resolution invariant, so 04541 * setup resolution dependent parameters 04542 */ 04543 /* film grain reduction */ 04544 smooth = scanner->val[OPT_SW_GRAIN].w; 04545 winsize_smooth = (scanner->resolution / 540) | 1; 04546 /* smoothen whole image or only replaced pixels */ 04547 if (smooth) 04548 { 04549 winsize_smooth += 2 * (smooth - 3); /* even */ 04550 if (winsize_smooth < 3) 04551 smooth = 0; 04552 } 04553 if (winsize_smooth < 3) 04554 winsize_smooth = 3; 04555 DBG (DBG_info, "pie_usb_sw_post: winsize_smooth %d\n", winsize_smooth); 04556 04557 /* RGBI post-processing if selected: 04558 * 1) remove spectral overlay from ired plane, 04559 * 2) remove dirt, smoothen if, crop if */ 04560 if (scanner-> processing & POST_SW_IRED_MASK) 04561 { 04562 int winsize_filter; /* primary size of filtering window */ 04563 int size_dilate; /* the dirt mask */ 04564 SANE_Byte *thresh_data; 04565 int static_thresh, too_thresh; /* static thresholds */ 04566 04567 /* size of filter detecting dirt */ 04568 winsize_filter = (int) (5.0 * (double) scanner->resolution / 300.0) | 1; 04569 if (winsize_filter < 3) 04570 winsize_filter = 3; 04571 /* dirt usually has smooth edges which also need correction */ 04572 size_dilate = scanner->resolution / 1000 + 1; 04573 04574 /* remove spectral overlay from ired plane */ 04575 status = 04576 sane_ir_spectral_clean (¶meters, scanner->ln_lut, cplane[0], 04577 cplane[3]); 04578 if (status != SANE_STATUS_GOOD) 04579 return status; 04580 if (DBG_LEVEL >= DBG_image) 04581 { 04582 snprintf (filename, 63, "/tmp/ir-spectral.pnm"); 04583 pie_usb_write_pnm_file (filename, cplane[3].b8, 04584 parameters.depth, 1, 04585 parameters.pixels_per_line, parameters.lines); 04586 } 04587 if (cancel_requ) /* asynchronous cancel ? */ 04588 return SANE_STATUS_CANCELLED; 04589 04590 /* remove dirt, smoothen if, crop if */ 04591 if (scanner->processing & POST_SW_DIRT) 04592 { 04593 double *norm_histo; 04594 int crop[4]; 04595 04596 /* first detect large dirt by a static threshold */ 04597 status = 04598 sanei_ir_create_norm_histogram (¶meters, cplane[3], &norm_histo); 04599 if (status != SANE_STATUS_GOOD) 04600 { 04601 DBG (DBG_error, "pie_usb_sw_post: no buffer\n"); 04602 return SANE_STATUS_NO_MEM; 04603 } 04604 /* generate a "bimodal" static threshold */ 04605 status = 04606 sanei_ir_threshold_yen (¶meters, norm_histo, &static_thresh); 04607 if (status != SANE_STATUS_GOOD) 04608 return status; 04609 /* generate traditional static threshold */ 04610 status = 04611 sanei_ir_threshold_otsu (¶meters, norm_histo, &too_thresh); 04612 if (status != SANE_STATUS_GOOD) 04613 return status; 04614 /* choose lower one */ 04615 if (too_thresh < static_thresh) 04616 static_thresh = too_thresh; 04617 free (norm_histo); 04618 04619 /* then generate dirt mask with adaptive thresholding filter 04620 * and add the dirt from the static threshold */ 04621 status = /* last two parameters: 10, 50 detects more, 20, 75 less */ 04622 sanei_ir_filter_madmean (¶meters, cplane[3], &thresh_data, 04623 winsize_filter, 20, 100); 04624 if (status != SANE_STATUS_GOOD) 04625 return status; 04626 sanei_ir_add_threshold (¶meters, cplane[3], thresh_data, 04627 static_thresh); 04628 if (DBG_LEVEL >= DBG_image) 04629 { 04630 snprintf (filename, 63, "/tmp/ir-threshold.pnm"); 04631 pie_usb_write_pnm_file (filename, thresh_data, 04632 8, 1, parameters.pixels_per_line, 04633 parameters.lines); 04634 } 04635 if (cancel_requ) /* asynchronous cancel ? */ 04636 return SANE_STATUS_CANCELLED; 04637 04638 /* replace the dirt and smoothen film grain and crop if possible */ 04639 if (((scanner->processing & POST_SW_CROP) != 0) && 04640 (scanner->val[OPT_SW_NEGA].w == SANE_FALSE)) 04641 { 04642 status = 04643 sanei_ir_dilate_mean (¶meters, cplane, thresh_data, 04644 500, size_dilate, winsize_smooth, smooth, 04645 (strcmp (scanner->val[OPT_SW_CROP].s, CROP_INNER_STR) == 0), 04646 crop); 04647 if (status != SANE_STATUS_GOOD) 04648 return status; 04649 status = 04650 pie_usb_sw_crop_planes (¶meters, scanner, cplane, 04651 crop[0], crop[1], crop[2], crop[3], 3); 04652 if (status != SANE_STATUS_GOOD) 04653 return status; 04654 } 04655 else 04656 { 04657 status = 04658 sanei_ir_dilate_mean (¶meters, cplane, thresh_data, 500, 04659 size_dilate, winsize_smooth, smooth, 0, NULL); 04660 if (status != SANE_STATUS_GOOD) 04661 return status; 04662 } 04663 smooth = 0; 04664 free (thresh_data); 04665 } 04666 } /* scanner-> processing & POST_SW_IRED_MASK */ 04667 04668 /* smoothen remaining cases */ 04669 if (smooth) 04670 pie_usb_smoothen_rgb (¶meters, cplane, winsize_smooth); 04671 04672 status = pie_usb_sw_store (scanner, cplane, out_planes); 04673 if (status != SANE_STATUS_GOOD) 04674 return status; 04675 04676 if (((scanner->processing & POST_SW_CROP) != 0) && 04677 (((scanner->processing & POST_SW_DIRT) == 0) || 04678 (scanner->val[OPT_SW_NEGA].w == SANE_TRUE))) 04679 status = pie_usb_sw_final_crop (scanner); 04680 04681 return status; 04682 } 04683 04684 04685 /* ------------------------- PIE_USB_READER_INDEXED --------------------------- */ 04705 static SANE_Status 04706 pie_usb_reader_indexed (Pie_Scanner * scanner, FILE * fp) 04707 { 04708 char idx_char[4] = { 04709 'R', 'G', 'B', 'I' 04710 }; 04711 char *idx_ptr[4]; 04712 char *iend_ptr[4]; 04713 int idx_buf[4]; 04714 int idx_found; 04715 unsigned char *src[4], *buffer; 04716 unsigned char *wrt_ptr, *end_ptr; 04717 int bytes_per_line, bytes_per_color; 04718 int chunk_lines, lines_todo; 04719 int read_lines, write_lines; 04720 SANE_Status status; 04721 int irgb; /* number of color planes = values per pixel */ 04722 int irgb_out; /* limit output as long as SANE disregards infrared */ 04723 SANE_Bool flag_accumulate; /* 1 : store all data read */ 04724 SANE_Bool flag_postprocess; /* 0 : write immediately */ 04725 int request_data, i, j; 04726 size_t chunk_size, size; 04727 04728 struct timeval start_time, end_time; 04729 long int elapsed_time; 04730 SANEI_IR_bufptr color_buf[4]; 04731 SANEI_IR_bufptr color_ptr[4]; 04732 char filename[64]; 04733 04734 DBG (DBG_read, 04735 "pie_usb_reader_indexed reading %d lines of %d bytes/line in mode %d, processing %d\n", 04736 scanner->params.lines, scanner->params.bytes_per_line, 04737 scanner->colormode, scanner->processing); 04738 04739 flag_postprocess = ((scanner->processing & POST_SW_ACCUM_MASK) != 0); 04740 flag_accumulate = flag_postprocess; 04741 if (DBG_LEVEL >= DBG_image) 04742 flag_accumulate = SANE_TRUE; 04743 04744 bytes_per_color = scanner->bytes_per_line + 2; 04745 if (scanner->colormode == RGB) 04746 { 04747 irgb = 3; 04748 irgb_out = 3; 04749 bytes_per_line = scanner->params.bytes_per_line + 6; 04750 } 04751 else if (scanner->colormode == RGBI) 04752 { 04753 if (scanner->processing & POST_SW_DIRT) 04754 { 04755 irgb = 4; 04756 irgb_out = 3; 04757 bytes_per_line = scanner->params.bytes_per_line + bytes_per_color + 6; 04758 } 04759 else 04760 { 04761 irgb = 4; 04762 #ifdef SANE_FRAME_RGBI 04763 irgb_out = 4; 04764 bytes_per_line = scanner->params.bytes_per_line + 8; 04765 #else 04766 irgb_out = 3; 04767 bytes_per_line = scanner->params.bytes_per_line + bytes_per_color + 6; 04768 #endif 04769 } 04770 } 04771 else 04772 { 04773 DBG (DBG_error, 04774 "pie_usb_reader_indexed: wrong colour format!\n"); 04775 return SANE_STATUS_UNSUPPORTED; 04776 } 04777 04778 /* split the image read into reasonably sized chunks */ 04779 chunk_lines = (scanner->params.lines + 7) / 8; 04780 chunk_size = chunk_lines * bytes_per_line; 04781 if (chunk_size > BUFFER_MAXSIZE) /* hardware limitation ? */ 04782 { 04783 chunk_lines = BUFFER_MAXSIZE / bytes_per_line; 04784 chunk_size = chunk_lines * bytes_per_line; 04785 } 04786 04787 size = bytes_per_line * /* deskewing needs a minimum */ 04788 (scanner->filter_offset1 + (scanner->filter_offset2 + 3) * 2); 04789 if (chunk_size < size) 04790 { 04791 chunk_lines = (size + bytes_per_line - 1) / bytes_per_line; 04792 chunk_size = chunk_lines * bytes_per_line; 04793 } 04794 04795 if (chunk_lines > scanner->params.lines) /* not larger than image */ 04796 { 04797 chunk_lines = scanner->params.lines; 04798 chunk_size = chunk_lines * bytes_per_line; 04799 } 04800 04801 buffer = malloc (chunk_size * 2); 04802 if (!buffer) 04803 { 04804 DBG (DBG_error, "pie_usb_reader_indexed: no buffer\n"); 04805 return SANE_STATUS_NO_MEM; 04806 } 04807 04808 size = scanner->bytes_per_line; 04809 if (flag_accumulate) 04810 size *= scanner->params.lines; 04811 for (i = 0; i < irgb; i++) 04812 { 04813 color_buf[i].b8 = malloc (size); 04814 if (!color_buf[i].b8) 04815 { 04816 DBG (DBG_error, "pie_usb_reader_indexed: no buffers\n"); 04817 for (j = 0; j < i; j++) 04818 free (color_buf[j].b8); 04819 free (buffer); 04820 return SANE_STATUS_NO_MEM; 04821 } 04822 color_ptr[i] = color_buf[i]; 04823 } 04824 gettimeofday (&start_time, NULL); 04825 04826 /* read one buffer in advance */ 04827 lines_todo = chunk_lines; 04828 set_read_length (sread.cmd, lines_todo * irgb); 04829 size = lines_todo * bytes_per_line; 04830 do 04831 { 04832 status = 04833 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, sread.size, 04834 buffer, &size); 04835 } 04836 while (status); 04837 DBG_DUMP (DBG_dump, buffer, 32); 04838 write_lines = scanner->params.lines; 04839 read_lines = write_lines - lines_todo; 04840 wrt_ptr = buffer + chunk_size; 04841 end_ptr = wrt_ptr + chunk_size; 04842 for (i = 0; i < irgb; i++) 04843 { 04844 idx_ptr[i] = (char *) buffer; 04845 iend_ptr[i] = idx_ptr[i] + chunk_size; 04846 idx_buf[i] = 1; 04847 src[i] = NULL; 04848 } 04849 request_data = 0; 04850 idx_found = 0; 04851 while (write_lines) 04852 { 04853 if (cancel_requ) 04854 { 04855 DBG (DBG_info, "pie_usb_reader_indexed: cancelled\n"); 04856 status = SANE_STATUS_CANCELLED; 04857 break; 04858 } 04859 for (i = 0; i < irgb; i++) /* find indices */ 04860 { 04861 while (src[i] == NULL) 04862 { 04863 if (*idx_ptr[i] == idx_char[i]) 04864 { 04865 src[i] = (unsigned char *) idx_ptr[i] + 2; 04866 idx_found++; 04867 } 04868 /* advance pointers unconditionally */ 04869 idx_ptr[i] += bytes_per_color; 04870 if (idx_ptr[i] >= iend_ptr[i]) 04871 { 04872 /* check for wrap */ 04873 if (idx_ptr[i] >= (char *) end_ptr) 04874 idx_ptr[i] = (char *) buffer; 04875 /* maintain private "end of buffer" */ 04876 iend_ptr[i] = idx_ptr[i] + chunk_size; 04877 idx_buf[i]--; 04878 /* request buffer fill if necessary */ 04879 if (idx_buf[i] == 0) 04880 { 04881 request_data = 1; 04882 break; 04883 } 04884 } 04885 } 04886 } 04887 04888 if (idx_found == irgb) /* success, reorder and line(s) */ 04889 { 04890 write_lines--; 04891 /* for (i = 0; i < irgb; i++) 04892 memcpy(color_ptr[i].b8, src[i], scanner->bytes_per_line); 04893 */ 04894 pie_usb_correct_shading (scanner, src, color_ptr, 04895 scanner->params.pixels_per_line, 04896 scanner->params.depth, 0, irgb - 1); 04897 if (!flag_postprocess) 04898 status = 04899 pie_usb_reader_write (scanner, fp, color_ptr, 04900 irgb_out, 1); 04901 if (flag_accumulate) 04902 { 04903 if (write_lines == 0) 04904 { 04905 if (DBG_LEVEL >= DBG_image) 04906 for (i = 0; i < irgb; i++) 04907 { 04908 snprintf (filename, 63, "/tmp/color-%d.pnm", i); 04909 status = 04910 pie_usb_write_pnm_file (filename, color_buf[i].b8, 04911 scanner->params.depth, 1, 04912 scanner->params.pixels_per_line, 04913 scanner->params.lines); 04914 if (status != SANE_STATUS_GOOD) 04915 break; 04916 } 04917 if (flag_postprocess) 04918 status = 04919 pie_usb_sw_post (scanner, color_buf, irgb, irgb_out); 04920 } 04921 else 04922 for (i = 0; i < irgb; i++) 04923 color_ptr[i].b8 += scanner->bytes_per_line; 04924 } 04925 if (status != SANE_STATUS_GOOD) 04926 { 04927 write_lines = 0; 04928 request_data = 0; 04929 } 04930 04931 for (i = 0; i < irgb; i++) /* setup for next line */ 04932 src[i] = NULL; 04933 idx_found = 0; 04934 } 04935 04936 if (request_data) /* read next data */ 04937 { 04938 if (read_lines) 04939 { 04940 lines_todo = chunk_lines; 04941 if (lines_todo > read_lines) 04942 lines_todo = read_lines; 04943 set_read_length (sread.cmd, lines_todo * irgb); 04944 size = lines_todo * bytes_per_line; 04945 do 04946 { 04947 status = 04948 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, 04949 sread.size, wrt_ptr, &size); 04950 } 04951 while (status); 04952 DBG_DUMP (DBG_dump, wrt_ptr, 32); 04953 read_lines -= lines_todo; 04954 wrt_ptr += chunk_size; 04955 if (wrt_ptr >= end_ptr) 04956 wrt_ptr = buffer; 04957 for (i = 0; i < irgb; i++) 04958 idx_buf[i]++; 04959 request_data = 0; 04960 } 04961 else if (write_lines) 04962 { 04963 DBG (DBG_error, 04964 "pie_usb_reader_indexed: deskew failed for %d lines\n", 04965 write_lines); 04966 write_lines = 0; 04967 } 04968 } 04969 } 04970 gettimeofday (&end_time, NULL); 04971 elapsed_time = ((end_time.tv_sec * 1000000 + end_time.tv_usec) 04972 - (start_time.tv_sec * 1000000 + 04973 start_time.tv_usec)) / 1000; 04974 DBG (DBG_read, 04975 "pie_usb_reader_indexed finished %d bytes in %ld ms, returning %s\n", 04976 (scanner->params.lines - read_lines) * scanner->params.bytes_per_line, 04977 elapsed_time, sane_strstatus (status)); 04978 04979 for (i = 0; i < irgb; i++) 04980 free (color_buf[i].b8); 04981 free (buffer); 04982 return status; 04983 } 04984 04985 #if 0 04986 /* ----------------------- PIE_USB_READER_PROCESS_LINE ------------------------ */ 04987 04988 /* Currently not used, and unused by the Windows programs. The scanners seem to support 04989 INQ_COLOR_FORMAT_LINE delivering ordered RGB data for one line */ 04990 04991 static int 04992 pie_usb_reader_process_line (Pie_Scanner * scanner, FILE * fp) 04993 { 04994 int status; 04995 int lines, lines_todo, chunk_lines; 04996 unsigned char *buffer, *reorder; 04997 size_t size, chunk_size; 04998 DBG (DBG_read, 04999 "pie_usb_reader_process reading %d lines of %d bytes/line\n", 05000 scanner->params.lines, scanner->params.bytes_per_line); 05001 chunk_lines = (scanner->params.lines + 7) / 8; 05002 chunk_size = chunk_lines * scanner->params.bytes_per_line; 05003 if (chunk_size > BUFFER_MAXSIZE) 05004 { 05005 chunk_lines = BUFFER_MAXSIZE / scanner->params.bytes_per_line; 05006 chunk_size = chunk_lines * scanner->params.bytes_per_line; 05007 } 05008 buffer = malloc (chunk_size); 05009 reorder = malloc (chunk_size); 05010 if (!buffer || !reorder) 05011 { 05012 free (buffer); 05013 free (reorder); 05014 return SANE_STATUS_NO_MEM; 05015 } 05016 05017 lines = scanner->params.lines; 05018 while (lines > 0) 05019 { 05020 lines_todo = chunk_lines; 05021 if (lines_todo > lines) 05022 lines_todo = lines; 05023 set_read_length (sread.cmd, lines_todo); 05024 size = lines_todo * scanner->params.bytes_per_line; 05025 do 05026 { 05027 status = 05028 pie_usb_scsi_wrapper (scanner->sfd, sread.cmd, 05029 sread.size, buffer, &size); 05030 } 05031 while (status); 05032 DBG_DUMP (DBG_dump, buffer, 64); 05033 if (scanner->colormode == RGB) 05034 { 05035 int offset = scanner->bytes_per_line; 05036 unsigned char *dest = reorder; 05037 unsigned char *src = buffer; 05038 int i, j; 05039 if (scanner->params.depth > 8) 05040 { 05041 for (j = lines_todo; j > 0; j--) 05042 { 05043 for (i = scanner->params.pixels_per_line; i > 0; i--) 05044 { 05045 *dest++ = *src; 05046 *dest++ = *(src + 1); 05047 *dest++ = *(src + offset); 05048 *dest++ = *(src + offset + 1); 05049 *dest++ = *(src + 2 * offset); 05050 *dest++ = *(src + 2 * offset + 1); 05051 src++; 05052 src++; 05053 } 05054 src += offset * 2; 05055 } 05056 } 05057 else 05058 { 05059 for (j = lines_todo; j > 0; j--) 05060 { 05061 for (i = scanner->params.pixels_per_line; i > 0; i--) 05062 { 05063 *dest++ = *src; 05064 *dest++ = *(src + offset); 05065 *dest++ = *(src + 2 * offset); 05066 src++; 05067 } 05068 src += offset * 2; 05069 } 05070 } 05071 fwrite (reorder, 1, size, fp); 05072 } 05073 else 05074 { 05075 fwrite (buffer, 1, size, fp); 05076 } 05077 lines -= lines_todo; 05078 } 05079 05080 free (buffer); 05081 free (reorder); 05082 return 0; 05083 } 05084 #endif 05085 05086 05087 /* ------------------------ PIE_USB_DO_CANCEL ------------------------------ */ 05096 static SANE_Status 05097 pie_usb_do_cancel (Pie_Scanner * scanner, int park) 05098 { 05099 05100 DBG (DBG_sane_proc, "pie_usb_do_cancel\n"); 05101 05102 if (scanner->scanning) 05103 { 05104 scanner->scanning = SANE_FALSE; 05105 05106 if (scanner->processing & POST_SW_ACCUM_MASK) /* single threaded case */ 05107 { 05108 cancel_requ = 1; 05109 } 05110 else /* threaded or forked case */ 05111 { 05112 if (scanner->pipe >= 0) /* cancel or error */ 05113 close (scanner->pipe); 05114 05115 if (scanner->reader_pid != NO_PID) 05116 { 05117 #if defined USE_PTHREAD || defined HAVE_OS2_H || defined __BEOS__ 05118 cancel_requ = 1; 05119 #else 05120 sanei_thread_kill (scanner->reader_pid); 05121 #endif 05122 sanei_thread_waitpid (scanner->reader_pid, 0); 05123 scanner->reader_pid = NO_PID; 05124 DBG (DBG_sane_info, "pie_usb_do_cancel: reader thread finished\n"); 05125 } 05126 05127 if (scanner->pipe >= 0) /* cancel or error */ 05128 { 05129 scanner->pipe = -1; 05130 pie_usb_scan (scanner, 0); 05131 } 05132 } 05133 } 05134 /* greatly improves handling when forked: watch scanner as it returns, 05135 * needs to be checked before another USB command is sent */ 05136 if ((scanner->parking_pid == NO_PID) && park) 05137 scanner->parking_pid = 05138 sanei_thread_begin (pie_usb_release_scanner, (void *) scanner); 05139 05140 return SANE_STATUS_CANCELLED; 05141 } 05142 05143 05144 /* ----------------------------- PIE_USB_READER_PROCESS_SIGTERM_HANDLER -------- */ 05148 static RETSIGTYPE 05149 pie_usb_reader_process_sigterm_handler (__sane_unused__ int signal) 05150 { 05151 cancel_requ = 1; 05152 return; 05153 } 05154 05155 05156 /* ------------------------ PIE_USB_READER_UNTHREADED ------------------------- */ 05171 static SANE_Status 05172 pie_usb_reader_unthreaded (Pie_Scanner * scanner) 05173 { 05174 SANE_Status status; 05175 05176 DBG (DBG_sane_proc, "pie_usb_reader_unthreaded\n"); 05177 05178 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 05179 { 05180 cancel_requ = 0; /* assume not canceled yet */ 05181 05182 status = pie_usb_reader_indexed (scanner, NULL); 05183 if (status != SANE_STATUS_GOOD) 05184 { 05185 pie_usb_scan (scanner, 0); 05186 scanner->scanning = SANE_FALSE; 05187 } 05188 else 05189 { 05190 scanner->total_bytes_stored = scanner->params.bytes_per_line * 05191 scanner->params.lines; 05192 scanner->total_bytes_read = 0; 05193 } 05194 return status; 05195 } 05196 else 05197 return SANE_STATUS_UNSUPPORTED; 05198 } 05199 05200 05201 /* ------------------------- PIE_USB_READER_PROCESS --------------------------- */ 05220 static int 05221 pie_usb_reader_process (void *data) /* executed as a child process */ 05222 { 05223 int status; 05224 FILE *fp; 05225 Pie_Scanner *scanner; 05226 sigset_t ignore_set; 05227 struct SIGACTION act; 05228 05229 scanner = (Pie_Scanner *) data; 05230 05231 if (sanei_thread_is_forked ()) 05232 { 05233 05234 close (scanner->pipe); 05235 05236 sigfillset (&ignore_set); 05237 sigdelset (&ignore_set, SIGTERM); 05238 #if defined (__APPLE__) && defined (__MACH__) 05239 sigdelset (&ignore_set, SIGUSR2); 05240 #endif 05241 sigprocmask (SIG_SETMASK, &ignore_set, 0); 05242 05243 memset (&act, 0, sizeof (act)); 05244 sigaction (SIGTERM, &act, 0); 05245 } 05246 05247 DBG (DBG_sane_proc, "pie_usb_reader_process started\n"); 05248 05249 cancel_requ = 0; /* assume not cancelled yet */ 05250 memset (&act, 0, sizeof (act)); /* define SIGTERM-handler */ 05251 act.sa_handler = pie_usb_reader_process_sigterm_handler; 05252 sigaction (SIGTERM, &act, 0); 05253 05254 fp = fdopen (scanner->reader_fds, "w"); 05255 if (!fp) 05256 return SANE_STATUS_IO_ERROR; 05257 05258 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 05259 status = pie_usb_reader_indexed (scanner, fp); 05260 else 05261 status = SANE_STATUS_UNSUPPORTED; 05262 05263 close (scanner->reader_fds); 05264 05265 DBG (DBG_sane_info, "pie_usb_reader_process: finished reading data\n"); 05266 05267 return status; 05268 } 05269 05270 05271 /* 05272 * @@ pie_usb_sane_xy routines replace large parts of the sane_xy functions 05273 */ 05274 05275 /* ------------------------------ PIE_USB_SANE_CONTROL_OPTION -------------------- */ 05281 static SANE_Status 05282 pie_usb_sane_control_option (SANE_Handle handle, SANE_Int option, 05283 SANE_Action action, void *val, SANE_Int * info) 05284 { 05285 Pie_Scanner *scanner = handle; 05286 SANE_Status status; 05287 SANE_Word cap; 05288 SANE_Int l_info; 05289 SANE_String_Const name; 05290 05291 l_info = 0; 05292 if (info) 05293 *info = l_info; 05294 05295 if (scanner->scanning) 05296 return SANE_STATUS_DEVICE_BUSY; 05297 05298 if ((unsigned) option >= NUM_OPTIONS) 05299 return SANE_STATUS_INVAL; 05300 05301 cap = scanner->opt[option].cap; 05302 if (!SANE_OPTION_IS_ACTIVE (cap)) 05303 return SANE_STATUS_INVAL; 05304 05305 name = scanner->opt[option].name; 05306 if (!name) 05307 name = "(no name)"; 05308 05309 if (action == SANE_ACTION_GET_VALUE) 05310 { 05311 05312 DBG (DBG_sane_option, "get %s [#%d]\n", name, option); 05313 05314 switch (option) 05315 { 05316 /* word options: */ 05317 case OPT_NUM_OPTS: 05318 case OPT_BIT_DEPTH: 05319 case OPT_RESOLUTION: 05320 case OPT_TL_X: 05321 case OPT_TL_Y: 05322 case OPT_BR_X: 05323 case OPT_BR_Y: 05324 case OPT_PREVIEW: 05325 case OPT_SW_GRAIN: 05326 case OPT_SW_SRGB: 05327 case OPT_SW_NEGA: 05328 *(SANE_Word *) val = scanner->val[option].w; 05329 break; 05330 05331 /* string options: */ 05332 case OPT_MODE: 05333 case OPT_SPEED: 05334 case OPT_SW_IRED: 05335 case OPT_SW_CROP: 05336 strcpy (val, scanner->val[option].s); 05337 } 05338 05339 return SANE_STATUS_GOOD; 05340 } 05341 else if (action == SANE_ACTION_SET_VALUE) 05342 { 05343 switch (scanner->opt[option].type) 05344 { 05345 case SANE_TYPE_INT: 05346 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 05347 *(SANE_Word *) val); 05348 break; 05349 05350 case SANE_TYPE_FIXED: 05351 DBG (DBG_sane_option, "set %s [#%d] to %f\n", name, option, 05352 SANE_UNFIX (*(SANE_Word *) val)); 05353 break; 05354 05355 case SANE_TYPE_STRING: 05356 DBG (DBG_sane_option, "set %s [#%d] to %s\n", name, option, 05357 (char *) val); 05358 break; 05359 05360 case SANE_TYPE_BOOL: 05361 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 05362 *(SANE_Word *) val); 05363 break; 05364 05365 default: 05366 DBG (DBG_sane_option, "set %s [#%d]\n", name, option); 05367 } 05368 05369 if (!SANE_OPTION_IS_SETTABLE (cap)) 05370 return SANE_STATUS_INVAL; 05371 05372 status = sanei_constrain_value (scanner->opt + option, val, &l_info); 05373 if (status != SANE_STATUS_GOOD) 05374 return status; 05375 05376 switch (option) 05377 { 05378 /* (mostly) side-effect-free word options: */ 05379 case OPT_RESOLUTION: 05380 case OPT_TL_X: 05381 case OPT_TL_Y: 05382 case OPT_BR_X: 05383 case OPT_BR_Y: 05384 l_info |= SANE_INFO_RELOAD_PARAMS; 05385 /* fall through */ 05386 case OPT_NUM_OPTS: 05387 case OPT_PREVIEW: 05388 case OPT_BIT_DEPTH: 05389 case OPT_SW_GRAIN: 05390 case OPT_SW_SRGB: 05391 case OPT_SW_NEGA: 05392 scanner->val[option].w = *(SANE_Word *) val; 05393 break; 05394 /* (mostly) side-effect-free string options: */ 05395 case OPT_SPEED: 05396 case OPT_SW_IRED: 05397 case OPT_SW_CROP: 05398 if (scanner->val[option].s) 05399 free (scanner->val[option].s); 05400 scanner->val[option].s = (SANE_Char *) strdup (val); 05401 break; 05402 /* options with side-effects: */ 05403 case OPT_MODE: 05404 { 05405 int is_rgbi = (strcmp (val, COLOR_IR_STR) == 0); 05406 05407 if (scanner->val[option].s) 05408 free (scanner->val[option].s); 05409 scanner->val[option].s = (SANE_Char *) strdup (val); 05410 l_info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 05411 05412 if (is_rgbi) 05413 { 05414 scanner->opt[OPT_SW_IRED].cap &= ~SANE_CAP_INACTIVE; 05415 } 05416 else 05417 { 05418 scanner->opt[OPT_SW_IRED].cap |= SANE_CAP_INACTIVE; 05419 } 05420 break; 05421 } 05422 } 05423 05424 if (info) 05425 *info = l_info; 05426 return SANE_STATUS_GOOD; 05427 } /* else */ 05428 return SANE_STATUS_INVAL; 05429 } 05430 05431 05432 /* ------------------------------------ PIE_USB_SANE_START ------------------------------ */ 05440 static SANE_Status 05441 pie_usb_sane_start (Pie_Scanner * scanner) 05442 { 05443 const char *mode; 05444 const char *prired; 05445 SANE_Status status; 05446 int fds[2]; 05447 05448 DBG (DBG_sane_init, "pie_usb_sane_start\n"); 05449 05450 mode = scanner->val[OPT_MODE].s; 05451 prired = scanner->val[OPT_SW_IRED].s; 05452 05453 status = pie_usb_is_scanner_released (scanner); 05454 if (status != SANE_STATUS_GOOD) 05455 return status; 05456 pie_power_save (scanner, 0); 05457 05458 scanner->colormode = RGB; 05459 scanner->processing = 0; 05460 if (scanner->val[OPT_PREVIEW].w != SANE_TRUE) 05461 { 05462 if (strcmp (mode, COLOR_IR_STR) == 0) 05463 { 05464 scanner->colormode = RGBI; 05465 if (strcmp (prired, IR_CLEAN_STR) == 0) 05466 scanner->processing |= POST_SW_DIRT; 05467 else 05468 if (strcmp (prired, IR_SPECT_STR) == 0) 05469 scanner->processing |= POST_SW_IRED; 05470 } 05471 if (scanner->val[OPT_SW_GRAIN].w != 0) 05472 scanner->processing |= POST_SW_GRAIN; 05473 if (strcmp (scanner->val[OPT_SW_CROP].s, THE_NONE_STR) != 0) 05474 scanner->processing |= POST_SW_CROP; 05475 } 05476 if ((scanner->val[OPT_SW_SRGB].w == SANE_TRUE) || 05477 (scanner->val[OPT_SW_NEGA].w == SANE_TRUE)) 05478 scanner->processing |= POST_SW_COLORS; 05479 05480 /* get and set geometric values for scanning */ 05481 scanner->resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w); 05482 05483 scanner->scanning = SANE_TRUE; /* definetly ! */ 05484 05485 status = pie_send_exposure (scanner); 05486 if (status != SANE_STATUS_GOOD) 05487 return status; 05488 status = pie_send_highlight_shadow (scanner); 05489 if (status != SANE_STATUS_GOOD) 05490 return status; 05491 status = pie_usb_set_window (scanner); 05492 if (status != SANE_STATUS_GOOD) 05493 return status; 05494 status = pie_usb_calibration_send (scanner, 0); 05495 if (status != SANE_STATUS_GOOD) 05496 return status; 05497 status = pie_usb_mode_select (scanner); 05498 if (status != SANE_STATUS_GOOD) 05499 return status; 05500 05501 status = pie_usb_scan (scanner, 1); 05502 if (status != SANE_STATUS_GOOD) 05503 return status; 05504 05505 /* if calibration data is there !! we have to get it */ 05506 if (scanner->cal_mode != scanner->device->model->op_mode[OPM_SKIPCAL]) 05507 { 05508 status = pie_usb_calibrate (scanner); 05509 if (status != SANE_STATUS_GOOD) 05510 return status; 05511 } 05512 status = pie_usb_copy_sensors (scanner); 05513 if (status != SANE_STATUS_GOOD) 05514 return status; 05515 05516 status = pie_usb_get_params (scanner); 05517 if (status != SANE_STATUS_GOOD) 05518 return status; 05519 05520 if (scanner->processing & POST_SW_ACCUM_MASK) 05521 { 05522 if (scanner->img_buffer.b8) /* reset buffer */ 05523 free (scanner->img_buffer.b8); 05524 scanner->img_buffer.b8 = NULL; 05525 scanner->total_bytes_stored = 0; 05526 scanner->total_bytes_read = 0; 05527 05528 if (scanner->processing & POST_SW_CROP) 05529 return pie_usb_reader_unthreaded (scanner); 05530 else 05531 return SANE_STATUS_GOOD; 05532 } 05533 else 05534 { 05535 if (pipe (fds) < 0) /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */ 05536 { 05537 DBG (DBG_error, "pie_usb_sane_start: could not create pipe\n"); 05538 scanner->scanning = SANE_FALSE; 05539 pie_usb_scan (scanner, 0); 05540 return SANE_STATUS_IO_ERROR; 05541 } 05542 05543 scanner->pipe = fds[0]; 05544 scanner->reader_fds = fds[1]; 05545 scanner->reader_pid = 05546 sanei_thread_begin (pie_usb_reader_process, (void *) scanner); 05547 05548 if (scanner->reader_pid == NO_PID) 05549 { 05550 DBG (DBG_error, "pie_usb_sane_start: sanei_thread_begin failed (%s)\n", 05551 strerror (errno)); 05552 return SANE_STATUS_NO_MEM; 05553 } 05554 05555 if (sanei_thread_is_forked ()) 05556 { 05557 close (scanner->reader_fds); 05558 scanner->reader_fds = -1; 05559 } 05560 05561 return SANE_STATUS_GOOD; 05562 } 05563 } 05564 05565 05566 /* ---------------------------------- PIE_USB_SANE_READ ------------------------------ */ 05574 static SANE_Status 05575 pie_usb_sane_read (Pie_Scanner * scanner, SANE_Byte * buf, SANE_Int max_len, 05576 SANE_Int * len) 05577 { 05578 SANE_Status status; 05579 ssize_t nread; 05580 05581 DBG (DBG_sane_proc, "pie_usb_sane_read\n"); 05582 05583 if (!(scanner->scanning)) /* OOPS, not scanning */ 05584 return SANE_STATUS_CANCELLED; 05585 05586 if (scanner->processing & POST_SW_ACCUM_MASK) 05587 { 05588 if (scanner->total_bytes_stored == 0) 05589 { 05590 status = pie_usb_reader_unthreaded (scanner); 05591 if (status != SANE_STATUS_GOOD) 05592 return status; 05593 } 05594 05595 nread = max_len; 05596 if(scanner->total_bytes_read + nread > scanner->total_bytes_stored) 05597 nread = scanner->total_bytes_stored - scanner->total_bytes_read; 05598 if (nread <= 0) 05599 return SANE_STATUS_EOF; 05600 05601 DBG (DBG_sane_info, "pie_usb_sane_read: copy %ld bytes\n", (long) nread); 05602 memcpy (buf, scanner->img_buffer.b8 + scanner->total_bytes_read, nread); 05603 scanner->total_bytes_read += nread; 05604 *len = nread; 05605 return SANE_STATUS_GOOD; 05606 } 05607 else 05608 { 05609 /* threaded or forked, read from pipe */ 05610 nread = read (scanner->pipe, buf, max_len); 05611 DBG (DBG_sane_info, "pie_usb_sane_read: read %ld bytes\n", (long) nread); 05612 05613 if (nread < 0) 05614 { 05615 if (errno == EAGAIN) 05616 { 05617 DBG (DBG_sane_info, "pie_usb_sane_read: EAGAIN\n"); 05618 return SANE_STATUS_GOOD; 05619 } 05620 else 05621 { 05622 pie_usb_do_cancel (scanner, SANE_TRUE); /* error, stop scanner */ 05623 return SANE_STATUS_IO_ERROR; 05624 } 05625 } 05626 05627 *len = nread; 05628 05629 if (nread == 0) /* EOF */ 05630 { 05631 /* presumably normal close of pipe, tell 05632 pie_usb_do_cancel to ommit some commands */ 05633 close (scanner->pipe); 05634 scanner->pipe = -1; 05635 pie_usb_do_cancel (scanner, SANE_FALSE); 05636 return SANE_STATUS_EOF; 05637 } 05638 05639 return SANE_STATUS_GOOD; 05640 } 05641 } 05642 05643 05644 /* ----------------------------------- PIE_USB_SANE_OPEN ------------------------------ */ 05656 static SANE_Status 05657 pie_usb_sane_open (Pie_Scanner * scanner, SANE_Handle * handle) 05658 { 05659 SANE_Status status; 05660 double di; 05661 int buf_size, i; 05662 05663 DBG (DBG_sane_proc, "pie_usb_sane_open started\n"); 05664 05665 status = pie_usb_attach_open (scanner->device->sane.name, &(scanner->sfd)); 05666 if (status != SANE_STATUS_GOOD) 05667 { 05668 DBG (DBG_error, "pie_usb_sane_open: open failed\n"); 05669 return SANE_STATUS_INVAL; 05670 } 05671 05672 /* During initial internal calibration of the scanner we can not issue all commands to 05673 complete our setup so the frontend will have to wait at some point. We have to 05674 query the scanner for initalizing options here. */ 05675 status = pie_usb_is_scanner_initialized (scanner->sfd); 05676 if (status != SANE_STATUS_GOOD) 05677 return status; 05678 05679 if (scanner->device->cal_info_count == 0) 05680 { 05681 pie_get_halftones (scanner->device, scanner->sfd); 05682 pie_get_cal_info (scanner->device, scanner->sfd); 05683 pie_get_speeds (scanner->device); 05684 } 05685 scanner->cal_mode = scanner->device->model->op_mode[OPM_QUALITY]; /* calibrate the first time */ 05686 scanner->reader_pid = NO_PID; 05687 scanner->parking_pid = NO_PID; 05688 05689 scanner->cal_data = malloc (sizeof (PIE_USB_Calibration)); 05690 if (!scanner->cal_data) 05691 return SANE_STATUS_NO_MEM; 05692 buf_size = scanner->device->cal_info[0].pixels_per_line; 05693 scanner->cal_data->sensors = malloc (buf_size); 05694 if (!scanner->cal_data->sensors) 05695 return SANE_STATUS_NO_MEM; 05696 buf_size *= 4 * sizeof (int); 05697 scanner->cal_data->shades = malloc (buf_size); 05698 if (!scanner->cal_data->shades) 05699 return SANE_STATUS_NO_MEM; 05700 05701 memcpy (&scanner->cal_data->cal_hiqual, 05702 &scanner->device->model->default_hiqual, 05703 sizeof (PIE_USB_Calibration_Set)); 05704 memcpy (&scanner->cal_data->cal_normal, 05705 &scanner->device->model->default_normal, 05706 sizeof (PIE_USB_Calibration_Set)); 05707 for (i = 0; i < 3; i++) 05708 scanner->cal_data->brightness[i] = 05709 scanner->device->model->default_brightness; 05710 05711 /* gamma lookup tables */ 05712 scanner->gamma_lut8 = malloc (256 * sizeof (double)); 05713 if (!scanner->gamma_lut8) 05714 return SANE_STATUS_NO_MEM; 05715 di = 255.0 / pow (255.0, CONST_GAMMA); 05716 for (i = 0; i < 256; i++) 05717 scanner->gamma_lut8[i] = di * pow ((double) i, CONST_GAMMA); 05718 scanner->gamma_lut16 = malloc (65536 * sizeof (double)); 05719 if (!scanner->gamma_lut16) 05720 return SANE_STATUS_NO_MEM; 05721 di = 65535.0 / pow (65535.0, CONST_GAMMA); 05722 for (i = 0; i < 65536; i++) 05723 scanner->gamma_lut16[i] = di * pow ((double) i, CONST_GAMMA); 05724 05725 pie_init_options (scanner); 05726 05727 /* ln lookup table for infrared cleaning */ 05728 status = sane_ir_ln_table (65536, &scanner->ln_lut); 05729 if (status != SANE_STATUS_GOOD) 05730 return status; 05731 05732 /* storage for software processing of whole image */ 05733 scanner->img_buffer.b8 = NULL; 05734 scanner->total_bytes_stored = 0; 05735 scanner->total_bytes_read = 0; 05736 05737 scanner->next = first_handle; /* insert newly opened handle into list of open handles: */ 05738 first_handle = scanner; 05739 *handle = scanner; 05740 05741 return SANE_STATUS_GOOD; 05742 } 05743 05744 05745 /* -------------------------------- PIE_USB_SANE_CLOSE ----------------------------- */ 05751 static void 05752 pie_usb_sane_close (Pie_Scanner * scanner) 05753 { 05754 DBG (DBG_sane_proc, "pie_usb_sane_close started\n"); 05755 05756 if (scanner->scanning) /* stop scan if still scanning */ 05757 pie_usb_do_cancel (scanner, SANE_TRUE); 05758 05759 pie_usb_is_scanner_released (scanner); /* not yet in parking position? */ 05760 05761 if (scanner->sfd >= 0) 05762 { 05763 sanei_usb_reset (scanner->sfd); /* close USB */ 05764 sanei_usb_close (scanner->sfd); 05765 } 05766 05767 if (scanner->cal_data) /* free calibration data */ 05768 { 05769 if (scanner->cal_data->shades) 05770 free (scanner->cal_data->shades); 05771 if (scanner->cal_data->sensors) 05772 free (scanner->cal_data->sensors); 05773 free (scanner->cal_data); 05774 } 05775 05776 /* ln lookup table for infrared cleaning */ 05777 free (scanner->ln_lut); 05778 /* gamma lookup tables */ 05779 free (scanner->gamma_lut8); 05780 free (scanner->gamma_lut16); 05781 05782 /* whole last image */ 05783 if (scanner->img_buffer.b8) 05784 free (scanner->img_buffer.b8); 05785 05786 return; 05787 } 05788 05789 05790 /* 05791 * @@ Original SCSI functions: Some of them call the pie_usb code 05792 * using the (*scanner->device->scsi_cmd) function pointer. 05793 */ 05794 05795 /*------------------------- PIE POWER SAVE -----------------------------*/ 05796 05797 static SANE_Status 05798 pie_power_save (Pie_Scanner * scanner, int time) 05799 { 05800 unsigned char buffer[128]; 05801 size_t size; 05802 SANE_Status status; 05803 unsigned char *data; 05804 05805 DBG (DBG_proc, "pie_power_save: %d min\n", time); 05806 05807 size = 6; 05808 05809 set_write_length (swrite.cmd, size); 05810 05811 memcpy (buffer, swrite.cmd, swrite.size); 05812 05813 data = buffer + swrite.size; 05814 memset (data, 0, size); 05815 05816 set_command (data, SET_POWER_SAVE_CONTROL); 05817 set_data_length (data, size - 4); 05818 data[4] = time & 0x7f; 05819 05820 status = 05821 (*scanner->device->scsi_cmd) (scanner->sfd, buffer, swrite.size + size, 05822 NULL, NULL); 05823 if (status) 05824 { 05825 DBG (DBG_error, "pie_power_save: write command returned status %s\n", 05826 sane_strstatus (status)); 05827 } 05828 05829 return status; 05830 } 05831 05832 05833 /*------------------------- PIE SEND EXPOSURE ONE -----------------------------*/ 05834 05835 05836 static SANE_Status 05837 pie_send_exposure_one (Pie_Scanner * scanner, int filter, int value) 05838 { 05839 unsigned char buffer[128]; 05840 size_t size; 05841 SANE_Status status; 05842 unsigned char *data; 05843 05844 DBG (DBG_proc, "pie_send_exposure_one\n"); 05845 05846 size = 8; 05847 05848 set_write_length (swrite.cmd, size); 05849 05850 memcpy (buffer, swrite.cmd, swrite.size); 05851 05852 data = buffer + swrite.size; 05853 memset (data, 0, size); 05854 05855 set_command (data, SET_EXP_TIME); 05856 set_data_length (data, size - 4); 05857 05858 data[4] = filter; 05859 05860 set_data (data, 6, (int) value, 2); 05861 05862 status = 05863 (*scanner->device->scsi_cmd) (scanner->sfd, buffer, swrite.size + size, 05864 NULL, NULL); 05865 if (status) 05866 { 05867 DBG (DBG_error, 05868 "pie_send_exposure_one: write command returned status %s\n", 05869 sane_strstatus (status)); 05870 } 05871 05872 return status; 05873 } 05874 05875 /*------------------------- PIE SEND EXPOSURE -----------------------------*/ 05876 05877 static SANE_Status 05878 pie_send_exposure (Pie_Scanner * scanner) 05879 { 05880 SANE_Status status; 05881 05882 DBG (DBG_proc, "pie_send_exposure\n"); 05883 05884 status = pie_send_exposure_one (scanner, FILTER_RED, 100); 05885 if (status) 05886 return status; 05887 05888 status = pie_send_exposure_one (scanner, FILTER_GREEN, 100); 05889 if (status) 05890 return status; 05891 05892 status = pie_send_exposure_one (scanner, FILTER_BLUE, 100); 05893 if (status) 05894 return status; 05895 05896 return SANE_STATUS_GOOD; 05897 } 05898 05899 05900 /*------------------------- PIE SEND HIGHLIGHT/SHADOW ONE -----------------------------*/ 05901 05902 static SANE_Status 05903 pie_send_highlight_shadow_one (Pie_Scanner * scanner, int filter, 05904 int highlight, int shadow) 05905 { 05906 unsigned char buffer[128]; 05907 size_t size; 05908 SANE_Status status; 05909 unsigned char *data; 05910 05911 DBG (DBG_proc, "pie_send_highlight_shadow_one\n"); 05912 05913 size = 8; 05914 05915 set_write_length (swrite.cmd, size); 05916 05917 memcpy (buffer, swrite.cmd, swrite.size); 05918 05919 data = buffer + swrite.size; 05920 memset (data, 0, size); 05921 05922 set_command (data, SET_EXP_TIME); 05923 set_data_length (data, size - 4); 05924 05925 data[4] = filter; 05926 05927 data[6] = highlight; 05928 data[7] = shadow; 05929 05930 status = 05931 (*scanner->device->scsi_cmd) (scanner->sfd, buffer, swrite.size + size, 05932 NULL, NULL); 05933 if (status) 05934 { 05935 DBG (DBG_error, 05936 "pie_send_highlight_shadow_one: write command returned status %s\n", 05937 sane_strstatus (status)); 05938 } 05939 05940 return status; 05941 } 05942 05943 /*------------------------- PIE SEND HIGHLIGHT/SHADOW -----------------------------*/ 05944 05945 static SANE_Status 05946 pie_send_highlight_shadow (Pie_Scanner * scanner) 05947 { 05948 SANE_Status status; 05949 05950 DBG (DBG_proc, "pie_send_highlight_shadow\n"); 05951 05952 status = pie_send_highlight_shadow_one (scanner, FILTER_RED, 100, 0); 05953 if (status) 05954 return status; 05955 05956 status = pie_send_highlight_shadow_one (scanner, FILTER_GREEN, 100, 0); 05957 if (status) 05958 return status; 05959 05960 status = pie_send_highlight_shadow_one (scanner, FILTER_BLUE, 100, 0); 05961 if (status) 05962 return status; 05963 05964 return SANE_STATUS_GOOD; 05965 } 05966 05967 /*------------------------- PIE PERFORM CAL ----------------------------*/ 05968 05969 static SANE_Status 05970 pie_perform_cal (Pie_Scanner * scanner, int cal_index) 05971 { 05972 long *red_result; 05973 long *green_result; 05974 long *blue_result; 05975 long *neutral_result; 05976 long *result = NULL; 05977 int rcv_length, send_length; 05978 int rcv_lines, rcv_bits, send_bits; 05979 int pixels_per_line; 05980 int i; 05981 unsigned char *rcv_buffer, *rcv_ptr; 05982 unsigned char *send_buffer, *send_ptr; 05983 size_t size; 05984 int fullscale; 05985 int cal_limit; 05986 int k; 05987 int filter; 05988 SANE_Status status; 05989 05990 DBG (DBG_proc, "pie_perform_cal\n"); 05991 05992 pixels_per_line = scanner->device->cal_info[cal_index].pixels_per_line; 05993 rcv_length = pixels_per_line; 05994 send_length = pixels_per_line; 05995 05996 rcv_bits = scanner->device->cal_info[cal_index].receive_bits; 05997 if (rcv_bits > 8) 05998 rcv_length *= 2; /* 2 bytes / sample */ 05999 06000 send_bits = scanner->device->cal_info[cal_index].send_bits; 06001 if (send_bits > 8) 06002 send_length *= 2; /* 2 bytes / sample */ 06003 06004 rcv_lines = scanner->device->cal_info[cal_index].num_lines; 06005 06006 send_length += 2; /* space for filter at start */ 06007 06008 if (scanner->colormode == RGB) 06009 { 06010 rcv_lines *= 3; 06011 send_length *= 3; 06012 rcv_length += 2; /* 2 bytes for index at front of data (only in RGB??) */ 06013 } 06014 06015 send_length += 4; /* space for header at start of data */ 06016 06017 /* alllocate buffers for the receive data, the result buffers, and for the send data */ 06018 rcv_buffer = (unsigned char *) malloc (rcv_length); 06019 06020 red_result = (long *) calloc (pixels_per_line, sizeof (long)); 06021 green_result = (long *) calloc (pixels_per_line, sizeof (long)); 06022 blue_result = (long *) calloc (pixels_per_line, sizeof (long)); 06023 neutral_result = (long *) calloc (pixels_per_line, sizeof (long)); 06024 06025 if (!rcv_buffer || !red_result || !green_result || !blue_result 06026 || !neutral_result) 06027 { 06028 /* at least one malloc failed, so free all buffers (free accepts NULL) */ 06029 free (rcv_buffer); 06030 free (red_result); 06031 free (green_result); 06032 free (blue_result); 06033 free (neutral_result); 06034 return SANE_STATUS_NO_MEM; 06035 } 06036 06037 /* read the cal data a line at a time, and accumulate into the result arrays */ 06038 while (rcv_lines--) 06039 { 06040 /* TUR */ 06041 status = pie_wait_scanner (scanner); 06042 if (status) 06043 { 06044 free (rcv_buffer); 06045 free (red_result); 06046 free (green_result); 06047 free (blue_result); 06048 free (neutral_result); 06049 return status; 06050 } 06051 06052 set_read_length (sread.cmd, 1); 06053 size = rcv_length; 06054 06055 DBG (DBG_info, "pie_perform_cal: reading 1 line (%lu bytes)\n", 06056 (u_long) size); 06057 06058 status = 06059 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, rcv_buffer, 06060 &size); 06061 06062 if (status) 06063 { 06064 DBG (DBG_error, 06065 "pie_perform_cal: read command returned status %s\n", 06066 sane_strstatus (status)); 06067 free (rcv_buffer); 06068 free (red_result); 06069 free (green_result); 06070 free (blue_result); 06071 free (neutral_result); 06072 return status; 06073 } 06074 06075 DBG_DUMP (DBG_dump, rcv_buffer, 32); 06076 06077 /* which result buffer does this line belong to? */ 06078 if (scanner->colormode == RGB) 06079 { 06080 if (*rcv_buffer == 'R') 06081 result = red_result; 06082 else if (*rcv_buffer == 'G') 06083 result = green_result; 06084 else if (*rcv_buffer == 'B') 06085 result = blue_result; 06086 else if (*rcv_buffer == 'N') 06087 result = neutral_result; 06088 else 06089 { 06090 DBG (DBG_error, "pie_perform_cal: invalid index byte (%02x)\n", 06091 *rcv_buffer); 06092 DBG_DUMP (DBG_error, rcv_buffer, 32); 06093 free (rcv_buffer); 06094 free (red_result); 06095 free (green_result); 06096 free (blue_result); 06097 free (neutral_result); 06098 return SANE_STATUS_INVAL; 06099 } 06100 rcv_ptr = rcv_buffer + 2; 06101 } 06102 else 06103 { 06104 /* monochrome - no bytes indicating filter here */ 06105 result = neutral_result; 06106 rcv_ptr = rcv_buffer; 06107 } 06108 06109 /* now add the values in this line to the result array */ 06110 for (i = 0; i < pixels_per_line; i++) 06111 { 06112 result[i] += *rcv_ptr++; 06113 if (rcv_bits > 8) 06114 { 06115 result[i] += (*rcv_ptr++) << 8; 06116 } 06117 } 06118 } 06119 06120 /* got all the cal data, now process it ready to send back */ 06121 free (rcv_buffer); 06122 send_buffer = (unsigned char *) malloc (send_length + swrite.size); 06123 06124 if (!send_buffer) 06125 { 06126 free (red_result); 06127 free (green_result); 06128 free (blue_result); 06129 free (neutral_result); 06130 return SANE_STATUS_NO_MEM; 06131 } 06132 06133 rcv_lines = scanner->device->cal_info[cal_index].num_lines; 06134 fullscale = (1 << rcv_bits) - 1; 06135 cal_limit = fullscale / (1 << scanner->device->inquiry_cal_eqn); 06136 k = (1 << scanner->device->inquiry_cal_eqn) - 1; 06137 06138 /* set up scsi command and data */ 06139 size = send_length; 06140 06141 memcpy (send_buffer, swrite.cmd, swrite.size); 06142 set_write_length (send_buffer, size); 06143 06144 set_command (send_buffer + swrite.size, SEND_CAL_DATA); 06145 set_data_length (send_buffer + swrite.size, size - 4); 06146 06147 send_ptr = send_buffer + swrite.size + 4; 06148 06149 for (filter = FILTER_NEUTRAL; filter <= FILTER_BLUE; filter <<= 1) 06150 { 06151 06152 /* only send data for filter we expect to send */ 06153 if (!(filter & scanner->cal_filter)) 06154 continue; 06155 06156 set_data (send_ptr, 0, filter, 2); 06157 send_ptr += 2; 06158 06159 if (scanner->colormode == RGB) 06160 { 06161 switch (filter) 06162 { 06163 case FILTER_RED: 06164 result = red_result; 06165 break; 06166 06167 case FILTER_GREEN: 06168 result = green_result; 06169 break; 06170 06171 case FILTER_BLUE: 06172 result = blue_result; 06173 break; 06174 06175 case FILTER_NEUTRAL: 06176 result = neutral_result; 06177 break; 06178 } 06179 } 06180 else 06181 result = neutral_result; 06182 06183 /* for each pixel */ 06184 for (i = 0; i < pixels_per_line; i++) 06185 { 06186 long x; 06187 06188 /* make average */ 06189 x = result[i] / rcv_lines; 06190 06191 /* ensure not overflowed */ 06192 if (x > fullscale) 06193 x = fullscale; 06194 06195 /* process according to required calibration equation */ 06196 if (scanner->device->inquiry_cal_eqn) 06197 { 06198 if (x <= cal_limit) 06199 x = fullscale; 06200 else 06201 x = ((fullscale - x) * fullscale) / (x * k); 06202 } 06203 06204 if (rcv_bits > send_bits) 06205 x >>= (rcv_bits - send_bits); 06206 else if (send_bits > rcv_bits) 06207 x <<= (send_bits - rcv_bits); 06208 06209 /* put result into send buffer */ 06210 *send_ptr++ = x; 06211 if (send_bits > 8) 06212 *send_ptr++ = x >> 8; 06213 } 06214 } 06215 06216 /* now send the data back to scanner */ 06217 06218 /* TUR */ 06219 status = pie_wait_scanner (scanner); 06220 if (status) 06221 { 06222 free (red_result); 06223 free (green_result); 06224 free (blue_result); 06225 free (neutral_result); 06226 free (send_buffer); 06227 return status; 06228 } 06229 06230 DBG (DBG_info, "pie_perform_cal: sending cal data (%lu bytes)\n", 06231 (u_long) size); 06232 DBG_DUMP (DBG_dump, send_buffer, 64); 06233 06234 status = 06235 sanei_scsi_cmd (scanner->sfd, send_buffer, swrite.size + size, NULL, 06236 NULL); 06237 if (status) 06238 { 06239 DBG (DBG_error, "pie_perform_cal: write command returned status %s\n", 06240 sane_strstatus (status)); 06241 free (red_result); 06242 free (green_result); 06243 free (blue_result); 06244 free (neutral_result); 06245 free (send_buffer); 06246 return status; 06247 } 06248 06249 free (red_result); 06250 free (green_result); 06251 free (blue_result); 06252 free (neutral_result); 06253 free (send_buffer); 06254 06255 return SANE_STATUS_GOOD; 06256 } 06257 06258 /*------------------------- PIE DO CAL -----------------------------*/ 06259 06260 static SANE_Status 06261 pie_do_cal (Pie_Scanner * scanner) 06262 { 06263 SANE_Status status; 06264 int cal_index; 06265 06266 DBG (DBG_proc, "pie_do_cal\n"); 06267 06268 if (scanner->device->inquiry_scan_capability & INQ_CAP_EXT_CAL) 06269 { 06270 for (cal_index = 0; cal_index < scanner->device->cal_info_count; 06271 cal_index++) 06272 if (scanner->device->cal_info[cal_index].cal_type == 06273 scanner->cal_mode) 06274 { 06275 status = pie_perform_cal (scanner, cal_index); 06276 if (status != SANE_STATUS_GOOD) 06277 return status; 06278 } 06279 } 06280 06281 return SANE_STATUS_GOOD; 06282 } 06283 06284 /*------------------------- PIE DWNLD GAMMA ONE -----------------------------*/ 06285 06286 static SANE_Status 06287 pie_dwnld_gamma_one (Pie_Scanner * scanner, int filter, SANE_Int * table) 06288 { 06289 unsigned char *buffer; 06290 size_t size; 06291 SANE_Status status; 06292 unsigned char *data; 06293 int i; 06294 06295 DBG (DBG_proc, "pie_dwnld_gamma_one\n"); 06296 06297 /* TUR */ 06298 status = pie_wait_scanner (scanner); 06299 if (status) 06300 { 06301 return status; 06302 } 06303 06304 if (scanner->device->inquiry_gamma_bits > 8) 06305 size = scanner->gamma_length * 2 + 6; 06306 else 06307 size = scanner->gamma_length + 6; 06308 06309 buffer = malloc (size + swrite.size); 06310 if (!buffer) 06311 return SANE_STATUS_NO_MEM; 06312 06313 set_write_length (swrite.cmd, size); 06314 06315 memcpy (buffer, swrite.cmd, swrite.size); 06316 06317 data = buffer + swrite.size; 06318 memset (data, 0, size); 06319 06320 set_command (data, DWNLD_GAMMA_TABLE); 06321 set_data_length (data, size - 4); 06322 06323 data[4] = filter; 06324 06325 for (i = 0; i < scanner->gamma_length; i++) 06326 { 06327 if (scanner->device->inquiry_gamma_bits > 8) 06328 { 06329 set_data (data, 6 + 2 * i, table ? table[i] : i, 2); 06330 } 06331 else 06332 { 06333 set_data (data, 6 + i, table ? table[i] : i, 1); 06334 } 06335 } 06336 06337 DBG_DUMP (DBG_dump, data, 128); 06338 06339 status = 06340 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 06341 if (status) 06342 { 06343 DBG (DBG_error, 06344 "pie_dwnld_gamma_one: write command returned status %s\n", 06345 sane_strstatus (status)); 06346 } 06347 06348 free (buffer); 06349 06350 return status; 06351 } 06352 06353 /*------------------------- PIE DWNLD GAMMA -----------------------------*/ 06354 06355 static SANE_Status 06356 pie_dwnld_gamma (Pie_Scanner * scanner) 06357 { 06358 SANE_Status status; 06359 06360 DBG (DBG_proc, "pie_dwnld_gamma\n"); 06361 06362 if (scanner->colormode == RGB) 06363 { 06364 status = 06365 pie_dwnld_gamma_one (scanner, FILTER_RED, scanner->gamma_table[1]); 06366 if (status) 06367 return status; 06368 06369 06370 status = 06371 pie_dwnld_gamma_one (scanner, FILTER_GREEN, scanner->gamma_table[2]); 06372 if (status) 06373 return status; 06374 06375 status = 06376 pie_dwnld_gamma_one (scanner, FILTER_BLUE, scanner->gamma_table[3]); 06377 if (status) 06378 return status; 06379 } 06380 else 06381 { 06382 SANE_Int *table; 06383 06384 /* if lineart or half tone, force gamma to be one to one by passing NULL */ 06385 if (scanner->colormode == GRAYSCALE) 06386 table = scanner->gamma_table[0]; 06387 else 06388 table = NULL; 06389 06390 status = pie_dwnld_gamma_one (scanner, FILTER_GREEN, table); 06391 if (status) 06392 return status; 06393 } 06394 06395 usleep (DOWNLOAD_GAMMA_WAIT_TIME); 06396 06397 return SANE_STATUS_GOOD; 06398 } 06399 06400 /*------------------------- PIE SET WINDOW -----------------------------*/ 06401 06402 static SANE_Status 06403 pie_set_window (Pie_Scanner * scanner) 06404 { 06405 unsigned char buffer[128]; 06406 size_t size; 06407 SANE_Status status; 06408 unsigned char *data; 06409 double x, dpmm; 06410 06411 DBG (DBG_proc, "pie_set_window\n"); 06412 06413 size = 14; 06414 06415 set_write_length (swrite.cmd, size); 06416 06417 memcpy (buffer, swrite.cmd, swrite.size); 06418 06419 data = buffer + swrite.size; 06420 memset (data, 0, size); 06421 06422 set_command (data, SET_SCAN_FRAME); 06423 set_data_length (data, size - 4); 06424 06425 data[4] = 0x80; 06426 if (scanner->colormode == HALFTONE) 06427 data[4] |= 0x40; 06428 06429 dpmm = (double) scanner->device->inquiry_pixel_resolution / MM_PER_INCH; 06430 06431 x = SANE_UNFIX (scanner->val[OPT_TL_X].w) * dpmm; 06432 set_data (data, 6, (int) x, 2); 06433 DBG (DBG_info, "TL_X: %d\n", (int) x); 06434 06435 x = SANE_UNFIX (scanner->val[OPT_TL_Y].w) * dpmm; 06436 set_data (data, 8, (int) x, 2); 06437 DBG (DBG_info, "TL_Y: %d\n", (int) x); 06438 06439 x = SANE_UNFIX (scanner->val[OPT_BR_X].w) * dpmm; 06440 set_data (data, 10, (int) x, 2); 06441 DBG (DBG_info, "BR_X: %d\n", (int) x); 06442 06443 x = SANE_UNFIX (scanner->val[OPT_BR_Y].w) * dpmm; 06444 set_data (data, 12, (int) x, 2); 06445 DBG (DBG_info, "BR_Y: %d\n", (int) x); 06446 06447 status = 06448 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL); 06449 if (status) 06450 { 06451 DBG (DBG_error, "pie_set_window: write command returned status %s\n", 06452 sane_strstatus (status)); 06453 } 06454 06455 return status; 06456 } 06457 06458 06459 /*------------------------- PIE MODE SELECT -----------------------------*/ 06460 06461 static SANE_Status 06462 pie_mode_select (Pie_Scanner * scanner) 06463 { 06464 06465 SANE_Status status; 06466 unsigned char buffer[128]; 06467 size_t size; 06468 unsigned char *data; 06469 int i; 06470 06471 DBG (DBG_proc, "pie_mode_select\n"); 06472 06473 size = 14; 06474 06475 set_mode_length (smode.cmd, size); 06476 06477 memcpy (buffer, smode.cmd, smode.size); 06478 06479 data = buffer + smode.size; 06480 memset (data, 0, size); 06481 06482 /* size of data */ 06483 data[1] = size - 2; 06484 06485 /* set resolution required */ 06486 set_data (data, 2, scanner->resolution, 2); 06487 06488 /* set color filter and color depth */ 06489 switch (scanner->colormode) 06490 { 06491 case RGB: 06492 if (scanner->device->inquiry_filters & INQ_ONE_PASS_COLOR) 06493 { 06494 data[4] = INQ_ONE_PASS_COLOR; 06495 scanner->cal_filter = FILTER_RED | FILTER_GREEN | FILTER_BLUE; 06496 } 06497 else 06498 { 06499 DBG (DBG_error, 06500 "pie_mode_select: support for multipass color not yet implemented\n"); 06501 return SANE_STATUS_UNSUPPORTED; 06502 } 06503 data[5] = INQ_COLOR_DEPTH_8; 06504 break; 06505 06506 case GRAYSCALE: 06507 case LINEART: 06508 case HALFTONE: 06509 /* choose which filter to use for monochrome mode */ 06510 if (scanner->device->inquiry_filters & INQ_FILTER_NEUTRAL) 06511 { 06512 data[4] = FILTER_NEUTRAL; 06513 scanner->cal_filter = FILTER_NEUTRAL; 06514 } 06515 else if (scanner->device->inquiry_filters & INQ_FILTER_GREEN) 06516 { 06517 data[4] = FILTER_GREEN; 06518 scanner->cal_filter = FILTER_GREEN; 06519 } 06520 else if (scanner->device->inquiry_filters & INQ_FILTER_RED) 06521 { 06522 data[4] = FILTER_RED; 06523 scanner->cal_filter = FILTER_RED; 06524 } 06525 else if (scanner->device->inquiry_filters & INQ_FILTER_BLUE) 06526 { 06527 data[4] = FILTER_BLUE; 06528 scanner->cal_filter = FILTER_BLUE; 06529 } 06530 else 06531 { 06532 DBG (DBG_error, 06533 "pie_mode_select: scanner doesn't appear to support monochrome\n"); 06534 return SANE_STATUS_UNSUPPORTED; 06535 } 06536 06537 if (scanner->colormode == GRAYSCALE) 06538 data[5] = INQ_COLOR_DEPTH_8; 06539 else 06540 data[5] = INQ_COLOR_DEPTH_1; 06541 break; 06542 } 06543 06544 /* choose color packing method */ 06545 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE) 06546 data[6] = INQ_COLOR_FORMAT_LINE; 06547 else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 06548 data[6] = INQ_COLOR_FORMAT_INDEX; 06549 else 06550 { 06551 DBG (DBG_error, 06552 "pie_mode_select: support for pixel packing not yet implemented\n"); 06553 return SANE_STATUS_UNSUPPORTED; 06554 } 06555 06556 /* choose data format */ 06557 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_INTEL) 06558 data[8] = INQ_IMG_FMT_INTEL; 06559 else 06560 { 06561 DBG (DBG_error, 06562 "pie_mode_select: support for Motorola format not yet implemented\n"); 06563 return SANE_STATUS_UNSUPPORTED; 06564 } 06565 06566 /* set required speed */ 06567 i = 0; 06568 while (scanner->device->speed_list[i] != NULL) 06569 { 06570 if (strcmp (scanner->device->speed_list[i], scanner->val[OPT_SPEED].s) 06571 == 0) 06572 break; 06573 i++; 06574 } 06575 06576 if (scanner->device->speed_list[i] == NULL) 06577 data[9] = 0; 06578 else 06579 data[9] = i; 06580 06581 scanner->cal_mode = CAL_MODE_FLATBED; 06582 06583 /* if preview supported, ask for preview, limit resolution to max for fast preview */ 06584 if (scanner->val[OPT_PREVIEW].w 06585 && (scanner->device->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW)) 06586 { 06587 DBG (DBG_info, "pie_mode_select: setting preview\n"); 06588 scanner->cal_mode |= CAL_MODE_PREVIEW; 06589 data[9] |= INQ_CAP_FAST_PREVIEW; 06590 data[9] &= ~INQ_CAP_SPEEDS; 06591 if (scanner->resolution > scanner->device->inquiry_fast_preview_res) 06592 set_data (data, 2, scanner->device->inquiry_fast_preview_res, 2); 06593 } 06594 06595 06596 /* set required halftone pattern */ 06597 i = 0; 06598 while (scanner->device->halftone_list[i] != NULL) 06599 { 06600 if (strcmp 06601 (scanner->device->halftone_list[i], 06602 scanner->val[OPT_HALFTONE_PATTERN].s) == 0) 06603 break; 06604 i++; 06605 } 06606 06607 if (scanner->device->halftone_list[i] == NULL) 06608 data[12] = 0; /* halftone pattern */ 06609 else 06610 data[12] = i; 06611 06612 data[13] = SANE_UNFIX (scanner->val[OPT_THRESHOLD].w) * 255 / 100; /* lineart threshold */ 06613 06614 DBG (DBG_info, "pie_mode_select: speed %02x\n", data[9]); 06615 DBG (DBG_info, "pie_mode_select: halftone %d\n", data[12]); 06616 DBG (DBG_info, "pie_mode_select: threshold %02x\n", data[13]); 06617 06618 status = 06619 sanei_scsi_cmd (scanner->sfd, buffer, smode.size + size, NULL, NULL); 06620 if (status) 06621 { 06622 DBG (DBG_error, "pie_mode_select: write command returned status %s\n", 06623 sane_strstatus (status)); 06624 } 06625 06626 return status; 06627 } 06628 06629 06630 /*------------------------- PIE SCAN -----------------------------*/ 06631 06632 static SANE_Status 06633 pie_scan (Pie_Scanner * scanner, int start) 06634 { 06635 SANE_Status status; 06636 06637 DBG (DBG_proc, "pie_scan\n"); 06638 06639 /* TUR */ 06640 status = pie_wait_scanner (scanner); 06641 if (status) 06642 { 06643 return status; 06644 } 06645 06646 set_scan_cmd (scan.cmd, start); 06647 06648 do 06649 { 06650 status = sanei_scsi_cmd (scanner->sfd, scan.cmd, scan.size, NULL, NULL); 06651 if (status) 06652 { 06653 DBG (DBG_error, "pie_scan: write command returned status %s\n", 06654 sane_strstatus (status)); 06655 usleep (SCAN_WARMUP_WAIT_TIME); 06656 } 06657 } 06658 while (start && status); 06659 06660 usleep (SCAN_WAIT_TIME); 06661 06662 return status; 06663 } 06664 06665 06666 /* --------------------------------------- PIE WAIT SCANNER -------------------------- */ 06667 06668 06669 static SANE_Status 06670 pie_wait_scanner (Pie_Scanner * scanner) 06671 { 06672 SANE_Status status; 06673 int cnt = 0; 06674 06675 DBG (DBG_proc, "wait_scanner\n"); 06676 06677 do 06678 { 06679 if (cnt > 100) /* maximal 100 * 0.5 sec = 50 sec */ 06680 { 06681 DBG (DBG_warning, "scanner does not get ready\n"); 06682 return -1; 06683 } 06684 /* test unit ready */ 06685 status = 06686 sanei_scsi_cmd (scanner->sfd, test_unit_ready.cmd, 06687 test_unit_ready.size, NULL, NULL); 06688 06689 cnt++; 06690 06691 if (status) 06692 { 06693 if (cnt == 1) 06694 { 06695 DBG (DBG_info2, "scanner reports %s, waiting ...\n", 06696 sane_strstatus (status)); 06697 } 06698 06699 usleep (TUR_WAIT_TIME); 06700 } 06701 } 06702 while (status != SANE_STATUS_GOOD); 06703 06704 DBG (DBG_info, "scanner ready\n"); 06705 06706 06707 return status; 06708 } 06709 06710 06711 /* -------------------------------------- PIE GET PARAMS -------------------------- */ 06712 06713 06714 static SANE_Status 06715 pie_get_params (Pie_Scanner * scanner) 06716 { 06717 SANE_Status status; 06718 size_t size; 06719 unsigned char buffer[128]; 06720 06721 DBG (DBG_proc, "pie_get_params\n"); 06722 06723 status = pie_wait_scanner (scanner); 06724 if (status) 06725 return status; 06726 06727 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE) 06728 size = 16; 06729 else 06730 06731 size = 14; 06732 06733 set_param_length (param.cmd, size); 06734 06735 status = 06736 sanei_scsi_cmd (scanner->sfd, param.cmd, param.size, buffer, &size); 06737 06738 if (status) 06739 { 06740 DBG (DBG_error, "pie_get_params: command returned status %s\n", 06741 sane_strstatus (status)); 06742 } 06743 else 06744 { 06745 DBG (DBG_info, "Scan Width: %d\n", get_param_scan_width (buffer)); 06746 DBG (DBG_info, "Scan Lines: %d\n", get_param_scan_lines (buffer)); 06747 DBG (DBG_info, "Scan bytes: %d\n", get_param_scan_bytes (buffer)); 06748 06749 DBG (DBG_info, "Offset 1: %d\n", 06750 get_param_scan_filter_offset1 (buffer)); 06751 DBG (DBG_info, "Offset 2: %d\n", 06752 get_param_scan_filter_offset2 (buffer)); 06753 DBG (DBG_info, "Scan period: %d\n", get_param_scan_period (buffer)); 06754 DBG (DBG_info, "Xfer rate: %d\n", get_param_scsi_xfer_rate (buffer)); 06755 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE) 06756 DBG (DBG_info, "Avail lines: %d\n", 06757 get_param_scan_available_lines (buffer)); 06758 06759 scanner->filter_offset1 = get_param_scan_filter_offset1 (buffer); 06760 scanner->filter_offset2 = get_param_scan_filter_offset2 (buffer); 06761 scanner->bytes_per_line = get_param_scan_bytes (buffer); 06762 06763 scanner->params.pixels_per_line = get_param_scan_width (buffer); 06764 scanner->params.lines = get_param_scan_lines (buffer); 06765 06766 switch (scanner->colormode) 06767 { 06768 case RGB: 06769 scanner->params.format = SANE_FRAME_RGB; 06770 scanner->params.depth = 8; 06771 scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer); 06772 break; 06773 06774 case GRAYSCALE: 06775 scanner->params.format = SANE_FRAME_GRAY; 06776 scanner->params.depth = 8; 06777 scanner->params.bytes_per_line = get_param_scan_bytes (buffer); 06778 break; 06779 06780 case HALFTONE: 06781 case LINEART: 06782 scanner->params.format = SANE_FRAME_GRAY; 06783 scanner->params.depth = 1; 06784 scanner->params.bytes_per_line = get_param_scan_bytes (buffer); 06785 break; 06786 } 06787 06788 scanner->params.last_frame = 0; 06789 } 06790 06791 return status; 06792 } 06793 06794 06795 /* -------------------------------------- PIE GRAB SCANNER -------------------------- */ 06796 06797 06798 static SANE_Status 06799 pie_grab_scanner (Pie_Scanner * scanner) 06800 { 06801 SANE_Status status; 06802 06803 DBG (DBG_proc, "grab_scanner\n"); 06804 06805 06806 status = pie_wait_scanner (scanner); 06807 if (status) 06808 return status; 06809 06810 status = 06811 sanei_scsi_cmd (scanner->sfd, reserve_unit.cmd, reserve_unit.size, NULL, 06812 NULL); 06813 06814 06815 if (status) 06816 { 06817 DBG (DBG_error, "pie_grab_scanner: command returned status %s\n", 06818 sane_strstatus (status)); 06819 } 06820 else 06821 { 06822 DBG (DBG_info, "scanner reserved\n"); 06823 } 06824 06825 return status; 06826 } 06827 06828 06829 /* ------------------------------------ PIE GIVE SCANNER -------------------------- */ 06830 06831 06832 static SANE_Status 06833 pie_give_scanner (Pie_Scanner * scanner) 06834 { 06835 SANE_Status status; 06836 06837 DBG (DBG_info2, "trying to release scanner ...\n"); 06838 06839 status = 06840 sanei_scsi_cmd (scanner->sfd, release_unit.cmd, release_unit.size, NULL, 06841 NULL); 06842 if (status) 06843 { 06844 DBG (DBG_error, "pie_give_scanner: command returned status %s\n", 06845 sane_strstatus (status)); 06846 } 06847 else 06848 { 06849 DBG (DBG_info, "scanner released\n"); 06850 } 06851 return status; 06852 } 06853 06854 06855 /* ------------------- PIE READER PROCESS INDEXED ------------------- */ 06856 06857 static int 06858 pie_reader_process_indexed (Pie_Scanner * scanner, FILE * fp) 06859 { 06860 int status; 06861 int lines; 06862 unsigned char *buffer, *reorder = NULL; 06863 unsigned char *red_buffer = NULL, *green_buffer = NULL; 06864 unsigned char *red_in = NULL, *red_out = NULL; 06865 unsigned char *green_in = NULL, *green_out = NULL; 06866 int red_size = 0, green_size = 0; 06867 int bytes_per_line; 06868 int red_count = 0, green_count = 0; 06869 06870 size_t size; 06871 06872 DBG (DBG_read, "reading %d lines of %d bytes/line (indexed)\n", 06873 scanner->params.lines, scanner->params.bytes_per_line); 06874 06875 lines = scanner->params.lines; 06876 bytes_per_line = scanner->bytes_per_line; 06877 06878 /* allocate receive buffer */ 06879 buffer = malloc (bytes_per_line + 2); 06880 if (!buffer) 06881 { 06882 return SANE_STATUS_NO_MEM; 06883 } 06884 06885 /* allocate deskew buffers for RGB mode */ 06886 if (scanner->colormode == RGB) 06887 { 06888 lines *= 3; 06889 06890 red_size = bytes_per_line * (scanner->filter_offset1 + 06891 scanner->filter_offset2 + 2); 06892 green_size = bytes_per_line * (scanner->filter_offset2 + 2); 06893 06894 DBG (DBG_info2, 06895 "pie_reader_process_indexed: alloc %d lines (%d bytes) for red buffer\n", 06896 red_size / bytes_per_line, red_size); 06897 DBG (DBG_info2, 06898 "pie_reader_process_indexed: alloc %d lines (%d bytes) for green buffer\n", 06899 green_size / bytes_per_line, green_size); 06900 06901 reorder = malloc (scanner->params.bytes_per_line); 06902 red_buffer = malloc (red_size); 06903 green_buffer = malloc (green_size); 06904 06905 if (!reorder || !red_buffer || !green_buffer) 06906 { 06907 free (buffer); 06908 free (reorder); 06909 free (red_buffer); 06910 free (green_buffer); 06911 return SANE_STATUS_NO_MEM; 06912 } 06913 06914 red_in = red_out = red_buffer; 06915 green_in = green_out = green_buffer; 06916 } 06917 06918 while (lines--) 06919 { 06920 set_read_length (sread.cmd, 1); 06921 size = bytes_per_line + 2; 06922 06923 do 06924 { 06925 status = 06926 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer, 06927 &size); 06928 } 06929 while (status); 06930 06931 DBG_DUMP (DBG_dump, buffer, 64); 06932 06933 if (scanner->colormode == RGB) 06934 { 06935 /* we're assuming that we get red before green before blue here */ 06936 switch (*buffer) 06937 { 06938 case 'R': 06939 /* copy to red buffer */ 06940 memcpy (red_in, buffer + 2, bytes_per_line); 06941 06942 /* advance in pointer, and check for wrap */ 06943 red_in += bytes_per_line; 06944 if (red_in >= (red_buffer + red_size)) 06945 red_in = red_buffer; 06946 06947 /* increment red line count */ 06948 red_count++; 06949 DBG (DBG_info2, 06950 "pie_reader_process_indexed: got a red line (%d)\n", 06951 red_count); 06952 break; 06953 06954 case 'G': 06955 /* copy to green buffer */ 06956 memcpy (green_in, buffer + 2, bytes_per_line); 06957 06958 /* advance in pointer, and check for wrap */ 06959 green_in += bytes_per_line; 06960 if (green_in >= (green_buffer + green_size)) 06961 green_in = green_buffer; 06962 06963 /* increment green line count */ 06964 green_count++; 06965 DBG (DBG_info2, 06966 "pie_reader_process_indexed: got a green line (%d)\n", 06967 green_count); 06968 break; 06969 06970 case 'B': 06971 /* check we actually have red and green data available */ 06972 if (!red_count || !green_count) 06973 { 06974 DBG (DBG_error, 06975 "pie_reader_process_indexed: deskew buffer empty (%d %d)\n", 06976 red_count, green_count); 06977 return SANE_STATUS_INVAL; 06978 } 06979 red_count--; 06980 green_count--; 06981 06982 DBG (DBG_info2, 06983 "pie_reader_process_indexed: got a blue line\n"); 06984 06985 { 06986 int i; 06987 unsigned char *red, *green, *blue, *dest; 06988 06989 /* now pack the pixels lines into RGB format */ 06990 dest = reorder; 06991 red = red_out; 06992 green = green_out; 06993 blue = buffer + 2; 06994 06995 for (i = bytes_per_line; i > 0; i--) 06996 { 06997 *dest++ = *red++; 06998 *dest++ = *green++; 06999 *dest++ = *blue++; 07000 } 07001 fwrite (reorder, 1, scanner->params.bytes_per_line, fp); 07002 07003 /* advance out pointers, and check for wrap */ 07004 red_out += bytes_per_line; 07005 if (red_out >= (red_buffer + red_size)) 07006 red_out = red_buffer; 07007 green_out += bytes_per_line; 07008 if (green_out >= (green_buffer + green_size)) 07009 green_out = green_buffer; 07010 } 07011 break; 07012 07013 default: 07014 DBG (DBG_error, 07015 "pie_reader_process_indexed: bad filter index\n"); 07016 } 07017 } 07018 else 07019 { 07020 DBG (DBG_info2, 07021 "pie_reader_process_indexed: got a line (%lu bytes)\n", 07022 (u_long) size); 07023 07024 /* just send the data on, assume filter bytes not present as per calibration case */ 07025 fwrite (buffer, 1, scanner->params.bytes_per_line, fp); 07026 } 07027 } 07028 07029 free (buffer); 07030 free (reorder); 07031 free (red_buffer); 07032 free (green_buffer); 07033 return 0; 07034 } 07035 07036 /* ----------------------------- PIE_READER_PROCESS_FMTLINE -------------------- */ 07037 07038 static int 07039 pie_reader_process_fmtline (Pie_Scanner * scanner, FILE * fp) 07040 { 07041 int status; 07042 int lines; 07043 unsigned char *buffer, *reorder; 07044 size_t size; 07045 07046 DBG (DBG_read, "reading %d lines of %d bytes/line\n", scanner->params.lines, 07047 scanner->params.bytes_per_line); 07048 07049 buffer = malloc (scanner->params.bytes_per_line); 07050 reorder = malloc (scanner->params.bytes_per_line); 07051 if (!buffer || !reorder) 07052 { 07053 free (buffer); 07054 free (reorder); 07055 return SANE_STATUS_NO_MEM; 07056 } 07057 07058 lines = scanner->params.lines; 07059 07060 while (lines--) 07061 { 07062 set_read_length (sread.cmd, 1); 07063 size = scanner->params.bytes_per_line; 07064 07065 do 07066 { 07067 status = 07068 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer, 07069 &size); 07070 } 07071 while (status); 07072 07073 DBG_DUMP (DBG_dump, buffer, 64); 07074 07075 if (scanner->colormode == RGB) 07076 { 07077 int i; 07078 unsigned char *src, *dest; 07079 int offset; 07080 07081 dest = reorder; 07082 src = buffer; 07083 offset = scanner->params.pixels_per_line; 07084 07085 for (i = scanner->params.pixels_per_line; i > 0; i--) 07086 { 07087 *dest++ = *src; 07088 *dest++ = *(src + offset); 07089 *dest++ = *(src + 2 * offset); 07090 src++; 07091 } 07092 fwrite (reorder, 1, scanner->params.bytes_per_line, fp); 07093 } 07094 else 07095 { 07096 fwrite (buffer, 1, scanner->params.bytes_per_line, fp); 07097 } 07098 07099 fflush (fp); 07100 } 07101 07102 free (buffer); 07103 free (reorder); 07104 07105 return 0; 07106 } 07107 07108 07109 07110 /* ------------------------------- PIE_READER_PROCESS_SIGTERM_HANDLER ---------- */ 07111 07112 07113 static RETSIGTYPE 07114 pie_reader_process_sigterm_handler (int signal) 07115 { 07116 DBG (DBG_sane_info, "pie_reader_process: terminated by signal %d\n", signal); 07117 07118 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 07119 sanei_scsi_req_flush_all (); /* flush SCSI queue */ 07120 #else 07121 sanei_scsi_req_flush_all (); /* flush SCSI queue */ 07122 #endif 07123 07124 _exit (SANE_STATUS_GOOD); 07125 } 07126 07127 07128 07129 /* ---------------------------- PIE_READER_PROCESS --------------------------- */ 07130 07131 07132 static int 07133 pie_reader_process (void *data) /* executed as a child process */ 07134 { 07135 int status; 07136 FILE *fp; 07137 Pie_Scanner *scanner; 07138 sigset_t ignore_set; 07139 struct SIGACTION act; 07140 07141 scanner = (Pie_Scanner *) data; 07142 07143 if (sanei_thread_is_forked ()) 07144 { 07145 07146 close (scanner->pipe); 07147 07148 sigfillset (&ignore_set); 07149 sigdelset (&ignore_set, SIGTERM); 07150 #if defined (__APPLE__) && defined (__MACH__) 07151 sigdelset (&ignore_set, SIGUSR2); 07152 #endif 07153 sigprocmask (SIG_SETMASK, &ignore_set, 0); 07154 07155 memset (&act, 0, sizeof (act)); 07156 sigaction (SIGTERM, &act, 0); 07157 } 07158 07159 DBG (DBG_sane_proc, "pie_reader_process started\n"); 07160 07161 memset (&act, 0, sizeof (act)); /* define SIGTERM-handler */ 07162 act.sa_handler = pie_reader_process_sigterm_handler; 07163 sigaction (SIGTERM, &act, 0); 07164 07165 fp = fdopen (scanner->reader_fds, "w"); 07166 if (!fp) 07167 { 07168 return SANE_STATUS_IO_ERROR; 07169 } 07170 07171 DBG (DBG_sane_info, "pie_reader_process: starting to READ data\n"); 07172 07173 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE) 07174 status = pie_reader_process_fmtline (scanner, fp); 07175 else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX) 07176 status = pie_reader_process_indexed (scanner, fp); 07177 else 07178 status = SANE_STATUS_UNSUPPORTED; 07179 07180 fclose (fp); 07181 07182 DBG (DBG_sane_info, "pie_reader_process: finished reading data\n"); 07183 07184 return status; 07185 } 07186 07187 07188 /* ------------------------------ PIE_ATTACH_ONE -------------------------------- */ 07189 07190 /* callback function for sanei_usb_attach_matching_devices */ 07191 static SANE_Status 07192 pie_attach_one (const char *name) 07193 { 07194 pie_attach_scanner (name, 0); 07195 return SANE_STATUS_GOOD; 07196 } 07197 07198 07199 /* --------------------------- PIE_CLOSE_PIPE -------------------------------- */ 07200 07201 static SANE_Status 07202 pie_close_pipe (Pie_Scanner * scanner) 07203 { 07204 DBG (DBG_sane_proc, "pie_close_pipe\n"); 07205 07206 if (scanner->pipe >= 0) 07207 { 07208 close (scanner->pipe); 07209 scanner->pipe = -1; 07210 } 07211 07212 return SANE_STATUS_EOF; 07213 } 07214 07215 07216 07217 /* -------------------------- PIE_DO_CANCEL -------------------------------- */ 07218 07219 07220 static SANE_Status 07221 pie_do_cancel (Pie_Scanner * scanner) 07222 { 07223 DBG (DBG_sane_proc, "pie_do_cancel\n"); 07224 07225 scanner->scanning = SANE_FALSE; 07226 07227 if (scanner->reader_pid != NO_PID) 07228 { 07229 DBG (DBG_sane_info, "killing pie_reader_process\n"); 07230 sanei_thread_kill (scanner->reader_pid); 07231 sanei_thread_waitpid (scanner->reader_pid, 0); 07232 scanner->reader_pid = NO_PID; 07233 DBG (DBG_sane_info, "pie_reader_process killed\n"); 07234 } 07235 07236 if (scanner->sfd >= 0) 07237 { 07238 pie_scan (scanner, 0); 07239 07240 pie_power_save (scanner, 15); 07241 07242 pie_give_scanner (scanner); /* reposition and release scanner */ 07243 07244 DBG (DBG_sane_info, "closing scannerdevice filedescriptor\n"); 07245 sanei_scsi_close (scanner->sfd); 07246 scanner->sfd = -1; 07247 } 07248 07249 return SANE_STATUS_CANCELLED; 07250 } 07251 07252 07253 /* 07254 * @@ sane_xy functions: Most of them call their pie_usb counterparts for USB scanners 07255 */ 07256 07257 /* --------------------------------------- SANE INIT ---------------------------------- */ 07258 07259 SANE_Status 07260 sane_init (SANE_Int * version_code, 07261 SANE_Auth_Callback __sane_unused__ authorize) 07262 { 07263 char dev_name[PATH_MAX]; 07264 size_t len; 07265 FILE *fp; 07266 07267 DBG_INIT (); 07268 07269 DBG (DBG_sane_init, "sane_init() build %d\n", BUILD); 07270 07271 if (version_code) 07272 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); 07273 07274 /* initialize usb use */ 07275 sanei_usb_init (); 07276 /* initialize infrared handling */ 07277 sanei_ir_init (); 07278 /* initialize magic handling */ 07279 sanei_magic_init (); 07280 07281 fp = sanei_config_open (PIE_CONFIG_FILE); 07282 if (!fp) 07283 { 07284 pie_attach_scanner ("/dev/scanner", 0); /* no config-file: /dev/scanner */ 07285 return SANE_STATUS_GOOD; 07286 } 07287 07288 while (sanei_config_read (dev_name, sizeof (dev_name), fp)) 07289 { 07290 if (dev_name[0] == '#') 07291 { 07292 continue; 07293 } /* ignore line comments */ 07294 07295 len = strlen (dev_name); 07296 07297 if (!len) /* ignore empty lines */ 07298 { 07299 continue; 07300 } 07301 07302 DBG (DBG_sane_proc, "sane_init() trying %s\n", dev_name); 07303 sanei_config_attach_matching_devices (dev_name, pie_usb_try_attach); 07304 } 07305 07306 fclose (fp); 07307 07308 return SANE_STATUS_GOOD; 07309 } 07310 07311 07312 /* ----------------------------------------- SANE EXIT ---------------------------------- */ 07313 07314 07315 void 07316 sane_exit (void) 07317 { 07318 Pie_Device *dev, *next; 07319 int i; 07320 07321 DBG (DBG_sane_init, "sane_exit()\n"); 07322 07323 for (dev = first_dev; dev; dev = next) 07324 { 07325 next = dev->next; 07326 free (dev->devicename); 07327 if (dev->model == NULL) 07328 { 07329 free (dev->vendor); 07330 free (dev->product); 07331 } 07332 free (dev->version); 07333 if (dev->cal_info) 07334 free (dev->cal_info); 07335 i = 0; 07336 while (dev->halftone_list[i] != NULL) 07337 free (dev->halftone_list[i++]); 07338 i = 0; 07339 while (dev->speed_list[i] != NULL) 07340 free (dev->speed_list[i++]); 07341 07342 free (dev); 07343 } 07344 07345 first_dev = NULL; 07346 07347 if (devlist) 07348 { 07349 free (devlist); 07350 devlist = NULL; 07351 } 07352 } 07353 07354 07355 /* ------------------------------------------ SANE GET DEVICES --------------------------- */ 07356 07357 07358 SANE_Status 07359 sane_get_devices (const SANE_Device *** device_list, 07360 SANE_Bool __sane_unused__ local_only) 07361 { 07362 Pie_Device *dev; 07363 int i; 07364 07365 DBG (DBG_sane_init, "sane_get_devices\n"); 07366 07367 i = 0; 07368 for (dev = first_dev; dev; dev = dev->next) 07369 i++; 07370 07371 if (devlist) 07372 { 07373 free (devlist); 07374 } 07375 07376 devlist = malloc ((i + 1) * sizeof (devlist[0])); 07377 if (!devlist) 07378 { 07379 return SANE_STATUS_NO_MEM; 07380 } 07381 07382 i = 0; 07383 07384 for (dev = first_dev; dev; dev = dev->next) 07385 { 07386 devlist[i++] = &dev->sane; 07387 } 07388 07389 devlist[i] = NULL; 07390 07391 *device_list = devlist; 07392 07393 return SANE_STATUS_GOOD; 07394 } 07395 07396 07397 /* --------------------------------------- SANE OPEN ---------------------------------- */ 07398 07399 SANE_Status 07400 sane_open (SANE_String_Const devicename, SANE_Handle * handle) 07401 { 07402 Pie_Device *dev; 07403 SANE_Status status; 07404 Pie_Scanner *scanner; 07405 int i, j; 07406 07407 DBG (DBG_sane_init, "sane_open(%s)\n", devicename); 07408 07409 if (devicename[0]) /* search for devicename */ 07410 { 07411 for (dev = first_dev; dev; dev = dev->next) 07412 { 07413 if (strcmp (dev->sane.name, devicename) == 0) 07414 { 07415 break; 07416 } 07417 } 07418 07419 if (!dev) 07420 { 07421 status = pie_attach_scanner (devicename, &dev); 07422 if (status != SANE_STATUS_GOOD) 07423 { 07424 return status; 07425 } 07426 } 07427 } 07428 else 07429 { 07430 dev = first_dev; /* empty devicename -> use first device */ 07431 } 07432 07433 07434 if (!dev) 07435 { 07436 return SANE_STATUS_INVAL; 07437 } 07438 07439 scanner = malloc (sizeof (*scanner)); 07440 if (!scanner) 07441 07442 { 07443 return SANE_STATUS_NO_MEM; 07444 } 07445 07446 memset (scanner, 0, sizeof (*scanner)); 07447 07448 scanner->device = dev; 07449 scanner->sfd = -1; 07450 scanner->pipe = -1; 07451 07452 if (scanner->device->model != NULL) /* USB film scanners */ 07453 return pie_usb_sane_open (scanner, handle); 07454 07455 scanner->gamma_length = 1 << (scanner->device->inquiry_gamma_bits); 07456 07457 DBG (DBG_sane_info, "Using %d bits for gamma input\n", 07458 scanner->device->inquiry_gamma_bits); 07459 07460 scanner->gamma_range.min = 0; 07461 scanner->gamma_range.max = scanner->gamma_length - 1; 07462 scanner->gamma_range.quant = 0; 07463 07464 scanner->gamma_table[0] = 07465 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 07466 scanner->gamma_table[1] = 07467 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 07468 scanner->gamma_table[2] = 07469 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 07470 scanner->gamma_table[3] = 07471 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int)); 07472 07473 for (i = 0; i < 4; ++i) /* gamma_table[0,1,2,3] */ 07474 { 07475 for (j = 0; j < scanner->gamma_length; ++j) 07476 { 07477 scanner->gamma_table[i][j] = j; 07478 } 07479 } 07480 07481 pie_init_options (scanner); 07482 07483 scanner->next = first_handle; /* insert newly opened handle into list of open handles: */ 07484 first_handle = scanner; 07485 07486 *handle = scanner; 07487 07488 return SANE_STATUS_GOOD; 07489 } 07490 07491 07492 /* ------------------------------------ SANE CLOSE --------------------------------- */ 07493 07494 07495 void 07496 sane_close (SANE_Handle handle) 07497 { 07498 Pie_Scanner *prev, *scanner; 07499 07500 DBG (DBG_sane_init, "sane_close\n"); 07501 07502 /* remove handle from list of open handles: */ 07503 prev = 0; 07504 07505 for (scanner = first_handle; scanner; scanner = scanner->next) 07506 { 07507 if (scanner == handle) 07508 { 07509 break; 07510 } 07511 07512 prev = scanner; 07513 } 07514 07515 if (!scanner) 07516 { 07517 DBG (DBG_error, "close: invalid handle %p\n", handle); 07518 return; /* oops, not a handle we know about */ 07519 } 07520 07521 if (prev) 07522 { 07523 prev->next = scanner->next; 07524 } 07525 else 07526 { 07527 first_handle = scanner->next; 07528 } 07529 07530 if (scanner->device->model != NULL) /* USB film scanners */ 07531 { 07532 pie_usb_sane_close (scanner); 07533 } 07534 else 07535 { 07536 if (scanner->scanning) /* stop scan if still scanning */ 07537 { 07538 pie_do_cancel (handle); 07539 } 07540 07541 free (scanner->gamma_table[0]); /* free custom gamma tables */ 07542 free (scanner->gamma_table[1]); 07543 free (scanner->gamma_table[2]); 07544 free (scanner->gamma_table[3]); 07545 } 07546 free (scanner->val[OPT_MODE].s); 07547 free (scanner->val[OPT_SPEED].s); 07548 free (scanner->val[OPT_HALFTONE_PATTERN].s); 07549 free (scanner->val[OPT_SW_IRED].s); 07550 free (scanner->val[OPT_SW_CROP].s); 07551 07552 scanner->bufsize = 0; 07553 07554 free (scanner); /* free scanner */ 07555 } 07556 07557 07558 /* ---------------------------------- SANE GET OPTION DESCRIPTOR ----------------- */ 07559 07560 const SANE_Option_Descriptor * 07561 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 07562 { 07563 Pie_Scanner *scanner = handle; 07564 07565 DBG (DBG_sane_option, "sane_get_option_descriptor %d\n", option); 07566 07567 if ((unsigned) option >= NUM_OPTIONS) 07568 { 07569 return 0; 07570 } 07571 07572 return scanner->opt + option; 07573 } 07574 07575 07576 /* ---------------------------------- SANE CONTROL OPTION ------------------------ */ 07577 07578 SANE_Status 07579 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action, 07580 void *val, SANE_Int * info) 07581 { 07582 Pie_Scanner *scanner = handle; 07583 SANE_Status status; 07584 SANE_Word cap; 07585 SANE_String_Const name; 07586 07587 if (scanner->device->model != NULL) 07588 return pie_usb_sane_control_option (handle, option, action, val, info); 07589 07590 if (info) 07591 { 07592 *info = 0; 07593 } 07594 07595 if (scanner->scanning) 07596 { 07597 return SANE_STATUS_DEVICE_BUSY; 07598 } 07599 07600 if ((unsigned) option >= NUM_OPTIONS) 07601 { 07602 return SANE_STATUS_INVAL; 07603 } 07604 07605 cap = scanner->opt[option].cap; 07606 if (!SANE_OPTION_IS_ACTIVE (cap)) 07607 { 07608 return SANE_STATUS_INVAL; 07609 } 07610 07611 name = scanner->opt[option].name; 07612 if (!name) 07613 { 07614 name = "(no name)"; 07615 } 07616 07617 if (action == SANE_ACTION_GET_VALUE) 07618 { 07619 07620 DBG (DBG_sane_option, "get %s [#%d]\n", name, option); 07621 07622 switch (option) 07623 { 07624 /* word options: */ 07625 case OPT_NUM_OPTS: 07626 case OPT_RESOLUTION: 07627 case OPT_TL_X: 07628 case OPT_TL_Y: 07629 case OPT_BR_X: 07630 case OPT_BR_Y: 07631 case OPT_PREVIEW: 07632 case OPT_THRESHOLD: 07633 *(SANE_Word *) val = scanner->val[option].w; 07634 return SANE_STATUS_GOOD; 07635 07636 /* word-array options: */ 07637 case OPT_GAMMA_VECTOR: 07638 case OPT_GAMMA_VECTOR_R: 07639 case OPT_GAMMA_VECTOR_G: 07640 case OPT_GAMMA_VECTOR_B: 07641 memcpy (val, scanner->val[option].wa, scanner->opt[option].size); 07642 return SANE_STATUS_GOOD; 07643 07644 #if 0 07645 /* string options: */ 07646 case OPT_SOURCE: 07647 #endif 07648 case OPT_MODE: 07649 case OPT_HALFTONE_PATTERN: 07650 case OPT_SPEED: 07651 strcpy (val, scanner->val[option].s); 07652 return SANE_STATUS_GOOD; 07653 } 07654 } 07655 else if (action == SANE_ACTION_SET_VALUE) 07656 { 07657 switch (scanner->opt[option].type) 07658 { 07659 case SANE_TYPE_INT: 07660 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 07661 *(SANE_Word *) val); 07662 break; 07663 07664 case SANE_TYPE_FIXED: 07665 DBG (DBG_sane_option, "set %s [#%d] to %f\n", name, option, 07666 SANE_UNFIX (*(SANE_Word *) val)); 07667 break; 07668 07669 case SANE_TYPE_STRING: 07670 DBG (DBG_sane_option, "set %s [#%d] to %s\n", name, option, 07671 (char *) val); 07672 break; 07673 07674 case SANE_TYPE_BOOL: 07675 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option, 07676 *(SANE_Word *) val); 07677 break; 07678 07679 default: 07680 DBG (DBG_sane_option, "set %s [#%d]\n", name, option); 07681 } 07682 07683 if (!SANE_OPTION_IS_SETTABLE (cap)) 07684 { 07685 return SANE_STATUS_INVAL; 07686 } 07687 07688 status = sanei_constrain_value (scanner->opt + option, val, info); 07689 if (status != SANE_STATUS_GOOD) 07690 { 07691 return status; 07692 } 07693 07694 switch (option) 07695 { 07696 /* (mostly) side-effect-free word options: */ 07697 case OPT_RESOLUTION: 07698 case OPT_TL_X: 07699 case OPT_TL_Y: 07700 case OPT_BR_X: 07701 case OPT_BR_Y: 07702 if (info) 07703 { 07704 *info |= SANE_INFO_RELOAD_PARAMS; 07705 } 07706 /* fall through */ 07707 case OPT_NUM_OPTS: 07708 case OPT_PREVIEW: 07709 case OPT_THRESHOLD: 07710 scanner->val[option].w = *(SANE_Word *) val; 07711 return SANE_STATUS_GOOD; 07712 07713 /* side-effect-free word-array options: */ 07714 case OPT_GAMMA_VECTOR: 07715 case OPT_GAMMA_VECTOR_R: 07716 case OPT_GAMMA_VECTOR_G: 07717 case OPT_GAMMA_VECTOR_B: 07718 memcpy (scanner->val[option].wa, val, scanner->opt[option].size); 07719 return SANE_STATUS_GOOD; 07720 07721 /* options with side-effects: */ 07722 07723 case OPT_MODE: 07724 { 07725 int halftoning; 07726 07727 if (scanner->val[option].s) 07728 { 07729 free (scanner->val[option].s); 07730 } 07731 07732 scanner->val[option].s = (SANE_Char *) strdup (val); 07733 07734 if (info) 07735 { 07736 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 07737 } 07738 07739 scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; 07740 07741 07742 scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 07743 scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 07744 scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 07745 scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 07746 scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 07747 07748 halftoning = (strcmp (val, HALFTONE_STR) == 0); 07749 07750 if (halftoning || strcmp (val, LINEART_STR) == 0) 07751 { /* one bit modes */ 07752 if (halftoning) 07753 { /* halftoning modes */ 07754 scanner->opt[OPT_HALFTONE_PATTERN].cap &= 07755 ~SANE_CAP_INACTIVE; 07756 } 07757 else 07758 { /* lineart modes */ 07759 } 07760 scanner->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE; 07761 } 07762 else 07763 { /* multi-bit modes(gray or color) */ 07764 } 07765 07766 if ((strcmp (val, LINEART_STR) == 0) 07767 || (strcmp (val, HALFTONE_STR) == 0) 07768 || (strcmp (val, GRAY_STR) == 0)) 07769 { 07770 scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; 07771 } 07772 else if (strcmp (val, COLOR_STR) == 0) 07773 { 07774 /* scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; */ 07775 scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE; 07776 scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE; 07777 scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE; 07778 } 07779 return SANE_STATUS_GOOD; 07780 } 07781 07782 case OPT_SPEED: 07783 case OPT_HALFTONE_PATTERN: 07784 { 07785 if (scanner->val[option].s) 07786 { 07787 free (scanner->val[option].s); 07788 } 07789 07790 scanner->val[option].s = (SANE_Char *) strdup (val); 07791 07792 return SANE_STATUS_GOOD; 07793 } 07794 } 07795 } /* else */ 07796 return SANE_STATUS_INVAL; 07797 } 07798 07799 07800 /* ------------------------------------ SANE GET PARAMETERS ------------------------ */ 07801 07802 07803 SANE_Status 07804 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 07805 { 07806 Pie_Scanner *scanner = handle; 07807 const char *mode; 07808 07809 DBG (DBG_sane_info, "sane_get_parameters\n"); 07810 07811 if (!scanner->scanning) 07812 { /* not scanning, so lets use recent values */ 07813 double width, length, x_dpi, y_dpi; 07814 07815 memset (&scanner->params, 0, sizeof (scanner->params)); 07816 07817 width = 07818 SANE_UNFIX (scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w); 07819 length = 07820 SANE_UNFIX (scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w); 07821 x_dpi = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w); 07822 y_dpi = x_dpi; 07823 07824 #if 0 07825 if ((scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE) 07826 || (scanner->val[OPT_PREVIEW].w == SANE_TRUE)) 07827 { 07828 y_dpi = x_dpi; 07829 } 07830 #endif 07831 if (x_dpi > 0.0 && y_dpi > 0.0 && width > 0.0 && length > 0.0) 07832 { 07833 double x_dots_per_mm = x_dpi / MM_PER_INCH; 07834 double y_dots_per_mm = y_dpi / MM_PER_INCH; 07835 07836 scanner->params.pixels_per_line = width * x_dots_per_mm; 07837 scanner->params.lines = length * y_dots_per_mm; 07838 } 07839 } 07840 07841 mode = scanner->val[OPT_MODE].s; 07842 07843 if (strcmp (mode, LINEART_STR) == 0 || strcmp (mode, HALFTONE_STR) == 0) 07844 { 07845 scanner->params.format = SANE_FRAME_GRAY; 07846 scanner->params.bytes_per_line = 07847 (scanner->params.pixels_per_line + 7) / 8; 07848 scanner->params.depth = 1; 07849 } 07850 else if (strcmp (mode, GRAY_STR) == 0) 07851 { 07852 scanner->params.format = SANE_FRAME_GRAY; 07853 scanner->params.bytes_per_line = scanner->params.pixels_per_line; 07854 scanner->params.depth = scanner->val[OPT_BIT_DEPTH].w; 07855 } 07856 else if ((strcmp (mode, COLOR_STR) == 0) || /* RGB */ 07857 ((strcmp (mode, COLOR_IR_STR) == 0) && /* RGB with infrared processing */ 07858 (strcmp (scanner->val[OPT_SW_IRED].s, IR_CLEAN_STR) == 0))) 07859 { 07860 scanner->params.format = SANE_FRAME_RGB; 07861 scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line; 07862 scanner->params.depth = scanner->val[OPT_BIT_DEPTH].w; 07863 } 07864 else /* pure RGBI */ 07865 { 07866 #ifdef SANE_FRAME_RGBI 07867 scanner->params.format = SANE_FRAME_RGBI; 07868 scanner->params.bytes_per_line = 4 * scanner->params.pixels_per_line; 07869 #else 07870 scanner->params.format = SANE_FRAME_RGB; 07871 scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line; 07872 #endif 07873 scanner->params.depth = scanner->val[OPT_BIT_DEPTH].w; 07874 } 07875 if (scanner->params.depth > 8) 07876 scanner->params.bytes_per_line *= 2; 07877 07878 scanner->params.last_frame = (scanner->params.format != SANE_FRAME_RED 07879 && scanner->params.format != 07880 SANE_FRAME_GREEN); 07881 07882 if (params) 07883 { 07884 *params = scanner->params; 07885 } 07886 07887 return SANE_STATUS_GOOD; 07888 } 07889 07890 07891 /* ----------------------------------------- SANE START --------------------------------- */ 07892 07893 07894 SANE_Status 07895 sane_start (SANE_Handle handle) 07896 { 07897 Pie_Scanner *scanner = handle; 07898 int fds[2]; 07899 const char *mode; 07900 int status; 07901 07902 DBG (DBG_sane_init, "sane_start\n"); 07903 07904 /* Check for inconsistencies */ 07905 07906 if (scanner->val[OPT_TL_X].w > scanner->val[OPT_BR_X].w) 07907 { 07908 DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) " 07909 "-- aborting\n", 07910 scanner->opt[OPT_TL_X].title, 07911 SANE_UNFIX (scanner->val[OPT_TL_X].w), 07912 scanner->opt[OPT_BR_X].title, 07913 SANE_UNFIX (scanner->val[OPT_BR_X].w)); 07914 return SANE_STATUS_INVAL; 07915 } 07916 if (scanner->val[OPT_TL_Y].w > scanner->val[OPT_BR_Y].w) 07917 { 07918 DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) " 07919 "-- aborting\n", 07920 scanner->opt[OPT_TL_Y].title, 07921 SANE_UNFIX (scanner->val[OPT_TL_Y].w), 07922 scanner->opt[OPT_BR_Y].title, 07923 SANE_UNFIX (scanner->val[OPT_BR_Y].w)); 07924 return SANE_STATUS_INVAL; 07925 } 07926 07927 if (scanner->device->model != NULL) /* USB film scanners */ 07928 return pie_usb_sane_start (scanner); 07929 07930 mode = scanner->val[OPT_MODE].s; 07931 07932 if (scanner->sfd < 0) /* first call, don`t run this routine again on multi frame or multi image scan */ 07933 { 07934 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 07935 int scsi_bufsize = 131072; /* 128KB */ 07936 07937 if (sanei_scsi_open_extended 07938 (scanner->device->sane.name, &(scanner->sfd), pie_sense_handler, 07939 scanner->device, &scsi_bufsize) != 0) 07940 07941 { 07942 DBG (DBG_error, "sane_start: open failed\n"); 07943 return SANE_STATUS_INVAL; 07944 } 07945 07946 if (scsi_bufsize < 32768) /* < 32KB */ 07947 { 07948 DBG (DBG_error, 07949 "sane_start: sanei_scsi_open_extended returned too small scsi buffer (%d)\n", 07950 scsi_bufsize); 07951 sanei_scsi_close ((scanner->sfd)); 07952 return SANE_STATUS_NO_MEM; 07953 } 07954 DBG (DBG_info, 07955 "sane_start: sanei_scsi_open_extended returned scsi buffer size = %d\n", 07956 scsi_bufsize); 07957 07958 07959 scanner->bufsize = scsi_bufsize; 07960 #else 07961 if (sanei_scsi_open 07962 (scanner->device->sane.name, &(scanner->sfd), pie_sense_handler, 07963 scanner->device) != SANE_STATUS_GOOD) 07964 { 07965 DBG (DBG_error, "sane_start: open of %s failed:\n", 07966 scanner->device->sane.name); 07967 return SANE_STATUS_INVAL; 07968 } 07969 07970 /* there is no need to reallocate the buffer because the size is fixed */ 07971 #endif 07972 07973 #if 0 07974 if (pie_check_values (scanner->device) != 0) 07975 { 07976 DBG (DBG_error, "ERROR: invalid scan-values\n"); 07977 scanner->scanning = SANE_FALSE; 07978 pie_give_scanner (scanner); /* reposition and release scanner */ 07979 sanei_scsi_close (scanner->sfd); 07980 scanner->sfd = -1; 07981 return SANE_STATUS_INVAL; 07982 } 07983 #endif 07984 #if 0 07985 scanner->params.bytes_per_line = scanner->device->row_len; 07986 scanner->params.pixels_per_line = scanner->device->width_in_pixels; 07987 scanner->params.lines = scanner->device->length_in_pixels; 07988 07989 sane_get_parameters (scanner, 0); 07990 07991 DBG (DBG_sane_info, "x_resolution (dpi) = %u\n", 07992 scanner->device->x_resolution); 07993 DBG (DBG_sane_info, "y_resolution (dpi) = %u\n", 07994 scanner->device->y_resolution); 07995 DBG (DBG_sane_info, "x_coordinate_base (dpi) = %u\n", 07996 scanner->device->x_coordinate_base); 07997 DBG (DBG_sane_info, "y_coordinate_base (dpi) = %u\n", 07998 scanner->device->y_coordinate_base); 07999 DBG (DBG_sane_info, "upper_left_x (xbase) = %d\n", 08000 scanner->device->upper_left_x); 08001 DBG (DBG_sane_info, "upper_left_y (ybase) = %d\n", 08002 scanner->device->upper_left_y); 08003 DBG (DBG_sane_info, "scanwidth (xbase) = %u\n", 08004 scanner->device->scanwidth); 08005 DBG (DBG_sane_info, "scanlength (ybase) = %u\n", 08006 scanner->device->scanlength); 08007 DBG (DBG_sane_info, "width in pixels = %u\n", 08008 scanner->device->width_in_pixels); 08009 DBG (DBG_sane_info, "length in pixels = %u\n", 08010 scanner->device->length_in_pixels); 08011 DBG (DBG_sane_info, "bits per pixel/color = %u\n", 08012 scanner->device->bits_per_pixel); 08013 DBG (DBG_sane_info, "bytes per line = %d\n", 08014 scanner->params.bytes_per_line); 08015 DBG (DBG_sane_info, "pixels_per_line = %d\n", 08016 scanner->params.pixels_per_line); 08017 DBG (DBG_sane_info, "lines = %d\n", 08018 scanner->params.lines); 08019 #endif 08020 08021 /* grab scanner */ 08022 if (pie_grab_scanner (scanner)) 08023 { 08024 sanei_scsi_close (scanner->sfd); 08025 scanner->sfd = -1; 08026 DBG (DBG_warning, 08027 "WARNING: unable to reserve scanner: device busy\n"); 08028 return SANE_STATUS_DEVICE_BUSY; 08029 } 08030 08031 scanner->scanning = SANE_TRUE; 08032 08033 pie_power_save (scanner, 0); 08034 } /* ------------ end of first call -------------- */ 08035 08036 08037 if (strcmp (mode, LINEART_STR) == 0) 08038 { 08039 scanner->colormode = LINEART; 08040 } 08041 else if (strcmp (mode, HALFTONE_STR) == 0) 08042 { 08043 scanner->colormode = HALFTONE; 08044 } 08045 else if (strcmp (mode, GRAY_STR) == 0) 08046 { 08047 scanner->colormode = GRAYSCALE; 08048 } 08049 else if (strcmp (mode, COLOR_STR) == 0) 08050 { 08051 scanner->colormode = RGB; 08052 } 08053 08054 /* get and set geometric values for scanning */ 08055 scanner->resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w); 08056 08057 pie_set_window (scanner); 08058 pie_send_exposure (scanner); 08059 pie_mode_select (scanner); 08060 pie_send_highlight_shadow (scanner); 08061 08062 pie_scan (scanner, 1); 08063 08064 status = pie_do_cal (scanner); 08065 if (status) 08066 return status; 08067 08068 /* send gammacurves */ 08069 08070 pie_dwnld_gamma (scanner); 08071 08072 pie_get_params (scanner); 08073 08074 if (pipe (fds) < 0) /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */ 08075 { 08076 DBG (DBG_error, "ERROR: could not create pipe\n"); 08077 scanner->scanning = SANE_FALSE; 08078 pie_scan (scanner, 0); 08079 pie_give_scanner (scanner); /* reposition and release scanner */ 08080 sanei_scsi_close (scanner->sfd); 08081 scanner->sfd = -1; 08082 return SANE_STATUS_IO_ERROR; 08083 } 08084 08085 scanner->pipe = fds[0]; 08086 scanner->reader_fds = fds[1]; 08087 scanner->reader_pid = sanei_thread_begin (pie_reader_process, (void *) scanner); 08088 08089 if (scanner->reader_pid == NO_PID) 08090 { 08091 DBG (1, "sane_start: sanei_thread_begin failed (%s)\n", 08092 strerror (errno)); 08093 return SANE_STATUS_NO_MEM; 08094 } 08095 08096 if (sanei_thread_is_forked ()) 08097 { 08098 close (scanner->reader_fds); 08099 scanner->reader_fds = -1; 08100 } 08101 08102 return SANE_STATUS_GOOD; 08103 } 08104 08105 08106 /* -------------------------------------- SANE READ ---------------------------------- */ 08107 08108 08109 SANE_Status 08110 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 08111 SANE_Int * len) 08112 { 08113 Pie_Scanner *scanner = handle; 08114 ssize_t nread; 08115 08116 *len = 0; 08117 08118 if (scanner->device->model != NULL) /* USB film scanners */ 08119 return pie_usb_sane_read (scanner, buf, max_len, len); 08120 08121 nread = read (scanner->pipe, buf, max_len); 08122 DBG (DBG_sane_info, "sane_read: read %ld bytes\n", (long) nread); 08123 08124 if (!(scanner->scanning)) /* OOPS, not scanning */ 08125 { 08126 return pie_do_cancel (scanner); 08127 } 08128 08129 if (nread < 0) 08130 { 08131 if (errno == EAGAIN) 08132 { 08133 DBG (DBG_sane_info, "sane_read: EAGAIN\n"); 08134 return SANE_STATUS_GOOD; 08135 } 08136 else 08137 { 08138 pie_do_cancel (scanner); /* we had an error, stop scanner */ 08139 return SANE_STATUS_IO_ERROR; 08140 } 08141 } 08142 08143 *len = nread; 08144 08145 if (nread == 0) /* EOF */ 08146 { 08147 pie_do_cancel (scanner); 08148 08149 return pie_close_pipe (scanner); /* close pipe */ 08150 } 08151 08152 return SANE_STATUS_GOOD; 08153 } 08154 08155 08156 /* ------------------------------------- SANE CANCEL -------------------------------- */ 08157 08158 08159 void 08160 sane_cancel (SANE_Handle handle) 08161 { 08162 Pie_Scanner *scanner = handle; 08163 08164 DBG (DBG_sane_init, "sane_cancel\n"); 08165 08166 if (scanner->device->model == NULL) 08167 { 08168 if (scanner->scanning) 08169 pie_do_cancel (scanner); 08170 } 08171 else /* USB film scanners */ 08172 pie_usb_do_cancel (scanner, SANE_TRUE); 08173 } 08174 08175 08176 /* -------------------------------------- SANE SET IO MODE --------------------------- */ 08177 08178 08179 SANE_Status 08180 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 08181 { 08182 Pie_Scanner *scanner = handle; 08183 08184 DBG (DBG_sane_init, "sane_set_io_mode: non_blocking=%d\n", non_blocking); 08185 08186 if (!scanner->scanning) 08187 { 08188 return SANE_STATUS_INVAL; 08189 } 08190 08191 if (fcntl (scanner->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0) 08192 { 08193 return SANE_STATUS_IO_ERROR; 08194 } 08195 08196 return SANE_STATUS_GOOD; 08197 } 08198 08199 08200 /* --------------------------------------- SANE GET SELECT FD ------------------------- */ 08201 08202 08203 SANE_Status 08204 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 08205 { 08206 Pie_Scanner *scanner = handle; 08207 08208 DBG (DBG_sane_init, "sane_get_select_fd\n"); 08209 08210 if (!scanner->scanning) 08211 { 08212 return SANE_STATUS_INVAL; 08213 } 08214 *fd = scanner->pipe; 08215 08216 return SANE_STATUS_GOOD; 08217 } 08218