diff --git a/backend/epson.c b/backend/epson.c index 4aba57bf6..16d424559 100644 --- a/backend/epson.c +++ b/backend/epson.c @@ -16,7 +16,7 @@ */ -#define SANE_EPSON_VERSION "SANE Epson Backend v0.1.39 - 2000-12-09" +#define SANE_EPSON_VERSION "SANE Epson Backend v0.2.01 - 2000-12-25" /* This file is part of the SANE package. @@ -58,14 +58,27 @@ If you do not wish that, delete this exception notice. */ /* - 2000-12-4 We've introduced the concept of inverting images - when scanning from a TPU. This is fine, but - the user supplied gamma tables no longer work. - This is because the data a frontend is going - to compute a gamma table for is not what the - scanner actually sent. So, we have to back into - the proper gamma table. (mjp) - + 2000-12-25 Version 0.2.01 + Fixed problem with bilevel scanning with Perfection610: The + line count has to be an even number with this scanner. + Several initialization fixes regarding bit depth selection. + This version goes back into the CVS repository, the 1.0.4 + release is out and therefore the code freeze is over. + Some general cleanup, added more comments. + 2000-12-09 Version 0.2.00 + Cleaned up printing of gamma table data. 16 elements + are now printed in one line without the [epson] in + between the values. Values are only printed for + Debug levels >= 10. + 2000-12-04 We've introduced the concept of inverting images + when scanning from a TPU. This is fine, but + the user supplied gamma tables no longer work. + This is because the data a frontend is going + to compute a gamma table for is not what the + scanner actually sent. So, we have to back into + the proper gamma table. I think this works. See + set_gamma_table. (mjp) + 2000-12-03 added the 12/14/16 bit support again. 2000-12-03 Version 0.1.38 removed changes regarding 12/14 bit support because of SANE feature freeze for 1.0.4. The D1 fix for @@ -403,52 +416,10 @@ static EpsonCmdRec epson_cmd [ ] = /* - -.) exposure time - -- no docs found - -- from epson_31101999.c - -u_char default_tval[4] = {2, 0x80, 0x80, 0x80}; -u_char neg_tval[4] = {2, 0x8e, 0x86, 0x92}; - -ESC T + 4 byte - -- there are defs in include/sane/saneopts.h - -#define SANE_NAME_CAL_EXPOS_TIME "cal-exposure-time" -#define SANE_NAME_CAL_EXPOS_TIME_R "cal-exposure-time-r" -#define SANE_NAME_CAL_EXPOS_TIME_G "cal-exposure-time-g" -#define SANE_NAME_CAL_EXPOS_TIME_B "cal-exposure-time-b" -#define SANE_NAME_SCAN_EXPOS_TIME "scan-exposure-time" -#define SANE_NAME_SCAN_EXPOS_TIME_R "scan-exposure-time-r" -#define SANE_NAME_SCAN_EXPOS_TIME_G "scan-exposure-time-g" -#define SANE_NAME_SCAN_EXPOS_TIME_B "scan-exposure-time-b" -#define SANE_NAME_SELECT_EXPOSURE_TIME "select-exposure-time" - -Einmal für Calibrierung, andere für Scan. lamp-density gibt es auch noch. -One for calibration, other one for scan. There is also lamp-density defined. - -- da war noch mal die blöde mail wo ganz genau drinsteht wie das geht. - -.) 12 bit - -- there are defs in include/sane/saneopts.h - -#define SANE_NAME_TEN_BIT_MODE "ten-bit-mode" -#define SANE_NAME_TWELVE_BIT_MODE "twelve-bit-mode" - -- not used by other backends. - - - - -*/ - -/* - * + * Definition of the mode_param struct, that is used to + * specify the valid parameters for the different scan modes. * + * The depth variable gets updated when the bit depth is modified. */ struct mode_param { @@ -458,18 +429,12 @@ struct mode_param { int depth; }; -static const struct mode_param mode_params [ ] = +static struct mode_param mode_params [ ] = { { 0, 0x00, 0x30, 1} , { 0, 0x00, 0x30, 8} , { 1, 0x02, 0x00, 8} }; -static const struct mode_param mode_params_5 [ ] = - { { 0, 0x00, 0x30, 1} - , { 0, 0x00, 0x30, 8} - , { 1, 0x03, 0x10, 8} - }; - static const SANE_String_Const mode_list [ ] = { "Binary" , "Gray" @@ -477,12 +442,10 @@ static const SANE_String_Const mode_list [ ] = , NULL }; -static const SANE_String_Const mode_list_5 [ ] = - { "Binary" - , "Gray" - , "Color" - , NULL - }; + +/* + * Define the different scan sources: + */ #define FBF_STR "Flatbed" #define TPU_STR "Transparency Unit" @@ -490,7 +453,8 @@ static const SANE_String_Const mode_list_5 [ ] = /* * source list need one dummy entry (save device settings is crashing). - * NOTE: no const. + * NOTE: no const - this list gets created while exploring the capabilities + * of the scanner. */ static SANE_String_Const source_list [ ] = @@ -500,6 +464,7 @@ static SANE_String_Const source_list [ ] = , NULL }; +/* some defines to make handling the TPU easier: */ #define FILM_TYPE_POSITIVE (0) #define FILM_TYPE_NEGATIVE (1) @@ -573,10 +538,10 @@ static const SANE_String_Const halftone_list_7 [ ] = }; static int dropout_params [ ] = - { 0x00 - , 0x10 - , 0x20 - , 0x30 + { 0x00 /* none */ + , 0x10 /* red */ + , 0x20 /* green */ + , 0x30 /* blue */ }; static const SANE_String_Const dropout_list [ ] = @@ -588,7 +553,10 @@ static const SANE_String_Const dropout_list [ ] = }; /* - * NOTE: if enable "User defined" change also default from 4 to 5. + * Color correction: + * One array for the actual parameters that get sent to the scanner (color_params[]), + * one array for the strings that get displayed in the user interface (color_list[]) + * and one array to mark the user defined color correction (dolor_userdefined[]). */ static int color_params [ ] = @@ -619,6 +587,13 @@ static const SANE_String_Const color_list [ ] = , NULL }; +/* + * Gamma correction: + * The A and B level scanners work differently than the D level scanners, therefore + * I define two different sets of arrays, plus one set of variables that get set to + * the actally used params and list arrays at runtime. + */ + static int gamma_params_ab [ ] = { 0x01 , 0x03 @@ -665,6 +640,11 @@ static SANE_Bool gamma_userdefined_d [ ] = static SANE_Bool * gamma_userdefined; static int * gamma_params; + +/* Bay list: + * this is used for the FilmScan + */ + static const SANE_String_Const bay_list [ ] = { " 1 " , " 2 " @@ -683,13 +663,18 @@ static const SANE_Range u8_range = { 0, 255, 0}; static const SANE_Range s8_range = { -127, 127, 0}; static const SANE_Range zoom_range = { 50, 200, 0}; -static int mirror_params [ ] = - { 0 - , 1 - }; +/* + * The "switch_params" are used for several boolean choices + */ +static int switch_params [ ] = +{ + 0, + 1 +}; -#define speed_params mirror_params -#define film_params mirror_params +#define mirror_params switch_params +#define speed_params switch_params +#define film_params switch_params static const SANE_Range outline_emphasis_range = { -2, 2, 0 }; /* static const SANE_Range gamma_range = { -2, 2, 0 }; */ @@ -721,6 +706,9 @@ static const SANE_String_Const qf_list [ ] = , NULL }; + +static SANE_Word * bitDepthList = NULL; + /* * this is now stored in the s->hw->resolution_list field @@ -1132,8 +1120,9 @@ static SANE_Status set_gamma_table ( Epson_Scanner * s) { params[ 1] = cmd; /* - Print the gamma tables before sending them to the scanner. -*/ + * Print the gamma tables before sending them to the scanner. + */ + if (DBG_LEVEL > 0) { int c, i, j; @@ -1156,7 +1145,7 @@ static SANE_Status set_gamma_table ( Epson_Scanner * s) { /* - * TODO: &status in send makes no sense like that. + * TODO: &status in send make no sense like that. */ /* @@ -1257,12 +1246,12 @@ static SANE_Status check_ext_status ( Epson_Scanner * s) { } /* + * reset() * + * Send the "initialize scanner" command to the device and reset it. * */ - -#if 0 static SANE_Status reset ( Epson_Scanner * s) { SANE_Status status; u_char param[2]; @@ -1278,11 +1267,12 @@ static SANE_Status reset ( Epson_Scanner * s) { return status; } -#endif /* + * close_scanner() * - * + * Close the open scanner. Depending on the connection method, a different + * close function is called. */ static void close_scanner ( Epson_Scanner * s) { @@ -1298,8 +1288,10 @@ static void close_scanner ( Epson_Scanner * s) { } /* + * open_scanner() * - * + * Open the scanner device. Depending on the connection method, + * different open functions are called. */ static SANE_Status open_scanner ( Epson_Scanner * s) { @@ -1351,8 +1343,13 @@ static SANE_Status open_scanner ( Epson_Scanner * s) { return status; } + + /* - * + * eject() + * + * Eject the current page from the ADF. The scanner is opened prior to + * sending the command and closed afterwards. * */ @@ -1440,17 +1437,10 @@ static EpsonHdr command ( Epson_Scanner * s, const u_char * cmd, switch (head->code) { - default: - if( 0 == head->code) - DBG( 1, "Incompatible printer port (probably bi/directional)\n"); - else if( cmd[cmd_size - 1] == head->code) - DBG( 1, "Incompatible printer port (probably not bi/directional)\n"); - - DBG( 2, "Illegal response of scanner for command: %02x\n", head->code); - break; case NAK: - /* fall through */ + /* fall through */ + /* !!! is this really sufficient to report an error ? */ case ACK: break; /* no need to read any more data after ACK or NAK */ @@ -1488,6 +1478,15 @@ static EpsonHdr command ( Epson_Scanner * s, const u_char * cmd, return (EpsonHdr) 0; break; + + default: + if( 0 == head->code) + DBG( 1, "Incompatible printer port (probably bi/directional)\n"); + else if( cmd[cmd_size - 1] == head->code) + DBG( 1, "Incompatible printer port (probably not bi/directional)\n"); + + DBG( 2, "Illegal response of scanner for command: %02x\n", head->code); + break; } return head; @@ -1683,23 +1682,11 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { } /* - * Initialize (ESC @). + * Initialize the scanner (ESC @). */ -/* NOTE: disabled cause of batch use of scanimage with ADF. */ + reset(s); -#if 1 - { - void * ptr; - u_char param[2]; - param[0] = ESC; - param[1] = s->hw->cmd->initialize_scanner; - - ptr = command( s, param, 2, &status); - - free(ptr); - } -#endif /* * Identification Request (ESC I). */ @@ -1724,6 +1711,50 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { } /* request identity 2 */ + /* + * Check for the max. supported color depth and assign + * the values to the bitDepthList. + */ + + bitDepthList = malloc(sizeof(SANE_Word) * 4); + if (bitDepthList == NULL) + return SANE_STATUS_NO_MEM; + + bitDepthList[0] = 1; /* we start with one element in the list */ + bitDepthList[1] = 8; /* 8bit is the default */ + + if (set_data_format(s, 16) == SANE_STATUS_GOOD) + { + s->hw->maxDepth = 16; + + bitDepthList[0]++; + bitDepthList[bitDepthList[0]] = 16; + + } + else if (set_data_format(s, 14) == SANE_STATUS_GOOD) + { + s->hw->maxDepth = 14; + + bitDepthList[0]++; + bitDepthList[bitDepthList[0]] = 14; + } + else if (set_data_format(s, 12) == SANE_STATUS_GOOD) + { + s->hw->maxDepth = 12; + + bitDepthList[0]++; + bitDepthList[bitDepthList[0]] = 12; + } + else + { + s->hw->maxDepth = 8; + + /* the default depth is already in the list */ + } + + DBG(1, "Max. supported color depth = %d\n", s->hw->maxDepth); + + /* * Check for "request focus position" command. If this command is * supported, then the scanner does also support the "set focus @@ -1870,7 +1901,7 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { *source_list_add = NULL; /* - * Get the device name and copy it to dummy_dev.sane.model + * Get the device name and copy it to dev->sane.model. * The device name starts at buf[0x1A] and is up to 16 bytes long * We are overwriting whatever was set previously! */ @@ -1910,39 +1941,19 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { qf_params[ XtNumber( qf_params) - 1].br_x = dev->x_range->max; qf_params[ XtNumber( qf_params) - 1].br_y = dev->y_range->max; -/* - * - */ - -#if 0 - { - u_char * buf; - EpsonHdr head; - -#define PUSH_BUTTON_STATUS_EN 0x01 - - if( NULL == ( head = ( EpsonHdr) command( s, "\033!", 2, &status) ) ) { - DBG( 0, "Request the push button status failed\n"); - return status; - } - - buf = &head->buf[ 0]; - - if( buf[ 0] & PUSH_BUTTON_STATUS_EN) - DBG( 1, "Push button was pressed\n"); - - - } -#endif /* - * now we can finally set the device name + * Now we can finally set the device name: */ str = malloc( strlen( dev_name) + 1); dev->sane.name = strcpy( str, dev_name); close_scanner( s); + /* + * we are done with this one, prepare for the next scanner: + */ + ++num_devices; dev->next = first_dev; first_dev = dev; @@ -1955,15 +1966,25 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { return SANE_STATUS_GOOD; } + + /* + * attach_one() * + * Part of the SANE API: Attaches the scanner with the device name in *dev. */ -static SANE_Status attach_one ( const char *dev) { +static SANE_Status attach_one ( const char *dev) +{ + DBG(5, "attach(%s)\n", dev); + return attach( dev, 0); } + /* + * sane_init() + * * */ @@ -1971,7 +1992,10 @@ SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) { size_t len; FILE *fp; - authorize = authorize; /* get rid of the compiler warning */ + authorize = authorize; /* get rid of compiler warning */ + + /* sanei_authorization(devicename, STRINGIFY(BACKEND_NAME), auth_callback); */ + DBG_INIT (); #if defined PACKAGE && defined VERSION @@ -2104,6 +2128,21 @@ static SANE_Status init_options ( Epson_Scanner * s) { s->opt[ OPT_MODE].constraint.string_list = mode_list; s->val[ OPT_MODE].w = 0; /* Binary */ + + /* bit depth */ + s->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH; + s->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH; + s->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH; + s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT; + s->opt[OPT_BIT_DEPTH].unit = SANE_UNIT_NONE; + s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; + s->opt[OPT_BIT_DEPTH].constraint.word_list = bitDepthList; + s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE; + s->val[OPT_BIT_DEPTH].w = bitDepthList[1]; + + if (bitDepthList[0] == 1) /* only one element in the list -> hide the option */ + s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE; + /* halftone */ s->opt[ OPT_HALFTONE].name = SANE_NAME_HALFTONE; s->opt[ OPT_HALFTONE].title = SANE_TITLE_HALFTONE; @@ -2382,6 +2421,16 @@ static SANE_Status init_options ( Epson_Scanner * s) { s->opt[ OPT_CCT_8].cap |= SANE_CAP_ADVANCED; s->opt[ OPT_CCT_9].cap |= SANE_CAP_ADVANCED; + s->opt[ OPT_CCT_1].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_2].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_3].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_4].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_5].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_6].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_7].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_8].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_9].cap |= SANE_CAP_INACTIVE; + s->opt[ OPT_CCT_1].unit = SANE_UNIT_NONE; s->opt[ OPT_CCT_2].unit = SANE_UNIT_NONE; s->opt[ OPT_CCT_3].unit = SANE_UNIT_NONE; @@ -2974,6 +3023,7 @@ static SANE_Status getvalue( SANE_Handle handle, case OPT_CCT_9: case OPT_THRESHOLD: case OPT_ZOOM: + case OPT_BIT_DEPTH: *((SANE_Word *) value) = sval->w; break; @@ -3267,6 +3317,7 @@ static SANE_Status setvalue( SANE_Handle handle, case OPT_RESOLUTION: handle_resolution( s, option, value ); + reload = SANE_TRUE; break; case OPT_TL_X: @@ -3312,20 +3363,39 @@ static SANE_Status setvalue( SANE_Handle handle, sane_optstate( ic && iccu, s, OPT_CCT_9, &reload ); } - reload = SANE_TRUE; + /* if binary, then disable the bit depth selection */ + if (optindex == 0) + { + s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE; + } + else + { + if (bitDepthList[0] == 1) + s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE; + else + { + s->opt[OPT_BIT_DEPTH].cap &= ~SANE_CAP_INACTIVE; + s->val[OPT_BIT_DEPTH].w = mode_params[optindex].depth; + } + } handle_depth_halftone( s, &reload ); + reload = SANE_TRUE; + break; } + case OPT_BIT_DEPTH : + sval->w = *((SANE_Word *) value); + mode_params[s->val[OPT_MODE].w].depth = sval->w; + reload = SANE_TRUE; + break; + case OPT_HALFTONE: sval->w = optindex; handle_depth_halftone( s, &reload ); break; - sval->w = optindex; - break; - case OPT_COLOR_CORRECTION: { SANE_Bool f = color_userdefined[ optindex ]; @@ -3434,13 +3504,20 @@ SANE_Status sane_control_option ( SANE_Handle handle, } /* + * sane_get_parameters() * + * This function is part of the SANE API and gets called when the front end + * requests information aobut the scan configuration (e.g. color depth, mode, + * bytes and pixels per line, number of lines. This information is returned + * in the SANE_Parameters structure. * */ -SANE_Status sane_get_parameters ( SANE_Handle handle, SANE_Parameters * params) { +SANE_Status sane_get_parameters ( SANE_Handle handle, SANE_Parameters * params) +{ Epson_Scanner * s = ( Epson_Scanner *) handle; int ndpi; + int bytes_per_pixel; DBG(5, "sane_get_parameters()\n"); @@ -3463,15 +3540,41 @@ SANE_Status sane_get_parameters ( SANE_Handle handle, SANE_Parameters * params) , SANE_UNFIX( s->val[ OPT_BR_Y].w) ); - /* pixels_per_line seems to be 8 * n. */ + /* Calculate bytes_per_pixel and bytes_per_line for + * any color depths. + * + * The default color depth is stored in mode_params.depth: + */ + + /* there must be a better way to do this, but it works for now */ + + if (mode_params[s->val[OPT_MODE].w].depth == 1) + s->params.depth = 1; + else + s->params.depth = s->val[OPT_BIT_DEPTH].w; + + if (s->params.depth > 8) + { + if (s->val[OPT_PREVIEW].w) /* for preview the frontends can only handle 8 bits */ + s->params.depth = 8; + else + s->params.depth = 16; /* the frontends can only handle 8 or 16 bits for gray or color */ + } + + bytes_per_pixel = s->params.depth / 8; + if (s->params.depth % 8) /* just in case ... */ + { + bytes_per_pixel++; + } + + /* pixels_per_line seems to be rounded to the next 8bit boundary */ s->params.pixels_per_line = s->params.pixels_per_line & ~7; s->params.last_frame = SANE_TRUE; - s->params.depth = mode_params[ s->val[ OPT_MODE].w].depth; if( mode_params[ s->val[ OPT_MODE].w].color) { s->params.format = SANE_FRAME_RGB; - s->params.bytes_per_line = 3 * s->params.pixels_per_line; + s->params.bytes_per_line = 3 * s->params.pixels_per_line * bytes_per_pixel; } else { s->params.format = SANE_FRAME_GRAY; s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8; @@ -3484,11 +3587,15 @@ SANE_Status sane_get_parameters ( SANE_Handle handle, SANE_Parameters * params) } /* + * sane_start() * + * This function is part of the SANE API and gets called from the front end to + * start the scan process. * */ -SANE_Status sane_start ( SANE_Handle handle) { +SANE_Status sane_start ( SANE_Handle handle) +{ Epson_Scanner * s = ( Epson_Scanner *) handle; SANE_Status status; const struct mode_param * mparam; @@ -3498,25 +3605,7 @@ SANE_Status sane_start ( SANE_Handle handle) { int lcount; int i, j; /* loop counter */ - DBG( 1, "preview %d\n", s->val[ OPT_PREVIEW].w); - -#if 0 - status = sane_get_parameters( handle, NULL); - if( status != SANE_STATUS_GOOD) - return status; -#endif - open_scanner( s); -/* - * NOTE: added cause there was error reported for some scanner. - * NOTE: disabled cause of batch use scanimage and ADF. - * reset( s); - */ - -/* - * - */ - /* * There is some undocumented special with TPU enable/disable. * TPU power ESC e status @@ -3527,11 +3616,6 @@ SANE_Status sane_start ( SANE_Handle handle) { * * probably it make no sense to scan with TPU powered on and source flatbed, cause light * will come from both sides. - */ - - -/* - * */ if( s->hw->extension) { @@ -3630,11 +3714,21 @@ SANE_Status sane_start ( SANE_Handle handle) { } /* - * + * Set the color depth. If a preview is requested, then always + * scan in 8bit mode if grayscale or color mode was selected. We + * are not testing for any of these modes, if preview is selected, + * and the color depth was more than 8 bits, then we just reset it + * to 8 bits. */ mparam = mode_params + s->val[ OPT_MODE].w; - status = set_data_format( s, mparam->depth); + + + if (s->val[OPT_PREVIEW].w && mparam->depth > 8) + status = set_data_format( s, 8); + else + status = set_data_format( s, mparam->depth); + if( SANE_STATUS_GOOD != status) { DBG( 1, "sane_start: set_data_format failed: %s\n", sane_strstatus( status)); @@ -3643,7 +3737,6 @@ SANE_Status sane_start ( SANE_Handle handle) { /* * The byte sequence mode was introduced in B5, for B34 we need line sequence mode - */ if( (s->hw->cmd->level[0] == 'D' || @@ -3697,7 +3790,6 @@ SANE_Status sane_start ( SANE_Handle handle) { } -#if 1 if( SANE_OPTION_IS_ACTIVE( s->opt[ OPT_SPEED].cap) ) { if( s->val[ OPT_PREVIEW].w) @@ -3711,9 +3803,6 @@ SANE_Status sane_start ( SANE_Handle handle) { } } -#else - status = set_speed( s, mode_params[ s->val[ OPT_MODE]].depth == 1 ? 1 : 0); -#endif /* * use of speed_params is ok here since they are false and true. @@ -3808,14 +3897,6 @@ SANE_Status sane_start ( SANE_Handle handle) { } } -#if 0 - status = set_color_correction( s, 0x80); - - if( SANE_STATUS_GOOD != status) { - DBG( 1, "sane_start: set_color_correction failed: %s\n", sane_strstatus (status)); - return status; - } -#else /* * TODO: think about if SANE_OPTION_IS_ACTIVE is a good criteria to send commands. */ @@ -3839,7 +3920,7 @@ SANE_Status sane_start ( SANE_Handle handle) { return status; } } -#endif + if (s->hw->cmd->set_threshold != 0 && SANE_OPTION_IS_ACTIVE( s->opt[ OPT_THRESHOLD].cap)) { @@ -3913,7 +3994,6 @@ SANE_Status sane_start ( SANE_Handle handle) { if ((s->hw->optical_res != 0) && (mparam->depth == 8) && (mparam->mode_flags != 0)) { - s->line_distance = s->hw->max_line_distance * ndpi / s->hw->optical_res; if (s->line_distance != 0) { @@ -3960,7 +4040,7 @@ SANE_Status sane_start ( SANE_Handle handle) { * 'D' and not for the actual numeric level. */ - if( ( (s->hw->cmd->level[0] == 'B') && + if (((s->hw->cmd->level[0] == 'B') && ( (s->hw->level >= 5) || ( (s->hw->level >= 4) && (! mode_params[s->val[ OPT_MODE].w].color)))) || ( s->hw->cmd->level[0] == 'D') ) { @@ -3970,6 +4050,19 @@ SANE_Status sane_start ( SANE_Handle handle) { if( lcount > 255) lcount = 255; + /* + * The D1 series of scanners only allow an even line number + * for bi-level scanning. If a bit depth of 1 is selected, then + * make sure the next lower even number is selected. + */ + if (s->hw->cmd->level[0] == 'D') + { + if (lcount % 2) + { + lcount -= 1; + } + } + if( lcount == 0) return SANE_STATUS_NO_MEM; @@ -4174,15 +4267,7 @@ static SANE_Status read_data_block ( Epson_Scanner * s, EpsonDataRec * result) { if( result->status & STATUS_FER) { DBG( 1, "fatal error - Status = %02x\n", result->status); -#if 0 - /* check extended status if the option bit in status is set */ - if( result->status & STATUS_OPTION) { - status = check_ext_status( s); - } else - status = SANE_STATUS_INVAL; -#else status = check_ext_status( s); -#endif /* * Hack Alert!!! @@ -4256,6 +4341,7 @@ SANE_Status sane_read ( SANE_Handle handle, SANE_Byte * data, SANE_Int max_lengt SANE_Status status; int index = 0; SANE_Bool reorder = SANE_FALSE; + SANE_Bool needStrangeReorder = SANE_FALSE; int i; /* loop counter */ int bytes_to_process = 0; @@ -4417,9 +4503,9 @@ START_READ: reorder = SANE_TRUE; } - receive( s, s->buf, buf_len, &status); + bytes_to_process = receive( s, s->buf, buf_len, &status); - bytes_to_process = buf_len; + /* bytes_to_process = buf_len; */ if( SANE_STATUS_GOOD != status) return status; @@ -4471,8 +4557,13 @@ START_READ: * This has to be checked again after new 14bit scanners are released !!! */ + needStrangeReorder = + strstr(s->hw->sane.model, "1640") && + strstr(s->hw->sane.model, "Perfection") && + s->params.format == SANE_FRAME_RGB && + s->hw->maxDepth == 14; - if (s->hw->maxDepth == 14) + if (needStrangeReorder) reorder = !reorder; /* !!! */ if (reorder) @@ -4516,7 +4607,7 @@ START_READ: * most of the stuff is hardcoded for the Perfection 610 */ - if (s->hw->cmd->level[0] == 'D' && SANE_FRAME_RGB == s->params.format && s->block) + if (s->hw->color_shuffle) { int new_length = 0; @@ -4577,7 +4668,6 @@ START_READ: } } } else { - if( max_length > s->end - s->ptr) max_length = s->end - s->ptr;