LiDE 200 almost OK

- 1200 dpi scans hang after calibration
- 4800 dpi shding data is incorrect
- move to scan area needs tuning
merge-requests/1/head
Stphane Voltz 2011-06-05 08:25:56 +02:00
rodzic 18beac8e63
commit c31eb26d1e
6 zmienionych plików z 135 dodań i 95 usunięć

Wyświetl plik

@ -3314,10 +3314,11 @@ genesys_restore_calibration (Genesys_Device * dev)
if (status == SANE_STATUS_GOOD)
{
memcpy (&dev->frontend, &cache->frontend, sizeof (dev->frontend));
/* don't restore the gamma fields */
memcpy (&dev->sensor, &cache->sensor,
offsetof (Genesys_Sensor, red_gamma));
/* we don't restore the gamma fields */
/* XXX STEF XXX
memcpy (&dev->sensor, &cache->sensor, offsetof (Genesys_Sensor, red_gamma));
*/
memcpy (dev->sensor.regs_0x10_0x1d, cache->sensor.regs_0x10_0x1d, 6);
free (dev->dark_average_data);
free (dev->white_average_data);
@ -3425,11 +3426,11 @@ genesys_save_calibration (Genesys_Device * dev)
}
else
{
cache = malloc (sizeof (*cache));
cache = malloc (sizeof (Genesys_Calibration_Cache));
if (!cache)
return SANE_STATUS_NO_MEM;
memset (cache, 0, sizeof (*cache));
memset (cache, 0, sizeof (Genesys_Calibration_Cache));
cache->next = dev->calibration_cache;
dev->calibration_cache = cache;
@ -5237,7 +5238,7 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination,
{
if (!(dev->model->flags & GENESYS_FLAG_SIS_SENSOR))
fprintf (rawfile,
"P%c\n%d %d\n%d\n",
"P%c\n%05d %05d\n%d\n",
dev->current_setup.channels == 1 ?
(dev->current_setup.depth == 1 ? '4' : '5') : '6',
dev->current_setup.pixels,
@ -5246,7 +5247,7 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination,
else
{
fprintf (rawfile,
"P5\n%d %d\n%d\n",
"P5\n%05d %05d\n%d\n",
(dev->sensor.sensor_pixels*3*dev->settings.xres)/dev->sensor.optical_res,
dev->current_setup.lines,
(1 << dev->current_setup.depth) - 1);
@ -6640,28 +6641,34 @@ probe_genesys_devices (void)
return status;
}
/* this should be changed if one of the substructures of
/**
* This should be changed if one of the substructures of
Genesys_Calibration_Cache change, but it must be changed if there are
changes that don't change size -- at least for now, as we store most
of Genesys_Calibration_Cache as is.
*/
#define CALIBRATION_VERSION 1
static void
read_calibration (Genesys_Device * dev)
/**
* reads previously cached calibration data
* from file
*/
SANE_Status
sanei_genesys_read_calibration (Genesys_Device * dev)
{
FILE *fp;
uint8_t vers = 0;
uint32_t size = 0;
struct Genesys_Calibration_Cache *cache;
SANE_Status status=SANE_STATUS_GOOD;
DBG (DBG_proc, "read_calibration: enter\n");
DBG (DBG_proc, "sanei_genesys_read_calibration: enter\n");
fp = fopen (dev->calib_file, "rb");
if (!fp)
{
DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file);
DBG (DBG_proc, "read_calibration: exit\n");
return;
DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n");
return SANE_STATUS_IO_ERROR;
}
/* these two checks ensure that most bad things cannot happen */
@ -6670,8 +6677,8 @@ read_calibration (Genesys_Device * dev)
{
DBG (DBG_info, "Calibration: Bad version\n");
fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n");
return;
DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n");
return SANE_STATUS_INVAL;
}
fread (&size, 4, 1, fp);
if (size != sizeof (struct Genesys_Calibration_Cache))
@ -6679,19 +6686,19 @@ read_calibration (Genesys_Device * dev)
DBG (DBG_info,
"Calibration: Size of calibration cache struct differs\n");
fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n");
return;
DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n");
return SANE_STATUS_INVAL;
}
while (!feof (fp))
while (!feof (fp) && status==SANE_STATUS_GOOD)
{
DBG (DBG_info, "read_calibration: reading one record\n");
DBG (DBG_info, "sanei_genesys_read_calibration: reading one record\n");
cache = (struct Genesys_Calibration_Cache *) malloc (sizeof (*cache));
if (!cache)
{
DBG (DBG_error,
"read_calibration: could not allocate cache struct\n");
"sanei_genesys_read_calibration: could not allocate cache struct\n");
break;
}
@ -6701,7 +6708,8 @@ read_calibration (Genesys_Device * dev)
if ((x) < 1) \
{ \
free(cache); \
DBG (DBG_warn, "read_calibration: partial calibration record\n"); \
DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n"); \
status=SANE_STATUS_EOF; \
break; \
} \
} while(0)
@ -6710,49 +6718,35 @@ read_calibration (Genesys_Device * dev)
if (fread (&cache->used_setup, sizeof (cache->used_setup), 1, fp) < 1)
{ /* eof is only detected here */
free (cache);
status=SANE_STATUS_GOOD;
break;
}
BILT1 (fread
(&cache->last_calibration, sizeof (cache->last_calibration), 1,
fp));
BILT1 (fread (&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 */
BILT1 (fread
(&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp));
BILT1 (fread
(&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/
sufficiently corrupted calibration file.
gl843 can do up to 0x5800 pixels. add some slack for the
dummy/blank pixel mess */
if (cache->average_size > 0x5800 * 2 * 3 * 2 + 0x100)
{
DBG (DBG_error, "read_calibration: bad size of calibration data\n");
free (cache);
break;
}
BILT1 (fread (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp));
BILT1 (fread (&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));
cache->white_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)
{
status=SANE_STATUS_NO_MEM;
FREE_IFNOT_NULL (cache->white_average_data);
FREE_IFNOT_NULL (cache->dark_average_data);
free (cache);
DBG (DBG_error,
"read_calibration: could not allocate space for average data\n");
"sanei_genesys_read_calibration: could not allocate space for average data\n");
break;
}
if (fread (cache->white_average_data, cache->average_size, 1, fp) < 1)
{
DBG (DBG_warn, "read_calibration: partial calibration record\n");
status=SANE_STATUS_EOF;
DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n");
free (cache->white_average_data);
free (cache->dark_average_data);
free (cache);
@ -6760,20 +6754,22 @@ read_calibration (Genesys_Device * dev)
}
if (fread (cache->dark_average_data, cache->average_size, 1, fp) < 1)
{
DBG (DBG_warn, "read_calibration: partial calibration record\n");
DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n");
free (cache->white_average_data);
free (cache->dark_average_data);
free (cache);
status=SANE_STATUS_EOF;
break;
}
#undef BILT1
DBG (DBG_info, "read_calibration: adding record to list\n");
DBG (DBG_info, "sanei_genesys_read_calibration: adding record to list\n");
cache->next = dev->calibration_cache;
dev->calibration_cache = cache;
}
fclose (fp);
DBG (DBG_proc, "read_calibration: exit\n");
DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n");
return status;
}
static void
@ -6783,10 +6779,12 @@ write_calibration (Genesys_Device * dev)
uint8_t vers = 0;
uint32_t size = 0;
struct Genesys_Calibration_Cache *cache;
DBGSTART;
fp = fopen (dev->calib_file, "wb");
if (!fp)
{
DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file);
DBG (DBG_info, "write_calibration: Cannot open %s for writing\n", dev->calib_file);
return;
}
@ -6798,18 +6796,18 @@ write_calibration (Genesys_Device * dev)
for (cache = dev->calibration_cache; cache; cache = cache->next)
{
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, fp);
fwrite (&cache->frontend, sizeof (cache->frontend), 1, fp);
/* the gamma (and later) fields are not stored */
fwrite (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp);
fwrite (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp);
fwrite (&cache->calib_channels, sizeof (cache->calib_channels), 1, fp);
fwrite (&cache->average_size, sizeof (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);
}
DBGCOMPLETED;
fclose (fp);
}
@ -7182,7 +7180,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
/* now open file, fetch calibration records */
read_calibration (s->dev);
sanei_genesys_read_calibration (s->dev);
DBG (DBG_proc, "sane_open: exit\n");
return SANE_STATUS_GOOD;

Wyświetl plik

@ -1565,7 +1565,7 @@ static Genesys_Model canon_lide_200_model = {
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW,
60,
40,
400
};

Wyświetl plik

@ -2753,13 +2753,6 @@ gl124_init_regs_for_scan (Genesys_Device * dev)
}
move=0;
}
else
{
if(channels==1)
{
move-=0;
}
}
DBG (DBG_info, "gl124_init_regs_for_scan: move=%f steps\n", move);
/* start */

