kopia lustrzana https://gitlab.com/sane-project/backends
calibration tuning for LiDE35 and LiDE80
rodzic
f5f88cefde
commit
a9dc869717
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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],
|
||||
|
|
Ładowanie…
Reference in New Issue