kopia lustrzana https://gitlab.com/sane-project/backends
add shading coefficient computing function for GL646/planar mode
rodzic
48df712552
commit
60ab4d8569
|
@ -737,8 +737,7 @@ sanei_genesys_create_slope_table3 (Genesys_Device * dev,
|
||||||
dev->motor.slopes[power_mode]
|
dev->motor.slopes[power_mode]
|
||||||
[step_type].minimum_steps <<
|
[step_type].minimum_steps <<
|
||||||
step_type,
|
step_type,
|
||||||
dev->
|
dev->motor.slopes[power_mode]
|
||||||
motor.slopes[power_mode]
|
|
||||||
[step_type].g, used_steps,
|
[step_type].g, used_steps,
|
||||||
&vfinal);
|
&vfinal);
|
||||||
|
|
||||||
|
@ -799,8 +798,7 @@ genesys_create_slope_table4 (Genesys_Device * dev,
|
||||||
dev->motor.slopes[power_mode]
|
dev->motor.slopes[power_mode]
|
||||||
[step_type].minimum_steps <<
|
[step_type].minimum_steps <<
|
||||||
step_type,
|
step_type,
|
||||||
dev->
|
dev->motor.slopes[power_mode]
|
||||||
motor.slopes[power_mode]
|
|
||||||
[step_type].g, NULL, NULL);
|
[step_type].g, NULL, NULL);
|
||||||
|
|
||||||
DBG (DBG_proc,
|
DBG (DBG_proc,
|
||||||
|
@ -2258,27 +2256,28 @@ genesys_dark_shading_calibration (Genesys_Device * dev)
|
||||||
calibration_data = malloc (size);
|
calibration_data = malloc (size);
|
||||||
if (!calibration_data)
|
if (!calibration_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error, "genesys_dark_shading_calibration: failed to allocate calibration data memory\n");
|
DBG (DBG_error,
|
||||||
|
"genesys_dark_shading_calibration: failed to allocate calibration data memory\n");
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners
|
/* turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners
|
||||||
* because they have a calibration sheet with a sufficent black strip */
|
* because they have a calibration sheet with a sufficent black strip */
|
||||||
if (dev->model->is_sheetfed==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_lamp_power (dev, dev->calib_reg, SANE_FALSE);
|
||||||
dev->model->cmd_set->set_motor_power (dev->calib_reg, SANE_FALSE);
|
dev->model->cmd_set->set_motor_power (dev->calib_reg, SANE_FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dev->model->cmd_set->set_lamp_power (dev, dev->calib_reg, SANE_TRUE);
|
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);
|
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->
|
dev->model->cmd_set->
|
||||||
cmd_set->bulk_full_size ());
|
bulk_full_size ());
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
|
@ -2484,8 +2483,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->
|
dev->model->cmd_set->
|
||||||
cmd_set->bulk_full_size ());
|
bulk_full_size ());
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
|
@ -2625,8 +2624,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->
|
dev->model->cmd_set->
|
||||||
cmd_set->bulk_full_size ());
|
bulk_full_size ());
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
|
@ -2916,6 +2915,75 @@ compute_coefficients (Genesys_Device * dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes shading coefficient using formula in data sheet. 16bit data values
|
||||||
|
* manipulated here are little endian. Data is in planar form, ie grouped by
|
||||||
|
* lines of the same color component.
|
||||||
|
* @param dev scanner's device
|
||||||
|
* @shading_data memory area where to store the computed shading coefficients
|
||||||
|
* @param pixels_per_line number of pixels per line
|
||||||
|
* @param channels number of color channels (actually 1 or 3)
|
||||||
|
* @param avgpixels number of pixels to average
|
||||||
|
* @param offset shading coefficients left offset
|
||||||
|
* @param coeff 4000h or 2000h depending on fast scan mode or not
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
compute_planar_coefficients (Genesys_Device * dev,
|
||||||
|
uint8_t * shading_data,
|
||||||
|
unsigned int pixels_per_line,
|
||||||
|
unsigned int channels,
|
||||||
|
unsigned int avgpixels,
|
||||||
|
unsigned int offset,
|
||||||
|
unsigned int coeff, unsigned int target_code)
|
||||||
|
{
|
||||||
|
uint8_t *ptr; /*contain 16bit words in little endian */
|
||||||
|
unsigned int x, j, c;
|
||||||
|
unsigned int val, dk;
|
||||||
|
|
||||||
|
for (c = 0; c < channels; c++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < pixels_per_line - offset - avgpixels - 1;
|
||||||
|
x += avgpixels)
|
||||||
|
{
|
||||||
|
/* x2 because of 16 bit values, and x2 since one coeff for dark
|
||||||
|
* and another for white */
|
||||||
|
ptr = shading_data + pixels_per_line * c + (x + offset) * 2 * 2;
|
||||||
|
|
||||||
|
/* dark data */
|
||||||
|
dk = 0;
|
||||||
|
for (j = 0; j < avgpixels; j++)
|
||||||
|
{
|
||||||
|
dk += 256 * dev->dark_average_data[(x + j) * 2 + 1];
|
||||||
|
dk += dev->dark_average_data[(x + j) * 2];
|
||||||
|
}
|
||||||
|
dk /= j;
|
||||||
|
if (dk > 65535)
|
||||||
|
dk = 65535;
|
||||||
|
for (j = 0; j < avgpixels; j++)
|
||||||
|
{
|
||||||
|
ptr[0 + j * 2] = dk & 255;
|
||||||
|
ptr[1 + j * 2] = dk / 256;
|
||||||
|
}
|
||||||
|
/* white data */
|
||||||
|
val = 0;
|
||||||
|
for (j = 0; j < avgpixels; j++)
|
||||||
|
{
|
||||||
|
val += 256 * dev->white_average_data[(x + j) * 2 + 1];
|
||||||
|
val += dev->white_average_data[(x + j) * 2];
|
||||||
|
}
|
||||||
|
val /= j;
|
||||||
|
val -= (256 * ptr[1] + ptr[0]);
|
||||||
|
val = compute_coefficient (coeff, target_code, val);
|
||||||
|
for (j = 0; j < avgpixels; j++)
|
||||||
|
{
|
||||||
|
ptr[2 + j * 2] = val & 0xff;
|
||||||
|
ptr[3 + j * 2] = val / 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
genesys_send_shading_coefficient (Genesys_Device * dev)
|
genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
{
|
{
|
||||||
|
@ -2970,7 +3038,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
coeff = 0x4000;
|
coeff = 0x4000;
|
||||||
else
|
else
|
||||||
coeff = 0x2000;
|
coeff = 0x2000;
|
||||||
|
|
||||||
/* for GL646, shading data is planar if REG01_FASTMOD is set and
|
/* for GL646, shading data is planar if REG01_FASTMOD is set and
|
||||||
* chunky if not. For now we rely on the fact that we know that
|
* chunky if not. For now we rely on the fact that we know that
|
||||||
* each sensor is used only in one mode. Currently only the CIS_XP200
|
* each sensor is used only in one mode. Currently only the CIS_XP200
|
||||||
|
@ -2981,13 +3049,15 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
{
|
{
|
||||||
case CIS_XP200:
|
case CIS_XP200:
|
||||||
target_code = 0xf000;
|
target_code = 0xf000;
|
||||||
memset (shading_data, 0x00, pixels_per_line * 4 * channels);
|
memset (shading_data, 0x00, pixels_per_line * 4 * 3);
|
||||||
o = 0;
|
o = 0;
|
||||||
|
/* XXX STEF XXX : TODO compute avgpixels on scan settings */
|
||||||
avgpixels = 1;
|
avgpixels = 1;
|
||||||
compute_coefficients (dev,
|
compute_planar_coefficients (dev,
|
||||||
shading_data,
|
shading_data,
|
||||||
pixels_per_line,
|
pixels_per_line,
|
||||||
channels, avgpixels, o, coeff, target_code);
|
channels, avgpixels, o, coeff,
|
||||||
|
target_code);
|
||||||
break;
|
break;
|
||||||
case CCD_5345:
|
case CCD_5345:
|
||||||
target_code = 0xfa00;
|
target_code = 0xfa00;
|
||||||
|
@ -3628,13 +3698,13 @@ genesys_sheetfed_calibration (Genesys_Device * dev)
|
||||||
/******************* shading calibration ***************************/
|
/******************* shading calibration ***************************/
|
||||||
/* send default shading data */
|
/* send default shading data */
|
||||||
/* XXX STEF XXX status = sanei_genesys_init_shading_data (dev, pixels_per_line);
|
/* XXX STEF XXX status = sanei_genesys_init_shading_data (dev, pixels_per_line);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
"genesys_sheetfed_calibration: failed to init shading process: %s\n",
|
"genesys_sheetfed_calibration: failed to init shading process: %s\n",
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}*/
|
} */
|
||||||
|
|
||||||
/* we know we hare on a black area */
|
/* we know we hare on a black area */
|
||||||
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
|
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
|
||||||
|
@ -4051,8 +4121,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->
|
dev->model->cmd_set->
|
||||||
cmd_set->bulk_full_size ());
|
bulk_full_size ());
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -6247,8 +6317,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->cmd_set->
|
RIE (s->dev->model->
|
||||||
set_powersaving (s->dev, s->val[option].w));
|
cmd_set->set_powersaving (s->dev, s->val[option].w));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6286,26 +6356,36 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
|
||||||
s->opt[OPT_GAMMA_VECTOR_R].size /
|
s->opt[OPT_GAMMA_VECTOR_R].size /
|
||||||
sizeof (SANE_Word),
|
sizeof (SANE_Word),
|
||||||
s->opt
|
s->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->opt[OPT_GAMMA_VECTOR_G].
|
s->
|
||||||
constraint.range->max,
|
opt
|
||||||
s->opt[OPT_GAMMA_VECTOR_G].
|
[OPT_GAMMA_VECTOR_G].constraint.
|
||||||
constraint.range->max,
|
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->opt[OPT_GAMMA_VECTOR_B].
|
s->
|
||||||
constraint.range->max,
|
opt
|
||||||
s->opt[OPT_GAMMA_VECTOR_B].
|
[OPT_GAMMA_VECTOR_B].constraint.
|
||||||
constraint.range->max,
|
range->max,
|
||||||
|
s->
|
||||||
|
opt
|
||||||
|
[OPT_GAMMA_VECTOR_B].constraint.
|
||||||
|
range->max,
|
||||||
s->dev->sensor.red_gamma);
|
s->dev->sensor.red_gamma);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Ładowanie…
Reference in New Issue