kopia lustrzana https://gitlab.com/sane-project/backends
* backend/genesys_devices.c: fixed gamma settings(1.0 now)
* backend/genesys.c backend/genesys_gl841.c: improved calibration for dark shadesmerge-requests/1/head
rodzic
735130b0ff
commit
dba2f29195
|
@ -1,3 +1,9 @@
|
|||
2006-12-02 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
* backend/genesys_devices.c: fixed gamma settings(1.0 now)
|
||||
* backend/genesys.c backend/genesys_gl841.c: improved calibration
|
||||
for dark shades
|
||||
|
||||
2006-12-02 Alessandro Zummo <a.zummo@towertech.it>
|
||||
|
||||
* Added missing bits for epson2 driver.
|
||||
|
|
|
@ -2726,6 +2726,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
|||
int x, j, o;
|
||||
unsigned int i;
|
||||
unsigned int coeff, target_code, val, avgpixels, dk, words_per_color = 0;
|
||||
unsigned int target_dark, target_bright, br;
|
||||
|
||||
DBG (DBG_proc, "genesys_send_shading_coefficient\n");
|
||||
|
||||
|
@ -2917,7 +2918,8 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
|||
}
|
||||
break;
|
||||
case CCD_CANONLIDE35:
|
||||
target_code = 0xfa00;
|
||||
target_bright = 0xfa00;
|
||||
target_dark = 0xa00;
|
||||
o = 4;/*first four pixels are ignored*/
|
||||
memset(shading_data, 0xff, words_per_color * 3);
|
||||
|
||||
|
@ -2931,6 +2933,22 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
|||
another one: the dark/white shading is actually performed _after_ reducing
|
||||
resolution via averaging. only dark/white shading data for what would be
|
||||
first pixel at full resolution is used.
|
||||
*/
|
||||
/*
|
||||
scanner raw input to output value calculation:
|
||||
o=(i-off)*(gain/coeff)
|
||||
|
||||
from datasheet:
|
||||
off=dark_average
|
||||
gain=coeff*bright_target/(bright_average-dark_average)
|
||||
works for dark_target==0
|
||||
|
||||
what we want is these:
|
||||
bright_target=(bright_average-off)*(gain/coeff)
|
||||
dark_target=(dark_average-off)*(gain/coeff)
|
||||
leading to
|
||||
off = (dark_average*bright_target - bright_average*dark_target)/(bright_target - dark_target)
|
||||
gain = (bright_target - dark_target)/(bright_average - dark_average)*coeff
|
||||
*/
|
||||
/*this should be evenly dividable*/
|
||||
avgpixels = dev->sensor.optical_res/genesys_dpiset(dev->calib_reg);
|
||||
|
@ -2946,8 +2964,21 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
|||
for ( j = 0; j < channels; j++) {
|
||||
|
||||
/* dark data */
|
||||
val = dev->dark_average_data[(x + pixels_per_line * j) * 2] |
|
||||
dk = dev->dark_average_data[(x + pixels_per_line * j) * 2] |
|
||||
(dev->dark_average_data[(x + pixels_per_line * j) * 2 + 1] << 8);
|
||||
|
||||
/* white data */
|
||||
br = (dev->white_average_data[(x + pixels_per_line * j) * 2]
|
||||
| (dev->white_average_data[(x + pixels_per_line * j) * 2 + 1] << 8));
|
||||
|
||||
if (br*target_dark > dk*target_bright)
|
||||
val = 0;
|
||||
else if (dk*target_bright - br*target_dark > 65535 * (target_bright - target_dark))
|
||||
val = 65535;
|
||||
else
|
||||
val = (dk*target_bright - br*target_dark)/(target_bright - target_dark);
|
||||
|
||||
|
||||
/*fill all pixels, even if only the first one is relevant*/
|
||||
for (i = 0; i < avgpixels; i++) {
|
||||
shading_data[
|
||||
|
@ -2958,16 +2989,10 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
|
|||
] = val >> 8;
|
||||
}
|
||||
|
||||
dk = val;
|
||||
val = br - dk;
|
||||
|
||||
/* white data */
|
||||
val = (dev->white_average_data[(x + pixels_per_line * j) * 2]
|
||||
| (dev->white_average_data[(x + pixels_per_line * j) * 2 + 1] << 8));
|
||||
|
||||
val -= dk;
|
||||
|
||||
if (65535 * val > target_code * coeff)
|
||||
val = (coeff * target_code) / val;
|
||||
if (65535 * val > (target_bright - target_dark) * coeff)
|
||||
val = (coeff * (target_bright - target_dark)) / val;
|
||||
else
|
||||
val = 65535;
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ static Genesys_Sensor Sensor[] = {
|
|||
0x00, 0x00, 0x00, 0x00 /*TODO (these do no harm, but may be neccessery for CCD)*/
|
||||
}
|
||||
,
|
||||
0.45, 0.45, 0.45,
|
||||
1.0, 1.0, 1.0,
|
||||
NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -4362,6 +4362,7 @@ gl841_offset_calibration (Genesys_Device * dev)
|
|||
int turn;
|
||||
char fn[20];
|
||||
SANE_Bool acceptable = SANE_FALSE;
|
||||
int mintgt = 0x600;
|
||||
|
||||
DBG (DBG_proc, "gl841_offset_calibration\n");
|
||||
|
||||
|
@ -4492,9 +4493,9 @@ gl841_offset_calibration (Genesys_Device * dev)
|
|||
val =
|
||||
first_line[i * 2 * channels + 2 * j + 1] * 256 +
|
||||
first_line[i * 2 * channels + 2 * j];
|
||||
if (val == 0)
|
||||
if (val < 10)
|
||||
cmin[j]++;
|
||||
if (val == 65535)
|
||||
if (val > 65525)
|
||||
cmax[j]++;
|
||||
}
|
||||
|
||||
|
@ -4578,7 +4579,7 @@ gl841_offset_calibration (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
DBG (DBG_info,
|
||||
"gl841_offset_calibration: starting first line reading\n");
|
||||
"gl841_offset_calibration: starting second line reading\n");
|
||||
RIE (gl841_begin_scan (dev, dev->calib_reg, SANE_TRUE));
|
||||
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
|
||||
|
||||
|
@ -4608,9 +4609,9 @@ gl841_offset_calibration (Genesys_Device * dev)
|
|||
val =
|
||||
second_line[i * 2 * channels + 2 * j + 1] * 256 +
|
||||
second_line[i * 2 * channels + 2 * j];
|
||||
if (val == 0)
|
||||
if (val < 10)
|
||||
cmin[j]++;
|
||||
if (val == 65535)
|
||||
if (val > 65525)
|
||||
cmax[j]++;
|
||||
}
|
||||
|
||||
|
@ -4676,17 +4677,35 @@ gl841_offset_calibration (Genesys_Device * dev)
|
|||
DBG(DBG_info,"gl841_offset_calibration: second set: %d/%d,%d/%d,%d/%d\n",
|
||||
off2[0],min2[0],off2[1],min2[1],off2[2],min2[2]);
|
||||
|
||||
/*
|
||||
calculate offset for each channel
|
||||
based on minimal pixel value min1 at offset off1 and minimal pixel value min2
|
||||
at offset off2
|
||||
|
||||
to get min at off, values are linearly interpolated:
|
||||
min=real+off*fact
|
||||
min1=real+off1*fact
|
||||
min2=real+off2*fact
|
||||
|
||||
fact=(min1-min2)/(off1-off2)
|
||||
real=min1-off1*(min1-min2)/(off1-off2)
|
||||
|
||||
off=(min-min1+off1*(min1-min2)/(off1-off2))/((min1-min2)/(off1-off2))
|
||||
|
||||
off=(min*(off1-off2)+min1*off2-off1*min2)/(min1-min2)
|
||||
|
||||
*/
|
||||
for (j = 0; j < channels; j++)
|
||||
{
|
||||
if (min2[j]-min1[j] == 0) {
|
||||
/*TODO: try to avoid this*/
|
||||
DBG(DBG_warn,"gl841_offset_calibration: difference too small\n");
|
||||
if (min1[j] * off2[j] - min2[j] * off1[j] >= 0)
|
||||
if (mintgt * (off1[j] - off2[j]) + min1[j] * off2[j] - min2[j] * off1[j] >= 0)
|
||||
off[j] = 0x0000;
|
||||
else
|
||||
off[j] = 0xffff;
|
||||
} else
|
||||
off[j] = -(min1[j] * off2[j] - min2[j] * off1[j])/(min2[j]-min1[j]);
|
||||
off[j] = -(mintgt * (off1[j] - off2[j]) + min2[j] * off1[j] - min1[j] * off2[j])/(min2[j]-min1[j]);
|
||||
dev->frontend.offset[j] = off[j];
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue