kopia lustrzana https://gitlab.com/sane-project/backends
work toward shading calibration
- black/white strip searching reliable - call to dar and white shading calibrationmerge-requests/1/head
rodzic
7c44981be0
commit
3135e94c90
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Ładowanie…
Reference in New Issue