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); DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size);
uint32_t length, x, pixels, i; uint32_t length, x, pixels, i;
std::uint16_t beginpixel;
uint8_t *ptr,*src; uint8_t *ptr,*src;
/* old method if no SHDAREA */ /* old method if no SHDAREA */
if ((dev->reg.find_reg(0x01).value & REG_0x01_SHDAREA) == 0) { 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); dev->interface->write_buffer(0x3c, 0x0000, data, size);
return; return;
} }
/* data is whole line, we extract only the part for the scanned area */ /* data is whole line, we extract only the part for the scanned area */
length = static_cast<std::uint32_t>(size / 3); 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 */ // turn pixel value into bytes 2x16 bits words
strpixel*=2*2; /* 2 words of 2 bytes */ pixels = dev->session.pixel_endx - dev->session.pixel_startx;
endpixel*=2*2; pixels *= 4;
pixels=endpixel-strpixel;
/* shading pixel begin is start pixel minus start pixel during shading // shading pixel begin is start pixel minus start pixel during shading
* calibration. Currently only cases handled are full and half ccd resolution. // calibration. Currently only cases handled are full and half ccd resolution.
*/ unsigned beginpixel = dev->session.params.startx * dev->session.optical_resolution /
beginpixel = sensor.ccd_start_xoffset / dev->session.ccd_size_divisor; dev->session.params.xres;
beginpixel += sensor.dummy_pixel + 1;
DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel); DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel);
beginpixel = (strpixel - beginpixel * 2 * 2) / sensor.shading_factor; beginpixel *= 4;
DBG(DBG_io2, "%s: BEGIN PIXEL=%d\n", __func__, beginpixel/4); beginpixel /= sensor.shading_factor;
dev->interface->record_key_value("shading_offset", std::to_string(beginpixel)); dev->interface->record_key_value("shading_offset", std::to_string(beginpixel));
dev->interface->record_key_value("shading_pixels", std::to_string(pixels)); dev->interface->record_key_value("shading_pixels", std::to_string(pixels));

Wyświetl plik

@ -1969,39 +1969,23 @@ void CommandSetGl843::send_shading_data(Genesys_Device* dev, const Genesys_Senso
uint8_t* data, int size) const uint8_t* data, int size) const
{ {
DBG_HELPER(dbg); DBG_HELPER(dbg);
uint32_t final_size, length, i; uint32_t final_size, i;
uint8_t *buffer; uint8_t *buffer;
int count,offset; int count;
uint16_t strpixel, endpixel, startx;
unsigned offset = 0;
unsigned length = size;
offset=0;
length=size;
if (dev->reg.get8(REG_0x01) & REG_0x01_SHDAREA) { if (dev->reg.get8(REG_0x01) & REG_0x01_SHDAREA) {
/* recompute STRPIXEL used shading calibration so we can offset = dev->session.params.startx * sensor.shading_resolution /
* compute offset within data for SHDAREA case */ dev->session.params.xres;
// FIXME: the following is likely incorrect length = dev->session.output_pixels * sensor.shading_resolution /
// start coordinate in optical dpi coordinates dev->session.params.xres;
startx = sensor.dummy_pixel;
startx = dev->session.pixel_count_ratio.apply(startx);
/* current scan coordinates */ // 16 bit words, 2 words per color, 3 color channels
strpixel = dev->session.pixel_startx; length *= 2 * 2 * 3;
endpixel = dev->session.pixel_endx; offset *= 2 * 2 * 3;
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);
} }
dev->interface->record_key_value("shading_offset", std::to_string(offset)); 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 uint8_t* data, int size) const
{ {
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); 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; uint8_t val,*ptr,*src;
/* shading data is plit in 3 (up to 5 with IR) areas unsigned length = static_cast<unsigned>(size / 3);
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;
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 */ // turn pixel value into bytes 2x16 bits words
strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res; offset *= 2 * 2;
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2;
pixels *= 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_pixels", std::to_string(pixels));
dev->interface->record_key_value("shading_length", std::to_string(length)); dev->interface->record_key_value("shading_length", std::to_string(length));
dev->interface->record_key_value("shading_factor", std::to_string(sensor.shading_factor)); 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 */ /* iterate on both sensor segment */
for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) { for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) {
/* coefficient source */ // coefficient source
src=(data+strpixel+i*length)+x; src = (data + offset + i * length) + x;
/* coefficient copy */ /* coefficient copy */
ptr[0]=src[0]; 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 uint8_t* data, int size) const
{ {
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); 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; uint8_t val,*ptr,*src;
/* shading data is plit in 3 (up to 5 with IR) areas unsigned length = static_cast<unsigned>(size / 3);
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;
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 */ // turn pixel value into bytes 2x16 bits words
strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res; offset *= 2 * 2;
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2;
pixels *= 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_pixels", std::to_string(pixels));
dev->interface->record_key_value("shading_length", std::to_string(length)); dev->interface->record_key_value("shading_length", std::to_string(length));
dev->interface->record_key_value("shading_factor", std::to_string(sensor.shading_factor)); 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 // iterate on both sensor segment
for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) { for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) {
/* coefficient source */ /* coefficient source */
src=(data+strpixel+i*length)+x; src = (data + offset + i * length) + x;
/* coefficient copy */ /* coefficient copy */
ptr[0]=src[0]; 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, void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
const Genesys_Sensor& sensor) const Genesys_Sensor& sensor)
{ {
unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel();
if (dev->model->asic_type == AsicType::GL646) { if (dev->model->asic_type == AsicType::GL646) {
s.pixel_startx += s.output_startx * sensor.optical_res / s.params.xres;
// 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_endx = s.pixel_startx + s.optical_pixels * s.ccd_size_divisor; s.pixel_endx = s.pixel_startx + s.optical_pixels * s.ccd_size_divisor;
} else if (dev->model->asic_type == AsicType::GL841) { } else if (dev->model->asic_type == AsicType::GL841) {
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres; s.pixel_startx = (s.output_startx * s.optical_resolution) / 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_endx = s.pixel_startx + s.optical_pixels; s.pixel_endx = s.pixel_startx + s.optical_pixels;
} else if (dev->model->asic_type == AsicType::GL843) { } else if (dev->model->asic_type == AsicType::GL843 ||
unsigned startx = s.params.startx * sensor.optical_res / s.params.xres; dev->model->asic_type == AsicType::GL845 ||
s.pixel_startx = (startx + sensor.dummy_pixel);
s.pixel_endx = s.pixel_startx + s.optical_pixels;
} else if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 || 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 = s.output_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_endx = s.pixel_startx + s.optical_pixels_raw; 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); 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' << " output_pixel_offset: " << sensor.output_pixel_offset << '\n'
<< " black_pixels: " << sensor.black_pixels << '\n' << " black_pixels: " << sensor.black_pixels << '\n'
<< " dummy_pixel: " << sensor.dummy_pixel << '\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' << " fau_gain_white_ref: " << sensor.fau_gain_white_ref << '\n'
<< " gain_white_ref: " << sensor.gain_white_ref << '\n' << " gain_white_ref: " << sensor.gain_white_ref << '\n'
<< " exposure: " << format_indent_braced_list(4, sensor.exposure) << '\n' << " exposure: " << format_indent_braced_list(4, sensor.exposure) << '\n'

Wyświetl plik

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

Wyświetl plik

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