genesys: Move pixel coordinate calculation to a single place

merge-requests/186/head
Povilas Kanapickas 2019-09-15 10:36:58 +03:00
rodzic 345be52f9e
commit db36dd8103
8 zmienionych plików z 126 dodań i 157 usunięć

Wyświetl plik

@ -781,8 +781,6 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
const ScanSession& session)
{
DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time);
unsigned int segcnt;
unsigned int startx, endx;
unsigned int dpihw;
GenesysRegister *r;
uint32_t expmax;
@ -801,21 +799,6 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
session.ccd_size_divisor);
gl124_setup_sensor(dev, sensor, sensor_profile, reg);
/* start and end coordinate in optical dpi coordinates */
/* startx = start / ccd_pixels_per_system_pixel + sensor.dummy_pixel; XXX STEF XXX */
unsigned start = session.params.startx;
if (session.num_staggered_lines > 0) {
start |= 1;
}
startx = start / ccd_pixels_per_system_pixel;
endx = startx + session.optical_pixels / ccd_pixels_per_system_pixel;
/* pixel coordinate factor correction when used dpihw is not maximal one */
startx /= session.hwdpi_divisor;
endx /= session.hwdpi_divisor;
gl124_set_fe(dev, sensor, AFE_SET);
/* enable shading */
@ -936,14 +919,8 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
}
}
reg->set24(REG_STRPIXEL, startx / session.segment_count);
DBG(DBG_io2, "%s: strpixel used=%d\n", __func__, startx / session.segment_count);
segcnt = reg->get24(REG_SEGCNT);
if (endx / session.segment_count == segcnt) {
endx=0;
}
reg->set24(REG_ENDPIXEL, endx / session.segment_count);
DBG(DBG_io2, "%s: endpixel used=%d\n", __func__, endx / session.segment_count);
reg->set24(REG_STRPIXEL, session.pixel_startx);
reg->set24(REG_ENDPIXEL, session.pixel_endx);
dev->line_count = 0;

Wyświetl plik

