work toward shading calibration

- black/white strip searching reliable
- call to dar and white shading calibration
merge-requests/1/head
Stphane Voltz 2009-06-15 22:16:06 +02:00
rodzic 7c44981be0
commit 3135e94c90
3 zmienionych plików z 359 dodań i 248 usunięć

Wyświetl plik

@ -221,7 +221,7 @@ sanei_genesys_write_pnm_file (char *filename, uint8_t * data, int depth,
{ {
if (depth == 8) if (depth == 8)
{ {
fputc (*(data+count), out); fputc (*(data + count), out);
} }
else else
{ {
@ -282,8 +282,7 @@ sanei_genesys_set_reg_from_set (Genesys_Register_Set * reg, SANE_Byte address,
/* Write to one register */ /* Write to one register */
SANE_Status SANE_Status
sanei_genesys_write_register (Genesys_Device * dev, uint8_t reg, sanei_genesys_write_register (Genesys_Device * dev, uint8_t reg, uint8_t val)
uint8_t val)
{ {
SANE_Status status; SANE_Status status;
@ -318,8 +317,7 @@ sanei_genesys_write_register (Genesys_Device * dev, uint8_t reg,
/* Read from one register */ /* Read from one register */
SANE_Status SANE_Status
sanei_genesys_read_register (Genesys_Device * dev, uint8_t reg, sanei_genesys_read_register (Genesys_Device * dev, uint8_t reg, uint8_t * val)
uint8_t * val)
{ {
SANE_Status status; SANE_Status status;
@ -428,7 +426,8 @@ sanei_genesys_init_structs (Genesys_Device * dev)
{ {
DBG (DBG_error0, DBG (DBG_error0,
"sanei_genesys_init_structs: bad description(s) for ccd/gpo/motor=%d/%d/%d\n", "sanei_genesys_init_structs: bad description(s) for ccd/gpo/motor=%d/%d/%d\n",
dev->model->ccd_type, dev->model->gpo_type, dev->model->motor_type); dev->model->ccd_type, dev->model->gpo_type,
dev->model->motor_type);
} }
} }
@ -448,7 +447,8 @@ sanei_genesys_init_fe (Genesys_Device * dev)
DBG (DBG_error0, DBG (DBG_error0,
"sanei_genesys_init_fe: failed to find description for dac_type %d\n", "sanei_genesys_init_fe: failed to find description for dac_type %d\n",
dev->model->dac_type); dev->model->dac_type);
DBG (DBG_info, "sanei_genesys_init_fe: dac_type %d set up\n", dev->model->dac_type); DBG (DBG_info, "sanei_genesys_init_fe: dac_type %d set up\n",
dev->model->dac_type);
} }
/* Write data for analog frontend */ /* Write data for analog frontend */
@ -734,12 +734,11 @@ sanei_genesys_create_slope_table3 (Genesys_Device * dev,
vtarget, vtarget,
vstart, vstart,
vend, vend,
dev->motor. dev->motor.slopes[power_mode]
slopes[power_mode] [step_type].minimum_steps <<
[step_type]. step_type,
minimum_steps << step_type, dev->
dev->motor. motor.slopes[power_mode]
slopes[power_mode]
[step_type].g, used_steps, [step_type].g, used_steps,
&vfinal); &vfinal);
@ -797,12 +796,11 @@ genesys_create_slope_table4 (Genesys_Device * dev,
vtarget, vtarget,
vstart, vstart,
vend, vend,
dev->motor. dev->motor.slopes[power_mode]
slopes[power_mode] [step_type].minimum_steps <<
[step_type]. step_type,
minimum_steps << step_type, dev->
dev->motor. motor.slopes[power_mode]
slopes[power_mode]
[step_type].g, NULL, NULL); [step_type].g, NULL, NULL);
DBG (DBG_proc, DBG (DBG_proc,
@ -977,8 +975,7 @@ sanei_genesys_create_slope_table (Genesys_Device * dev,
divider = 1 << step_type; divider = 1 << step_type;
time_period = time_period =
(uint32_t) (yres * exposure_time / (uint32_t) (yres * exposure_time / dev->motor.base_ydpi /*MOTOR_GEAR */ );
dev->motor.base_ydpi /*MOTOR_GEAR */ );
if ((time_period < 2000) && (same_speed)) if ((time_period < 2000) && (same_speed))
same_speed = SANE_FALSE; same_speed = SANE_FALSE;
@ -1064,7 +1061,7 @@ sanei_genesys_create_slope_table (Genesys_Device * dev,
{ {
time_period = time_period =
(uint32_t) (yres * exposure_time / (uint32_t) (yres * exposure_time /
dev->motor.base_ydpi /*MOTOR_GEAR */ ); dev->motor.base_ydpi /*MOTOR_GEAR */ );
time_period = time_period / divider; time_period = time_period / divider;
if (time_period > 65535) if (time_period > 65535)
@ -1095,8 +1092,8 @@ sanei_genesys_create_slope_table (Genesys_Device * dev,
time_period = /* time required for full steps */ time_period = /* time required for full steps */
(uint32_t) (yres * exposure_time / (uint32_t) (yres * exposure_time /
dev->motor.base_ydpi /*MOTOR_GEAR */ * dev->motor.base_ydpi /*MOTOR_GEAR */ *
(start_speed + (1 - start_speed) * t)); (start_speed + (1 - start_speed) * t));
time_period = time_period / divider; time_period = time_period / divider;
if (time_period > 65535) if (time_period > 65535)
@ -1507,7 +1504,7 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, uint8_t * data,
} }
/* laplace filter to denoise picture */ /* laplace filter to denoise picture */
memcpy (image, data, size); /* to initialize unprocessed part of the image buffer */ memcpy (image, data, size); /* to initialize unprocessed part of the image buffer */
for (y = 1; y < height - 1; y++) for (y = 1; y < height - 1; y++)
for (x = 1; x < width - 1; x++) for (x = 1; x < width - 1; x++)
{ {
@ -1740,8 +1737,7 @@ sanei_genesys_calculate_zmode (Genesys_Device * dev, uint32_t exposure_time,
uint32_t steps_sum, uint16_t last_speed, uint32_t steps_sum, uint16_t last_speed,
uint32_t feedl, uint8_t fastfed, uint32_t feedl, uint8_t fastfed,
uint8_t scanfed, uint8_t fwdstep, uint8_t scanfed, uint8_t fwdstep,
uint8_t tgtime, uint32_t * z1, uint8_t tgtime, uint32_t * z1, uint32_t * z2)
uint32_t * z2)
{ {
uint8_t exposure_factor; uint8_t exposure_factor;
@ -2164,21 +2160,21 @@ genesys_coarse_calibration (Genesys_Device * dev)
default: default:
dev->dark[0] = dev->dark[0] =
(uint16_t) (1.6925 * dark[i * 3 + 0] + (uint16_t) (1.6925 * dark[i * 3 + 0] +
(1.1895 - 1.0) * 256); (1.1895 - 1.0) * 256);
dev->dark[1] = dev->dark[2] = dev->dark[0]; dev->dark[1] = dev->dark[2] = dev->dark[0];
break; break;
case 1: case 1:
dev->dark[1] = dev->dark[1] =
(uint16_t) (1.4013 * dark[i * 3 + 1] + (uint16_t) (1.4013 * dark[i * 3 + 1] +
(1.3147 - 1.0) * 256); (1.3147 - 1.0) * 256);
dev->dark[0] = dev->dark[2] = dev->dark[1]; dev->dark[0] = dev->dark[2] = dev->dark[1];
break; break;
case 2: case 2:
dev->dark[2] = dev->dark[2] =
(uint16_t) (1.2931 * dark[i * 3 + 2] + (uint16_t) (1.2931 * dark[i * 3 + 2] +
(1.1558 - 1.0) * 256); (1.1558 - 1.0) * 256);
dev->dark[0] = dev->dark[1] = dev->dark[2]; dev->dark[0] = dev->dark[1] = dev->dark[2];
break; break;
} }
@ -2257,24 +2253,32 @@ genesys_dark_shading_calibration (Genesys_Device * dev)
} }
/* size is size in bytes for scanarea: bytes_per_line * lines */ /* size is size in bytes for scanarea: bytes_per_line * lines */
size = channels * 2 * pixels_per_line * (dev->model->shading_lines+1); size = channels * 2 * pixels_per_line * (dev->model->shading_lines + 1);
calibration_data = malloc (size); calibration_data = malloc (size);
if (!calibration_data) if (!calibration_data)
{ {
DBG (DBG_error, "genesys_dark_shading_calibration: " DBG (DBG_error, "genesys_dark_shading_calibration: failed to allocate calibration data memory\n");
"failed to allocate calibration data memory\n");
return SANE_STATUS_NO_MEM; return SANE_STATUS_NO_MEM;
} }
/* turn off motor and lamp power */ /* turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners
dev->model->cmd_set->set_lamp_power (dev, dev->calib_reg, SANE_FALSE); * because they have a calibration sheet with a sufficent black strip */
dev->model->cmd_set->set_motor_power (dev->calib_reg, SANE_FALSE); if (dev->model->is_sheetfed==SANE_FALSE)
{
dev->model->cmd_set->set_lamp_power (dev, dev->calib_reg, SANE_FALSE);
dev->model->cmd_set->set_motor_power (dev->calib_reg, SANE_FALSE);
}
else
{
dev->model->cmd_set->set_lamp_power (dev, dev->calib_reg, SANE_TRUE);
dev->model->cmd_set->set_motor_power (dev->calib_reg, SANE_TRUE);
}
status = status =
dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg,
dev->model->cmd_set-> dev->model->
bulk_full_size ()); cmd_set->bulk_full_size ());
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
free (calibration_data); free (calibration_data);
@ -2321,13 +2325,14 @@ genesys_dark_shading_calibration (Genesys_Device * dev)
pixels_per_line * channels); pixels_per_line * channels);
if (DBG_LEVEL >= DBG_data) if (DBG_LEVEL >= DBG_data)
{ {
sanei_genesys_write_pnm_file ("black_shading.pnm", calibration_data, 16, sanei_genesys_write_pnm_file ("black_shading.pnm", calibration_data, 16,
channels, pixels_per_line, channels, pixels_per_line,
dev->model->shading_lines); dev->model->shading_lines);
sanei_genesys_write_pnm_file ("black_average.pnm", dev->dark_average_data, sanei_genesys_write_pnm_file ("black_average.pnm",
16, channels, pixels_per_line, 1); dev->dark_average_data, 16, channels,
} pixels_per_line, 1);
}
free (calibration_data); free (calibration_data);
@ -2479,8 +2484,8 @@ genesys_white_shading_calibration (Genesys_Device * dev)
status = status =
dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg,
dev->model->cmd_set-> dev->model->
bulk_full_size ()); cmd_set->bulk_full_size ());
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
free (calibration_data); free (calibration_data);
@ -2558,7 +2563,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
} }
/* This calibration uses a scan over the calibration target, comprising a /* This calibration uses a scan over the calibration target, comprising a
* black and a white stripe. (So the motor must be on.) * black and a white strip. (So the motor must be on.)
*/ */
static SANE_Status static SANE_Status
genesys_dark_white_shading_calibration (Genesys_Device * dev) genesys_dark_white_shading_calibration (Genesys_Device * dev)
@ -2620,8 +2625,8 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
status = status =
dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg,
dev->model->cmd_set-> dev->model->
bulk_full_size ()); cmd_set->bulk_full_size ());
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
free (calibration_data); free (calibration_data);
@ -2930,7 +2935,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
channels = dev->calib_channels; channels = dev->calib_channels;
/* we always build data for three channels, even for gray */ /* we always build data for three channels, even for gray */
if (dev->model->is_cis) if (dev->model->is_cis && dev->model->asic_type != GENESYS_GL646)
{ {
switch (sanei_genesys_read_reg_from_set (dev->reg, 0x05) >> 6) switch (sanei_genesys_read_reg_from_set (dev->reg, 0x05) >> 6)
{ {
@ -2968,6 +2973,16 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
switch (dev->model->ccd_type) switch (dev->model->ccd_type)
{ {
case CIS_XP200:
target_code = 0xfa00;
memset (shading_data, 0x00, pixels_per_line * 4 * channels);
o = 0;
avgpixels = 1;
compute_coefficients (dev,
shading_data,
pixels_per_line,
channels, avgpixels, o, coeff, target_code);
break;
case CCD_5345: case CCD_5345:
target_code = 0xfa00; target_code = 0xfa00;
memset (shading_data, 0x00, pixels_per_line * 4 * channels); memset (shading_data, 0x00, pixels_per_line * 4 * channels);
@ -3196,64 +3211,65 @@ genesys_restore_calibration (Genesys_Device * dev)
{ {
SANE_Status status; SANE_Status status;
Genesys_Calibration_Cache *cache; Genesys_Calibration_Cache *cache;
DBG (DBG_proc, "genesys_restore_calibration\n"); DBG (DBG_proc, "genesys_restore_calibration\n");
/* if no cache or no function to evaluate cache entry ther can be no match */ /* if no cache or no function to evaluate cache entry ther can be no match */
if (!dev->model->cmd_set->is_compatible_calibration || dev->calibration_cache==NULL) if (!dev->model->cmd_set->is_compatible_calibration
|| dev->calibration_cache == NULL)
return SANE_STATUS_UNSUPPORTED; return SANE_STATUS_UNSUPPORTED;
/* we walk the link list of calibration cache in search for a /* we walk the link list of calibration cache in search for a
* matching one */ * matching one */
for(cache = dev->calibration_cache; cache; cache = cache->next) for (cache = dev->calibration_cache; cache; cache = cache->next)
{ {
status = dev->model->cmd_set->is_compatible_calibration(dev, cache, status = dev->model->cmd_set->is_compatible_calibration (dev, cache,
SANE_FALSE); SANE_FALSE);
/* SANE_STATUS_GOOD, a matching cache has been found /* SANE_STATUS_GOOD, a matching cache has been found
* so we use it to populate calibration data * so we use it to populate calibration data
*/ */
if(status==SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
memcpy(&dev->frontend, &cache->frontend, sizeof(dev->frontend)); memcpy (&dev->frontend, &cache->frontend, sizeof (dev->frontend));
/* don't restore the gamma fields */ /* don't restore the gamma fields */
memcpy(&dev->sensor, &cache->sensor, memcpy (&dev->sensor, &cache->sensor,
offsetof(Genesys_Sensor,red_gamma)); offsetof (Genesys_Sensor, red_gamma));
free(dev->dark_average_data);
free(dev->white_average_data);
dev->average_size = cache->average_size; free (dev->dark_average_data);
dev->calib_pixels = cache->calib_pixels; free (dev->white_average_data);
dev->calib_channels = cache->calib_channels;
dev->dark_average_data = (uint8_t*)malloc(cache->average_size); dev->average_size = cache->average_size;
dev->white_average_data = (uint8_t*)malloc(cache->average_size); dev->calib_pixels = cache->calib_pixels;
dev->calib_channels = cache->calib_channels;
if (!dev->dark_average_data || !dev->white_average_data)
return SANE_STATUS_NO_MEM;
memcpy(dev->dark_average_data, dev->dark_average_data = (uint8_t *) malloc (cache->average_size);
cache->dark_average_data, dev->average_size); dev->white_average_data = (uint8_t *) malloc (cache->average_size);
memcpy(dev->white_average_data,
cache->white_average_data, dev->average_size);
status = genesys_send_shading_coefficient (dev); if (!dev->dark_average_data || !dev->white_average_data)
return SANE_STATUS_NO_MEM;
if (status != SANE_STATUS_GOOD) memcpy (dev->dark_average_data,
{ cache->dark_average_data, dev->average_size);
DBG (DBG_error, memcpy (dev->white_average_data,
"genesys_restore_calibration: failed to send shading data: %s\n", cache->white_average_data, dev->average_size);
sane_strstatus (status));
return status; status = genesys_send_shading_coefficient (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_restore_calibration: failed to send shading data: %s\n",
sane_strstatus (status));
return status;
}
DBG (DBG_proc, "genesys_restore_calibration: restored\n");
return SANE_STATUS_GOOD;
} }
DBG (DBG_proc, "genesys_restore_calibration: restored\n"); /* here status is either SANE_STATUS_UNSUPPORTED which mean tested cache
return SANE_STATUS_GOOD; * entry doesn't match, or an fatal error */
} if (status != SANE_STATUS_UNSUPPORTED)
/* here status is either SANE_STATUS_UNSUPPORTED which mean tested cache
* entry doesn't match, or an fatal error */
if (status != SANE_STATUS_UNSUPPORTED)
{ {
DBG (DBG_error, DBG (DBG_error,
"genesys_restore_calibration: fail while checking compatibility: %s\n", "genesys_restore_calibration: fail while checking compatibility: %s\n",
@ -3426,7 +3442,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)
{ {
@ -3436,7 +3452,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);
@ -3487,6 +3503,7 @@ genesys_flatbed_calibration (Genesys_Device * dev)
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;
/* XXX STEF XXX ??? could this be the root of 2300 shading problems */
/* 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);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
@ -3571,12 +3588,12 @@ genesys_sheetfed_calibration (Genesys_Device * dev)
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
DBG (DBG_proc, "genesys_sheetfed_calibration: start\n"); DBG (DBG_proc, "genesys_sheetfed_calibration: start\n");
if(dev->model->cmd_set->search_strip==NULL) if (dev->model->cmd_set->search_strip == NULL)
{ {
DBG (DBG_error, DBG (DBG_error,
"genesys_sheetfed_calibration: no strip searching function available\n"); "genesys_sheetfed_calibration: no strip searching function available\n");
return SANE_STATUS_UNSUPPORTED; return SANE_STATUS_UNSUPPORTED;
} }
/* first step, load document */ /* first step, load document */
status = dev->model->cmd_set->load_document (dev); status = dev->model->cmd_set->load_document (dev);
@ -3602,6 +3619,78 @@ genesys_sheetfed_calibration (Genesys_Device * dev)
return status; return status;
} }
/******************* shading calibration ***************************/
/* send default shading data */
/* XXX STEF XXX status = sanei_genesys_init_shading_data (dev, pixels_per_line);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to init shading process: %s\n",
sane_strstatus (status));
return status;
}*/
/* we know we hare on a black area */
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
{
status = dev->model->cmd_set->init_regs_for_shading (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to do wset up registers for shading calibration: %s\n",
sane_strstatus (status));
return status;
}
status = genesys_dark_shading_calibration (dev);
if (status != SANE_STATUS_GOOD)
{
dev->model->cmd_set->eject_document (dev);
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to do dark shading calibration: %s\n",
sane_strstatus (status));
return status;
}
}
/* go back to a white area */
status = dev->model->cmd_set->search_strip (dev, SANE_FALSE, SANE_FALSE);
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;
}
status = dev->model->cmd_set->init_regs_for_shading (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to do wset up registers for shading calibration: %s\n",
sane_strstatus (status));
return status;
}
status = genesys_white_shading_calibration (dev);
if (status != SANE_STATUS_GOOD)
{
dev->model->cmd_set->eject_document (dev);
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to do white shading calibration: %s\n",
sane_strstatus (status));
return status;
}
/* send the shading coefficient */
status = genesys_send_shading_coefficient (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_sheetfed_calibration: failed to send shading calibration coefficients: %s\n",
sane_strstatus (status));
return status;
}
/* and finally eject calibration sheet */ /* and finally eject calibration sheet */
status = dev->model->cmd_set->eject_document (dev); status = dev->model->cmd_set->eject_document (dev);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
@ -3916,7 +4005,7 @@ genesys_start_scan (Genesys_Device * dev)
/* try to use cached calibration first */ /* 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 */
@ -3930,11 +4019,11 @@ genesys_start_scan (Genesys_Device * dev)
sane_strstatus (status)); sane_strstatus (status));
return status; return status;
} }
genesys_save_calibration(dev); genesys_save_calibration (dev);
} }
} }
else if(status != SANE_STATUS_GOOD) else if (status != SANE_STATUS_GOOD)
{ {
DBG (DBG_error, DBG (DBG_error,
"genesys_start_scan: failed to restore calibration: %s\n", "genesys_start_scan: failed to restore calibration: %s\n",
@ -3953,8 +4042,8 @@ genesys_start_scan (Genesys_Device * dev)
status = status =
dev->model->cmd_set->bulk_write_register (dev, dev->reg, dev->model->cmd_set->bulk_write_register (dev, dev->reg,
dev->model->cmd_set-> dev->model->
bulk_full_size ()); cmd_set->bulk_full_size ());
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
DBG (DBG_error, DBG (DBG_error,
@ -5158,8 +5247,9 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_SCAN_SW].desc = SANE_DESC_SCAN; s->opt[OPT_SCAN_SW].desc = SANE_DESC_SCAN;
s->opt[OPT_SCAN_SW].type = SANE_TYPE_BOOL; s->opt[OPT_SCAN_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_SCAN_SW].unit = SANE_UNIT_NONE; s->opt[OPT_SCAN_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_SCAN_SW) if (model->buttons & GENESYS_HAS_SCAN_SW)
s->opt[OPT_SCAN_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; s->opt[OPT_SCAN_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else else
s->opt[OPT_SCAN_SW].cap = SANE_CAP_INACTIVE; s->opt[OPT_SCAN_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_SCAN_SW].b = 0; s->val[OPT_SCAN_SW].b = 0;
@ -5167,11 +5257,11 @@ init_options (Genesys_Scanner * s)
/* SANE_NAME_FILE is not for buttons */ /* SANE_NAME_FILE is not for buttons */
s->opt[OPT_FILE_SW].name = "file"; s->opt[OPT_FILE_SW].name = "file";
s->opt[OPT_FILE_SW].title = SANE_I18N("File button"); s->opt[OPT_FILE_SW].title = SANE_I18N ("File button");
s->opt[OPT_FILE_SW].desc = SANE_I18N("File button"); s->opt[OPT_FILE_SW].desc = SANE_I18N ("File button");
s->opt[OPT_FILE_SW].type = SANE_TYPE_BOOL; s->opt[OPT_FILE_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_FILE_SW].unit = SANE_UNIT_NONE; s->opt[OPT_FILE_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_FILE_SW) if (model->buttons & GENESYS_HAS_FILE_SW)
s->opt[OPT_FILE_SW].cap = s->opt[OPT_FILE_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else else
@ -5220,8 +5310,8 @@ init_options (Genesys_Scanner * s)
/* OCR button */ /* OCR button */
s->opt[OPT_OCR_SW].name = "ocr"; s->opt[OPT_OCR_SW].name = "ocr";
s->opt[OPT_OCR_SW].title = SANE_I18N("OCR button"); s->opt[OPT_OCR_SW].title = SANE_I18N ("OCR button");
s->opt[OPT_OCR_SW].desc = SANE_I18N("OCR button"); s->opt[OPT_OCR_SW].desc = SANE_I18N ("OCR button");
s->opt[OPT_OCR_SW].type = SANE_TYPE_BOOL; s->opt[OPT_OCR_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_OCR_SW].unit = SANE_UNIT_NONE; s->opt[OPT_OCR_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_OCR_SW) if (model->buttons & GENESYS_HAS_OCR_SW)
@ -5234,8 +5324,8 @@ init_options (Genesys_Scanner * s)
/* power button */ /* power button */
s->opt[OPT_POWER_SW].name = "power"; s->opt[OPT_POWER_SW].name = "power";
s->opt[OPT_POWER_SW].title = SANE_I18N("Power button"); s->opt[OPT_POWER_SW].title = SANE_I18N ("Power button");
s->opt[OPT_POWER_SW].desc = SANE_I18N("Power button"); s->opt[OPT_POWER_SW].desc = SANE_I18N ("Power button");
s->opt[OPT_POWER_SW].type = SANE_TYPE_BOOL; s->opt[OPT_POWER_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_POWER_SW].unit = SANE_UNIT_NONE; s->opt[OPT_POWER_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_POWER_SW) if (model->buttons & GENESYS_HAS_POWER_SW)
@ -5248,19 +5338,22 @@ init_options (Genesys_Scanner * s)
/* button group */ /* button group */
s->opt[OPT_BUTTON_GROUP].name = "Buttons"; s->opt[OPT_BUTTON_GROUP].name = "Buttons";
s->opt[OPT_BUTTON_GROUP].title = SANE_I18N("Buttons"); s->opt[OPT_BUTTON_GROUP].title = SANE_I18N ("Buttons");
s->opt[OPT_BUTTON_GROUP].desc = SANE_I18N("Buttons"); s->opt[OPT_BUTTON_GROUP].desc = SANE_I18N ("Buttons");
s->opt[OPT_BUTTON_GROUP].type = SANE_TYPE_GROUP; s->opt[OPT_BUTTON_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_BUTTON_GROUP].constraint_type = SANE_CONSTRAINT_NONE; s->opt[OPT_BUTTON_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
/* calibrate button */ /* calibrate button */
s->opt[OPT_CALIBRATE].name = "calibrate"; s->opt[OPT_CALIBRATE].name = "calibrate";
s->opt[OPT_CALIBRATE].title = SANE_I18N("Calibrate"); s->opt[OPT_CALIBRATE].title = SANE_I18N ("Calibrate");
s->opt[OPT_CALIBRATE].desc = SANE_I18N("Start calibration using special sheet"); s->opt[OPT_CALIBRATE].desc =
SANE_I18N ("Start calibration using special sheet");
s->opt[OPT_CALIBRATE].type = SANE_TYPE_BUTTON; s->opt[OPT_CALIBRATE].type = SANE_TYPE_BUTTON;
s->opt[OPT_CALIBRATE].unit = SANE_UNIT_NONE; s->opt[OPT_CALIBRATE].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_CALIBRATE) if (model->buttons & GENESYS_HAS_CALIBRATE)
s->opt[OPT_CALIBRATE].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED | SANE_CAP_AUTOMATIC; s->opt[OPT_CALIBRATE].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED |
SANE_CAP_AUTOMATIC;
else else
s->opt[OPT_CALIBRATE].cap = SANE_CAP_INACTIVE; s->opt[OPT_CALIBRATE].cap = SANE_CAP_INACTIVE;
s->val[OPT_CALIBRATE].b = 0; s->val[OPT_CALIBRATE].b = 0;
@ -5268,11 +5361,13 @@ init_options (Genesys_Scanner * s)
/* clear calibration cache button */ /* clear calibration cache button */
s->opt[OPT_CLEAR_CALIBRATION].name = "clear"; s->opt[OPT_CLEAR_CALIBRATION].name = "clear";
s->opt[OPT_CLEAR_CALIBRATION].title = SANE_I18N("Clear calibration"); s->opt[OPT_CLEAR_CALIBRATION].title = SANE_I18N ("Clear calibration");
s->opt[OPT_CLEAR_CALIBRATION].desc = SANE_I18N("Clear calibration cache"); s->opt[OPT_CLEAR_CALIBRATION].desc = SANE_I18N ("Clear calibration cache");
s->opt[OPT_CLEAR_CALIBRATION].type = SANE_TYPE_BUTTON; s->opt[OPT_CLEAR_CALIBRATION].type = SANE_TYPE_BUTTON;
s->opt[OPT_CLEAR_CALIBRATION].unit = SANE_UNIT_NONE; s->opt[OPT_CLEAR_CALIBRATION].unit = SANE_UNIT_NONE;
s->opt[OPT_CLEAR_CALIBRATION].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED | SANE_CAP_AUTOMATIC; s->opt[OPT_CLEAR_CALIBRATION].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED |
SANE_CAP_AUTOMATIC;
s->val[OPT_CLEAR_CALIBRATION].b = 0; s->val[OPT_CLEAR_CALIBRATION].b = 0;
s->last_val[OPT_CLEAR_CALIBRATION].b = 0; s->last_val[OPT_CLEAR_CALIBRATION].b = 0;
@ -5463,7 +5558,7 @@ probe_genesys_devices (void)
#define CALIBRATION_VERSION 1 #define CALIBRATION_VERSION 1
static void static void
read_calibration(Genesys_Device * dev) read_calibration (Genesys_Device * dev)
{ {
FILE *fp; FILE *fp;
uint8_t vers = 0; uint8_t vers = 0;
@ -5471,43 +5566,45 @@ read_calibration(Genesys_Device * dev)
struct Genesys_Calibration_Cache *cache; struct Genesys_Calibration_Cache *cache;
DBG (DBG_proc, "read_calibration: enter\n"); DBG (DBG_proc, "read_calibration: enter\n");
fp = fopen(dev->calib_file,"rb"); fp = fopen (dev->calib_file, "rb");
if (!fp) if (!fp)
{ {
DBG ( DBG_info, "Calibration: Cannot open %s\n", dev->calib_file ); DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file);
DBG (DBG_proc, "read_calibration: exit\n"); DBG (DBG_proc, "read_calibration: exit\n");
return; return;
} }
/* these two checks ensure that most bad things cannot happen */ /* these two checks ensure that most bad things cannot happen */
fread(&vers,1,1,fp); fread (&vers, 1, 1, fp);
if (vers != CALIBRATION_VERSION) if (vers != CALIBRATION_VERSION)
{ {
DBG ( DBG_info, "Calibration: Bad version\n" ); DBG (DBG_info, "Calibration: Bad version\n");
fclose(fp); fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n"); DBG (DBG_proc, "read_calibration: exit\n");
return; return;
} }
fread(&size,4,1,fp); fread (&size, 4, 1, fp);
if (size != sizeof(struct Genesys_Calibration_Cache)) if (size != sizeof (struct Genesys_Calibration_Cache))
{ {
DBG ( DBG_info, "Calibration: Size of calibration cache struct differs\n" ); DBG (DBG_info,
fclose(fp); "Calibration: Size of calibration cache struct differs\n");
fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n"); DBG (DBG_proc, "read_calibration: exit\n");
return; return;
} }
while(!feof(fp)) while (!feof (fp))
{ {
DBG (DBG_info, "read_calibration: reading one record\n"); DBG (DBG_info, "read_calibration: reading one record\n");
cache = (struct Genesys_Calibration_Cache *)malloc(sizeof(*cache)); cache = (struct Genesys_Calibration_Cache *) malloc (sizeof (*cache));
if (!cache) if (!cache)
{ {
DBG (DBG_error, "read_calibration: could not allocate cache struct\n"); DBG (DBG_error,
"read_calibration: could not allocate cache struct\n");
break; break;
} }
#define BILT1( x ) \ #define BILT1( x ) \
do \ do \
{ \ { \
@ -5518,104 +5615,112 @@ read_calibration(Genesys_Device * dev)
break; \ break; \
} \ } \
} while(0) } while(0)
if (fread(&cache->used_setup,sizeof(cache->used_setup),1,fp) < 1)
{ /* eof is only detected here */ if (fread (&cache->used_setup, sizeof (cache->used_setup), 1, fp) < 1)
free(cache); { /* eof is only detected here */
break; free (cache);
break;
} }
BILT1(fread(&cache->last_calibration,sizeof(cache->last_calibration),1,fp)); BILT1 (fread
BILT1(fread(&cache->frontend,sizeof(cache->frontend),1,fp)); (&cache->last_calibration, sizeof (cache->last_calibration), 1,
fp));
BILT1 (fread (&cache->frontend, sizeof (cache->frontend), 1, fp));
/* the gamma (and later) fields are not stored */ /* the gamma (and later) fields are not stored */
BILT1(fread(&cache->sensor,offsetof(Genesys_Sensor,red_gamma),1,fp)); BILT1 (fread
BILT1(fread(&cache->calib_pixels,sizeof(cache->calib_pixels),1,fp)); (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp));
BILT1(fread(&cache->calib_channels,sizeof(cache->calib_channels),1,fp)); BILT1 (fread
BILT1(fread(&cache->average_size,sizeof(cache->average_size),1,fp)); (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp));
BILT1 (fread
(&cache->calib_channels, sizeof (cache->calib_channels), 1, fp));
BILT1 (fread
(&cache->average_size, sizeof (cache->average_size), 1, fp));
/* Make sure we don't do bad things if someone feeds us a forged/ /* Make sure we don't do bad things if someone feeds us a forged/
sufficiently corrupted calibration file. sufficiently corrupted calibration file.
gl843 can do up to 0x5800 pixels. add some slack for the gl843 can do up to 0x5800 pixels. add some slack for the
dummy/blank pixel mess */ dummy/blank pixel mess */
if (cache->average_size > 0x5800*2*3*2+0x100) if (cache->average_size > 0x5800 * 2 * 3 * 2 + 0x100)
{ {
DBG (DBG_error, "read_calibration: bad size of calibration data\n"); DBG (DBG_error, "read_calibration: bad size of calibration data\n");
free(cache); free (cache);
break; break;
} }
cache->white_average_data = (uint8_t*)malloc(cache->average_size); cache->white_average_data = (uint8_t *) malloc (cache->average_size);
cache->dark_average_data = (uint8_t*)malloc(cache->average_size); cache->dark_average_data = (uint8_t *) malloc (cache->average_size);
if (!cache->white_average_data || !cache->dark_average_data) if (!cache->white_average_data || !cache->dark_average_data)
{ {
FREE_IFNOT_NULL(cache->white_average_data); FREE_IFNOT_NULL (cache->white_average_data);
FREE_IFNOT_NULL(cache->dark_average_data); FREE_IFNOT_NULL (cache->dark_average_data);
free(cache); free (cache);
DBG (DBG_error, "read_calibration: could not allocate space for average data\n"); DBG (DBG_error,
"read_calibration: could not allocate space for average data\n");
break; break;
} }
if (fread(cache->white_average_data,cache->average_size,1,fp) < 1) if (fread (cache->white_average_data, cache->average_size, 1, fp) < 1)
{ {
DBG (DBG_warn, "read_calibration: partial calibration record\n"); DBG (DBG_warn, "read_calibration: partial calibration record\n");
free(cache->white_average_data); free (cache->white_average_data);
free(cache->dark_average_data); free (cache->dark_average_data);
free(cache); free (cache);
break; break;
} }
if (fread(cache->dark_average_data,cache->average_size,1,fp) < 1) if (fread (cache->dark_average_data, cache->average_size, 1, fp) < 1)
{ {
DBG (DBG_warn, "read_calibration: partial calibration record\n"); DBG (DBG_warn, "read_calibration: partial calibration record\n");
free(cache->white_average_data); free (cache->white_average_data);
free(cache->dark_average_data); free (cache->dark_average_data);
free(cache); free (cache);
break; break;
} }
#undef BILT1 #undef BILT1
DBG (DBG_info, "read_calibration: adding record to list\n"); DBG (DBG_info, "read_calibration: adding record to list\n");
cache->next = dev->calibration_cache; cache->next = dev->calibration_cache;
dev->calibration_cache = cache; dev->calibration_cache = cache;
} }
fclose(fp); fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n"); DBG (DBG_proc, "read_calibration: exit\n");
} }
static void static void
write_calibration(Genesys_Device * dev) write_calibration (Genesys_Device * dev)
{ {
FILE *fp; FILE *fp;
uint8_t vers = 0; uint8_t vers = 0;
uint32_t size = 0; uint32_t size = 0;
struct Genesys_Calibration_Cache *cache; struct Genesys_Calibration_Cache *cache;
fp = fopen(dev->calib_file,"wb"); fp = fopen (dev->calib_file, "wb");
if (!fp) if (!fp)
{ {
DBG ( DBG_info, "Calibration: Cannot open %s\n", dev->calib_file ); DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file);
return; return;
} }
vers = CALIBRATION_VERSION; vers = CALIBRATION_VERSION;
fwrite(&vers,1,1,fp); fwrite (&vers, 1, 1, fp);
size = sizeof(struct Genesys_Calibration_Cache); size = sizeof (struct Genesys_Calibration_Cache);
fwrite(&size,4,1,fp); fwrite (&size, 4, 1, fp);
for(cache = dev->calibration_cache; cache; cache = cache->next) for (cache = dev->calibration_cache; cache; cache = cache->next)
{ {
fwrite(&cache->used_setup,sizeof(cache->used_setup),1,fp); fwrite (&cache->used_setup, sizeof (cache->used_setup), 1, fp);
fwrite(&cache->last_calibration,sizeof(cache->last_calibration),1,fp); fwrite (&cache->last_calibration, sizeof (cache->last_calibration), 1,
fwrite(&cache->frontend,sizeof(cache->frontend),1,fp); fp);
fwrite (&cache->frontend, sizeof (cache->frontend), 1, fp);
/* the gamma (and later) fields are not stored */ /* the gamma (and later) fields are not stored */
fwrite(&cache->sensor,offsetof(Genesys_Sensor,red_gamma),1,fp); fwrite (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp);
fwrite(&cache->calib_pixels,sizeof(cache->calib_pixels),1,fp); fwrite (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp);
fwrite(&cache->calib_channels,sizeof(cache->calib_channels),1,fp); fwrite (&cache->calib_channels, sizeof (cache->calib_channels), 1, fp);
fwrite(&cache->average_size,sizeof(cache->average_size),1,fp); fwrite (&cache->average_size, sizeof (cache->average_size), 1, fp);
fwrite(cache->white_average_data,cache->average_size,1,fp); fwrite (cache->white_average_data, cache->average_size, 1, fp);
fwrite(cache->dark_average_data,cache->average_size,1,fp); fwrite (cache->dark_average_data, cache->average_size, 1, fp);
} }
fclose(fp); fclose (fp);
} }
/* -------------------------- SANE API functions ------------------------- */ /* -------------------------- SANE API functions ------------------------- */
@ -5807,7 +5912,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
s->dev->read_active = SANE_FALSE; s->dev->read_active = SANE_FALSE;
s->dev->white_average_data = NULL; s->dev->white_average_data = NULL;
s->dev->dark_average_data = NULL; s->dev->dark_average_data = NULL;
s->dev->calibration_cache = NULL; s->dev->calibration_cache = NULL;
/* insert newly opened handle into list of open handles: */ /* insert newly opened handle into list of open handles: */
s->next = first_handle; s->next = first_handle;
@ -5837,20 +5942,23 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
knowledge, there is no such thing in these scanners. knowledge, there is no such thing in these scanners.
(At least the usb serial is always "0".) (At least the usb serial is always "0".)
*/ */
ptr = getenv ("HOME"); ptr = getenv ("HOME");
if( NULL == ptr ) { if (NULL == ptr)
sprintf( tmp_str, "/tmp/%s.cal", s->dev->model->name ); {
} else { sprintf (tmp_str, "/tmp/%s.cal", s->dev->model->name);
sprintf( tmp_str, "%s/.sane/%s.cal", ptr, s->dev->model->name ); }
} else
s->dev->calib_file = strdup( tmp_str ); {
DBG( DBG_info, "Calibration filename set to:\n" ); sprintf (tmp_str, "%s/.sane/%s.cal", ptr, s->dev->model->name);
DBG( DBG_info, ">%s<\n", s->dev->calib_file ); }
s->dev->calib_file = strdup (tmp_str);
DBG (DBG_info, "Calibration filename set to:\n");
DBG (DBG_info, ">%s<\n", s->dev->calib_file);
/* now open file, fetch calibration records */ /* now open file, fetch calibration records */
read_calibration(s->dev); read_calibration (s->dev);
DBG (DBG_proc, "sane_open: exit\n"); DBG (DBG_proc, "sane_open: exit\n");
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
@ -5878,17 +5986,23 @@ sane_close (SANE_Handle handle)
return; /* oops, not a handle we know about */ return; /* oops, not a handle we know about */
} }
/* here is the place to store calibration cache */ /* eject document for shhetfed scanners */
write_calibration(s->dev); if (s->dev->model->is_sheetfed == SANE_TRUE)
{
s->dev->model->cmd_set->eject_document (s->dev);
}
for(cache = s->dev->calibration_cache; cache; cache = next_cache) /* here is the place to store calibration cache */
write_calibration (s->dev);
for (cache = s->dev->calibration_cache; cache; cache = next_cache)
{ {
next_cache = cache->next; next_cache = cache->next;
free(cache->dark_average_data); free (cache->dark_average_data);
free(cache->white_average_data); free (cache->white_average_data);
free(cache); free (cache);
} }
sanei_genesys_buffer_free (&(s->dev->read_buffer)); sanei_genesys_buffer_free (&(s->dev->read_buffer));
sanei_genesys_buffer_free (&(s->dev->lines_buffer)); sanei_genesys_buffer_free (&(s->dev->lines_buffer));
sanei_genesys_buffer_free (&(s->dev->shrink_buffer)); sanei_genesys_buffer_free (&(s->dev->shrink_buffer));
@ -6124,8 +6238,8 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
if (*(SANE_Word *) val != s->val[option].w) if (*(SANE_Word *) val != s->val[option].w)
{ {
s->val[option].w = *(SANE_Word *) val; s->val[option].w = *(SANE_Word *) val;
RIE (s->dev->model-> RIE (s->dev->model->cmd_set->
cmd_set->set_powersaving (s->dev, s->val[option].w)); set_powersaving (s->dev, s->val[option].w));
} }
break; break;
@ -6162,38 +6276,27 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
sanei_genesys_create_gamma_table (s->dev->sensor.red_gamma_table, sanei_genesys_create_gamma_table (s->dev->sensor.red_gamma_table,
s->opt[OPT_GAMMA_VECTOR_R].size / s->opt[OPT_GAMMA_VECTOR_R].size /
sizeof (SANE_Word), sizeof (SANE_Word),
s-> s->opt
opt [OPT_GAMMA_VECTOR_R].
[OPT_GAMMA_VECTOR_R].constraint. constraint.range->max,
range->max, s->opt[OPT_GAMMA_VECTOR_R].
s-> constraint.range->max,
opt
[OPT_GAMMA_VECTOR_R].constraint.
range->max,
s->dev->sensor.red_gamma); s->dev->sensor.red_gamma);
sanei_genesys_create_gamma_table (s->dev->sensor.green_gamma_table, sanei_genesys_create_gamma_table (s->dev->sensor.green_gamma_table,
s->opt[OPT_GAMMA_VECTOR_G].size / s->opt[OPT_GAMMA_VECTOR_G].size /
sizeof (SANE_Word), sizeof (SANE_Word),
s-> s->opt[OPT_GAMMA_VECTOR_G].
opt constraint.range->max,
[OPT_GAMMA_VECTOR_G].constraint. s->opt[OPT_GAMMA_VECTOR_G].
range->max, constraint.range->max,
s->
opt
[OPT_GAMMA_VECTOR_G].constraint.
range->max,
s->dev->sensor.red_gamma); s->dev->sensor.red_gamma);
sanei_genesys_create_gamma_table (s->dev->sensor.blue_gamma_table, sanei_genesys_create_gamma_table (s->dev->sensor.blue_gamma_table,
s->opt[OPT_GAMMA_VECTOR_B].size / s->opt[OPT_GAMMA_VECTOR_B].size /
sizeof (SANE_Word), sizeof (SANE_Word),
s-> s->opt[OPT_GAMMA_VECTOR_B].
opt constraint.range->max,
[OPT_GAMMA_VECTOR_B].constraint. s->opt[OPT_GAMMA_VECTOR_B].
range->max, constraint.range->max,
s->
opt
[OPT_GAMMA_VECTOR_B].constraint.
range->max,
s->dev->sensor.red_gamma); s->dev->sensor.red_gamma);
} }
break; break;
@ -6233,17 +6336,17 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
break; break;
case OPT_CLEAR_CALIBRATION: case OPT_CLEAR_CALIBRATION:
/* clear calibration cache */ /* clear calibration cache */
if(s->dev->calibration_cache!=NULL) if (s->dev->calibration_cache != NULL)
{
for (cache = s->dev->calibration_cache; cache; cache = next_cache)
{ {
next_cache = cache->next; for (cache = s->dev->calibration_cache; cache; cache = next_cache)
free (cache->dark_average_data); {
free (cache->white_average_data); next_cache = cache->next;
free (cache); free (cache->dark_average_data);
free (cache->white_average_data);
free (cache);
}
} }
} s->dev->calibration_cache = NULL;
s->dev->calibration_cache=NULL;
/* remove file */ /* remove file */
unlink (s->dev->calib_file); unlink (s->dev->calib_file);
break; break;

