Merge branch 'genesys-output-pixel-offset' into 'master'

genesys: Allow to specify output pixel offset within model configuration

See merge request sane-project/backends!403
merge-requests/213/head^2
Povilas Kanapickas 2020-04-13 14:04:43 +00:00
commit 0932b751e0
9 zmienionych plików z 355 dodań i 387 usunięć

Wyświetl plik

@ -2838,33 +2838,30 @@ void CommandSetGl841::send_shading_data(Genesys_Device* dev, const Genesys_Senso
{
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size);
uint32_t length, x, pixels, i;
std::uint16_t beginpixel;
uint8_t *ptr,*src;
/* old method if no SHDAREA */
if ((dev->reg.find_reg(0x01).value & REG_0x01_SHDAREA) == 0) {
// Note that this requires the sensor pixel offset to be exactly the same as to start
// reading from dummy_pixel + 1 position.
dev->interface->write_buffer(0x3c, 0x0000, data, size);
return;
}
/* data is whole line, we extract only the part for the scanned area */
length = static_cast<std::uint32_t>(size / 3);
unsigned strpixel = dev->session.pixel_startx;
unsigned endpixel = dev->session.pixel_endx;
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2; /* 2 words of 2 bytes */
endpixel*=2*2;
pixels=endpixel-strpixel;
// turn pixel value into bytes 2x16 bits words
pixels = dev->session.pixel_endx - dev->session.pixel_startx;
pixels *= 4;
/* shading pixel begin is start pixel minus start pixel during shading
* calibration. Currently only cases handled are full and half ccd resolution.
*/
beginpixel = sensor.ccd_start_xoffset / dev->session.ccd_size_divisor;
beginpixel += sensor.dummy_pixel + 1;
DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel);
beginpixel = (strpixel - beginpixel * 2 * 2) / sensor.shading_factor;
DBG(DBG_io2, "%s: BEGIN PIXEL=%d\n", __func__, beginpixel/4);
// shading pixel begin is start pixel minus start pixel during shading
// calibration. Currently only cases handled are full and half ccd resolution.
unsigned beginpixel = dev->session.params.startx * dev->session.optical_resolution /
dev->session.params.xres;
DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel);
beginpixel *= 4;
beginpixel /= sensor.shading_factor;
dev->interface->record_key_value("shading_offset", std::to_string(beginpixel));
dev->interface->record_key_value("shading_pixels", std::to_string(pixels));
@ -2888,7 +2885,7 @@ void CommandSetGl841::send_shading_data(Genesys_Device* dev, const Genesys_Senso
for(x=0;x<pixels;x+=4)
{
/* coefficient source */
src=data+x+beginpixel+i*length;
src = data + x + beginpixel + i * length;
ptr[0]=src[0];
ptr[1]=src[1];
ptr[2]=src[2];

Wyświetl plik

@ -1969,39 +1969,23 @@ void CommandSetGl843::send_shading_data(Genesys_Device* dev, const Genesys_Senso
uint8_t* data, int size) const
{
DBG_HELPER(dbg);
uint32_t final_size, length, i;
uint32_t final_size, i;
uint8_t *buffer;
int count,offset;
uint16_t strpixel, endpixel, startx;
int count;
unsigned offset = 0;
unsigned length = size;
offset=0;
length=size;
if (dev->reg.get8(REG_0x01) & REG_0x01_SHDAREA) {
/* recompute STRPIXEL used shading calibration so we can
* compute offset within data for SHDAREA case */
offset = dev->session.params.startx * sensor.shading_resolution /
dev->session.params.xres;
// FIXME: the following is likely incorrect
// start coordinate in optical dpi coordinates
startx = sensor.dummy_pixel;
startx = dev->session.pixel_count_ratio.apply(startx);
length = dev->session.output_pixels * sensor.shading_resolution /
dev->session.params.xres;
/* current scan coordinates */
strpixel = dev->session.pixel_startx;
endpixel = dev->session.pixel_endx;
if (dev->model->model_id == ModelId::CANON_4400F ||
dev->model->model_id == ModelId::CANON_8600F)
{
int half_ccd_factor = dev->session.optical_resolution / sensor.shading_resolution;
strpixel = dev->session.pixel_count_ratio.apply(strpixel / half_ccd_factor);
endpixel = dev->session.pixel_count_ratio.apply(endpixel / half_ccd_factor);
}
/* 16 bit words, 2 words per color, 3 color channels */
offset=(strpixel-startx)*2*2*3;
length=(endpixel-strpixel)*2*2*3;
DBG(DBG_info, "%s: STRPIXEL=%d, ENDPIXEL=%d, startx=%d\n", __func__, strpixel, endpixel,
startx);
// 16 bit words, 2 words per color, 3 color channels
length *= 2 * 2 * 3;
offset *= 2 * 2 * 3;
}
dev->interface->record_key_value("shading_offset", std::to_string(offset));

Wyświetl plik

@ -1012,29 +1012,21 @@ void CommandSetGl846::send_shading_data(Genesys_Device* dev, const Genesys_Senso
uint8_t* data, int size) const
{
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size);
std::uint32_t addr, length, i, pixels;
std::uint32_t addr, i;
uint8_t val,*ptr,*src;
/* shading data is plit in 3 (up to 5 with IR) areas
write(0x10014000,0x00000dd8)
URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x....
write(0x1003e000,0x00000dd8)
write(0x10068000,0x00000dd8)
*/
length = static_cast<uint32_t>(size / 3);
unsigned strpixel = dev->session.pixel_startx;
unsigned endpixel = dev->session.pixel_endx;
unsigned length = static_cast<unsigned>(size / 3);
pixels=endpixel-strpixel;
// we're using SHDAREA, thus we only need to upload part of the line
unsigned offset = dev->session.pixel_count_ratio.apply(
dev->session.params.startx * sensor.optical_res / dev->session.params.xres);
unsigned pixels = dev->session.pixel_count_ratio.apply(dev->session.optical_pixels_raw);
/* since we're using SHDAREA, substract startx coordinate from shading */
strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res;
// turn pixel value into bytes 2x16 bits words
offset *= 2 * 2;
pixels *= 2 * 2;
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2;
pixels*=2*2;
dev->interface->record_key_value("shading_offset", std::to_string(strpixel));
dev->interface->record_key_value("shading_offset", std::to_string(offset));
dev->interface->record_key_value("shading_pixels", std::to_string(pixels));
dev->interface->record_key_value("shading_length", std::to_string(length));
dev->interface->record_key_value("shading_factor", std::to_string(sensor.shading_factor));
@ -1055,8 +1047,8 @@ void CommandSetGl846::send_shading_data(Genesys_Device* dev, const Genesys_Senso
/* iterate on both sensor segment */
for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) {
/* coefficient source */
src=(data+strpixel+i*length)+x;
// coefficient source
src = (data + offset + i * length) + x;
/* coefficient copy */
ptr[0]=src[0];

Wyświetl plik

@ -880,29 +880,21 @@ void CommandSetGl847::send_shading_data(Genesys_Device* dev, const Genesys_Senso
uint8_t* data, int size) const
{
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size);
std::uint32_t addr, length, i, pixels;
std::uint32_t addr, i;
uint8_t val,*ptr,*src;
/* shading data is plit in 3 (up to 5 with IR) areas
write(0x10014000,0x00000dd8)
URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x....
write(0x1003e000,0x00000dd8)
write(0x10068000,0x00000dd8)
*/
length = static_cast<std::uint32_t>(size / 3);
std::uint32_t strpixel = dev->session.pixel_startx;
std::uint32_t endpixel = dev->session.pixel_endx;
unsigned length = static_cast<unsigned>(size / 3);
pixels=endpixel-strpixel;
// we're using SHDAREA, thus we only need to upload part of the line
unsigned offset = dev->session.pixel_count_ratio.apply(
dev->session.params.startx * sensor.optical_res / dev->session.params.xres);
unsigned pixels = dev->session.pixel_count_ratio.apply(dev->session.optical_pixels_raw);
/* since we're using SHDAREA, substract startx coordinate from shading */
strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res;
// turn pixel value into bytes 2x16 bits words
offset *= 2 * 2;
pixels *= 2 * 2;
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2;
pixels*=2*2;
dev->interface->record_key_value("shading_offset", std::to_string(strpixel));
dev->interface->record_key_value("shading_offset", std::to_string(offset));
dev->interface->record_key_value("shading_pixels", std::to_string(pixels));
dev->interface->record_key_value("shading_length", std::to_string(length));
dev->interface->record_key_value("shading_factor", std::to_string(sensor.shading_factor));
@ -924,7 +916,7 @@ void CommandSetGl847::send_shading_data(Genesys_Device* dev, const Genesys_Senso
// iterate on both sensor segment
for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) {
/* coefficient source */
src=(data+strpixel+i*length)+x;
src = (data + offset + i * length) + x;
/* coefficient copy */
ptr[0]=src[0];

Wyświetl plik

@ -827,51 +827,22 @@ void compute_session_pipeline(const Genesys_Device* dev, ScanSession& s)
void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
const Genesys_Sensor& sensor)
{
unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel();
if (dev->model->asic_type == AsicType::GL646) {
// startx cannot be below dummy pixel value
s.pixel_startx = sensor.dummy_pixel;
s.pixel_startx += s.params.startx * sensor.optical_res / s.params.xres;
s.pixel_startx += s.output_startx * sensor.optical_res / s.params.xres;
s.pixel_endx = s.pixel_startx + s.optical_pixels * s.ccd_size_divisor;
} else if (dev->model->asic_type == AsicType::GL841) {
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres;
s.pixel_startx = ((sensor.ccd_start_xoffset + startx) * s.optical_resolution)
/ sensor.optical_res;
s.pixel_startx += sensor.dummy_pixel + 1;
s.pixel_startx = (s.output_startx * s.optical_resolution) / s.params.xres;
s.pixel_endx = s.pixel_startx + s.optical_pixels;
} else if (dev->model->asic_type == AsicType::GL843) {
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres;
s.pixel_startx = (startx + sensor.dummy_pixel);
s.pixel_endx = s.pixel_startx + s.optical_pixels;
} else if (dev->model->asic_type == AsicType::GL845 ||
} else if (dev->model->asic_type == AsicType::GL843 ||
dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
dev->model->asic_type == AsicType::GL847 ||
dev->model->asic_type == AsicType::GL124)
{
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres;
s.pixel_startx = startx;
s.pixel_startx += sensor.ccd_start_xoffset * ccd_pixels_per_system_pixel;
s.pixel_startx = s.output_startx * sensor.optical_res / s.params.xres;
s.pixel_endx = s.pixel_startx + s.optical_pixels_raw;
} else if (dev->model->asic_type == AsicType::GL124) {
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres;
s.pixel_startx = startx;
// FIXME: should we add sensor.dummy_pxel to pixel_startx at this point?
s.pixel_endx = s.pixel_startx + s.optical_pixels;
}
s.pixel_startx = sensor.pixel_count_ratio.apply(s.pixel_startx);

Wyświetl plik

@ -133,7 +133,6 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Sensor& sensor)
<< " output_pixel_offset: " << sensor.output_pixel_offset << '\n'
<< " black_pixels: " << sensor.black_pixels << '\n'
<< " dummy_pixel: " << sensor.dummy_pixel << '\n'
<< " ccd_start_xoffset: " << sensor.ccd_start_xoffset << '\n'
<< " fau_gain_white_ref: " << sensor.fau_gain_white_ref << '\n'
<< " gain_white_ref: " << sensor.gain_white_ref << '\n'
<< " exposure: " << format_indent_braced_list(4, sensor.exposure) << '\n'

Wyświetl plik

@ -296,8 +296,6 @@ struct Genesys_Sensor {
int black_pixels = 0;
// value of the dummy register
int dummy_pixel = 0;
// last pixel of CCD margin at optical resolution
int ccd_start_xoffset = 0;
// TA CCD target code (reference gain)
int fau_gain_white_ref = 0;
// CCD target code (reference gain)
@ -371,7 +369,6 @@ struct Genesys_Sensor {
output_pixel_offset == other.output_pixel_offset &&
black_pixels == other.black_pixels &&
dummy_pixel == other.dummy_pixel &&
ccd_start_xoffset == other.ccd_start_xoffset &&
fau_gain_white_ref == other.fau_gain_white_ref &&
gain_white_ref == other.gain_white_ref &&
exposure == other.exposure &&
@ -401,7 +398,6 @@ void serialize(Stream& str, Genesys_Sensor& x)
serialize(str, x.pixel_count_ratio);
serialize(str, x.black_pixels);
serialize(str, x.dummy_pixel);
serialize(str, x.ccd_start_xoffset);
serialize(str, x.fau_gain_white_ref);
serialize(str, x.gain_white_ref);
serialize_newline(str);

Wyświetl plik

@ -69,7 +69,6 @@ Genesys_Calibration_Cache create_fake_calibration_entry()
sensor.optical_res = 1200;
sensor.black_pixels = 48;
sensor.dummy_pixel = 64;
sensor.ccd_start_xoffset = 0;
sensor.fau_gain_white_ref = 210;
sensor.gain_white_ref = 230;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };