- 1200 shading working
- 600 and below resolution are ok, but shading needs to be fixed
- 1200 dpi motor resolution doesn't work
merge-requests/1/head
Stphane Voltz 2013-11-21 07:38:30 +01:00
rodzic ebcc2c0a3f
commit e500d44e65
5 zmienionych plików z 307 dodań i 169 usunięć

Wyświetl plik

@ -919,10 +919,11 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
int start_address;
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
* 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)
{
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_DP665
&& dev->model->ccd_type != CCD_DP685
&& dev->model->ccd_type != CIS_CANONLIDE80
&& dev->model->ccd_type != CCD_ROADWARRIOR
&& dev->model->ccd_type != CCD_HP2300
&& dev->model->ccd_type != CCD_HP2400
@ -967,17 +969,15 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
status = sanei_genesys_set_buffer_address (dev, start_address);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_send_offset_and_shading: failed to set buffer address: %s\n",
sane_strstatus (status));
DBG (DBG_error, "%s: failed to set buffer address: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_send_offset_and_shading: failed to send shading table: %s\n",
DBG (DBG_error, "%s: failed to send shading table: %s\n", __FUNCTION__,
sane_strstatus (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 */
}
status =
genesys_send_offset_and_shading (dev, shading_data,
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));
status = genesys_send_offset_and_shading (dev,
shading_data,
pixels_per_line * 4 * channels);
free (shading_data);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to send shading data: %s\n", __FUNCTION__,
sane_strstatus (status));
}
DBGCOMPLETED;
return status;
@ -2153,7 +2153,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
/* This calibration uses a scan over the calibration target, comprising a
* 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)
{
SANE_Status status;
@ -2168,8 +2168,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
SANE_Bool motor;
DBG (DBG_proc, "genesys_black_white_shading_calibration (lines = %d)\n",
(unsigned int)dev->calib_lines);
DBG (DBG_proc, "%s: (lines = %d)\n", __FUNCTION__, (unsigned int)dev->calib_lines);
pixels_per_line = dev->calib_pixels;
channels = dev->calib_channels;
@ -2182,8 +2181,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
dev->white_average_data = malloc (dev->average_size);
if (!dev->white_average_data)
{
DBG (DBG_error,
"genesys_dark_white_shading_calibration: failed to allocate average memory\n");
DBG (DBG_error, "%s: failed to allocate white average memory\n", __FUNCTION__);
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);
if (!dev->dark_average_data)
{
DBG (DBG_error,
"genesys_dark_white_shading_shading_calibration: failed to allocate average memory\n");
DBG (DBG_error, "%s: failed to allocate dark average memory\n", __FUNCTION__);
return SANE_STATUS_NO_MEM;
}
@ -2203,8 +2200,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
calibration_data = malloc (size);
if (!calibration_data)
{
DBG (DBG_error,
"genesys_dark_white_shading_calibration: failed to allocate calibration memory\n");
DBG (DBG_error, "%s: failed to allocate calibration memory\n", __FUNCTION__);
return SANE_STATUS_NO_MEM;
}
@ -2225,9 +2221,8 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
free (calibration_data);
DBG (DBG_error,
"genesys_dark_white_shading_calibration: failed to bulk write registers: %s\n",
sane_strstatus (status));
DBG (DBG_error, "%s: failed to bulk write registers: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
@ -2236,8 +2231,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
free (calibration_data);
DBG (DBG_error,
"genesys_dark_white_shading_calibration: Failed to begin scan: %s\n",
DBG (DBG_error, "%s: failed to begin scan: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
@ -2246,8 +2240,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
free (calibration_data);
DBG (DBG_error,
"genesys_dark_white_shading_calibration: Failed to read data: %s\n",
DBG (DBG_error, "%s: failed to read data: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
@ -2256,16 +2249,26 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
free (calibration_data);
DBG (DBG_error,
"genesys_dark_white_shading_calibration: Failed to end scan: %s\n",
DBG (DBG_error, "%s: Failed to end scan: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file ("black_white_shading.pnm", calibration_data,
16, channels, pixels_per_line,
dev->calib_lines);
{
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,
16, channels, pixels_per_line,
dev->calib_lines);
}
}
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;
DBG (DBG_info, "%s: pixels=%d, offset=%d\n", __FUNCTION__, pixels_per_line,
o);
DBG (DBG_info, "%s: pixels=%d, offset=%d\n", __FUNCTION__, pixels_per_line, o);
/* initialize result */
memset (shading_data, 0xff, words_per_color * 3 * 2);
@ -2455,10 +2458,10 @@ compute_averaged_planar (Genesys_Device * dev,
if ((dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE) &&
dev->settings.xres <= dev->sensor.optical_res / 2)
res *= 2; /* scanner is using half-ccd mode */
/*this should be evenly dividable */
/* this should be evenly dividable */
basepixels = dev->sensor.optical_res / res;
/* gl841 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */
/* gl841 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */
if (basepixels < 1)
avgpixels = 1;
else if (basepixels < 6)
@ -2478,7 +2481,6 @@ compute_averaged_planar (Genesys_Device * dev,
for (x = 0; x <= pixels_per_line - avgpixels; x += avgpixels)
{
if ((x + o) * 2 * 2 + 3 > words_per_color * 2)
break;
@ -2515,59 +2517,47 @@ compute_averaged_planar (Genesys_Device * dev,
65535 * (target_bright - target_dark))
val = 65535;
else
val =
(dk * target_bright - br * target_dark) / (target_bright -
target_dark);
{
val = (dk * target_bright - br * target_dark) / (target_bright - 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++)
{
shading_data[(x + o + i) * 2 * 2 +
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] = val & 0xff;
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 1] = val >> 8;
}
val = br - dk;
if (65535 * val > (target_bright - target_dark) * coeff)
val = (coeff * (target_bright - target_dark)) / val;
{
val = (coeff * (target_bright - target_dark)) / val;
}
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++)
{
shading_data[(x + o + i) * 2 * 2 +
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 + 2] = val & 0xff;
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 3] = val >> 8;
}
}
/*fill remaining channels*/
/* fill remaining channels */
for (j = channels; j < 3; j++)
{
for (i = 0; i < avgpixels; i++)
{
shading_data[(x + o + i) * 2 * 2 +
words_per_color * 2 * j] =
shading_data[(x + o + i) * 2 * 2 + words_per_color * 0];
shading_data[(x + o + i) * 2 * 2 +
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];
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j ] = shading_data[(x + o + i) * 2 * 2 ];
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 * 2 * j + 2] = shading_data[(x + o + i) * 2 * 2 + 2];
shading_data[(x + o + i) * 2 * 2 + words_per_color * 2 * j + 3] = shading_data[(x + o + i) * 2 * 2 + 3];
}
}
}
}
@ -2870,13 +2860,21 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
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;
/* allocate computed size */
shading_data = malloc (length);
if (!shading_data)
{
DBG (DBG_error,
"genesys_send_shading_coefficient: failed to allocate memory\n");
DBG (DBG_error, "%s: failed to allocate memory\n", __FUNCTION__);
return SANE_STATUS_NO_MEM;
}
memset (shading_data, 0, length);
@ -3040,8 +3038,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
shading_data = malloc (length);
if (!shading_data)
{
DBG (DBG_error,
"genesys_send_shading_coefficient: failed to allocate memory\n");
DBG (DBG_error, "%s: failed to allocate memory\n", __FUNCTION__);
return SANE_STATUS_NO_MEM;
}
memset (shading_data, 0, length);
@ -3057,7 +3054,6 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
target_code);
break;
case CCD_CANONLIDE35:
case CIS_CANONLIDE80:
compute_averaged_planar (dev,
shading_data,
pixels_per_line,
@ -3068,6 +3064,17 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
0xfa00,
0x0a00);
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:
compute_shifted_coefficients (dev,
shading_data,
@ -3081,23 +3088,21 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
256); /* patch_size: contigous extent */
break;
default:
DBG (DBG_error,
"genesys_send_shading_coefficient: sensor %d not supported\n",
dev->model->ccd_type);
DBG (DBG_error, "%s: sensor %d not supported\n", __FUNCTION__, dev->model->ccd_type);
return SANE_STATUS_UNSUPPORTED;
break;
}
/* do the actual write of shading calibration data to the scanner */
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);
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;
}

