kopia lustrzana https://gitlab.com/sane-project/backends
first step in adding sheetfed scanners calibration
- added search_strip function to command set - coded search_strip for gl646 - initial calibration process for sheetfed scanners upto strip finding - create a scanner calibration function that switches between flatbed or sheetfed calibration - added a sheetfed calibration function - removed gamma table setting from calibration process - call gamma setting during sane_start but before scanner calibrationmerge-requests/1/head
rodzic
2b80045dcf
commit
7c44981be0
|
@ -1576,7 +1576,7 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, uint8_t * data,
|
||||||
dev->sensor.CCD_start_xoffset =
|
dev->sensor.CCD_start_xoffset =
|
||||||
start_pixel + (left * dev->sensor.optical_res) / dpi;
|
start_pixel + (left * dev->sensor.optical_res) / dpi;
|
||||||
|
|
||||||
/* find top edge by detecting black stripe */
|
/* find top edge by detecting black strip */
|
||||||
/* apply Y direction sobel filter
|
/* apply Y direction sobel filter
|
||||||
-1 -2 -1
|
-1 -2 -1
|
||||||
0 0 0
|
0 0 0
|
||||||
|
@ -3356,6 +3356,14 @@ genesys_save_calibration (Genesys_Device * dev)
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* does the calibration process for a flatbed scanner
|
||||||
|
* - offset calibration
|
||||||
|
* - gain calibration
|
||||||
|
* - shading calibration
|
||||||
|
* @param dev device to calibrate
|
||||||
|
* @return SANE_STATUS_GOOD if everything when all right, else the error code.
|
||||||
|
*/
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
genesys_flatbed_calibration (Genesys_Device * dev)
|
genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
{
|
{
|
||||||
|
@ -3369,25 +3377,6 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
if (dev->settings.yres <= dev->sensor.optical_res / 2)
|
if (dev->settings.yres <= dev->sensor.optical_res / 2)
|
||||||
yres /= 2;
|
yres /= 2;
|
||||||
|
|
||||||
/* send custom or generic gamma tables depending on flag */
|
|
||||||
if (dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA)
|
|
||||||
{
|
|
||||||
/* use custom gamma table */
|
|
||||||
status = dev->model->cmd_set->send_gamma_table (dev, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* send default gamma table if no custom gamma */
|
|
||||||
status = dev->model->cmd_set->send_gamma_table (dev, 1);
|
|
||||||
}
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
{
|
|
||||||
DBG (DBG_error,
|
|
||||||
"genesys_flatbed_calibration: failed to init gamma table: %s\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do offset calibration if needed */
|
/* do offset calibration if needed */
|
||||||
if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION)
|
if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION)
|
||||||
{
|
{
|
||||||
|
@ -3437,7 +3426,7 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
|
|
||||||
if (dev->model->is_cis)
|
if (dev->model->is_cis)
|
||||||
{
|
{
|
||||||
/*the afe now sends valid data for doing led calibration*/
|
/* the afe now sends valid data for doing led calibration*/
|
||||||
status = dev->model->cmd_set->led_calibration (dev);
|
status = dev->model->cmd_set->led_calibration (dev);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
|
@ -3447,7 +3436,7 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*calibrate afe again to match new exposure*/
|
/* calibrate afe again to match new exposure*/
|
||||||
if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION)
|
if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION)
|
||||||
{
|
{
|
||||||
status = dev->model->cmd_set->offset_calibration (dev);
|
status = dev->model->cmd_set->offset_calibration (dev);
|
||||||
|
@ -3469,7 +3458,6 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* since we have 2 gain calibration proc, skip second if first one was
|
/* since we have 2 gain calibration proc, skip second if first one was
|
||||||
|
@ -3493,13 +3481,11 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixels_per_line = (SANE_UNFIX (dev->model->x_size) * dev->settings.xres) /
|
||||||
pixels_per_line = (SANE_UNFIX(dev->model->x_size) * dev->settings.xres) /
|
MM_PER_INCH;
|
||||||
MM_PER_INCH;
|
|
||||||
|
|
||||||
/* send default shading data */
|
/* send default shading data */
|
||||||
status = sanei_genesys_init_shading_data (dev, pixels_per_line);
|
status = sanei_genesys_init_shading_data (dev, pixels_per_line);
|
||||||
|
@ -3564,21 +3550,85 @@ genesys_flatbed_calibration (Genesys_Device * dev)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send specific gamma tables if needed */
|
DBG (DBG_info, "genesys_flatbed_calibration: completed\n");
|
||||||
status = dev->model->cmd_set->send_gamma_table (dev, 0);
|
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the calibration process for a sheetfed scanner
|
||||||
|
* - offset calibration
|
||||||
|
* - gain calibration
|
||||||
|
* - shading calibration
|
||||||
|
* During calibration a predefined calibration sheet with specific black and white
|
||||||
|
* areas is used.
|
||||||
|
* @param dev device to calibrate
|
||||||
|
* @return SANE_STATUS_GOOD if everything when all right, else the error code.
|
||||||
|
*/
|
||||||
|
static SANE_Status
|
||||||
|
genesys_sheetfed_calibration (Genesys_Device * dev)
|
||||||
|
{
|
||||||
|
SANE_Status status = SANE_STATUS_GOOD;
|
||||||
|
|
||||||
|
DBG (DBG_proc, "genesys_sheetfed_calibration: start\n");
|
||||||
|
if(dev->model->cmd_set->search_strip==NULL)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"genesys_sheetfed_calibration: no strip searching function available\n");
|
||||||
|
return SANE_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first step, load document */
|
||||||
|
status = dev->model->cmd_set->load_document (dev);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
"genesys_flatbed_calibration: failed to send specific gamma tables: %s\n",
|
"genesys_sheetfed_calibration: failed to load document: %s\n",
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_info, "genesys_flatbed_calibration: completed\n");
|
/* we set up for shading calibration, start scan and then scan lines by lines until
|
||||||
|
* we find a black strip crossing the calibration sheet */
|
||||||
|
|
||||||
|
/* seek black/white reverse/forward */
|
||||||
|
status = dev->model->cmd_set->search_strip (dev, SANE_TRUE, SANE_TRUE);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"genesys_sheetfed_calibration: failed to find black strip: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
dev->model->cmd_set->eject_document (dev);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and finally eject calibration sheet */
|
||||||
|
status = dev->model->cmd_set->eject_document (dev);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"genesys_sheetfed_calibration: failed to eject document: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
DBG (DBG_proc, "genesys_sheetfed_calibration: end\n");
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* does the calibration process for a device
|
||||||
|
* @param dev device to calibrate
|
||||||
|
*/
|
||||||
|
static SANE_Status
|
||||||
|
genesys_scanner_calibration (Genesys_Device * dev)
|
||||||
|
{
|
||||||
|
if (dev->model->is_sheetfed == SANE_FALSE)
|
||||||
|
{
|
||||||
|
return genesys_flatbed_calibration (dev);
|
||||||
|
}
|
||||||
|
return genesys_sheetfed_calibration (dev);
|
||||||
|
}
|
||||||
|
|
||||||
/* unused function kept in case it may be usefull in the futur */
|
/* unused function kept in case it may be usefull in the futur */
|
||||||
#if 0
|
#if 0
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
|
@ -3845,46 +3895,38 @@ genesys_start_scan (Genesys_Device * dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: STEF we should move gamma table handling out of calibration, when cache
|
/* send custom or generic gamma tables depending on flag */
|
||||||
* is active, custom gamma tables don't seem to be sent */
|
if (dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA)
|
||||||
|
{
|
||||||
|
/* use custom gamma table */
|
||||||
|
status = dev->model->cmd_set->send_gamma_table (dev, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* send default gamma table if no custom gamma */
|
||||||
|
status = dev->model->cmd_set->send_gamma_table (dev, 1);
|
||||||
|
}
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"genesys_flatbed_calibration: failed to init gamma table: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try to use cached calibration first */
|
||||||
status = genesys_restore_calibration (dev);
|
status = genesys_restore_calibration (dev);
|
||||||
if(status == SANE_STATUS_UNSUPPORTED)
|
if(status == SANE_STATUS_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
/* calibration : sheetfed scanners can't calibrate before each scan */
|
/* calibration : sheetfed scanners can't calibrate before each scan */
|
||||||
/* so we use a NO_CALIBRATION flags for those scanners */
|
/* so we use a NO_CALIBRATION flags for those scanners */
|
||||||
if (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)
|
if (!dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)
|
||||||
{
|
{
|
||||||
/* TODO send predefined calibration values from default
|
status = genesys_scanner_calibration (dev);
|
||||||
* values or built from a calibration scan */
|
|
||||||
/* send custom or generic gamma tables depending on flag */
|
|
||||||
if (dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA)
|
|
||||||
{
|
|
||||||
/* use custom gamma table */
|
|
||||||
status = dev->model->cmd_set->send_gamma_table (dev, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* send default gamma table if no custom gamma */
|
|
||||||
status = dev->model->cmd_set->send_gamma_table (dev, 1);
|
|
||||||
}
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
"genesys_start_scan: failed to init gamma table: %s\n",
|
"genesys_start_scan: failed to do scanner calibration: %s\n",
|
||||||
sane_strstatus (status));
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* head hasn't moved */
|
|
||||||
dev->scanhead_position_in_steps = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = genesys_flatbed_calibration (dev);
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
{
|
|
||||||
DBG (DBG_error,
|
|
||||||
"genesys_start_scan: failed to do flatbed calibration: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -5988,7 +6030,7 @@ static SANE_Status
|
||||||
set_option_value (Genesys_Scanner * s, int option, void *val,
|
set_option_value (Genesys_Scanner * s, int option, void *val,
|
||||||
SANE_Int * myinfo)
|
SANE_Int * myinfo)
|
||||||
{
|
{
|
||||||
SANE_Status status;
|
SANE_Status status = SANE_STATUS_GOOD;
|
||||||
SANE_Word *table;
|
SANE_Word *table;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
Genesys_Calibration_Cache *cache, *next_cache;
|
Genesys_Calibration_Cache *cache, *next_cache;
|
||||||
|
@ -6187,7 +6229,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_CALIBRATE:
|
case OPT_CALIBRATE:
|
||||||
/* TODO call for calibration using special sheet here */
|
status = genesys_scanner_calibration (s->dev);
|
||||||
break;
|
break;
|
||||||
case OPT_CLEAR_CALIBRATION:
|
case OPT_CLEAR_CALIBRATION:
|
||||||
/* clear calibration cache */
|
/* clear calibration cache */
|
||||||
|
@ -6210,7 +6252,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
|
||||||
DBG (DBG_warn, "set_option_value: can't set unknown option %d\n",
|
DBG (DBG_warn, "set_option_value: can't set unknown option %d\n",
|
||||||
option);
|
option);
|
||||||
}
|
}
|
||||||
return SANE_STATUS_GOOD;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -975,7 +975,7 @@ Genesys_Model visioneer_xp200_model = {
|
||||||
| GENESYS_FLAG_CUSTOM_GAMMA
|
| GENESYS_FLAG_CUSTOM_GAMMA
|
||||||
| GENESYS_FLAG_SKIP_WARMUP
|
| GENESYS_FLAG_SKIP_WARMUP
|
||||||
| GENESYS_FLAG_NO_CALIBRATION,
|
| GENESYS_FLAG_NO_CALIBRATION,
|
||||||
GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW, /* | GENESYS_HAS_CALIBRATE, */
|
GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE,
|
||||||
20,
|
20,
|
||||||
132
|
132
|
||||||
};
|
};
|
||||||
|
|
|
@ -154,7 +154,7 @@ gl646_bulk_write_register (Genesys_Device * dev,
|
||||||
{
|
{
|
||||||
DBG (DBG_io2, "reg[0x%02x] = 0x%02x\n", buffer[i], buffer[i + 1]);
|
DBG (DBG_io2, "reg[0x%02x] = 0x%02x\n", buffer[i], buffer[i + 1]);
|
||||||
}
|
}
|
||||||
/* when full size, decode regfister content */
|
/* when full size, decode register content */
|
||||||
if (elems > 60)
|
if (elems > 60)
|
||||||
{
|
{
|
||||||
DBG (DBG_io2, "DPISET =%d\n",
|
DBG (DBG_io2, "DPISET =%d\n",
|
||||||
|
@ -591,7 +591,7 @@ is_half_ccd (int sensor, int required, SANE_Bool color)
|
||||||
&& sensor_master[i].color == color)
|
&& sensor_master[i].color == color)
|
||||||
{
|
{
|
||||||
DBG (DBG_io, "is_half_ccd: match found for %d (half_ccd=%d)\n",
|
DBG (DBG_io, "is_half_ccd: match found for %d (half_ccd=%d)\n",
|
||||||
required,sensor_master[i].half_ccd);
|
required, sensor_master[i].half_ccd);
|
||||||
return sensor_master[i].half_ccd;
|
return sensor_master[i].half_ccd;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -934,11 +934,16 @@ gl646_setup_registers (Genesys_Device * dev,
|
||||||
DBG (DBG_info, "gl646_setup_registers : max_shift=%d, stagger=%d lines\n",
|
DBG (DBG_info, "gl646_setup_registers : max_shift=%d, stagger=%d lines\n",
|
||||||
max_shift, stagger);
|
max_shift, stagger);
|
||||||
|
|
||||||
|
/* big to get any doc out of the feeder */
|
||||||
|
/* XXX STEF XXX clashes with calibration process
|
||||||
|
if (dev->model->is_sheetfed == SANE_TRUE)
|
||||||
|
{
|
||||||
|
linecnt = (1000 * motor->ydpi) / MM_PER_INCH;
|
||||||
|
} */
|
||||||
|
|
||||||
/* CIS scanners read one line per color channel */
|
/* CIS scanners read one line per color channel */
|
||||||
if (dev->model->is_cis == SANE_TRUE)
|
if (dev->model->is_cis == SANE_TRUE)
|
||||||
{
|
{
|
||||||
/* big to get any doc out of the feeder */
|
|
||||||
linecnt = (1000 * motor->ydpi) / MM_PER_INCH;
|
|
||||||
linecnt *= channels;
|
linecnt *= channels;
|
||||||
}
|
}
|
||||||
gl646_set_triple_reg (regs, REG_LINCNT, linecnt);
|
gl646_set_triple_reg (regs, REG_LINCNT, linecnt);
|
||||||
|
@ -2460,21 +2465,31 @@ end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
|
||||||
DBG (DBG_proc, "end_scan (check_stop = %d, eject = %d)\n", check_stop,
|
DBG (DBG_proc, "end_scan (check_stop = %d, eject = %d)\n", check_stop,
|
||||||
eject);
|
eject);
|
||||||
|
|
||||||
/*status = sanei_genesys_get_status (dev, &val);
|
/*
|
||||||
if (val & REG41_SCANFSH)
|
status = sanei_genesys_get_status (dev, &val);
|
||||||
scanfsh = 1;
|
|
||||||
DBG (DBG_info, "end_scan: current status =0x%02x\n", val);
|
|
||||||
if (DBG_LEVEL > DBG_io)
|
if (DBG_LEVEL > DBG_io)
|
||||||
{
|
{
|
||||||
print_status (val);
|
print_status (val);
|
||||||
read_triple_reg (dev, REG_SCANCNT, &value);
|
read_triple_reg (dev, REG_SCANCNT, &value);
|
||||||
} */
|
DBG (DBG_info, "end_scan: SCANCNT=%d\n", value);
|
||||||
|
} */
|
||||||
/* for sheetfed scanners, we have to eject document and read
|
/* ends scan */
|
||||||
* left data in buffers */
|
val = sanei_genesys_read_reg_from_set (reg, 0x01);
|
||||||
if (dev->model->is_sheetfed == SANE_TRUE && dev->document == SANE_TRUE)
|
val &= ~REG01_SCAN;
|
||||||
|
sanei_genesys_set_reg_from_set (reg, 0x01, val);
|
||||||
|
status = sanei_genesys_write_register (dev, 0x01, val);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
if (eject == SANE_TRUE)
|
DBG (DBG_error,
|
||||||
|
"end_scan: failed to write register 01: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for sheetfed scanners, we may have to eject document */
|
||||||
|
if (dev->model->is_sheetfed == SANE_TRUE)
|
||||||
|
{
|
||||||
|
if (eject == SANE_TRUE && dev->document == SANE_TRUE)
|
||||||
{
|
{
|
||||||
status = gl646_eject_document (dev);
|
status = gl646_eject_document (dev);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
@ -2486,19 +2501,6 @@ end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
|
||||||
}
|
}
|
||||||
else /* flat bed scanners */
|
else /* flat bed scanners */
|
||||||
{
|
{
|
||||||
/* ends scan */
|
|
||||||
val = sanei_genesys_read_reg_from_set (reg, 0x01);
|
|
||||||
val &= ~REG01_SCAN;
|
|
||||||
sanei_genesys_set_reg_from_set (reg, 0x01, val);
|
|
||||||
status = sanei_genesys_write_register (dev, 0x01, val);
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
{
|
|
||||||
DBG (DBG_error,
|
|
||||||
"end_scan: failed to write register 01: %s\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_stop)
|
if (check_stop)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 300; i++) /* do not wait longer than wait 30 seconds */
|
for (i = 0; i < 300; i++) /* do not wait longer than wait 30 seconds */
|
||||||
|
@ -2754,7 +2756,7 @@ gl646_search_start_position (Genesys_Device * dev)
|
||||||
settings.exposure_time = 0;
|
settings.exposure_time = 0;
|
||||||
|
|
||||||
/* scan the desired area */
|
/* scan the desired area */
|
||||||
status = simple_scan (dev, settings, SANE_TRUE, &data);
|
status = simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, &data);
|
||||||
|
|
||||||
/* process data if scan is OK */
|
/* process data if scan is OK */
|
||||||
if (status == SANE_STATUS_GOOD)
|
if (status == SANE_STATUS_GOOD)
|
||||||
|
@ -2852,7 +2854,8 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
|
||||||
if (dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)
|
if (dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)
|
||||||
{
|
{
|
||||||
/* walk the master mode list to find if half_ccd */
|
/* walk the master mode list to find if half_ccd */
|
||||||
if (is_half_ccd (dev->model->ccd_type, dev->settings.xres, SANE_TRUE) == SANE_TRUE)
|
if (is_half_ccd (dev->model->ccd_type, dev->settings.xres, SANE_TRUE) ==
|
||||||
|
SANE_TRUE)
|
||||||
{
|
{
|
||||||
half_ccd = 2;
|
half_ccd = 2;
|
||||||
}
|
}
|
||||||
|
@ -3341,7 +3344,7 @@ gl646_offset_calibration (Genesys_Device * dev)
|
||||||
dev->frontend.offset[0] = bottom;
|
dev->frontend.offset[0] = bottom;
|
||||||
dev->frontend.offset[1] = bottom;
|
dev->frontend.offset[1] = bottom;
|
||||||
dev->frontend.offset[2] = bottom;
|
dev->frontend.offset[2] = bottom;
|
||||||
status = simple_scan (dev, settings, SANE_FALSE, &first_line);
|
status = simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, &first_line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -3367,7 +3370,7 @@ gl646_offset_calibration (Genesys_Device * dev)
|
||||||
dev->frontend.offset[0] = top;
|
dev->frontend.offset[0] = top;
|
||||||
dev->frontend.offset[1] = top;
|
dev->frontend.offset[1] = top;
|
||||||
dev->frontend.offset[2] = top;
|
dev->frontend.offset[2] = top;
|
||||||
status = simple_scan (dev, settings, SANE_FALSE, &second_line);
|
status = simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, &second_line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -3397,7 +3400,8 @@ gl646_offset_calibration (Genesys_Device * dev)
|
||||||
dev->frontend.offset[2] = (top + bottom) / 2;
|
dev->frontend.offset[2] = (top + bottom) / 2;
|
||||||
|
|
||||||
/* scan with no move */
|
/* scan with no move */
|
||||||
status = simple_scan (dev, settings, SANE_FALSE, &second_line);
|
status =
|
||||||
|
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, &second_line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -3435,7 +3439,8 @@ gl646_offset_calibration (Genesys_Device * dev)
|
||||||
/* in case of debug do a final scan to get result */
|
/* in case of debug do a final scan to get result */
|
||||||
if (DBG_LEVEL >= DBG_data)
|
if (DBG_LEVEL >= DBG_data)
|
||||||
{
|
{
|
||||||
status = simple_scan (dev, settings, SANE_FALSE, &second_line);
|
status =
|
||||||
|
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, &second_line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -3535,7 +3540,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
|
||||||
|| (average[2] < dev->sensor.gain_white_ref)) && (pass < 30))
|
|| (average[2] < dev->sensor.gain_white_ref)) && (pass < 30))
|
||||||
{
|
{
|
||||||
/* scan with no move */
|
/* scan with no move */
|
||||||
status = simple_scan (dev, settings, SANE_FALSE, &line);
|
status = simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, &line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -4043,18 +4048,26 @@ gl646_init (Genesys_Device * dev)
|
||||||
* @param dev device of the scanner
|
* @param dev device of the scanner
|
||||||
* @param settings parameters of the scan
|
* @param settings parameters of the scan
|
||||||
* @param move SANE_TRUE if moving during scan
|
* @param move SANE_TRUE if moving during scan
|
||||||
|
* @param move SANE_TRUE if moving forward during scan
|
||||||
* @param data pointer for the data
|
* @param data pointer for the data
|
||||||
*/
|
*/
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
|
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
|
||||||
unsigned char **data)
|
SANE_Bool forward, unsigned char **data)
|
||||||
{
|
{
|
||||||
SANE_Status status;
|
SANE_Status status = SANE_STATUS_INVAL;
|
||||||
unsigned int size, lines, x, y, bpp;
|
unsigned int size, lines, x, y, bpp;
|
||||||
SANE_Bool empty;
|
SANE_Bool empty;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
|
|
||||||
DBG (DBG_proc, "simple_scan: starting\n");
|
DBG (DBG_proc, "simple_scan: starting\n");
|
||||||
|
|
||||||
|
/* round up to multiple of 3 in case of CIS scanner */
|
||||||
|
if (dev->model->is_cis == SANE_TRUE)
|
||||||
|
{
|
||||||
|
settings.lines = ((settings.lines + 2) / 3) * 3;
|
||||||
|
}
|
||||||
|
|
||||||
status = setup_for_scan (dev, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE);
|
status = setup_for_scan (dev, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
|
@ -4113,6 +4126,14 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
|
||||||
/* no automatic go home if no movement */
|
/* no automatic go home if no movement */
|
||||||
dev->reg[reg_0x02].value &= ~REG02_AGOHOME;
|
dev->reg[reg_0x02].value &= ~REG02_AGOHOME;
|
||||||
}
|
}
|
||||||
|
if (forward == SANE_FALSE)
|
||||||
|
{
|
||||||
|
dev->reg[reg_0x02].value |= REG02_MTRREV;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dev->reg[reg_0x02].value &= ~REG02_MTRREV;
|
||||||
|
}
|
||||||
|
|
||||||
/* write scan registers */
|
/* write scan registers */
|
||||||
status = gl646_bulk_write_register (dev, dev->reg,
|
status = gl646_bulk_write_register (dev, dev->reg,
|
||||||
|
@ -4460,6 +4481,125 @@ gl646_is_compatible_calibration (Genesys_Device * dev,
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for a full width black or white strip.
|
||||||
|
* @param dev scanner device
|
||||||
|
* @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward
|
||||||
|
* @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip
|
||||||
|
* @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not
|
||||||
|
*/
|
||||||
|
static SANE_Status
|
||||||
|
gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
|
||||||
|
{
|
||||||
|
SANE_Status status = SANE_STATUS_GOOD;
|
||||||
|
SANE_Bool half_ccd = SANE_FALSE;
|
||||||
|
Genesys_Settings settings;
|
||||||
|
int res = get_closest_resolution (dev->model->ccd_type, 75, SANE_FALSE);
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
unsigned int pass, count, found, x, y;
|
||||||
|
char titre[80];
|
||||||
|
|
||||||
|
DBG (DBG_proc, "gl646_search_strip: start\n");
|
||||||
|
/* adapt to half_ccd case */
|
||||||
|
if (dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)
|
||||||
|
{
|
||||||
|
/* walk the master mode list to find if half_ccd */
|
||||||
|
if (is_half_ccd (dev->model->ccd_type, res, SANE_TRUE) == SANE_TRUE)
|
||||||
|
{
|
||||||
|
half_ccd = SANE_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we set up for a lowest available resolution color grey scan, full width */
|
||||||
|
settings.scan_method = SCAN_METHOD_FLATBED;
|
||||||
|
settings.scan_mode = SCAN_MODE_GRAY;
|
||||||
|
settings.xres = res;
|
||||||
|
settings.yres = res;
|
||||||
|
settings.tl_x = 0;
|
||||||
|
settings.tl_y = 0;
|
||||||
|
settings.pixels =
|
||||||
|
(dev->sensor.sensor_pixels * res) / dev->sensor.optical_res;
|
||||||
|
if (half_ccd == SANE_TRUE)
|
||||||
|
{
|
||||||
|
settings.pixels /= 2;
|
||||||
|
}
|
||||||
|
/* 15 mm at at time */
|
||||||
|
settings.lines = (15 * settings.yres) / MM_PER_INCH; /* may become a parameter from genesys_devices.c */
|
||||||
|
settings.depth = 8;
|
||||||
|
settings.color_filter = 0;
|
||||||
|
|
||||||
|
settings.disable_interpolation = 0;
|
||||||
|
settings.threshold = 0;
|
||||||
|
settings.exposure_time = 0;
|
||||||
|
|
||||||
|
/* signals if a strip of the given color has been found */
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
/* detection pass done */
|
||||||
|
pass = 0;
|
||||||
|
|
||||||
|
/* loop until strip is found or maximum pass number done */
|
||||||
|
while (pass < 20 && !found)
|
||||||
|
{
|
||||||
|
/* scan a full width strip */
|
||||||
|
status = simple_scan (dev, settings, SANE_TRUE, forward, &data);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "gl646_search_strip: simple_scan failed\n");
|
||||||
|
free (data);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (DBG_LEVEL >= DBG_data)
|
||||||
|
{
|
||||||
|
sprintf (titre, "search_strip%02d.pnm", pass);
|
||||||
|
sanei_genesys_write_pnm_file (titre, data, settings.depth, 1,
|
||||||
|
settings.pixels, settings.lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search data to find black strip */
|
||||||
|
for (y = 0; y < settings.lines && !found; y++)
|
||||||
|
{
|
||||||
|
/* count of white/black pixels depending on the color searched */
|
||||||
|
count = 0;
|
||||||
|
for (x = 0; x < settings.pixels; x++)
|
||||||
|
{
|
||||||
|
/* when searching for black, detect white pixels */
|
||||||
|
if (black && data[y * settings.pixels + x] > 60)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
/* when searching for white, detect black pixels */
|
||||||
|
if (!black && data[y * settings.pixels + x] < 60)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* at end of line, if count >0, line is not fully of the desired color
|
||||||
|
* so we must go to next line of the buffer */
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
DBG (DBG_data,
|
||||||
|
"gl646_search_strip: strip found during pass %d at line %d\n",
|
||||||
|
pass, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (data);
|
||||||
|
pass++;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
status = SANE_STATUS_GOOD;
|
||||||
|
DBG (DBG_info, "gl646_search_strip: strip found\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = SANE_STATUS_UNSUPPORTED;
|
||||||
|
DBG (DBG_info, "gl646_search_strip: strip not found\n");
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/** the gl646 command set */
|
/** the gl646 command set */
|
||||||
static Genesys_Command_Set gl646_cmd_set = {
|
static Genesys_Command_Set gl646_cmd_set = {
|
||||||
"gl646-generic", /* the name of this set */
|
"gl646-generic", /* the name of this set */
|
||||||
|
@ -4505,9 +4645,11 @@ static Genesys_Command_Set gl646_cmd_set = {
|
||||||
|
|
||||||
gl646_update_hardware_sensors,
|
gl646_update_hardware_sensors,
|
||||||
|
|
||||||
|
/* sheetfed related functions */
|
||||||
gl646_load_document,
|
gl646_load_document,
|
||||||
gl646_detect_document_end,
|
gl646_detect_document_end,
|
||||||
gl646_eject_document,
|
gl646_eject_document,
|
||||||
|
gl646_search_strip,
|
||||||
|
|
||||||
gl646_is_compatible_calibration
|
gl646_is_compatible_calibration
|
||||||
};
|
};
|
||||||
|
|
|
@ -315,10 +315,11 @@ gl646_setup_registers (Genesys_Device * dev,
|
||||||
* @param device device to set up
|
* @param device device to set up
|
||||||
* @param settings settings of the scan
|
* @param settings settings of the scan
|
||||||
* @param move flag to enable scanhead to move
|
* @param move flag to enable scanhead to move
|
||||||
|
* @param forward flag to tell movement direction
|
||||||
* @param data pointer that will point to the scanned data
|
* @param data pointer that will point to the scanned data
|
||||||
*/
|
*/
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
|
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, SANE_Bool forward,
|
||||||
unsigned char **data);
|
unsigned char **data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5859,6 +5859,7 @@ static Genesys_Command_Set gl841_cmd_set = {
|
||||||
gl841_load_document,
|
gl841_load_document,
|
||||||
gl841_detect_document_end,
|
gl841_detect_document_end,
|
||||||
gl841_eject_document,
|
gl841_eject_document,
|
||||||
|
NULL,
|
||||||
|
|
||||||
gl841_is_compatible_calibration,
|
gl841_is_compatible_calibration,
|
||||||
};
|
};
|
||||||
|
|
|
@ -394,6 +394,10 @@ typedef struct Genesys_Command_Set
|
||||||
* eject document from scanner
|
* eject document from scanner
|
||||||
*/
|
*/
|
||||||
SANE_Status (*eject_document) (Genesys_Device * dev);
|
SANE_Status (*eject_document) (Genesys_Device * dev);
|
||||||
|
/**
|
||||||
|
* search for an black or white area in forward or reverse
|
||||||
|
* direction */
|
||||||
|
SANE_Status (*search_strip) (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black);
|
||||||
|
|
||||||
SANE_Status (*is_compatible_calibration) (
|
SANE_Status (*is_compatible_calibration) (
|
||||||
Genesys_Device * dev,
|
Genesys_Device * dev,
|
||||||
|
|
Ładowanie…
Reference in New Issue