Wyświetl plik

@ -869,6 +869,8 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
unsigned int min_restep = 0x20;
uint8_t val, effective;
int fast_step_type;
int acdcdis;
unsigned int ccdlmt,tgtime;
DBGSTART;
DBG (DBG_proc, "gl847_init_motor_regs_scan : scan_exposure_time=%d, "
@ -882,12 +884,8 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
/* get step multiplier */
factor = gl847_get_step_multiplier (reg);
/* we never use fast fed since we do manual feed for the scans */
use_fast_fed=0;
if(scan_yres>600 && feed_steps>900)
use_fast_fed=1;
/* we are doing custom feeding at high resolution */
if(scan_step_type>2)
use_fast_fed=0;
sanei_genesys_set_triple(reg, REG_LINCNT, scan_lines);
DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, scan_lines);
@ -905,8 +903,12 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
r->value |= REG02_AGOHOME;
if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE || scan_yres>=2400)
r->value |= REG02_ACDCDIS;
acdcdis=0;
if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
{
r->value |= REG02_ACDCDIS;
acdcdis=1;
}
/* scan and backtracking slope table */
slow_time=sanei_genesys_slope_table(scan_table,
@ -945,13 +947,17 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
/* substract acceleration distance from feedl XXX STEF XXX : 2 different step type */
feedl=feed_steps;
feedl<<=fast_step_type;
dist = scan_steps;
if (use_fast_fed)
{
feedl<<=fast_step_type;
dist += fast_steps*2;
}
else
{
feedl<<=scan_step_type;
}
dist *=factor;
DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
@ -964,14 +970,11 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
sanei_genesys_set_triple(reg,REG_FEEDL,feedl);
DBG (DBG_io ,"%s: feedl=%d\n",__FUNCTION__,feedl);
sanei_genesys_calculate_zmode2 (use_fast_fed,
scan_exposure_time,
scan_table,
scan_steps*factor,
feedl,
fast_steps*factor,
&z1,
&z2);
r = sanei_genesys_get_address (reg, REG0C);
ccdlmt=(r->value & REG0C_CCDLMT)+1;
r = sanei_genesys_get_address (reg, REG1C);
tgtime=1<<(r->value & REG1C_TGTIME);
/* hi res motor speed GPIO */
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
@ -1007,6 +1010,15 @@ gl847_init_motor_regs_scan (Genesys_Device * dev,
r = sanei_genesys_get_address (reg, REG_BWDSTEP);
r->value = min_restep;
sanei_genesys_calculate_zmode2(use_fast_fed,
scan_exposure_time*ccdlmt*tgtime,
scan_table,
scan_steps*factor,
feedl,
min_restep*factor,
&z1,
&z2);
DBG (DBG_info, "gl847_init_motor_regs_scan: z1 = %d\n", z1);
r = sanei_genesys_get_address (reg, REG60);
r->value = ((z1 >> 16) & REG60_Z1MOD) | (scan_step_type << REG60S_STEPSEL);
@ -1348,7 +1360,8 @@ gl847_init_scan_regs (Genesys_Device * dev,
float lines,
unsigned int depth,
unsigned int channels,
int color_filter, unsigned int flags)
int color_filter,
unsigned int flags)
{
int used_res;
int start, used_pixels;
@ -1381,6 +1394,23 @@ gl847_init_scan_regs (Genesys_Device * dev,
"Flags : %x\n\n",
xres, yres, lines, pixels, startx, starty, depth, channels, flags);
#ifdef SANE_DEBUG_LOG_RAW_DATA
/* for raw data debug, we know here the exact raw image
* attributes */
if (rawfile == NULL && DBG_LEVEL >= DBG_data)
{
if (rawfile != NULL)
{
rewind(rawfile);
fprintf (rawfile,
"P5\n%05d %05d\n%d\n",
pixels*channel,
lines,
(1 << depth) - 1);
}
}
#endif
/* we may have 2 domains for ccd: xres below or above half ccd max dpi */
if (dev->sensor.optical_res < 2 * xres ||
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
@ -2112,7 +2142,6 @@ gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_FEEDING |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
SCAN_FLAG_IGNORE_LINE_DISTANCE);
sanei_genesys_set_double(local_reg,REG_EXPR,0);
sanei_genesys_set_double(local_reg,REG_EXPG,0);
@ -2206,8 +2235,7 @@ gl847_search_start_position (Genesys_Device * dev)
600, dev->model->search_lines, 8, 1, 1, /*green */
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE);
SCAN_FLAG_IGNORE_LINE_DISTANCE);
/* send to scanner */
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
@ -2435,7 +2463,7 @@ gl847_feed (Genesys_Device * dev, unsigned int steps)
memset (local_reg, 0, sizeof (local_reg));
memcpy (local_reg, dev->reg, GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
resolution=300;
resolution=200;
gl847_init_scan_regs (dev,
local_reg,
resolution,
@ -2450,7 +2478,6 @@ gl847_feed (Genesys_Device * dev, unsigned int steps)
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_FEEDING |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
SCAN_FLAG_IGNORE_LINE_DISTANCE);
sanei_genesys_set_triple(local_reg,REG_EXPR,0);
sanei_genesys_set_triple(local_reg,REG_EXPG,0);
@ -2549,11 +2576,11 @@ gl847_init_regs_for_scan (Genesys_Device * dev)
move = SANE_UNFIX (dev->model->y_offset);
move += dev->settings.tl_y;
move = (move * move_dpi) / MM_PER_INCH;
DBG (DBG_info, "gl847_init_regs_for_scan: move=%f steps\n", move);
DBG (DBG_info, "%s: move=%f steps\n",__FUNCTION__, move);
/* at high res we do fast move to scan area */
if(dev->settings.xres>1200 && move > 900)
if(dev->settings.yres>=1200)
{
move -= 90; /* [90,80] */
status = gl847_feed (dev, move);
if (status != SANE_STATUS_GOOD)
{
@ -2562,6 +2589,7 @@ gl847_init_regs_for_scan (Genesys_Device * dev)
}
move=0;
}
DBG (DBG_info, "%s: move=%f steps\n", __FUNCTION__, move);
/* clear scancnt and fedcnt */
val = REG0D_CLRLNCNT;
@ -2579,6 +2607,9 @@ gl847_init_regs_for_scan (Genesys_Device * dev)
/* emulated lineart from gray data is required for now */
flags |= SCAN_FLAG_DYNAMIC_LINEART;
/* backtracking isn't handled well, so don't enable it */
flags |= SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE;
status = gl847_init_scan_regs (dev,
dev->reg,
dev->settings.xres,
@ -2594,7 +2625,7 @@ gl847_init_regs_for_scan (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
return status;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -152,6 +152,9 @@
#define REG0B_48MHZ 0x60
#define REG0B_60MHZ 0x80
#define REG0C 0x0c
#define REG0C_CCDLMT 0x0f
#define REG0D 0x0d
#define REG0D_FULLSTP 0x10
#define REG0D_SEND 0x80
@ -192,6 +195,7 @@
#define REG1A_CK3INV 0x04
#define REG1A_LINECLP 0x02
#define REG1C 0x1c
#define REG1C_TGTIME 0x07
#define REG1D_CK4LOW 0x80

Wyświetl plik

@ -1009,7 +1009,7 @@ SANE_Status
sanei_genesys_write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * data)
{
uint8_t outdata[8];
size_t written;
size_t written,blksize;
SANE_Status status = SANE_STATUS_GOOD;
int i;
char msg[60]="AHB=";
@ -1045,14 +1045,28 @@ sanei_genesys_write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * da
}
/* write actual data */
written = size;
status = sanei_usb_write_bulk (dn, data, &written);
if (status != SANE_STATUS_GOOD)
written = 0;
do
{
DBG (DBG_error, "sanei_genesys_write_ahb: failed while writing bulk data: %s\n",
sane_strstatus (status));
return status;
if (size - written > BULKOUT_MAXSIZE)
{
blksize = BULKOUT_MAXSIZE;
}
else
{
blksize = size - written;
}
status = sanei_usb_write_bulk (dn, data + written, &blksize);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"sanei_genesys_write_ahb: failed while writing bulk data: %s\n",
sane_strstatus (status));
return status;
}
written += blksize;
}
while (written < size);
return status;
}