Wyświetl plik

@ -146,4 +146,7 @@ typedef struct Genesys_Scanner
SANE_Int bpp_list[5]; /**< */
} Genesys_Scanner;
#ifdef UNIT_TESTING
SANE_Status genesys_dark_white_shading_calibration (Genesys_Device * dev);
#endif
#endif /* not GENESYS_H */

Wyświetl plik

@ -305,11 +305,12 @@ static Genesys_Sensor Sensor[] = {
}
,
/* CANOLIDE35 */
{CCD_CANONLIDE35, 1200,
87, /*(black) */
{CCD_CANONLIDE35,
1200,
87, /* (black) */
87, /* (dummy) */
0, /* (startxoffset) */
10400, /*sensor_pixels */
10400, /* sensor_pixels */
210,
200,
{0x00, 0x00, 0x00, 0x00},
@ -760,10 +761,10 @@ static Genesys_Sensor Sensor[] = {
/* CANOLIDE80 */
{CIS_CANONLIDE80,
1200, /* real hardware limit is 2400 */
9*2,
9*2,
0,
10304, /* up to 5144, 5390, 10264, 20504, 21762 : capped by max exposure from logs */
20, /* black pixels */
6, /* expdummy */
31, /* CCD_start_xoffset 14=>3, 20=>2 */
10240, /* 10400, too wide=>10288 in shading data 10240~, 10208 too short for shading, max shading data = 10240 pixels, endpix-startpix=10208 */
230,
230,
{0x00, 0x05, 0x07, 0x09}, /* in fact ,maps to 0x70-0x73 for GL841 */
@ -1288,16 +1289,16 @@ static Genesys_Motor Motor[] = {
},},
{MOTOR_CANONLIDE80,
2400, /* 2400 ???? */
7200,
2, /* max step type */
9600, /* 7200 ???? */
1, /* max step type */
1, /* power mode count */
{
{ /* start speed, max end speed, step number */
/* 5144 = max pixels at 600 dpi */
/* 1288=(5144+8)*ydpi(=300)/base_dpi(=1200) , where 5152 is exposure */
/* 6440=9660/(1932/1288) */
{ 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 */
{ 6440, 1288, 60, 0.8 }, /* full step 9660 1932 32 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,
NULL,
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
{2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */
{ 1200, 600, 400, 300, 240, 200, 150, 75, 0}, /* possible x-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 color mode */
@ -2128,14 +2129,14 @@ static Genesys_Model canon_lide_80_model = {
GENESYS_GL841,
NULL,
{ 1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */
{2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */
{ 1200, 600, 400, 300, 240, 150, 100, 75, 0}, /* possible x-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 color mode */
SANE_FIX (6.5), /* Start of scan area in mm (x) */
SANE_FIX (7.9), /* Start of scan area in mm (y) */
SANE_FIX (218.0), /* Size of scan area in mm (x) */
SANE_FIX (0.42), /* Start of scan area in mm (x) 0.42 */
SANE_FIX (7.90), /* Start of scan area in mm (y) 7.90 */
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 (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_EMAIL_SW |
GENESYS_HAS_COPY_SW,
200,
280,
400
};

Wyświetl plik

@ -214,8 +214,8 @@ gl841_bulk_read_data (Genesys_Device * dev, uint8_t addr,
uint8_t * data, size_t len)
{
SANE_Status status;
size_t size;
uint8_t outdata[8];
size_t size, target;
uint8_t outdata[8], *buffer;
DBG (DBG_io, "gl841_bulk_read_data: requesting %lu bytes\n",
(u_long) len);
@ -254,12 +254,14 @@ gl841_bulk_read_data (Genesys_Device * dev, uint8_t addr,
return status;
}
while (len)
target = len;
buffer = data;
while (target)
{
if (len > BULKIN_MAXSIZE)
if (target > BULKIN_MAXSIZE)
size = BULKIN_MAXSIZE;
else
size = len;
size = target;
DBG (DBG_io2,
"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,
"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;
}
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;
}
@ -788,12 +794,12 @@ gl841_init_lide80 (Genesys_Device * dev)
uint8_t val;
int index=0;
INITREG (0x01, 0x02);
INITREG (0x01, 0x82); /* 0x02 = SHDAREA and no CISSET ! */
INITREG (0x02, 0x10);
INITREG (0x03, 0x50);
INITREG (0x04, 0x02);
INITREG (0x05, 0x4c);
INITREG (0x06, 0x38);
INITREG (0x05, 0x4c); /* 1200 DPI */
INITREG (0x06, 0x30); /* 0x38 scanmod=1, pwrbit, GAIN4 */
INITREG (0x07, 0x00);
INITREG (0x08, 0x00);
INITREG (0x09, 0x11);
@ -1975,8 +1981,11 @@ gl841_init_motor_regs_scan(Genesys_Device * dev,
&fast_slope_steps,
&fast_exposure,
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
2-feed mode */
@ -2428,19 +2437,9 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
r = sanei_genesys_get_address (reg, 0x29);
r->value = 255; /*<<<"magic" number, only suitable for cis*/
r = sanei_genesys_get_address (reg, 0x2c);
r->value = HIBYTE (dpiset);
r = sanei_genesys_get_address (reg, 0x2d);
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);
sanei_genesys_set_double(reg, REG_DPISET, dpiset);
sanei_genesys_set_double(reg, REG_STRPIXEL, start);
sanei_genesys_set_double(reg, REG_ENDPIXEL, end);
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
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->value = dev->sensor.dummy_pixel;
DBG (DBG_proc, "gl841_init_optical_regs_scan : completed. \n");
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -2704,10 +2703,6 @@ dummy \ scanned lines
scan_step_type = 1;
else
scan_step_type = 2;
if (dev->model->motor_type == MOTOR_CANONLIDE80 && yres>=600)
{
scan_step_type = 1;
}
/* exposure_time */
led_exposure = gl841_get_led_exposure(dev);
@ -2734,7 +2729,6 @@ dummy \ scanned lines
scan_power_mode++;
}
DBG (DBG_info, "gl841_init_scan_regs : exposure_time=%d pixels\n",
exposure_time);
@ -3096,10 +3090,6 @@ dummy \ scanned lines
scan_step_type = 1;
else
scan_step_type = 2;
if (dev->model->motor_type == MOTOR_CANONLIDE80 && yres>=600)
{
scan_step_type = 1;
}
led_exposure = gl841_get_led_exposure(dev);
@ -3126,8 +3116,7 @@ dummy \ scanned lines
scan_power_mode++;
}
DBG (DBG_info, "gl841_calculate_current_setup : exposure_time=%d pixels\n",
exposure_time);
DBG (DBG_info, "%s : exposure_time=%d pixels\n", __FUNCTION__, exposure_time);
/* scanned area must be enlarged by max color shift needed */
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.max_shift = max_shift + stagger;
DBG (DBG_proc, "gl841_calculate_current_setup: completed\n");
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -4254,8 +4243,7 @@ gl841_init_regs_for_coarse_calibration (Genesys_Device * dev)
uint8_t channels;
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 */
@ -4303,13 +4291,11 @@ gl841_init_regs_for_coarse_calibration (Genesys_Device * dev)
return status;
}
DBG (DBG_proc,
"gl841_init_register_for_coarse_calibration: completed\n");
/* if (DBG_LEVEL >= DBG_info)
sanei_gl841_print_registers (dev->calib_reg);*/
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -4320,14 +4306,30 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
{
SANE_Status status;
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;
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;
}
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_lines = dev->model->shading_lines;
@ -4336,7 +4338,7 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
dev->settings.xres,
ydpi,
0,
0,
starty,
(dev->sensor.sensor_pixels * dev->settings.xres) / dev->sensor.optical_res,
dev->calib_lines,
16,
@ -4344,14 +4346,8 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
dev->settings.color_filter,
SCAN_FLAG_DISABLE_SHADING |
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_USE_OPTICAL_RES
);
dev->calib_pixels = dev->current_setup.pixels;
SCAN_FLAG_USE_OPTICAL_RES);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -4360,20 +4356,18 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
return status;
}
dev->calib_pixels = dev->current_setup.pixels;
dev->scanhead_position_in_steps += dev->calib_lines;
status =
gl841_bulk_write_register (dev, dev->calib_reg, GENESYS_GL841_MAX_REGS);
status = gl841_bulk_write_register (dev, dev->calib_reg, GENESYS_GL841_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl841_init_registers_for_shading: failed to bulk write registers: %s\n",
DBG (DBG_error, "%s: failed to bulk write registers: %s\n", __FUNCTION__,
sane_strstatus (status));
return status;
}
DBG (DBG_proc, "gl841_init_regs_for_shading: completed\n");
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -4434,7 +4428,9 @@ gl841_init_regs_for_scan (Genesys_Device * dev)
move = 0;
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);
@ -5424,7 +5420,7 @@ gl841_coarse_gain_calibration (Genesys_Device * dev, int dpi)
}
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,
@ -6145,6 +6141,132 @@ gl841_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
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 */
static Genesys_Command_Set gl841_cmd_set = {
"gl841-generic", /* the name of this set */
@ -6198,7 +6320,7 @@ static Genesys_Command_Set gl841_cmd_set = {
gl841_is_compatible_calibration,
NULL,
NULL,
gl841_send_shading_data,
gl841_calculate_current_setup,
NULL
};

Wyświetl plik

@ -162,6 +162,11 @@
#define REG1E_LINESEL 0x0f
#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_MOTMFLG 0x02
#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_led_calibration (Genesys_Device * dev);
SANE_Status gl841_send_shading_data (Genesys_Device * dev, uint8_t * data, int size);
#endif