Wyświetl plik

@ -974,6 +974,7 @@ Genesys_Model visioneer_xp200_model = {
GENESYS_FLAG_14BIT_GAMMA GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_CUSTOM_GAMMA | GENESYS_FLAG_CUSTOM_GAMMA
| GENESYS_FLAG_SKIP_WARMUP | GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_DARK_CALIBRATION
| 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,

Wyświetl plik

@ -941,10 +941,12 @@ gl646_setup_registers (Genesys_Device * dev,
linecnt = (1000 * motor->ydpi) / MM_PER_INCH; linecnt = (1000 * motor->ydpi) / MM_PER_INCH;
} */ } */
/* CIS scanners read one line per color channel */ /* CIS scanners read one line per color channel
* since gray mode use 'add' we also read 3 channels even not in
* color mode */
if (dev->model->is_cis == SANE_TRUE) if (dev->model->is_cis == SANE_TRUE)
{ {
linecnt *= channels; linecnt *= 3;
} }
gl646_set_triple_reg (regs, REG_LINCNT, linecnt); gl646_set_triple_reg (regs, REG_LINCNT, linecnt);
@ -2547,7 +2549,7 @@ static SANE_Status
gl646_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, gl646_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
SANE_Bool check_stop) SANE_Bool check_stop)
{ {
return end_scan (dev, reg, check_stop, SANE_TRUE); return end_scan (dev, reg, check_stop, SANE_FALSE);
} }
/** /**
@ -4228,6 +4230,10 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
} }
free (buffer); free (buffer);
} }
/* put back real line number in settings */
/* XXX STEF XXX */
settings.lines = lines;
/* end scan , waiting the motor to stop if needed (if moving), but without ejecting doc */ /* end scan , waiting the motor to stop if needed (if moving), but without ejecting doc */
status = end_scan (dev, dev->reg, SANE_TRUE, SANE_FALSE); status = end_scan (dev, dev->reg, SANE_TRUE, SANE_FALSE);
@ -4497,7 +4503,7 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
int res = get_closest_resolution (dev->model->ccd_type, 75, SANE_FALSE); int res = get_closest_resolution (dev->model->ccd_type, 75, SANE_FALSE);
unsigned char *data = NULL; unsigned char *data = NULL;
unsigned int pass, count, found, x, y; unsigned int pass, count, found, x, y;
char titre[80]; char title[80];
DBG (DBG_proc, "gl646_search_strip: start\n"); DBG (DBG_proc, "gl646_search_strip: start\n");
/* adapt to half_ccd case */ /* adapt to half_ccd case */
@ -4517,12 +4523,12 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
settings.yres = res; settings.yres = res;
settings.tl_x = 0; settings.tl_x = 0;
settings.tl_y = 0; settings.tl_y = 0;
settings.pixels = settings.pixels = (SANE_UNFIX (dev->model->x_size) * res) / MM_PER_INCH;
(dev->sensor.sensor_pixels * res) / dev->sensor.optical_res;
if (half_ccd == SANE_TRUE) if (half_ccd == SANE_TRUE)
{ {
settings.pixels /= 2; settings.pixels /= 2;
} }
/* 15 mm at at time */ /* 15 mm at at time */
settings.lines = (15 * settings.yres) / MM_PER_INCH; /* may become a parameter from genesys_devices.c */ settings.lines = (15 * settings.yres) / MM_PER_INCH; /* may become a parameter from genesys_devices.c */
settings.depth = 8; settings.depth = 8;
@ -4551,8 +4557,8 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
} }
if (DBG_LEVEL >= DBG_data) if (DBG_LEVEL >= DBG_data)
{ {
sprintf (titre, "search_strip%02d.pnm", pass); sprintf (title, "search_strip_%s%02d.pnm", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file (titre, data, settings.depth, 1, sanei_genesys_write_pnm_file (title, data, settings.depth, 1,
settings.pixels, settings.lines); settings.pixels, settings.lines);
} }
@ -4574,6 +4580,7 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
count++; count++;
} }
} }
/* at end of line, if count >0, line is not fully of the desired color /* 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 */ * so we must go to next line of the buffer */
if (count == 0) if (count == 0)