* backend/genesys_devices.c: fixed gamma settings(1.0 now)

* backend/genesys.c backend/genesys_gl841.c: improved calibration for dark
  shades
merge-requests/1/head
Pierre Willenbrock 2006-12-02 21:57:08 +00:00
rodzic 735130b0ff
commit dba2f29195
4 zmienionych plików z 69 dodań i 19 usunięć

Wyświetl plik

@ -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.

Wyświetl plik

@ -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;

Wyświetl plik

@ -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}
};

Wyświetl plik

@ -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];
}