@ -319,8 +319,7 @@ static void gl646_setup_registers(Genesys_Device* dev,
Genesys_Register_Set* regs,
const ScanSession& session,
std::vector<uint16_t>& slope_table1,
std::vector<uint16_t>& slope_table2,
bool xcorrection)
std::vector<uint16_t>& slope_table2)
{
DBG_HELPER(dbg);
session.assert_computed();
@ -329,39 +328,12 @@ static void gl646_setup_registers(Genesys_Device* dev,
uint32_t move = session.params.starty;
uint32_t startx = 0;
/* pixels are allways given at full CCD optical resolution */
/* use detected left margin and fixed value */
if (xcorrection == SANE_TRUE) {
if (sensor.CCD_start_xoffset > 0) {
startx = sensor.CCD_start_xoffset;
} else {
startx = sensor.dummy_pixel;
}
} else {
// startx cannot be below dummy pixel value
startx = sensor.dummy_pixel;
}
/* add x coordinates : expressed in sensor max dpi */
startx += session.params.startx;
/* stagger works with odd start cordinates */
if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) {
startx |= 1;
}
/* TODO check for pixel width overflow */
uint32_t endx = startx + session.optical_pixels;
int i, nb;
Motor_Master *motor = NULL;
unsigned int used1, used2, vfinal;
uint32_t z1, z2;
uint16_t ex, sx;
int feedl;
DBG(DBG_info, "%s: startx=%d, endx=%d\n", __func__, startx, endx);
/* for the given resolution, search for master
* motor mode setting */
@ -555,13 +527,8 @@ static void gl646_setup_registers(Genesys_Device* dev,
regs->set24(REG_LINCNT, session.output_line_count);
}
/* scanner's x coordinates are expressed in physical DPI but they must be divided by cksel */
sx = startx / sensor.ccd_pixels_per_system_pixel() / session.ccd_size_divisor;
ex = endx / sensor.ccd_pixels_per_system_pixel() / session.ccd_size_divisor;
regs->set16(REG_STRPIXEL, sx);
regs->set16(REG_ENDPIXEL, ex);
DBG(DBG_info, "%s: startx=%d, endx=%d, ccd_size_divisor=%d\n", __func__, sx, ex,
session.ccd_size_divisor);
regs->set16(REG_STRPIXEL, session.pixel_startx);
regs->set16(REG_ENDPIXEL, session.pixel_endx);
regs->set24(REG_MAXWD, session.output_line_bytes);
@ -2166,13 +2133,16 @@ static void setup_for_scan(Genesys_Device* dev,
if (settings.scan_method == ScanMethod::TRANSPARENCY) {
session.params.flags |= SCAN_FLAG_USE_XPA;
}
if (xcorrection) {
session.params.flags |= SCAN_FLAG_USE_XCORRECTION;
}
gl646_compute_session(dev, session, sensor);
std::vector<uint16_t> slope_table0;
std::vector<uint16_t> slope_table1;
// set up correct values for scan (gamma and shading enabled)
gl646_setup_registers(dev, sensor, regs, session, slope_table0, slope_table1, xcorrection);
gl646_setup_registers(dev, sensor, regs, session, slope_table0, slope_table1);
// send computed slope tables
gl646_send_slope_table(dev, 0, slope_table0, regs->get8(0x21));

Wyświetl plik

@ -1453,15 +1453,12 @@ static void gl841_init_optical_regs_off(Genesys_Register_Set* reg)
static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set* reg, unsigned int exposure_time,
const ScanSession& session, unsigned int start)
const ScanSession& session)
{
DBG_HELPER_ARGS(dbg, "exposure_time=%d, start=%d", exposure_time, start);
unsigned int end;
DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time);
GenesysRegister* r;
uint16_t expavg, expr, expb, expg;
end = start + session.optical_pixels;
gl841_set_fe(dev, sensor, AFE_SET);
/* gpio part.*/
@ -1600,9 +1597,8 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
r->value = 255; /*<<<"magic" number, only suitable for cis*/
reg->set16(REG_DPISET, gl841_get_dpihw(dev) * session.output_resolution / session.optical_resolution);
reg->set16(REG_STRPIXEL, start);
reg->set16(REG_ENDPIXEL, end);
DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d\n", __func__, start, end);
reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx);
reg->set24(REG_MAXWD, session.output_line_bytes);
@ -1735,10 +1731,8 @@ static void gl841_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
DBG_HELPER(dbg);
session.assert_computed();
int start;
int move;
int exposure_time;
int avg;
int slope_dpi = 0;
int dummy = 0;
@ -1774,29 +1768,6 @@ independent of our calculated values:
gl841_assert_supported_resolution(session);
/* compute scan parameters values */
/* pixels are allways given at half or full CCD optical resolution */
/* use detected left margin and fixed value */
start = ((sensor.CCD_start_xoffset + session.params.startx) * session.optical_resolution)
/ sensor.optical_res;
start += sensor.dummy_pixel + 1;
if (session.num_staggered_lines > 0) {
start |= 1;
}
/* in case of SHDAREA, we need to align start
* on pixel average factor, startx is different of
* 0 only when calling for function to setup for
* scan, where shading data needs to be align */
if((dev->reg.find_reg(0x01).value & REG01_SHDAREA) != 0)
{
avg = session.optical_resolution / session.params.xres;
start=(start/avg)*avg;
}
/* dummy */
/* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1
dummy line. Maybe the dummy line adds correctness since the motor runs
@ -1839,11 +1810,11 @@ dummy \ scanned lines
exposure_time = gl841_exposure_time(dev, sensor,
slope_dpi,
scan_step_type,
start,
session.pixel_startx,
session.optical_pixels);
DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time);
gl841_init_optical_regs_scan(dev, sensor, reg, exposure_time, session, start);
gl841_init_optical_regs_scan(dev, sensor, reg, exposure_time, session);
move = session.params.starty;
DBG(DBG_info, "%s: move=%d steps\n", __func__, move);
@ -1939,17 +1910,6 @@ static void gl841_calculate_current_setup(Genesys_Device * dev, const Genesys_Se
gl841_assert_supported_resolution(session);
/* compute scan parameters values */
/* pixels are allways given at half or full CCD optical resolution */
/* use detected left margin and fixed value */
start = ((sensor.CCD_start_xoffset + session.params.startx) * session.optical_resolution) / sensor.optical_res;
start += sensor.dummy_pixel + 1;
if (session.num_staggered_lines > 0) {
start |= 1;
}
/* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1
dummy line. Maybe the dummy line adds correctness since the motor runs
slower (higher dpi)
@ -1990,7 +1950,7 @@ dummy \ scanned lines
exposure_time = gl841_exposure_time(dev, sensor,
slope_dpi,
scan_step_type,
start,
session.pixel_startx,
session.optical_pixels);
DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time);

Wyświetl plik

@ -1190,20 +1190,6 @@ static void gl843_compute_session(Genesys_Device* dev, ScanSession& s,
compute_session(dev, s, sensor);
// compute physical pixel positions
unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel();
s.pixel_startx = (s.params.startx + sensor.dummy_pixel) / ccd_pixels_per_system_pixel;
s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel;
s.pixel_startx /= s.hwdpi_divisor;
s.pixel_endx /= s.hwdpi_divisor;
// in case of stagger we have to start at an odd coordinate
if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) {
s.pixel_startx++;
s.pixel_endx++;
}
s.computed = true;
DBG(DBG_info, "%s ", __func__);

Wyświetl plik

@ -700,19 +700,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
const auto& sensor_profile = get_sensor_profile(dev->model->asic_type, sensor, dpihw, 1);
gl846_setup_sensor(dev, sensor, sensor_profile, reg);
// start and end coordinate in optical dpi coordinates
unsigned start = session.params.startx;
if (session.num_staggered_lines > 0) {
start |= 1;
}
unsigned startx = start + sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel;
unsigned endx = startx + session.optical_pixels_raw;
// compute pixel coordinate in the given dpihw space, taking segments into account
startx /= session.hwdpi_divisor * session.segment_count;
endx /= session.hwdpi_divisor * session.segment_count;
gl846_set_fe(dev, sensor, AFE_SET);
/* enable shading */
@ -811,10 +798,8 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_DPISET, dpiset);
DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset);
reg->set16(REG_STRPIXEL, startx / ccd_pixels_per_system_pixel);
reg->set16(REG_ENDPIXEL, endx / ccd_pixels_per_system_pixel);
DBG(DBG_io2, "%s: startx=%d\n", __func__, startx / ccd_pixels_per_system_pixel);
DBG(DBG_io2, "%s: endx =%d\n", __func__, endx / ccd_pixels_per_system_pixel);
reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx);
DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);

