kopia lustrzana https://gitlab.com/sane-project/backends
LiDE 80 WIP:
- 1200 shading working - 600 and below resolution are ok, but shading needs to be fixed - 1200 dpi motor resolution doesn't workmerge-requests/1/head
rodzic
ebcc2c0a3f
commit
e500d44e65
|
@ -919,10 +919,11 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
|
||||||
int start_address;
|
int start_address;
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
|
|
||||||
DBG (DBG_proc, "genesys_send_offset_and_shading (size = %d)\n", size);
|
DBG (DBG_proc, "%s: (size = %d)\n", __FUNCTION__, size);
|
||||||
|
|
||||||
/* ASIC higher than gl843 doesn't have register 2A/2B, so we route to
|
/* ASIC higher than gl843 doesn't have register 2A/2B, so we route to
|
||||||
* a per ASIC shading data loading function if available */
|
* a per ASIC shading data loading function if available.
|
||||||
|
* It is also used for scanners using SHDAREA */
|
||||||
if(dev->model->cmd_set->send_shading_data!=NULL)
|
if(dev->model->cmd_set->send_shading_data!=NULL)
|
||||||
{
|
{
|
||||||
status=dev->model->cmd_set->send_shading_data(dev, data, size);
|
status=dev->model->cmd_set->send_shading_data(dev, data, size);
|
||||||
|
@ -946,6 +947,7 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
|
||||||
&& dev->model->ccd_type != CCD_XP300
|
&& dev->model->ccd_type != CCD_XP300
|
||||||
&& dev->model->ccd_type != CCD_DP665
|
&& dev->model->ccd_type != CCD_DP665
|
||||||
&& dev->model->ccd_type != CCD_DP685
|
&& dev->model->ccd_type != CCD_DP685
|
||||||
|
&& dev->model->ccd_type != CIS_CANONLIDE80
|
||||||
&& dev->model->ccd_type != CCD_ROADWARRIOR
|
&& dev->model->ccd_type != CCD_ROADWARRIOR
|
||||||
&& dev->model->ccd_type != CCD_HP2300
|
&& dev->model->ccd_type != CCD_HP2300
|
||||||
&& dev->model->ccd_type != CCD_HP2400
|
&& dev->model->ccd_type != CCD_HP2400
|
||||||
|
@ -967,8 +969,7 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
|
||||||
status = sanei_genesys_set_buffer_address (dev, start_address);
|
status = sanei_genesys_set_buffer_address (dev, start_address);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to set buffer address: %s\n", __FUNCTION__,
|
||||||
"genesys_send_offset_and_shading: failed to set buffer address: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -976,8 +977,7 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
|
||||||
status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size);
|
status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size);
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to send shading table: %s\n", __FUNCTION__,
|
||||||
"genesys_send_offset_and_shading: failed to send shading table: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1031,15 +1031,15 @@ sanei_genesys_init_shading_data (Genesys_Device * dev, int pixels_per_line)
|
||||||
*shading_data_ptr++ = 0x40; /* white hi -> 0x4000 */
|
*shading_data_ptr++ = 0x40; /* white hi -> 0x4000 */
|
||||||
}
|
}
|
||||||
|
|
||||||
status =
|
status = genesys_send_offset_and_shading (dev,
|
||||||
genesys_send_offset_and_shading (dev, shading_data,
|
shading_data,
|
||||||
pixels_per_line * 4 * channels);
|
pixels_per_line * 4 * channels);
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
DBG (DBG_error,
|
|
||||||
"sanei_genesys_init_shading_data: failed to send shading data: %s\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
|
|
||||||
free (shading_data);
|
free (shading_data);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "%s: failed to send shading data: %s\n", __FUNCTION__,
|
||||||
|
sane_strstatus (status));
|
||||||
|
}
|
||||||
|
|
||||||
DBGCOMPLETED;
|
DBGCOMPLETED;
|
||||||
return status;
|
return status;
|
||||||
|
@ -2153,7 +2153,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 strip. (So the motor must be on.)
|
* black and a white strip. (So the motor must be on.)
|
||||||
*/
|
*/
|
||||||
static SANE_Status
|
GENESYS_STATIC SANE_Status
|
||||||
genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
{
|
{
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
|
@ -2168,8 +2168,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
SANE_Bool motor;
|
SANE_Bool motor;
|
||||||
|
|
||||||
|
|
||||||
DBG (DBG_proc, "genesys_black_white_shading_calibration (lines = %d)\n",
|
DBG (DBG_proc, "%s: (lines = %d)\n", __FUNCTION__, (unsigned int)dev->calib_lines);
|
||||||
(unsigned int)dev->calib_lines);
|
|
||||||
|
|
||||||
pixels_per_line = dev->calib_pixels;
|
pixels_per_line = dev->calib_pixels;
|
||||||
channels = dev->calib_channels;
|
channels = dev->calib_channels;
|
||||||
|
@ -2182,8 +2181,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
dev->white_average_data = malloc (dev->average_size);
|
dev->white_average_data = malloc (dev->average_size);
|
||||||
if (!dev->white_average_data)
|
if (!dev->white_average_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to allocate white average memory\n", __FUNCTION__);
|
||||||
"genesys_dark_white_shading_calibration: failed to allocate average memory\n");
|
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2193,8 +2191,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
dev->dark_average_data = malloc (channels * 2 * pixels_per_line);
|
dev->dark_average_data = malloc (channels * 2 * pixels_per_line);
|
||||||
if (!dev->dark_average_data)
|
if (!dev->dark_average_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to allocate dark average memory\n", __FUNCTION__);
|
||||||
"genesys_dark_white_shading_shading_calibration: failed to allocate average memory\n");
|
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2203,8 +2200,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
calibration_data = malloc (size);
|
calibration_data = malloc (size);
|
||||||
if (!calibration_data)
|
if (!calibration_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to allocate calibration memory\n", __FUNCTION__);
|
||||||
"genesys_dark_white_shading_calibration: failed to allocate calibration memory\n");
|
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2225,8 +2221,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to bulk write registers: %s\n", __FUNCTION__,
|
||||||
"genesys_dark_white_shading_calibration: failed to bulk write registers: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2236,8 +2231,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to begin scan: %s\n", __FUNCTION__,
|
||||||
"genesys_dark_white_shading_calibration: Failed to begin scan: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2246,8 +2240,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to read data: %s\n", __FUNCTION__,
|
||||||
"genesys_dark_white_shading_calibration: Failed to read data: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2256,16 +2249,26 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
free (calibration_data);
|
free (calibration_data);
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: Failed to end scan: %s\n", __FUNCTION__,
|
||||||
"genesys_dark_white_shading_calibration: Failed to end scan: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBG_LEVEL >= DBG_data)
|
if (DBG_LEVEL >= DBG_data)
|
||||||
|
{
|
||||||
|
if (dev->model->is_cis)
|
||||||
|
{
|
||||||
|
sanei_genesys_write_pnm_file ("black_white_shading.pnm", calibration_data,
|
||||||
|
16, 1, pixels_per_line*channels,
|
||||||
|
dev->calib_lines);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sanei_genesys_write_pnm_file ("black_white_shading.pnm", calibration_data,
|
sanei_genesys_write_pnm_file ("black_white_shading.pnm", calibration_data,
|
||||||
16, channels, pixels_per_line,
|
16, channels, pixels_per_line,
|
||||||
dev->calib_lines);
|
dev->calib_lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
average_white = dev->white_average_data;
|
average_white = dev->white_average_data;
|
||||||
|
@ -2418,8 +2421,8 @@ compute_averaged_planar (Genesys_Device * dev,
|
||||||
{
|
{
|
||||||
unsigned int x, i, j, br, dk, res, avgpixels, basepixels, val;
|
unsigned int x, i, j, br, dk, res, avgpixels, basepixels, val;
|
||||||
|
|
||||||
DBG (DBG_info, "%s: pixels=%d, offset=%d\n", __FUNCTION__, pixels_per_line,
|
DBG (DBG_info, "%s: pixels=%d, offset=%d\n", __FUNCTION__, pixels_per_line, o);
|
||||||
o);
|
|
||||||
/* initialize result */
|
/* initialize result */
|
||||||
memset (shading_data, 0xff, words_per_color * 3 * 2);
|
memset (shading_data, 0xff, words_per_color * 3 * 2);
|
||||||
|
|
||||||
|
@ -2478,7 +2481,6 @@ compute_averaged_planar (Genesys_Device * dev,
|
||||||
|
|
||||||
for (x = 0; x <= pixels_per_line - avgpixels; x += avgpixels)
|
for (x = 0; x <= pixels_per_line - avgpixels; x += avgpixels)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((x + o) * 2 * 2 + 3 > words_per_color * 2)
|
if ((x + o) * 2 * 2 + 3 > words_per_color * 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2515,33 +2517,33 @@ compute_averaged_planar (Genesys_Device * dev,
|
||||||
65535 * (target_bright - target_dark))
|
65535 * (target_bright - target_dark))
|
||||||
val = 65535;
|
val = 65535;
|
||||||
else
|
else
|
||||||
val =
|
{
|
||||||
(dk * target_bright - br * target_dark) / (target_bright -
|
val = (dk * target_bright - br * target_dark) / (target_bright - target_dark);
|
||||||
target_dark);
|
}
|
||||||
|
|
||||||
/*fill all pixels, even if only the last one is relevant*/
|
/*fill all pixels, even if only the last one is relevant*/
|
||||||
for (i = 0; i < avgpixels; i++)
|
for (i = 0; i < avgpixels; i++)
|
||||||
{
|
{
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j] = val & 0xff;
|
||||||
words_per_color * 2 * j] = val & 0xff;
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 1] = val >> 8;
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * j + 1] = val >> 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val = br - dk;
|
val = br - dk;
|
||||||
|
|
||||||
if (65535 * val > (target_bright - target_dark) * coeff)
|
if (65535 * val > (target_bright - target_dark) * coeff)
|
||||||
|
{
|
||||||
val = (coeff * (target_bright - target_dark)) / val;
|
val = (coeff * (target_bright - target_dark)) / val;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
val = 65535;
|
val = 65535;
|
||||||
|
}
|
||||||
|
|
||||||
/*fill all pixels, even if only the last one is relevant*/
|
/*fill all pixels, even if only the last one is relevant*/
|
||||||
for (i = 0; i < avgpixels; i++)
|
for (i = 0; i < avgpixels; i++)
|
||||||
{
|
{
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 2] = val & 0xff;
|
||||||
words_per_color * 2 * j + 2] = val & 0xff;
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 3] = val >> 8;
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * j + 3] = val >> 8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2550,24 +2552,12 @@ compute_averaged_planar (Genesys_Device * dev,
|
||||||
{
|
{
|
||||||
for (i = 0; i < avgpixels; i++)
|
for (i = 0; i < avgpixels; i++)
|
||||||
{
|
{
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j ] = shading_data[(x + o + i) * 2 * 2 ];
|
||||||
words_per_color * 2 * j] =
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 1] = shading_data[(x + o + i) * 2 * 2 + 1];
|
||||||
shading_data[(x + o + i) * 2 * 2 + words_per_color * 0];
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 2] = shading_data[(x + o + i) * 2 * 2 + 2];
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 3] = shading_data[(x + o + i) * 2 * 2 + 3];
|
||||||
words_per_color * 2 * j + 1] =
|
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * 0 + 1];
|
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * j + 2] =
|
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * 0 + 2];
|
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * j + 3] =
|
|
||||||
shading_data[(x + o + i) * 2 * 2 +
|
|
||||||
words_per_color * 2 * 0 + 3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2870,13 +2860,21 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* special case, memory is aligned on 0x5400, this has yet to be explained */
|
||||||
|
/* could be 0xa800 because sensor is truly 2400 dpi, then halved because
|
||||||
|
* we only set 1200 dpi */
|
||||||
|
if(dev->model->ccd_type==CIS_CANONLIDE80)
|
||||||
|
{
|
||||||
|
words_per_color = 0x5400;
|
||||||
|
}
|
||||||
|
|
||||||
length = words_per_color * 3 * 2;
|
length = words_per_color * 3 * 2;
|
||||||
|
|
||||||
/* allocate computed size */
|
/* allocate computed size */
|
||||||
shading_data = malloc (length);
|
shading_data = malloc (length);
|
||||||
if (!shading_data)
|
if (!shading_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to allocate memory\n", __FUNCTION__);
|
||||||
"genesys_send_shading_coefficient: failed to allocate memory\n");
|
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
memset (shading_data, 0, length);
|
memset (shading_data, 0, length);
|
||||||
|
@ -3040,8 +3038,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
shading_data = malloc (length);
|
shading_data = malloc (length);
|
||||||
if (!shading_data)
|
if (!shading_data)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to allocate memory\n", __FUNCTION__);
|
||||||
"genesys_send_shading_coefficient: failed to allocate memory\n");
|
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
}
|
}
|
||||||
memset (shading_data, 0, length);
|
memset (shading_data, 0, length);
|
||||||
|
@ -3057,7 +3054,6 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
target_code);
|
target_code);
|
||||||
break;
|
break;
|
||||||
case CCD_CANONLIDE35:
|
case CCD_CANONLIDE35:
|
||||||
case CIS_CANONLIDE80:
|
|
||||||
compute_averaged_planar (dev,
|
compute_averaged_planar (dev,
|
||||||
shading_data,
|
shading_data,
|
||||||
pixels_per_line,
|
pixels_per_line,
|
||||||
|
@ -3068,6 +3064,17 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
0xfa00,
|
0xfa00,
|
||||||
0x0a00);
|
0x0a00);
|
||||||
break;
|
break;
|
||||||
|
case CIS_CANONLIDE80:
|
||||||
|
compute_averaged_planar (dev,
|
||||||
|
shading_data,
|
||||||
|
pixels_per_line,
|
||||||
|
words_per_color,
|
||||||
|
channels,
|
||||||
|
0,
|
||||||
|
coeff,
|
||||||
|
0xfa00,
|
||||||
|
0x0a00);
|
||||||
|
break;
|
||||||
case CCD_PLUSTEK_3600:
|
case CCD_PLUSTEK_3600:
|
||||||
compute_shifted_coefficients (dev,
|
compute_shifted_coefficients (dev,
|
||||||
shading_data,
|
shading_data,
|
||||||
|
@ -3081,23 +3088,21 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
||||||
256); /* patch_size: contigous extent */
|
256); /* patch_size: contigous extent */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: sensor %d not supported\n", __FUNCTION__, dev->model->ccd_type);
|
||||||
"genesys_send_shading_coefficient: sensor %d not supported\n",
|
|
||||||
dev->model->ccd_type);
|
|
||||||
return SANE_STATUS_UNSUPPORTED;
|
return SANE_STATUS_UNSUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do the actual write of shading calibration data to the scanner */
|
/* do the actual write of shading calibration data to the scanner */
|
||||||
status = genesys_send_offset_and_shading (dev, shading_data, length);
|
status = genesys_send_offset_and_shading (dev, shading_data, length);
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
DBG (DBG_error,
|
|
||||||
"genesys_send_shading_coefficient: failed to send shading data: %s\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
|
|
||||||
free (shading_data);
|
free (shading_data);
|
||||||
DBGCOMPLETED;
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "%s: failed to send shading data: %s\n", __FUNCTION__,
|
||||||
|
sane_strstatus (status));
|
||||||
|
}
|
||||||
|
|
||||||
|
DBGCOMPLETED;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,4 +146,7 @@ typedef struct Genesys_Scanner
|
||||||
SANE_Int bpp_list[5]; /**< */
|
SANE_Int bpp_list[5]; /**< */
|
||||||
} Genesys_Scanner;
|
} Genesys_Scanner;
|
||||||
|
|
||||||
|
#ifdef UNIT_TESTING
|
||||||
|
SANE_Status genesys_dark_white_shading_calibration (Genesys_Device * dev);
|
||||||
|
#endif
|
||||||
#endif /* not GENESYS_H */
|
#endif /* not GENESYS_H */
|
||||||
|
|
|
@ -305,7 +305,8 @@ static Genesys_Sensor Sensor[] = {
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
/* CANOLIDE35 */
|
/* CANOLIDE35 */
|
||||||
{CCD_CANONLIDE35, 1200,
|
{CCD_CANONLIDE35,
|
||||||
|
1200,
|
||||||
87, /* (black) */
|
87, /* (black) */
|
||||||
87, /* (dummy) */
|
87, /* (dummy) */
|
||||||
0, /* (startxoffset) */
|
0, /* (startxoffset) */
|
||||||
|
@ -760,10 +761,10 @@ static Genesys_Sensor Sensor[] = {
|
||||||
/* CANOLIDE80 */
|
/* CANOLIDE80 */
|
||||||
{CIS_CANONLIDE80,
|
{CIS_CANONLIDE80,
|
||||||
1200, /* real hardware limit is 2400 */
|
1200, /* real hardware limit is 2400 */
|
||||||
9*2,
|
20, /* black pixels */
|
||||||
9*2,
|
6, /* expdummy */
|
||||||
0,
|
31, /* CCD_start_xoffset 14=>3, 20=>2 */
|
||||||
10304, /* up to 5144, 5390, 10264, 20504, 21762 : capped by max exposure from logs */
|
10240, /* 10400, too wide=>10288 in shading data 10240~, 10208 too short for shading, max shading data = 10240 pixels, endpix-startpix=10208 */
|
||||||
230,
|
230,
|
||||||
230,
|
230,
|
||||||
{0x00, 0x05, 0x07, 0x09}, /* in fact ,maps to 0x70-0x73 for GL841 */
|
{0x00, 0x05, 0x07, 0x09}, /* in fact ,maps to 0x70-0x73 for GL841 */
|
||||||
|
@ -1288,8 +1289,8 @@ static Genesys_Motor Motor[] = {
|
||||||
},},
|
},},
|
||||||
{MOTOR_CANONLIDE80,
|
{MOTOR_CANONLIDE80,
|
||||||
2400, /* 2400 ???? */
|
2400, /* 2400 ???? */
|
||||||
7200,
|
9600, /* 7200 ???? */
|
||||||
2, /* max step type */
|
1, /* max step type */
|
||||||
1, /* power mode count */
|
1, /* power mode count */
|
||||||
{
|
{
|
||||||
{ /* start speed, max end speed, step number */
|
{ /* start speed, max end speed, step number */
|
||||||
|
@ -1297,7 +1298,7 @@ static Genesys_Motor Motor[] = {
|
||||||
/* 1288=(5144+8)*ydpi(=300)/base_dpi(=1200) , where 5152 is exposure */
|
/* 1288=(5144+8)*ydpi(=300)/base_dpi(=1200) , where 5152 is exposure */
|
||||||
/* 6440=9660/(1932/1288) */
|
/* 6440=9660/(1932/1288) */
|
||||||
{ 6440, 1288, 60, 0.8 }, /* full step 9660 1932 32 values from logs */
|
{ 6440, 1288, 60, 0.8 }, /* full step 9660 1932 32 values from logs */
|
||||||
{ 18750, 1875, 60, 0.8 }, /* half step 18750 1875 16 values from logs */
|
{ 15869, 15869, 16, 0.8 }, /* half step 18750 1875 16 values from logs */
|
||||||
},
|
},
|
||||||
},},
|
},},
|
||||||
};
|
};
|
||||||
|
@ -1360,8 +1361,8 @@ static Genesys_Model canon_lide_50_model = {
|
||||||
GENESYS_GL841,
|
GENESYS_GL841,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
|
{ 1200, 600, 400, 300, 240, 200, 150, 75, 0}, /* possible x-resolutions */
|
||||||
{2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */
|
{2400, 1200, 600, 400, 300, 240, 200, 150, 75, 0}, /* possible y-resolutions */
|
||||||
{16, 8, 0}, /* possible depths in gray mode */
|
{16, 8, 0}, /* possible depths in gray mode */
|
||||||
{16, 8, 0}, /* possible depths in color mode */
|
{16, 8, 0}, /* possible depths in color mode */
|
||||||
|
|
||||||
|
@ -2128,14 +2129,14 @@ static Genesys_Model canon_lide_80_model = {
|
||||||
GENESYS_GL841,
|
GENESYS_GL841,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
||||||
{ 1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */
|
{ 1200, 600, 400, 300, 240, 150, 100, 75, 0}, /* possible x-resolutions */
|
||||||
{2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */
|
{2400, 1200, 600, 400, 300, 240, 150, 100, 75, 0}, /* possible y-resolutions */
|
||||||
{16, 8, 0}, /* possible depths in gray mode */
|
{16, 8, 0}, /* possible depths in gray mode */
|
||||||
{16, 8, 0}, /* possible depths in color mode */
|
{16, 8, 0}, /* possible depths in color mode */
|
||||||
|
|
||||||
SANE_FIX (6.5), /* Start of scan area in mm (x) */
|
SANE_FIX (0.42), /* Start of scan area in mm (x) 0.42 */
|
||||||
SANE_FIX (7.9), /* Start of scan area in mm (y) */
|
SANE_FIX (7.90), /* Start of scan area in mm (y) 7.90 */
|
||||||
SANE_FIX (218.0), /* Size of scan area in mm (x) */
|
SANE_FIX (216.07), /* Size of scan area in mm (x) 218.00 */
|
||||||
SANE_FIX (299.0), /* Size of scan area in mm (y) */
|
SANE_FIX (299.0), /* Size of scan area in mm (y) */
|
||||||
|
|
||||||
SANE_FIX (3.0), /* Start of white strip in mm (y) */
|
SANE_FIX (3.0), /* Start of white strip in mm (y) */
|
||||||
|
@ -2173,7 +2174,7 @@ static Genesys_Model canon_lide_80_model = {
|
||||||
GENESYS_HAS_FILE_SW |
|
GENESYS_HAS_FILE_SW |
|
||||||
GENESYS_HAS_EMAIL_SW |
|
GENESYS_HAS_EMAIL_SW |
|
||||||
GENESYS_HAS_COPY_SW,
|
GENESYS_HAS_COPY_SW,
|
||||||
200,
|
280,
|
||||||
400
|
400
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -214,8 +214,8 @@ gl841_bulk_read_data (Genesys_Device * dev, uint8_t addr,
|
||||||
uint8_t * data, size_t len)
|
uint8_t * data, size_t len)
|
||||||
{
|
{
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
size_t size;
|
size_t size, target;
|
||||||
uint8_t outdata[8];
|
uint8_t outdata[8], *buffer;
|
||||||
|
|
||||||
DBG (DBG_io, "gl841_bulk_read_data: requesting %lu bytes\n",
|
DBG (DBG_io, "gl841_bulk_read_data: requesting %lu bytes\n",
|
||||||
(u_long) len);
|
(u_long) len);
|
||||||
|
@ -254,12 +254,14 @@ gl841_bulk_read_data (Genesys_Device * dev, uint8_t addr,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len)
|
target = len;
|
||||||
|
buffer = data;
|
||||||
|
while (target)
|
||||||
{
|
{
|
||||||
if (len > BULKIN_MAXSIZE)
|
if (target > BULKIN_MAXSIZE)
|
||||||
size = BULKIN_MAXSIZE;
|
size = BULKIN_MAXSIZE;
|
||||||
else
|
else
|
||||||
size = len;
|
size = target;
|
||||||
|
|
||||||
DBG (DBG_io2,
|
DBG (DBG_io2,
|
||||||
"gl841_bulk_read_data: trying to read %lu bytes of data\n",
|
"gl841_bulk_read_data: trying to read %lu bytes of data\n",
|
||||||
|
@ -277,14 +279,18 @@ gl841_bulk_read_data (Genesys_Device * dev, uint8_t addr,
|
||||||
|
|
||||||
DBG (DBG_io2,
|
DBG (DBG_io2,
|
||||||
"gl841_bulk_read_data read %lu bytes, %lu remaining\n",
|
"gl841_bulk_read_data read %lu bytes, %lu remaining\n",
|
||||||
(u_long) size, (u_long) (len - size));
|
(u_long) size, (u_long) (target - size));
|
||||||
|
|
||||||
len -= size;
|
target -= size;
|
||||||
data += size;
|
data += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_io, "gl841_bulk_read_data: completed\n");
|
|
||||||
|
|
||||||
|
if (DBG_LEVEL >= DBG_data && dev->binary!=NULL)
|
||||||
|
{
|
||||||
|
fwrite(buffer, len, 1, dev->binary);
|
||||||
|
}
|
||||||
|
DBGCOMPLETED;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,12 +794,12 @@ gl841_init_lide80 (Genesys_Device * dev)
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
int index=0;
|
int index=0;
|
||||||
|
|
||||||
INITREG (0x01, 0x02);
|
INITREG (0x01, 0x82); /* 0x02 = SHDAREA and no CISSET ! */
|
||||||
INITREG (0x02, 0x10);
|
INITREG (0x02, 0x10);
|
||||||
INITREG (0x03, 0x50);
|
INITREG (0x03, 0x50);
|
||||||
INITREG (0x04, 0x02);
|
INITREG (0x04, 0x02);
|
||||||
INITREG (0x05, 0x4c);
|
INITREG (0x05, 0x4c); /* 1200 DPI */
|
||||||
INITREG (0x06, 0x38);
|
INITREG (0x06, 0x30); /* 0x38 scanmod=1, pwrbit, GAIN4 */
|
||||||
INITREG (0x07, 0x00);
|
INITREG (0x07, 0x00);
|
||||||
INITREG (0x08, 0x00);
|
INITREG (0x08, 0x00);
|
||||||
INITREG (0x09, 0x11);
|
INITREG (0x09, 0x11);
|
||||||
|
@ -1976,7 +1982,10 @@ gl841_init_motor_regs_scan(Genesys_Device * dev,
|
||||||
&fast_exposure,
|
&fast_exposure,
|
||||||
scan_power_mode);
|
scan_power_mode);
|
||||||
|
|
||||||
if (dev->model->gpo_type == GPO_XP300 || dev->model->gpo_type == GPO_DP685)
|
/* fast fed special cases handling */
|
||||||
|
if (dev->model->gpo_type == GPO_XP300
|
||||||
|
|| ((dev->model->motor_type== MOTOR_CANONLIDE80) && (scan_yres>600)) /* no fast fed at high res for this motor */
|
||||||
|
|| dev->model->gpo_type == GPO_DP685)
|
||||||
{
|
{
|
||||||
/* quirk: looks like at least this scanner is unable to use
|
/* quirk: looks like at least this scanner is unable to use
|
||||||
2-feed mode */
|
2-feed mode */
|
||||||
|
@ -2428,19 +2437,9 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
|
||||||
r = sanei_genesys_get_address (reg, 0x29);
|
r = sanei_genesys_get_address (reg, 0x29);
|
||||||
r->value = 255; /*<<<"magic" number, only suitable for cis*/
|
r->value = 255; /*<<<"magic" number, only suitable for cis*/
|
||||||
|
|
||||||
r = sanei_genesys_get_address (reg, 0x2c);
|
sanei_genesys_set_double(reg, REG_DPISET, dpiset);
|
||||||
r->value = HIBYTE (dpiset);
|
sanei_genesys_set_double(reg, REG_STRPIXEL, start);
|
||||||
r = sanei_genesys_get_address (reg, 0x2d);
|
sanei_genesys_set_double(reg, REG_ENDPIXEL, end);
|
||||||
r->value = LOBYTE (dpiset);
|
|
||||||
|
|
||||||
r = sanei_genesys_get_address (reg, 0x30);
|
|
||||||
r->value = HIBYTE (start);
|
|
||||||
r = sanei_genesys_get_address (reg, 0x31);
|
|
||||||
r->value = LOBYTE (start);
|
|
||||||
r = sanei_genesys_get_address (reg, 0x32);
|
|
||||||
r->value = HIBYTE (end);
|
|
||||||
r = sanei_genesys_get_address (reg, 0x33);
|
|
||||||
r->value = LOBYTE (end);
|
|
||||||
|
|
||||||
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
|
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
|
||||||
words_per_line = (pixels * dpiset) / gl841_get_dpihw(dev);
|
words_per_line = (pixels * dpiset) / gl841_get_dpihw(dev);
|
||||||
|
@ -2470,7 +2469,7 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
|
||||||
r = sanei_genesys_get_address (reg, 0x34);
|
r = sanei_genesys_get_address (reg, 0x34);
|
||||||
r->value = dev->sensor.dummy_pixel;
|
r->value = dev->sensor.dummy_pixel;
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_init_optical_regs_scan : completed. \n");
|
DBGCOMPLETED;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2704,10 +2703,6 @@ dummy \ scanned lines
|
||||||
scan_step_type = 1;
|
scan_step_type = 1;
|
||||||
else
|
else
|
||||||
scan_step_type = 2;
|
scan_step_type = 2;
|
||||||
if (dev->model->motor_type == MOTOR_CANONLIDE80 && yres>=600)
|
|
||||||
{
|
|
||||||
scan_step_type = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* exposure_time */
|
/* exposure_time */
|
||||||
led_exposure = gl841_get_led_exposure(dev);
|
led_exposure = gl841_get_led_exposure(dev);
|
||||||
|
@ -2734,7 +2729,6 @@ dummy \ scanned lines
|
||||||
scan_power_mode++;
|
scan_power_mode++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DBG (DBG_info, "gl841_init_scan_regs : exposure_time=%d pixels\n",
|
DBG (DBG_info, "gl841_init_scan_regs : exposure_time=%d pixels\n",
|
||||||
exposure_time);
|
exposure_time);
|
||||||
|
|
||||||
|
@ -3096,10 +3090,6 @@ dummy \ scanned lines
|
||||||
scan_step_type = 1;
|
scan_step_type = 1;
|
||||||
else
|
else
|
||||||
scan_step_type = 2;
|
scan_step_type = 2;
|
||||||
if (dev->model->motor_type == MOTOR_CANONLIDE80 && yres>=600)
|
|
||||||
{
|
|
||||||
scan_step_type = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
led_exposure = gl841_get_led_exposure(dev);
|
led_exposure = gl841_get_led_exposure(dev);
|
||||||
|
|
||||||
|
@ -3126,8 +3116,7 @@ dummy \ scanned lines
|
||||||
scan_power_mode++;
|
scan_power_mode++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_info, "gl841_calculate_current_setup : exposure_time=%d pixels\n",
|
DBG (DBG_info, "%s : exposure_time=%d pixels\n", __FUNCTION__, exposure_time);
|
||||||
exposure_time);
|
|
||||||
|
|
||||||
/* scanned area must be enlarged by max color shift needed */
|
/* scanned area must be enlarged by max color shift needed */
|
||||||
max_shift=sanei_genesys_compute_max_shift(dev,channels,yres,0);
|
max_shift=sanei_genesys_compute_max_shift(dev,channels,yres,0);
|
||||||
|
@ -3146,7 +3135,7 @@ dummy \ scanned lines
|
||||||
dev->current_setup.stagger = stagger;
|
dev->current_setup.stagger = stagger;
|
||||||
dev->current_setup.max_shift = max_shift + stagger;
|
dev->current_setup.max_shift = max_shift + stagger;
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_calculate_current_setup: completed\n");
|
DBGCOMPLETED;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4254,8 +4243,7 @@ gl841_init_regs_for_coarse_calibration (Genesys_Device * dev)
|
||||||
uint8_t channels;
|
uint8_t channels;
|
||||||
uint8_t cksel;
|
uint8_t cksel;
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_init_regs_for_coarse_calibration\n");
|
DBGSTART;
|
||||||
|
|
||||||
|
|
||||||
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
|
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
|
||||||
|
|
||||||
|
@ -4303,13 +4291,11 @@ gl841_init_regs_for_coarse_calibration (Genesys_Device * dev)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_proc,
|
|
||||||
"gl841_init_register_for_coarse_calibration: completed\n");
|
|
||||||
|
|
||||||
/* if (DBG_LEVEL >= DBG_info)
|
/* if (DBG_LEVEL >= DBG_info)
|
||||||
sanei_gl841_print_registers (dev->calib_reg);*/
|
sanei_gl841_print_registers (dev->calib_reg);*/
|
||||||
|
|
||||||
|
DBGCOMPLETED;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4320,14 +4306,30 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
|
||||||
{
|
{
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
SANE_Int ydpi;
|
SANE_Int ydpi;
|
||||||
|
float starty;
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_init_regs_for_shading: lines = %d\n", (int)dev->calib_lines);
|
DBGSTART;
|
||||||
|
DBG (DBG_proc, "%s: lines = %d\n", __FUNCTION__, (int)dev->calib_lines);
|
||||||
|
|
||||||
ydpi = dev->motor.base_ydpi;
|
ydpi = dev->motor.base_ydpi;
|
||||||
if (dev->motor.motor_id == MOTOR_PLUSTEK_3600) /* TODO PLUSTEK_3600: 1200dpi not yet working, produces dark bar */
|
starty = 0;
|
||||||
|
if (dev->model->motor_type == MOTOR_PLUSTEK_3600) /* TODO PLUSTEK_3600: 1200dpi not yet working, produces dark bar */
|
||||||
{
|
{
|
||||||
ydpi = 600;
|
ydpi = 600;
|
||||||
}
|
}
|
||||||
|
if (dev->model->motor_type== MOTOR_CANONLIDE80)
|
||||||
|
{
|
||||||
|
/* ydpi = sensor dpi * channels / (1+half_ccd) */
|
||||||
|
if(dev->settings.xres>600)
|
||||||
|
{
|
||||||
|
ydpi = 1200;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ydpi = 600;
|
||||||
|
}
|
||||||
|
starty = (SANE_UNFIX (dev->model->y_offset_calib)*ydpi)/MM_PER_INCH;
|
||||||
|
}
|
||||||
|
|
||||||
dev->calib_channels = 3;
|
dev->calib_channels = 3;
|
||||||
dev->calib_lines = dev->model->shading_lines;
|
dev->calib_lines = dev->model->shading_lines;
|
||||||
|
@ -4336,7 +4338,7 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
|
||||||
dev->settings.xres,
|
dev->settings.xres,
|
||||||
ydpi,
|
ydpi,
|
||||||
0,
|
0,
|
||||||
0,
|
starty,
|
||||||
(dev->sensor.sensor_pixels * dev->settings.xres) / dev->sensor.optical_res,
|
(dev->sensor.sensor_pixels * dev->settings.xres) / dev->sensor.optical_res,
|
||||||
dev->calib_lines,
|
dev->calib_lines,
|
||||||
16,
|
16,
|
||||||
|
@ -4344,14 +4346,8 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
|
||||||
dev->settings.color_filter,
|
dev->settings.color_filter,
|
||||||
SCAN_FLAG_DISABLE_SHADING |
|
SCAN_FLAG_DISABLE_SHADING |
|
||||||
SCAN_FLAG_DISABLE_GAMMA |
|
SCAN_FLAG_DISABLE_GAMMA |
|
||||||
/* we don't handle differing shading areas very well */
|
|
||||||
/* SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |*/
|
|
||||||
SCAN_FLAG_IGNORE_LINE_DISTANCE |
|
SCAN_FLAG_IGNORE_LINE_DISTANCE |
|
||||||
SCAN_FLAG_USE_OPTICAL_RES
|
SCAN_FLAG_USE_OPTICAL_RES);
|
||||||
);
|
|
||||||
|
|
||||||
dev->calib_pixels = dev->current_setup.pixels;
|
|
||||||
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error,
|
||||||
|
@ -4360,20 +4356,18 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev->calib_pixels = dev->current_setup.pixels;
|
||||||
dev->scanhead_position_in_steps += dev->calib_lines;
|
dev->scanhead_position_in_steps += dev->calib_lines;
|
||||||
|
|
||||||
status =
|
status = gl841_bulk_write_register (dev, dev->calib_reg, GENESYS_GL841_MAX_REGS);
|
||||||
gl841_bulk_write_register (dev, dev->calib_reg, GENESYS_GL841_MAX_REGS);
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
if (status != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_error,
|
DBG (DBG_error, "%s: failed to bulk write registers: %s\n", __FUNCTION__,
|
||||||
"gl841_init_registers_for_shading: failed to bulk write registers: %s\n",
|
|
||||||
sane_strstatus (status));
|
sane_strstatus (status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_init_regs_for_shading: completed\n");
|
DBGCOMPLETED;
|
||||||
|
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4434,7 +4428,9 @@ gl841_init_regs_for_scan (Genesys_Device * dev)
|
||||||
|
|
||||||
move = 0;
|
move = 0;
|
||||||
if (dev->model->flags & GENESYS_FLAG_SEARCH_START)
|
if (dev->model->flags & GENESYS_FLAG_SEARCH_START)
|
||||||
|
{
|
||||||
move += SANE_UNFIX (dev->model->y_offset_calib);
|
move += SANE_UNFIX (dev->model->y_offset_calib);
|
||||||
|
}
|
||||||
|
|
||||||
DBG (DBG_info, "gl841_init_regs_for_scan: move=%f steps\n", move);
|
DBG (DBG_info, "gl841_init_regs_for_scan: move=%f steps\n", move);
|
||||||
|
|
||||||
|
@ -5424,7 +5420,7 @@ gl841_coarse_gain_calibration (Genesys_Device * dev, int dpi)
|
||||||
}
|
}
|
||||||
else if (dev->model->dac_type == DAC_CANONLIDE80)
|
else if (dev->model->dac_type == DAC_CANONLIDE80)
|
||||||
{
|
{
|
||||||
dev->frontend.gain[j] = gain[j]*8;
|
dev->frontend.gain[j] = gain[j]*12;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_proc,
|
DBG (DBG_proc,
|
||||||
|
@ -6145,6 +6141,132 @@ gl841_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send shading calibration data. The buffer is considered to always hold values
|
||||||
|
* for all the channels.
|
||||||
|
*/
|
||||||
|
GENESYS_STATIC
|
||||||
|
SANE_Status
|
||||||
|
gl841_send_shading_data (Genesys_Device * dev, uint8_t * data, int size)
|
||||||
|
{
|
||||||
|
SANE_Status status = SANE_STATUS_GOOD;
|
||||||
|
uint32_t length, x, factor, pixels, i;
|
||||||
|
uint32_t lines, channels;
|
||||||
|
uint16_t dpiset, dpihw, strpixel ,endpixel, beginpixel;
|
||||||
|
uint8_t *buffer,*ptr,*src;
|
||||||
|
|
||||||
|
DBGSTART;
|
||||||
|
DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__FUNCTION__,size);
|
||||||
|
|
||||||
|
/* old method if no SHDAREA */
|
||||||
|
if((dev->reg[reg_0x01].value & REG01_SHDAREA) == 0)
|
||||||
|
{
|
||||||
|
/* start address */
|
||||||
|
status = sanei_genesys_set_buffer_address (dev, 0x0000);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "%s: failed to set buffer address: %s\n", __FUNCTION__,
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shading data whole line */
|
||||||
|
status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "%s: failed to send shading table: %s\n", __FUNCTION__,
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
DBGCOMPLETED;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* data is whole line, we extract only the part for the scanned area */
|
||||||
|
length = (uint32_t) (size / 3);
|
||||||
|
sanei_genesys_get_double(dev->reg,REG_STRPIXEL,&strpixel);
|
||||||
|
sanei_genesys_get_double(dev->reg,REG_ENDPIXEL,&endpixel);
|
||||||
|
DBG( DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d\n",__FUNCTION__,strpixel,endpixel,endpixel-strpixel);
|
||||||
|
|
||||||
|
/* compute deletion/average factor */
|
||||||
|
sanei_genesys_get_double(dev->reg,REG_DPISET,&dpiset);
|
||||||
|
dpihw = dev->reg[reg_0x05].value >> 6;
|
||||||
|
if (dpihw == 0)
|
||||||
|
{
|
||||||
|
dpihw=600;
|
||||||
|
}
|
||||||
|
else if (dpihw == 1)
|
||||||
|
{
|
||||||
|
dpihw=1200;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dpihw=2400;
|
||||||
|
}
|
||||||
|
factor=dpihw/dpiset;
|
||||||
|
DBG( DBG_io2, "%s: factor=%d\n",__FUNCTION__,factor);
|
||||||
|
|
||||||
|
/* binary data logging */
|
||||||
|
if(DBG_LEVEL>=DBG_data)
|
||||||
|
{
|
||||||
|
dev->binary=fopen("binary.pnm","wb");
|
||||||
|
sanei_genesys_get_triple(dev->reg, REG_LINCNT, &lines);
|
||||||
|
channels=dev->current_setup.channels;
|
||||||
|
if(dev->binary!=NULL)
|
||||||
|
{
|
||||||
|
fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels,lines/channels,255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* turn pixel value into bytes 2x16 bits words */
|
||||||
|
strpixel*=2*2; /* 2 words of 2 bytes */
|
||||||
|
endpixel*=2*2;
|
||||||
|
pixels=endpixel-strpixel;
|
||||||
|
/* shading pixel begin is start pixel minus start pixel during shading
|
||||||
|
* calibration */
|
||||||
|
beginpixel = dev->sensor.CCD_start_xoffset / factor + dev->sensor.dummy_pixel + 1;
|
||||||
|
beginpixel = strpixel-beginpixel*2*2;
|
||||||
|
DBG( DBG_io2, "%s: begin pixel %d\n",__FUNCTION__,beginpixel/4);
|
||||||
|
|
||||||
|
DBG( DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n",__FUNCTION__,length, length/4);
|
||||||
|
buffer=(uint8_t *)malloc(pixels);
|
||||||
|
memset(buffer,0,pixels);
|
||||||
|
|
||||||
|
/* write actual shading data contigously
|
||||||
|
* channel by channel, starting at addr 0x0000
|
||||||
|
* */
|
||||||
|
for(i=0;i<3;i++)
|
||||||
|
{
|
||||||
|
/* copy data to work buffer and process it */
|
||||||
|
/* coefficent destination */
|
||||||
|
ptr=buffer;
|
||||||
|
|
||||||
|
/* iterate on both sensor segment */
|
||||||
|
for(x=0;x<pixels;x+=4*factor)
|
||||||
|
{
|
||||||
|
/* coefficient source */
|
||||||
|
src=data+x+beginpixel+i*length;
|
||||||
|
|
||||||
|
ptr[0]=src[0];
|
||||||
|
ptr[1]=src[1];
|
||||||
|
ptr[2]=src[2];
|
||||||
|
ptr[3]=src[3];
|
||||||
|
|
||||||
|
/* next shading coefficient */
|
||||||
|
ptr+=4;
|
||||||
|
}
|
||||||
|
/* 0x5400 alignment for LIDE80 internal memory */
|
||||||
|
RIEF(sanei_genesys_set_buffer_address (dev, 0x5400*i), buffer);
|
||||||
|
RIEF(dev->model->cmd_set->bulk_write_data (dev, 0x3c, buffer, pixels), buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
DBGCOMPLETED;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** the gl841 command set */
|
/** the gl841 command set */
|
||||||
static Genesys_Command_Set gl841_cmd_set = {
|
static Genesys_Command_Set gl841_cmd_set = {
|
||||||
"gl841-generic", /* the name of this set */
|
"gl841-generic", /* the name of this set */
|
||||||
|
@ -6198,7 +6320,7 @@ static Genesys_Command_Set gl841_cmd_set = {
|
||||||
|
|
||||||
gl841_is_compatible_calibration,
|
gl841_is_compatible_calibration,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
gl841_send_shading_data,
|
||||||
gl841_calculate_current_setup,
|
gl841_calculate_current_setup,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -162,6 +162,11 @@
|
||||||
#define REG1E_LINESEL 0x0f
|
#define REG1E_LINESEL 0x0f
|
||||||
#define REG1ES_LINESEL 0
|
#define REG1ES_LINESEL 0
|
||||||
|
|
||||||
|
#define REG_LINCNT 0x25
|
||||||
|
#define REG_DPISET 0x2c
|
||||||
|
#define REG_STRPIXEL 0x30
|
||||||
|
#define REG_ENDPIXEL 0x32
|
||||||
|
|
||||||
#define REG40_HISPDFLG 0x04
|
#define REG40_HISPDFLG 0x04
|
||||||
#define REG40_MOTMFLG 0x02
|
#define REG40_MOTMFLG 0x02
|
||||||
#define REG40_DATAENB 0x01
|
#define REG40_DATAENB 0x01
|
||||||
|
@ -426,4 +431,6 @@ SANE_Status gl841_offset_calibration (Genesys_Device * dev);
|
||||||
SANE_Status gl841_coarse_gain_calibration (Genesys_Device * dev, int dpi);
|
SANE_Status gl841_coarse_gain_calibration (Genesys_Device * dev, int dpi);
|
||||||
|
|
||||||
SANE_Status gl841_led_calibration (Genesys_Device * dev);
|
SANE_Status gl841_led_calibration (Genesys_Device * dev);
|
||||||
|
|
||||||
|
SANE_Status gl841_send_shading_data (Genesys_Device * dev, uint8_t * data, int size);
|
||||||
#endif
|
#endif
|
||||||
|
|
Ładowanie…
Reference in New Issue