diff --git a/backend/genesys.c b/backend/genesys.c index 1e444647f..5784b56b0 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -55,7 +55,7 @@ #include "../include/sane/config.h" -#define BUILD 12 +#define BUILD 13 #include #include @@ -114,23 +114,11 @@ static SANE_String_Const cis_color_filter_list[] = { }; static SANE_String_Const source_list[] = { - SANE_I18N ("Flatbed"), - SANE_I18N ("Transparency Adapter"), + SANE_I18N (FLATBED), + SANE_I18N (TRANSPARENCY_ADAPTER), 0 }; -static SANE_Range x_range = { - SANE_FIX (0.0), /* minimum */ - SANE_FIX (216.0), /* maximum */ - SANE_FIX (0.0) /* quantization */ -}; - -static SANE_Range y_range = { - SANE_FIX (0.0), /* minimum */ - SANE_FIX (299.0), /* maximum */ - SANE_FIX (0.0) /* quantization */ -}; - static SANE_Range time_range = { 0, /* minimum */ 60, /* maximum */ @@ -4321,8 +4309,10 @@ genesys_start_scan (Genesys_Device * dev) return status; } - /* wait for lamp warmup */ - if (!(dev->model->flags & GENESYS_FLAG_SKIP_WARMUP)) + /* wait for lamp warmup : until a warmup for TRANSPARENCY is designed, skip + * it when scanning from XPA */ + if (!(dev->model->flags & GENESYS_FLAG_SKIP_WARMUP) + && (dev->settings.scan_method == SCAN_METHOD_FLATBED)) { RIE (genesys_warmup_lamp (dev)); } @@ -4370,6 +4360,20 @@ genesys_start_scan (Genesys_Device * dev) } } + /* move to calibration area for transparency adapter */ + if ((dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + && dev->model->cmd_set->move_to_ta != NULL) + { + status=dev->model->cmd_set->move_to_ta(dev); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, + "genesys_start_scan: failed to move to start of transparency adapter: %s\n", + sane_strstatus (status)); + return status; + } + } + /* load document if needed (for sheetfed scanner for instance) */ if (dev->model->is_sheetfed == SANE_TRUE && dev->model->cmd_set->load_document != NULL) @@ -4530,7 +4534,7 @@ genesys_start_scan (Genesys_Device * dev) if (status != SANE_STATUS_GOOD) { DBG (DBG_error, - "genesys_start_scan: Failed to read valid words: %s\n", + "genesys_start_scan: failed to read valid words: %s\n", sane_strstatus (status)); return status; } @@ -5334,7 +5338,7 @@ calc_parameters (Genesys_Scanner * s) s->dev->settings.scan_mode = SCAN_MODE_LINEART; /* todo: change and check */ - if (strcmp (source, "Flatbed") == 0) + if (strcmp (source, FLATBED) == 0) s->dev->settings.scan_method = SCAN_METHOD_FLATBED; else /* transparency */ s->dev->settings.scan_method = SCAN_METHOD_TRANSPARENCY; @@ -5427,6 +5431,26 @@ init_gamma_vector_option (Genesys_Scanner * scanner, int option) scanner->val[option].wa = NULL; } +/** + * allocate a geometry range + * @param size maximum size of the range + * @return a poiter to a valid range or NULL + */ +static create_range(SANE_Fixed size) +{ +SANE_Range *range=NULL; + + range=(SANE_Range *)malloc(sizeof(SANE_Range)); + if(range!=NULL) + { + range->min = SANE_FIX (0.0); + range->max = size; + range->quant = SANE_FIX (0.0); + } + return range; +} + + static SANE_Status init_options (Genesys_Scanner * s) { @@ -5435,6 +5459,7 @@ init_options (Genesys_Scanner * s) SANE_Word *dpi_list; Genesys_Model *model = s->dev->model; SANE_Bool has_ta; + SANE_Range *x_range, *y_range; DBG (DBG_proc, "init_options: start\n"); @@ -5482,7 +5507,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST; s->opt[OPT_SOURCE].size = max_string_size (source_list); s->opt[OPT_SOURCE].constraint.string_list = source_list; - s->val[OPT_SOURCE].s = strdup ("Flatbed"); + s->val[OPT_SOURCE].s = strdup (FLATBED); DISABLE (OPT_SOURCE); /* preview */ @@ -5533,8 +5558,17 @@ init_options (Genesys_Scanner * s) s->opt[OPT_GEOMETRY_GROUP].size = 0; s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; - x_range.max = model->x_size; - y_range.max = model->y_size; + x_range=create_range(model->x_size); + if(x_range==NULL) + { + return SANE_STATUS_NO_MEM; + } + + y_range=create_range(model->y_size); + if(y_range==NULL) + { + return SANE_STATUS_NO_MEM; + } /* top-left x */ s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; @@ -5543,7 +5577,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; s->opt[OPT_TL_X].unit = SANE_UNIT_MM; s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_X].constraint.range = &x_range; + s->opt[OPT_TL_X].constraint.range = x_range; s->val[OPT_TL_X].w = 0; /* top-left y */ @@ -5553,7 +5587,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_Y].constraint.range = &y_range; + s->opt[OPT_TL_Y].constraint.range = y_range; s->val[OPT_TL_Y].w = 0; /* bottom-right x */ @@ -5563,8 +5597,8 @@ init_options (Genesys_Scanner * s) s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; s->opt[OPT_BR_X].unit = SANE_UNIT_MM; s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_X].constraint.range = &x_range; - s->val[OPT_BR_X].w = x_range.max; + s->opt[OPT_BR_X].constraint.range = x_range; + s->val[OPT_BR_X].w = x_range->max; /* bottom-right y */ s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; @@ -5573,8 +5607,8 @@ init_options (Genesys_Scanner * s) s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_Y].constraint.range = &y_range; - s->val[OPT_BR_Y].w = y_range.max; + s->opt[OPT_BR_Y].constraint.range = y_range; + s->val[OPT_BR_Y].w = y_range->max; /* "Enhancement" group: */ s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement"); @@ -6523,6 +6557,8 @@ sane_close (SANE_Handle handle) free (s->val[OPT_SOURCE].s); free (s->val[OPT_MODE].s); free (s->val[OPT_COLOR_FILTER].s); + FREE_IFNOT_NULL (s->opt[OPT_TL_X].constraint.range); + FREE_IFNOT_NULL (s->opt[OPT_TL_Y].constraint.range); if (prev) prev->next = s->next; @@ -6685,6 +6721,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, SANE_Status status = SANE_STATUS_GOOD; SANE_Word *table; unsigned int i; + SANE_Range *x_range, *y_range; Genesys_Calibration_Cache *cache, *next_cache; switch (option) @@ -6714,6 +6751,36 @@ set_option_value (Genesys_Scanner * s, int option, void *val, if (s->val[option].s) free (s->val[option].s); s->val[option].s = strdup (val); + + /* change geometry constraint to the new source value */ + if (strcmp (s->val[option].s, FLATBED) == 0) + { + x_range=create_range(s->dev->model->x_size); + y_range=create_range(s->dev->model->y_size); + } + else + { + x_range=create_range(s->dev->model->x_size_ta); + y_range=create_range(s->dev->model->y_size_ta); + } + if(x_range==NULL || y_range==NULL) + { + return SANE_STATUS_NO_MEM; + } + + /* assign new values */ + free(s->opt[OPT_TL_X].constraint.range); + free(s->opt[OPT_TL_Y].constraint.range); + s->opt[OPT_TL_X].constraint.range = x_range; + s->val[OPT_TL_X].w = 0; + s->opt[OPT_TL_Y].constraint.range = y_range; + s->val[OPT_TL_Y].w = 0; + s->opt[OPT_BR_X].constraint.range = x_range; + s->val[OPT_BR_Y].w = y_range->max; + s->opt[OPT_BR_Y].constraint.range = y_range; + s->val[OPT_BR_X].w = x_range->max; + + /* signals reload */ *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; } break; diff --git a/backend/genesys.h b/backend/genesys.h index 6ef01a869..0c474042b 100644 --- a/backend/genesys.h +++ b/backend/genesys.h @@ -56,7 +56,10 @@ #define GENESYS_CONFIG_FILE "genesys.conf" /* Maximum time for lamp warm-up */ -#define WARMUP_TIME 45 +#define WARMUP_TIME 65 + +#define FLATBED "Flatbed" +#define TRANSPARENCY_ADAPTER "Transparency Adapter" #ifndef SANE_I18N #define SANE_I18N(text) text diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index fd331f914..7d7baddd8 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -1060,12 +1060,12 @@ static Genesys_Model hp3670c_model = { SANE_FIX (0.0), /* Start of white strip in mm (y) */ SANE_FIX (1.0), /* Start of black mark in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ + SANE_FIX (104.0), /* Start of scan area in TA mode in mm (x) */ + SANE_FIX (55.6), /* Start of scan area in TA mode in mm (y) */ + SANE_FIX (25.6), /* Size of scan area in TA mode in mm (x) */ + SANE_FIX (78.0), /* Size of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ + SANE_FIX (76.0), /* Start of white strip in TA mode in mm (y) */ SANE_FIX (0.0), /* Size of scan area after paper sensor stops sensing document in mm */ @@ -1087,7 +1087,6 @@ static Genesys_Model hp3670c_model = { | GENESYS_FLAG_XPA | GENESYS_FLAG_DARK_CALIBRATION | GENESYS_FLAG_OFFSET_CALIBRATION - /* | GENESYS_FLAG_SKIP_WARMUP */ | GENESYS_FLAG_STAGGERED_LINE | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index 4130429c9..54beaa990 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -530,6 +530,39 @@ gl646_stop_motor (Genesys_Device * dev) } +/** + * find the lowest resolution for the sensor in the given mode. + * @param sensor id of the sensor + * @param required required resolution + * @param color true is color mode + * @return the closest resolution for the sensor and mode + */ +static int +get_lowest_resolution (int sensor, SANE_Bool color) +{ + int i, nb; + int dpi; + + i = 0; + dpi = 9600; + nb = sizeof (sensor_master) / sizeof (Sensor_Master); + while (sensor_master[i].sensor != -1 && i < nb) + { + /* computes distance and keep mode if it is closer than previous */ + if (sensor == sensor_master[i].sensor + && sensor_master[i].color == color) + { + if (sensor_master[i].dpi < dpi) + { + dpi = sensor_master[i].dpi; + } + } + i++; + } + DBG (DBG_info, "get_lowest_resolution: %d\n", dpi); + return dpi; +} + /** * find the closest match in mode tables for the given resolution and scan mode. * @param sensor id of the sensor @@ -993,13 +1026,15 @@ gl646_setup_registers (Genesys_Device * dev, if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) { /* for HP3670, stagger happens only at >=1200 dpi */ - if((dev->model->motor_type != MOTOR_HP3670 && dev->model->motor_type != MOTOR_HP2400)|| scan_settings.yres >= dev->sensor.optical_res) - { - stagger = (4 * scan_settings.yres) / dev->motor.base_ydpi; - } + if ((dev->model->motor_type != MOTOR_HP3670 + && dev->model->motor_type != MOTOR_HP2400) + || scan_settings.yres >= dev->sensor.optical_res) + { + stagger = (4 * scan_settings.yres) / dev->motor.base_ydpi; + } } linecnt += stagger; - + DBG (DBG_info, "gl646_setup_registers : max_shift=%d, stagger=%d lines\n", max_shift, stagger); @@ -3198,7 +3233,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev) Genesys_Settings settings; /* 1: no half_ccd, 2: use half number of pixels */ int half_ccd = 1; - int cksel=1; + int cksel = 1; DBG (DBG_proc, "gl646_init_register_for_shading: start\n"); @@ -3214,14 +3249,14 @@ gl646_init_regs_for_shading (Genesys_Device * dev) } /* fill settings for scan : always a color scan */ - settings.scan_method = SCAN_METHOD_FLATBED; + settings.scan_method = dev->settings.scan_method; settings.scan_mode = dev->settings.scan_mode; if (dev->model->is_cis == SANE_FALSE) { settings.scan_mode = SCAN_MODE_COLOR; } settings.xres = dev->sensor.optical_res / half_ccd; - cksel=get_cksel(dev->model->ccd_type, dev->settings.xres, SANE_TRUE); + cksel = get_cksel (dev->model->ccd_type, dev->settings.xres, SANE_TRUE); settings.xres = settings.xres / cksel; settings.yres = settings.xres; settings.tl_x = 0; @@ -3297,7 +3332,8 @@ gl646_init_regs_for_scan (Genesys_Device * dev) SANE_Status status; /* park head after calibration if needed */ - if (dev->scanhead_position_in_steps > 0) + if (dev->scanhead_position_in_steps > 0 + && dev->settings.scan_method == SCAN_METHOD_FLATBED) { status = gl646_slow_back_home (dev, SANE_TRUE); if (status != SANE_STATUS_GOOD) @@ -3335,9 +3371,10 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, DBG (DBG_proc, "setup_for_scan: start\n"); DBG (DBG_info, "setup_for_scan settings:\nResolution: %ux%uDPI\n" - "Lines : %u\nPixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n", - settings.xres, settings.yres, settings.lines, - settings.pixels, settings.tl_x, settings.tl_y, settings.scan_mode); + "Lines : %u\nPixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\nScan method: %s\n\n", + settings.xres, settings.yres, settings.lines, settings.pixels, + settings.tl_x, settings.tl_y, settings.scan_mode, + settings.scan_method == SCAN_METHOD_FLATBED ? "flatbed" : "XPA"); if (settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */ { @@ -3393,9 +3430,18 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, startx = dev->sensor.CCD_start_xoffset; else startx = dev->sensor.dummy_pixel; - startx += - ((SANE_UNFIX (dev->model->x_offset) * dev->sensor.optical_res) / - MM_PER_INCH); + if (settings.scan_method == SCAN_METHOD_FLATBED) + { + startx += + ((SANE_UNFIX (dev->model->x_offset) * dev->sensor.optical_res) / + MM_PER_INCH); + } + else + { + startx += + ((SANE_UNFIX (dev->model->x_offset_ta) * + dev->sensor.optical_res) / MM_PER_INCH); + } } else { @@ -3442,7 +3488,7 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, /* select color filter based on settings */ dev->reg[reg_0x04].value &= ~REG04_FILTER; - if(channels==1) + if (channels == 1) { switch (settings.color_filter) { @@ -4139,11 +4185,9 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi) /* setup for a RGB scan, one full sensor's width line */ /* resolution is the one from the final scan */ - resolution = - get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); - channels = 3; - settings.scan_mode = SCAN_MODE_COLOR; - + resolution = get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); + channels = 3; + settings.scan_mode = SCAN_MODE_COLOR; settings.scan_method = SCAN_METHOD_FLATBED; settings.xres = resolution; @@ -4224,7 +4268,10 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi) /** * Alternative coarse gain calibration - * this on uses the settings from offset_calibration. + * this on uses the settings from offset_calibration. First scan moves so + * we can go to calibration area for XPA. + * @param dev device for scan + * @param dpi resolutnio to calibrate at */ static SANE_Status gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) @@ -4257,17 +4304,27 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) else { resolution = - get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); + get_closest_resolution (dev->model->ccd_type, dev->settings.xres, + SANE_TRUE); } - settings.scan_method = SCAN_METHOD_FLATBED; + settings.scan_method = dev->settings.scan_method; settings.scan_mode = SCAN_MODE_COLOR; settings.xres = resolution; settings.yres = resolution; - settings.tl_x = 0; settings.tl_y = 0; - settings.pixels = - (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; + if (settings.scan_method == SCAN_METHOD_FLATBED) + { + settings.tl_x = 0; + settings.pixels = + (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; + } + else + { + settings.tl_x = SANE_UNFIX (dev->model->x_offset_ta); + settings.pixels = + (SANE_UNFIX (dev->model->x_size_ta) * resolution) / MM_PER_INCH; + } settings.lines = CALIBRATION_LINES; settings.depth = 8; settings.color_filter = 0; @@ -4295,10 +4352,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) average[0] = 255; average[1] = 255; average[2] = 255; - if (dev->model->ccd_type == CIS_XP200) - idx = 0; - else - idx = dev->settings.color_filter; + idx = dev->settings.color_filter; average[idx] = 0; } pass = 0; @@ -4442,7 +4496,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev, /* don't enable any correction for this scan */ dev->reg[reg_0x01].value &= ~REG01_DVDSET; /* XXX STEF XXX - dev->reg[reg_0x05].value &= ~REG05_GMMENB; */ + dev->reg[reg_0x05].value &= ~REG05_GMMENB; */ /* turn off motor during this scan */ gl646_set_motor_power (local_reg, SANE_FALSE); @@ -4832,6 +4886,26 @@ gl646_init (Genesys_Device * dev) return SANE_STATUS_GOOD; } +#ifndef UNIT_TESTING +static +#endif +gl646_move_to_ta (Genesys_Device * dev) +{ + SANE_Status status = SANE_STATUS_GOOD; + + DBG (DBG_proc, "gl646_move_to_ta: starting\n"); + if (simple_move (dev, SANE_UNFIX (dev->model->y_offset_calib_ta)) != + SANE_STATUS_GOOD) + { + DBG (DBG_error, + "gl646_move_to_ta: failed to move to calibration area\n"); + return status; + } + DBG (DBG_proc, "gl646_move_to_ta: end\n"); + + return status; +} + /** * Does a simple scan: ie no line reordering and avanced data buffering and @@ -4852,10 +4926,14 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, { SANE_Status status = SANE_STATUS_INVAL; unsigned int size, lines, x, y, bpp; - SANE_Bool empty; + SANE_Bool empty, split; unsigned char *buffer; + int count; + u_int8_t val; DBG (DBG_proc, "simple_scan: starting\n"); + DBG (DBG_io, "simple_scan: move=%d, forward=%d, shading=%d\n", move, + forward, shading); /* round up to multiple of 3 in case of CIS scanner */ if (dev->model->is_cis == SANE_TRUE) @@ -4863,7 +4941,16 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, settings.lines = ((settings.lines + 2) / 3) * 3; } - status = setup_for_scan (dev, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE); + /* setup for move then scan */ + if (move == SANE_TRUE && settings.tl_y > 0) + { + split = SANE_FALSE; + } + else + { + split = SANE_TRUE; + } + status = setup_for_scan (dev, settings, split, SANE_FALSE, SANE_FALSE); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "simple_scan: setup_for_scan failed (%s)\n", @@ -4939,6 +5026,12 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, dev->reg[reg_0x02].value &= ~REG02_MTRREV; } + /* no automatic go home when using XPA */ + if (settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + dev->reg[reg_0x02].value &= ~REG02_AGOHOME; + } + /* write scan registers */ status = gl646_bulk_write_register (dev, dev->reg, sizeof (dev->reg) / @@ -4962,11 +5055,25 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, } /* wait for buffers to be filled */ + count = 0; do { + usleep (10000UL); + RIE (sanei_genesys_get_status (dev, &val)); + if (DBG_LEVEL > DBG_info) + { + print_status (val); + } RIE (sanei_genesys_test_buffer_empty (dev, &empty)); + count++; + } + while (empty && count < 1000); + if (count == 1000) + { + free (*data); + DBG (DBG_error, "simple_scan: failed toread data\n"); + return SANE_STATUS_IO_ERROR; } - while (empty); /* now we're on target, we can read data */ status = sanei_genesys_read_data_from_scanner (dev, *data, size); @@ -5057,6 +5164,55 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, return status; } +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +#ifndef UNIT_TESTING +static +#endif + SANE_Status +simple_move (Genesys_Device * dev, SANE_Int distance) +{ + SANE_Status status = SANE_STATUS_INVAL; + unsigned char *data = NULL; + Genesys_Settings settings; + + DBG (DBG_proc, "simple_move: %d mm\n", distance); + + /* TODO give a no AGOHOME flag */ + settings.scan_method = SCAN_METHOD_TRANSPARENCY; + settings.scan_mode = SCAN_MODE_COLOR; + settings.xres = get_lowest_resolution (dev->model->ccd_type, SANE_TRUE); + settings.yres = settings.xres; + settings.tl_y = 0; + settings.tl_x = 0; + settings.pixels = + (dev->sensor.sensor_pixels * settings.xres) / dev->sensor.optical_res; + settings.lines = (distance * settings.xres) / MM_PER_INCH; + settings.depth = 8; + settings.color_filter = 0; + + settings.disable_interpolation = 0; + settings.threshold = 0; + settings.exposure_time = 0; + + status = + simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, &data); + free (data); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "simple_move: simple_scan failed\n"); + return status; + } + + DBG (DBG_proc, "simple_move: end.\n"); + return status; +} + /** * update the status of the required sensor in the scanner session * the last_val fileds are used to make events 'sticky' @@ -5305,8 +5461,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, "gl646_is_compatible_calibration: start (for_overwrite=%d)\n", for_overwrite); - /* calibration caching not supported yet for HP3670 */ - if (cache == NULL || dev->model->ccd_type == CCD_HP2400) + if (cache == NULL) return SANE_STATUS_UNSUPPORTED; /* build minimal current_setup for calibration cache use only, it will be better @@ -5321,6 +5476,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, dev->current_setup.channels = 1; } dev->current_setup.xres = dev->settings.xres; + dev->current_setup.scan_method = dev->settings.scan_method; DBG (DBG_io, "gl646_is_compatible_calibration: requested=(%d,%f), tested=(%d,%f)\n", @@ -5341,6 +5497,13 @@ gl646_is_compatible_calibration (Genesys_Device * dev, compatible = (dev->current_setup.channels == cache->used_setup.channels); } + if (dev->current_setup.scan_method != cache->used_setup.scan_method) + { + DBG (DBG_io, + "gl646_is_compatible_calibration: current method=%d, used=%d\n", + dev->current_setup.scan_method, cache->used_setup.scan_method); + compatible = 0; + } if (!compatible) { DBG (DBG_proc, @@ -5348,12 +5511,12 @@ gl646_is_compatible_calibration (Genesys_Device * dev, return SANE_STATUS_UNSUPPORTED; } - /* a cache entry expires after 10 minutes for non CIS scanners */ - /* TODO have depend on s->val[OPT_LAMP_OFF_TIME].w */ + /* a cache entry expires after 30 minutes for non CIS scanners */ #ifdef HAVE_SYS_TIME_H gettimeofday (&time, NULL); - if ((time.tv_sec - cache->last_calibration > 10 * 60) - && (dev->model->is_cis == SANE_FALSE)) + if ((time.tv_sec - cache->last_calibration > 30 * 60) + && (dev->model->is_cis == SANE_FALSE) + && (dev->settings.scan_method == SCAN_METHOD_FLATBED)) { DBG (DBG_proc, "gl646_is_compatible_calibration: expired entry, non compatible cache\n"); @@ -5588,7 +5751,8 @@ static Genesys_Command_Set gl646_cmd_set = { gl646_eject_document, gl646_search_strip, - gl646_is_compatible_calibration + gl646_is_compatible_calibration, + gl646_move_to_ta }; SANE_Status diff --git a/backend/genesys_gl646.h b/backend/genesys_gl646.h index e45711310..c51f99377 100644 --- a/backend/genesys_gl646.h +++ b/backend/genesys_gl646.h @@ -312,6 +312,19 @@ gl646_setup_registers (Genesys_Device * dev, uint16_t startx, uint16_t endx, SANE_Bool color, SANE_Int depth); +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +#ifndef UNIT_TESTING +static +#endif + SANE_Status +simple_move (Genesys_Device * dev, SANE_Int distance); + /** * Does a simple scan of the area given by the settings. Scanned data * it put in an allocated area which must be freed by the caller. diff --git a/backend/genesys_gl841.c b/backend/genesys_gl841.c index 26749ca50..1e46e8d96 100644 --- a/backend/genesys_gl841.c +++ b/backend/genesys_gl841.c @@ -6296,6 +6296,7 @@ static Genesys_Command_Set gl841_cmd_set = { gl841_search_strip, gl841_is_compatible_calibration, + NULL }; SANE_Status diff --git a/backend/genesys_low.h b/backend/genesys_low.h index a65613e31..bf38ac391 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -3,7 +3,7 @@ Copyright (C) 2003 Oliver Rauch Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2004, 2005 Gerhard Jaeger - Copyright (C) 2004-2009 Stéphane Voltz + Copyright (C) 2004-2010 Stéphane Voltz Copyright (C) 2005-2009 Pierre Willenbrock Copyright (C) 2006 Laurent Charpentier Parts of the structs have been taken from the gt68xx backend by @@ -410,6 +410,12 @@ typedef struct Genesys_Command_Set Genesys_Device * dev, Genesys_Calibration_Cache *cache, SANE_Bool for_overwrite); + + /* functions for transparency adapter */ + /** + * move scanning head to transparency adapter + */ + SANE_Status (*move_to_ta) (Genesys_Device * dev); } Genesys_Command_Set; typedef struct Genesys_Model @@ -520,6 +526,7 @@ typedef struct Genesys_Current_Setup int lines; /* line count expected from scanner */ int depth; /* depth expected from scanner */ int channels; /* channel count expected from scanner */ + int scan_method; /* scanning method: flatbed or XPA */ int exposure_time; /* used exposure time */ float xres; /* used xres */ float yres; /* used yres*/