Wyświetl plik

@ -717,19 +717,6 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
const auto& sensor_profile = get_sensor_profile(dev->model->asic_type, sensor, dpihw, 1);
gl847_setup_sensor(dev, sensor, sensor_profile, reg);
unsigned start = session.params.startx;
if (session.num_staggered_lines > 0) {
start |= 1;
}
// start and end coordinate in optical dpi coordinates
unsigned startx = start + sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel;
unsigned endx = startx + session.optical_pixels_raw;
// compute pixel coordinate in the given dpihw space, taking segments into account
startx /= session.hwdpi_divisor * session.segment_count;
endx /= session.hwdpi_divisor * session.segment_count;
gl847_set_fe(dev, sensor, AFE_SET);
/* enable shading */
@ -828,10 +815,8 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_DPISET, dpiset);
DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset);
reg->set16(REG_STRPIXEL, startx / ccd_pixels_per_system_pixel);
reg->set16(REG_ENDPIXEL, endx / ccd_pixels_per_system_pixel);
DBG(DBG_io2, "%s: startx=%d\n", __func__, startx / ccd_pixels_per_system_pixel);
DBG(DBG_io2, "%s: endx =%d\n", __func__, endx / ccd_pixels_per_system_pixel);
reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx);
DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);

Wyświetl plik

