calibration tuning for LiDE35 and LiDE80

merge-requests/1/head
Stphane Voltz 2013-12-23 06:17:15 +01:00
rodzic f5f88cefde
commit a9dc869717
4 zmienionych plików z 78 dodań i 55 usunięć

Wyświetl plik

@ -1,3 +1,8 @@
2013-12-23 Stéphane Voltz <stef.dev@free.fr>
* backend/genesys_devices.c backend/genesys.c backend/genesys_low.h
backend/genesys_gl841.[ch]: color calibration improvement for LiDE80,
working LEDADD for gl841 CIS scanners
2013-12-16 Rolf Bensch <rolf at bensch hyphen online dot de>
* backend/pixma_imageclass.c, doc/descriptions/pixma.desc,
doc/sane-pixma.man:

Wyświetl plik

@ -58,7 +58,7 @@
* SANE backend for Genesys Logic GL646/GL841/GL842/GL843/GL846/GL847/GL124 based scanners
*/
#define BUILD 2501
#define BUILD 2502
#define BACKEND_NAME genesys
#include "genesys.h"
@ -3078,7 +3078,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
channels,
4,
coeff,
0xfa00,
0xe000,
0x0a00);
break;
case CIS_CANONLIDE80:
@ -3089,8 +3089,8 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
channels,
0,
coeff,
0xfa00,
0x0a00);
0xd000,
0x0800);
break;
case CCD_PLUSTEK_3600:
compute_shifted_coefficients (dev,

Wyświetl plik

@ -311,8 +311,8 @@ static Genesys_Sensor Sensor[] = {
87, /* (dummy) */
0, /* (startxoffset) */
10400, /* sensor_pixels */
210,
200,
0,
0,
{0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x50,
0x00, 0x00, 0x00, 0x02 /* TODO(these do no harm, but may be neccessery for CCD) */
@ -766,14 +766,14 @@ static Genesys_Sensor Sensor[] = {
/* tuned to give 3*8 multiple startx coordinate during shading calibration */
34, /* 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,
150,
150,
{0x00, 0x05, 0x07, 0x09}, /* in fact ,maps to 0x70-0x73 for GL841 */
/* [0x10-0x15] values are initial led exposure values */
/* 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d*/
{0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04},
{0x10, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04},
{0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x29, 0x69, 0x55, 0x00, 0x00, 0x20, 0x41} ,
{0.8, 0.8, 0.8},
{1.0, 1.0, 1.0},
{NULL, NULL, NULL}}
};
@ -2175,7 +2175,7 @@ static Genesys_Model canon_lide_80_model = {
GENESYS_HAS_FILE_SW |
GENESYS_HAS_EMAIL_SW |
GENESYS_HAS_COPY_SW,
240, /* 280 @2400 */
160, /* 280 @2400 */
400
};

Wyświetl plik

@ -799,7 +799,7 @@ gl841_init_lide80 (Genesys_Device * dev)
INITREG (0x03, 0x50);
INITREG (0x04, 0x02);
INITREG (0x05, 0x4c); /* 1200 DPI */
INITREG (0x06, 0x30); /* 0x38 scanmod=1, pwrbit, GAIN4 */
INITREG (0x06, 0x38); /* 0x38 scanmod=1, pwrbit, GAIN4 */
INITREG (0x07, 0x00);
INITREG (0x08, 0x00);
INITREG (0x09, 0x11);
@ -4356,7 +4356,7 @@ gl841_init_regs_for_shading (Genesys_Device * dev)
{
ydpi = gl841_get_dpihw(dev);
/* get over extra dark area for this model */
starty = 100;
starty = 140;
}
dev->calib_channels = 3;
@ -4588,7 +4588,7 @@ gl841_led_calibration (Genesys_Device * dev)
int avg[3], avga, avge;
int turn;
char fn[20];
uint16_t expr, expg, expb;
uint16_t exp[3], target;
Genesys_Register_Set *r;
int move;
@ -4662,23 +4662,24 @@ gl841_led_calibration (Genesys_Device * dev)
adjust exposure times
*/
expr = (dev->sensor.regs_0x10_0x1d[0] << 8) | dev->sensor.regs_0x10_0x1d[1];
expg = (dev->sensor.regs_0x10_0x1d[2] << 8) | dev->sensor.regs_0x10_0x1d[3];
expb = (dev->sensor.regs_0x10_0x1d[4] << 8) | dev->sensor.regs_0x10_0x1d[5];
exp[0] = (dev->sensor.regs_0x10_0x1d[0] << 8) | dev->sensor.regs_0x10_0x1d[1];
exp[1] = (dev->sensor.regs_0x10_0x1d[2] << 8) | dev->sensor.regs_0x10_0x1d[3];
exp[2] = (dev->sensor.regs_0x10_0x1d[4] << 8) | dev->sensor.regs_0x10_0x1d[5];
turn = 0;
/* max exposure is set to ~2 time initial average
* exposure, or 2 time last calibration exposure */
max_exposure=((expr+expg+expb)/3)*2;
max_exposure=((exp[0]+exp[1]+exp[2])/3)*2;
target=dev->sensor.gain_white_ref*256;
do {
dev->sensor.regs_0x10_0x1d[0] = (expr >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[1] = expr & 0xff;
dev->sensor.regs_0x10_0x1d[2] = (expg >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[3] = expg & 0xff;
dev->sensor.regs_0x10_0x1d[4] = (expb >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[5] = expb & 0xff;
dev->sensor.regs_0x10_0x1d[0] = (exp[0] >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[1] = exp[0] & 0xff;
dev->sensor.regs_0x10_0x1d[2] = (exp[1] >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[3] = exp[1] & 0xff;
dev->sensor.regs_0x10_0x1d[4] = (exp[2] >> 8) & 0xff;
dev->sensor.regs_0x10_0x1d[5] = exp[2] & 0xff;
r = &(dev->calib_reg[reg_0x10]);
for (i = 0; i < 6; i++, r++) {
@ -4686,8 +4687,7 @@ gl841_led_calibration (Genesys_Device * dev)
RIE (sanei_genesys_write_register (dev, 0x10+i, dev->sensor.regs_0x10_0x1d[i]));
}
RIE (gl841_bulk_write_register
(dev, dev->calib_reg, GENESYS_GL841_MAX_REGS));
RIE (gl841_bulk_write_register (dev, dev->calib_reg, GENESYS_GL841_MAX_REGS));
DBG (DBG_info, "%s: starting line reading\n", __FUNCTION__);
RIE (gl841_begin_scan (dev, dev->calib_reg, SANE_TRUE));
@ -4741,34 +4741,51 @@ gl841_led_calibration (Genesys_Device * dev)
{
acceptable = SANE_FALSE;
}
if (!acceptable)
/* for scanners using target value */
if(target>0)
{
avga = (avg[0]+avg[1]+avg[2])/3;
expr = (expr * avga) / avg[0];
expg = (expg * avga) / avg[1];
expb = (expb * avga) / avg[2];
/*
keep the resulting exposures below this value.
too long exposure drives the ccd into saturation.
we may fix this by relying on the fact that
we get a striped scan without shading, by means of
statistical calculation
*/
avge = (expr + expg + expb) / 3;
acceptable = SANE_TRUE;
for(i=0;i<3;i++)
{
/* we accept +- 2% delta from target */
if(abs(avg[i]-target)>target/50)
{
exp[i]=(exp[i]*target)/avg[i];
acceptable = SANE_FALSE;
}
}
}
else
{
if (!acceptable)
{
avga = (avg[0]+avg[1]+avg[2])/3;
exp[0] = (exp[0] * avga) / avg[0];
exp[1] = (exp[1] * avga) / avg[1];
exp[2] = (exp[2] * avga) / avg[2];
/*
keep the resulting exposures below this value.
too long exposure drives the ccd into saturation.
we may fix this by relying on the fact that
we get a striped scan without shading, by means of
statistical calculation
*/
avge = (exp[0] + exp[1] + exp[2]) / 3;
if (avge > max_exposure) {
expr = (expr * max_exposure) / avge;
expg = (expg * max_exposure) / avge;
expb = (expb * max_exposure) / avge;
}
if (avge < min_exposure) {
expr = (expr * min_exposure) / avge;
expg = (expg * min_exposure) / avge;
expb = (expb * min_exposure) / avge;
}
if (avge > max_exposure) {
exp[0] = (exp[0] * max_exposure) / avge;
exp[1] = (exp[1] * max_exposure) / avge;
exp[2] = (exp[2] * max_exposure) / avge;
}
if (avge < min_exposure) {
exp[0] = (exp[0] * min_exposure) / avge;
exp[1] = (exp[1] * min_exposure) / avge;
exp[2] = (exp[2] * min_exposure) / avge;
}
}
}
}
RIE (gl841_stop_action (dev));
@ -4776,7 +4793,7 @@ gl841_led_calibration (Genesys_Device * dev)
} while (!acceptable && turn < 100);
DBG(DBG_info,"%s: acceptable exposure: %d,%d,%d\n", __FUNCTION__, expr,expg,expb);
DBG(DBG_info,"%s: acceptable exposure: %d,%d,%d\n", __FUNCTION__, exp[0],exp[1],exp[2]);
/* cleanup before return */
free (line);
@ -4833,9 +4850,7 @@ ad_fe_offset_calibration (Genesys_Device * dev)
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_USE_OPTICAL_RES |
SCAN_FLAG_DISABLE_LAMP
);
SCAN_FLAG_USE_OPTICAL_RES);
if (status != SANE_STATUS_GOOD)
{
@ -4904,6 +4919,9 @@ ad_fe_offset_calibration (Genesys_Device * dev)
turn++;
} while ((top-bottom)>1 && turn < 100);
dev->frontend.offset[0]=0;
dev->frontend.offset[1]=0;
dev->frontend.offset[2]=0;
free(line);
DBG (DBG_info, "%s: offset=(%d,%d,%d)\n", __FUNCTION__,
dev->frontend.offset[0],