@ -1234,6 +1234,110 @@ void compute_session_pipeline(const Genesys_Device* dev, ScanSession& s)
s.pipeline_needs_reverse = depth == 1;
}
void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
const Genesys_Sensor& sensor,
const SensorProfile* sensor_profile)
{
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;
if ((s.params.flags & SCAN_FLAG_USE_XCORRECTION) && sensor.CCD_start_xoffset > 0) {
s.pixel_startx = sensor.CCD_start_xoffset;
}
s.pixel_startx += s.params.startx;
if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) {
s.pixel_startx |= 1;
}
s.pixel_endx = s.pixel_startx + s.optical_pixels;
s.pixel_startx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor;
s.pixel_endx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor;
} else if (dev->model->asic_type == AsicType::GL841) {
s.pixel_startx = ((sensor.CCD_start_xoffset + s.params.startx) * s.optical_resolution)
/ sensor.optical_res;
s.pixel_startx += sensor.dummy_pixel + 1;
if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) {
s.pixel_startx++;
}
/* In case of SHDAREA, we need to align start on pixel average factor, startx is
different than 0 only when calling for function to setup for scan, where shading data
needs to be align.
NOTE: we can check the value of the register here, because we don't set this bit
anywhere except in initialization.
*/
const uint8_t REG01_SHDAREA = 0x02;
if ((dev->reg.find_reg(0x01).value & REG01_SHDAREA) != 0) {
unsigned average_factor = s.optical_resolution / s.params.xres;
s.pixel_startx = align_multiple_floor(s.pixel_startx, average_factor);
}
s.pixel_endx = s.pixel_startx + s.optical_pixels;
} else if (dev->model->asic_type == AsicType::GL843) {
s.pixel_startx = (s.params.startx + sensor.dummy_pixel) / ccd_pixels_per_system_pixel;
s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel;
s.pixel_startx /= s.hwdpi_divisor;
s.pixel_endx /= s.hwdpi_divisor;
// in case of stagger we have to start at an odd coordinate
if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) {
s.pixel_startx++;
s.pixel_endx++;
}
} else if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
{
s.pixel_startx = s.params.startx;
if (s.num_staggered_lines > 0) {
s.pixel_startx |= 1;
}
s.pixel_startx += sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel;
s.pixel_endx = s.pixel_startx + s.optical_pixels_raw;
s.pixel_startx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel;
s.pixel_endx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel;
} else if (dev->model->asic_type == AsicType::GL124) {
s.pixel_startx = s.params.startx;
if (s.num_staggered_lines > 0) {
s.pixel_startx |= 1;
}
s.pixel_startx /= ccd_pixels_per_system_pixel;
// FIXME: should we add sensor.dummy_pxel to pixel_startx at this point?
s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel;
s.pixel_startx /= s.hwdpi_divisor * s.segment_count;
s.pixel_endx /= s.hwdpi_divisor * s.segment_count;
const uint16_t REG_SEGCNT = 0x93;
std::uint32_t segcnt = (sensor_profile->custom_regs.get_value(REG_SEGCNT) << 16) +
(sensor_profile->custom_regs.get_value(REG_SEGCNT + 1) << 8) +
sensor_profile->custom_regs.get_value(REG_SEGCNT + 2);
if (s.pixel_endx == segcnt) {
s.pixel_endx = 0;
}
}
}
void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor)
{
DBG_HELPER(dbg);
@ -1417,6 +1521,7 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor&
compute_session_buffer_sizes(dev->model->asic_type, s);
compute_session_pipeline(dev, s);
compute_session_pixel_offsets(dev, s, sensor, sensor_profile);
}
static std::size_t get_usb_buffer_read_size(AsicType asic, const ScanSession& session)

Wyświetl plik

@ -378,6 +378,7 @@ extern Motor_Profile gl124_motor_profiles[];
#define SCAN_FLAG_FEEDING 0x200
#define SCAN_FLAG_USE_XPA 0x400
#define SCAN_FLAG_ENABLE_LEDADD 0x800
#define SCAN_FLAG_USE_XCORRECTION 0x1000
#define MOTOR_FLAG_AUTO_GO_HOME 0x01
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 0x02
#define MOTOR_FLAG_FEED 0x04