genesys: Extract computation of session setup to callers

merge-requests/81/head
Povilas Kanapickas 2019-06-02 11:47:34 +03:00
rodzic d688429ccd
commit a287f4945c
1 zmienionych plików z 85 dodań i 74 usunięć

Wyświetl plik

@ -1447,107 +1447,113 @@ struct ScanSessionParams {
struct ScanSession { struct ScanSession {
ScanSessionParams params; ScanSessionParams params;
};
struct GenesysPhysicalParams { // whether the session setup has been computed via gl843_compute_session()
bool computed = false;
// whether CCD operates as half-resolution or full resolution at a specific resolution // whether CCD operates as half-resolution or full resolution at a specific resolution
SANE_Bool half_ccd; SANE_Bool half_ccd = 0;
// the optical resolution of the scanner. // the optical resolution of the scanner.
unsigned optical_resolution; unsigned optical_resolution = 0;
// the number of pixels at the optical resolution. // the number of pixels at the optical resolution.
unsigned optical_pixels; unsigned optical_pixels = 0;
// the number of bytes in the output of a single line directly from scanner // the number of bytes in the output of a single line directly from scanner
unsigned optical_line_bytes; unsigned optical_line_bytes = 0;
// the resolution of the output data. // the resolution of the output data.
unsigned output_resolution; unsigned output_resolution = 0;
// the number of pixels in output data // the number of pixels in output data
unsigned output_pixels; unsigned output_pixels = 0;
// the number of bytes in the output of a single line // the number of bytes in the output of a single line
unsigned output_line_bytes; unsigned output_line_bytes = 0;
// the number of lines in the output of the scanner. This must be larger than the user // the number of lines in the output of the scanner. This must be larger than the user
// requested number due to line staggering and color channel shifting. // requested number due to line staggering and color channel shifting.
unsigned output_line_count; unsigned output_line_count = 0;
// the number of staggered lines (i.e. lines that overlap during scanning due to line being // the number of staggered lines (i.e. lines that overlap during scanning due to line being
// thinner than the CCD element) // thinner than the CCD element)
unsigned num_staggered_lines; unsigned num_staggered_lines = 0;
// the number of lines that color channels shift due to different physical positions of // the number of lines that color channels shift due to different physical positions of
// different color channels // different color channels
unsigned max_color_shift_lines; unsigned max_color_shift_lines = 0;
void assert_computed() const
{
if (!computed) {
throw std::runtime_error("ScanSession is not computed");
}
}
}; };
// computes physical parameters for specific scan setup // computes physical parameters for specific scan setup
static struct GenesysPhysicalParams static void gl843_compute_session(Genesys_Device* dev, ScanSession& s)
gl843_compute_physical_params(Genesys_Device* dev, const ScanSessionParams& sp)
{ {
GenesysPhysicalParams p; s.params.assert_valid();
if (dev->sensor.optical_res < 4 * s.params.xres ||
if (dev->sensor.optical_res < 4 * sp.xres ||
!(dev->sensor.half_ccd_mode)) !(dev->sensor.half_ccd_mode))
{ {
p.half_ccd = SANE_FALSE; s.half_ccd = SANE_FALSE;
} else { } else {
p.half_ccd = SANE_TRUE; s.half_ccd = SANE_TRUE;
} }
p.optical_resolution = dev->sensor.optical_res; s.optical_resolution = dev->sensor.optical_res;
if (p.half_ccd) if (s.half_ccd)
p.optical_resolution /= 4; s.optical_resolution /= 4;
if (sp.flags & SCAN_FLAG_USE_OPTICAL_RES) { if (s.params.flags & SCAN_FLAG_USE_OPTICAL_RES) {
p.output_resolution = p.optical_resolution; s.output_resolution = s.optical_resolution;
} else { } else {
// resolution is choosen from a fixed list and can be used directly // resolution is choosen from a fixed list and can be used directly
// unless we have ydpi higher than sensor's maximum one // unless we have ydpi higher than sensor's maximum one
if (sp.xres > p.optical_resolution) if (s.params.xres > s.optical_resolution)
p.output_resolution = p.optical_resolution; s.output_resolution = s.optical_resolution;
else else
p.output_resolution = sp.xres; s.output_resolution = s.params.xres;
} }
// compute rounded up number of optical pixels // compute rounded up number of optical pixels
p.optical_pixels = (sp.pixels * p.optical_resolution) / sp.xres; s.optical_pixels = (s.params.pixels * s.optical_resolution) / s.params.xres;
if (p.optical_pixels * sp.xres < sp.pixels * p.optical_resolution) if (s.optical_pixels * s.params.xres < s.params.pixels * s.optical_resolution)
p.optical_pixels++; s.optical_pixels++;
// ensure the number of optical pixels is divisible by 2. // ensure the number of optical pixels is divisible by 2.
// In half-CCD mode optical_pixels is 4x larger than the actual physical number // In half-CCD mode optical_pixels is 4x larger than the actual physical number
if (p.half_ccd) { if (s.half_ccd) {
if (p.optical_pixels & 0x7) if (s.optical_pixels & 0x7)
p.optical_pixels = (p.optical_pixels & ~0x7) + 8; s.optical_pixels = (s.optical_pixels & ~0x7) + 8;
} else { } else {
if (p.optical_pixels & 1) if (s.optical_pixels & 1)
p.optical_pixels++; s.optical_pixels++;
} }
p.output_pixels = s.output_pixels =
(p.optical_pixels * p.output_resolution) / p.optical_resolution; (s.optical_pixels * s.output_resolution) / s.optical_resolution;
// Note: staggering is not applied for calibration. Staggering starts at 2400 dpi // Note: staggering is not applied for calibration. Staggering starts at 2400 dpi
p.num_staggered_lines = 0; s.num_staggered_lines = 0;
if ((sp.yres > 1200) && if ((s.params.yres > 1200) &&
((sp.flags & SCAN_FLAG_IGNORE_LINE_DISTANCE) == 0) && ((s.params.flags & SCAN_FLAG_IGNORE_LINE_DISTANCE) == 0) &&
(dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
{ {
p.num_staggered_lines = (4 * sp.yres) / dev->motor.base_ydpi; s.num_staggered_lines = (4 * s.params.yres) / dev->motor.base_ydpi;
} }
p.max_color_shift_lines = sanei_genesys_compute_max_shift(dev, sp.channels, sp.yres, sp.flags); s.max_color_shift_lines = sanei_genesys_compute_max_shift(dev, s.params.channels,
s.params.yres, s.params.flags);
p.output_line_count = sp.lines + p.max_color_shift_lines + p.num_staggered_lines; s.output_line_count = s.params.lines + s.max_color_shift_lines + s.num_staggered_lines;
p.optical_line_bytes = (p.optical_pixels * sp.channels * sp.depth) / 8; s.optical_line_bytes = (s.optical_pixels * s.params.channels * s.params.depth) / 8;
p.output_line_bytes = (p.output_pixels * sp.channels * sp.depth) / 8; s.output_line_bytes = (s.output_pixels * s.params.channels * s.params.depth) / 8;
s.computed = true;
return p;
} }
/* set up registers for an actual scan /* set up registers for an actual scan
@ -1557,7 +1563,7 @@ static struct GenesysPhysicalParams
static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Set* reg, static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Set* reg,
ScanSession& session) ScanSession& session)
{ {
session.params.assert_valid(); session.assert_computed();
int start; int start;
int move; int move;
@ -1583,9 +1589,7 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
session.params.pixels, session.params.startx, session.params.starty, session.params.pixels, session.params.startx, session.params.starty,
session.params.depth, session.params.channels, session.params.flags); session.params.depth, session.params.channels, session.params.flags);
GenesysPhysicalParams params = gl843_compute_physical_params(dev, session.params); DBG(DBG_info, "%s : stagger=%d lines\n", __func__, session.num_staggered_lines);
DBG(DBG_info, "%s : stagger=%d lines\n", __func__, params.num_staggered_lines);
/* we enable true gray for cis scanners only, and just when doing /* we enable true gray for cis scanners only, and just when doing
* scan since color calibration is OK for this mode * scan since color calibration is OK for this mode
@ -1599,7 +1603,7 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
oflags |= OPTICAL_FLAG_DISABLE_LAMP; oflags |= OPTICAL_FLAG_DISABLE_LAMP;
if (session.params.flags & SCAN_FLAG_CALIBRATION) if (session.params.flags & SCAN_FLAG_CALIBRATION)
oflags |= OPTICAL_FLAG_DISABLE_DOUBLE; oflags |= OPTICAL_FLAG_DISABLE_DOUBLE;
if (params.num_staggered_lines) if (session.num_staggered_lines)
oflags |= OPTICAL_FLAG_STAGGER; oflags |= OPTICAL_FLAG_STAGGER;
if (session.params.flags & SCAN_FLAG_USE_XPA) if (session.params.flags & SCAN_FLAG_USE_XPA)
oflags |= OPTICAL_FLAG_USE_XPA; oflags |= OPTICAL_FLAG_USE_XPA;
@ -1630,7 +1634,7 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
} }
else else
{ {
exposure = gl843_compute_exposure (dev, params.output_resolution, oflags); exposure = gl843_compute_exposure (dev, session.output_resolution, oflags);
scan_step_type = sanei_genesys_compute_step_type(gl843_motors, dev->model->motor_type, exposure); scan_step_type = sanei_genesys_compute_step_type(gl843_motors, dev->model->motor_type, exposure);
} }
@ -1655,12 +1659,12 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
status = gl843_init_optical_regs_scan (dev, status = gl843_init_optical_regs_scan (dev,
reg, reg,
exposure, exposure,
params.output_resolution, session.output_resolution,
start, start,
params.optical_pixels, session.optical_pixels,
session.params.channels, session.params.channels,
session.params.depth, session.params.depth,
params.half_ccd, session.half_ccd,
session.params.color_filter, session.params.color_filter,
oflags); oflags);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
@ -1700,8 +1704,8 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
exposure, exposure,
slope_dpi, slope_dpi,
scan_step_type, scan_step_type,
dev->model->is_cis ? params.output_line_count * session.params.channels dev->model->is_cis ? session.output_line_count * session.params.channels
: params.output_line_count, : session.output_line_count,
dummy, dummy,
move, move,
scan_power_mode, scan_power_mode,
@ -1712,11 +1716,11 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
/* since we don't have sheetfed scanners to handle, /* since we don't have sheetfed scanners to handle,
* use huge read buffer */ * use huge read buffer */
/* TODO find the best size according to settings */ /* TODO find the best size according to settings */
requested_buffer_size = 16 * params.output_line_bytes; requested_buffer_size = 16 * session.output_line_bytes;
read_buffer_size = read_buffer_size =
2 * requested_buffer_size + 2 * requested_buffer_size +
(params.max_color_shift_lines + params.num_staggered_lines) * params.optical_line_bytes; (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes;
dev->read_buffer.clear(); dev->read_buffer.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(read_buffer_size);
@ -1730,22 +1734,22 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, Genesys_Register_Se
dev->out_buffer.clear(); dev->out_buffer.clear();
dev->out_buffer.alloc((8 * dev->settings.pixels * session.params.channels * session.params.depth) / 8); dev->out_buffer.alloc((8 * dev->settings.pixels * session.params.channels * session.params.depth) / 8);
dev->read_bytes_left = params.output_line_bytes * params.output_line_count; dev->read_bytes_left = session.output_line_bytes * session.output_line_count;
DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left);
dev->read_active = SANE_TRUE; dev->read_active = SANE_TRUE;
dev->current_setup.pixels = params.output_pixels; dev->current_setup.pixels = session.output_pixels;
DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels);
dev->current_setup.lines = params.output_line_count; dev->current_setup.lines = session.output_line_count;
dev->current_setup.depth = session.params.depth; dev->current_setup.depth = session.params.depth;
dev->current_setup.channels = session.params.channels; dev->current_setup.channels = session.params.channels;
dev->current_setup.exposure_time = exposure; dev->current_setup.exposure_time = exposure;
dev->current_setup.xres = params.output_resolution; dev->current_setup.xres = session.output_resolution;
dev->current_setup.yres = session.params.yres; dev->current_setup.yres = session.params.yres;
dev->current_setup.half_ccd = params.half_ccd; dev->current_setup.half_ccd = session.half_ccd;
dev->current_setup.stagger = params.num_staggered_lines; dev->current_setup.stagger = session.num_staggered_lines;
dev->current_setup.max_shift = params.max_color_shift_lines + params.num_staggered_lines; dev->current_setup.max_shift = session.max_color_shift_lines + session.num_staggered_lines;
dev->total_bytes_read = 0; dev->total_bytes_read = 0;
if (session.params.depth == 1) if (session.params.depth == 1)
@ -2673,6 +2677,7 @@ gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
SCAN_FLAG_IGNORE_LINE_DISTANCE; SCAN_FLAG_IGNORE_LINE_DISTANCE;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &local_reg, session); status = gl843_init_scan_regs(dev, &local_reg, session);
@ -2777,6 +2782,8 @@ gl843_search_start_position (Genesys_Device * dev)
SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_IGNORE_LINE_DISTANCE | SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &local_reg, session); status = gl843_init_scan_regs(dev, &local_reg, session);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
@ -2884,6 +2891,7 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
session.params.scan_mode = dev->settings.scan_mode; session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter; session.params.color_filter = dev->settings.color_filter;
session.params.flags = flags; session.params.flags = flags;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &dev->calib_reg, session); status = gl843_init_scan_regs(dev, &dev->calib_reg, session);
@ -2943,6 +2951,7 @@ gl843_feed (Genesys_Device * dev, unsigned int steps)
SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_FEEDING | SCAN_FLAG_FEEDING |
SCAN_FLAG_IGNORE_LINE_DISTANCE; SCAN_FLAG_IGNORE_LINE_DISTANCE;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &local_reg, session); status = gl843_init_scan_regs(dev, &local_reg, session);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
@ -3047,6 +3056,7 @@ gl843_init_regs_for_shading (Genesys_Device * dev)
session.params.scan_mode = dev->settings.scan_mode; session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter; session.params.color_filter = dev->settings.color_filter;
session.params.flags = flags; session.params.flags = flags;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &dev->calib_reg, session); status = gl843_init_scan_regs(dev, &dev->calib_reg, session);
@ -3163,6 +3173,7 @@ gl843_init_regs_for_scan (Genesys_Device * dev)
session.params.scan_mode = dev->settings.scan_mode; session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter; session.params.color_filter = dev->settings.color_filter;
session.params.flags = flags; session.params.flags = flags;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &dev->reg, session); status = gl843_init_scan_regs(dev, &dev->reg, session);
@ -3269,6 +3280,7 @@ gl843_led_calibration (Genesys_Device * dev)
SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE | SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE; SCAN_FLAG_IGNORE_LINE_DISTANCE;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &dev->calib_reg, session); status = gl843_init_scan_regs(dev, &dev->calib_reg, session);
@ -3485,10 +3497,8 @@ gl843_offset_calibration (Genesys_Device * dev)
session.params.scan_mode = SCAN_MODE_COLOR; session.params.scan_mode = SCAN_MODE_COLOR;
session.params.color_filter = 0; session.params.color_filter = 0;
session.params.flags = flags; session.params.flags = flags;
gl843_compute_session(dev, session);
GenesysPhysicalParams params = gl843_compute_physical_params(dev, session.params); pixels = session.output_pixels;
pixels = params.output_pixels;
DBG(DBG_io, "%s: dpihw =%d\n", __func__, dpihw); DBG(DBG_io, "%s: dpihw =%d\n", __func__, dpihw);
DBG(DBG_io, "%s: factor =%d\n", __func__, factor); DBG(DBG_io, "%s: factor =%d\n", __func__, factor);
@ -3711,9 +3721,8 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi)
session.params.scan_mode = SCAN_MODE_COLOR; session.params.scan_mode = SCAN_MODE_COLOR;
session.params.color_filter = dev->settings.color_filter; session.params.color_filter = dev->settings.color_filter;
session.params.flags = flags; session.params.flags = flags;
gl843_compute_session(dev, session);
GenesysPhysicalParams params = gl843_compute_physical_params(dev, session.params); pixels = session.output_pixels;
pixels = params.output_pixels;
status = gl843_init_scan_regs(dev, &dev->calib_reg, session); status = gl843_init_scan_regs(dev, &dev->calib_reg, session);
gl843_set_motor_power(&dev->calib_reg, SANE_FALSE); gl843_set_motor_power(&dev->calib_reg, SANE_FALSE);
@ -3868,6 +3877,7 @@ gl843_init_regs_for_warmup (Genesys_Device * dev,
SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE | SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE; SCAN_FLAG_IGNORE_LINE_DISTANCE;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, reg, session); status = gl843_init_scan_regs(dev, reg, session);
@ -4166,6 +4176,7 @@ gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
session.params.scan_mode = SCAN_MODE_GRAY; session.params.scan_mode = SCAN_MODE_GRAY;
session.params.color_filter = 0; session.params.color_filter = 0;
session.params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_SHADING; session.params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_SHADING;
gl843_compute_session(dev, session);
status = gl843_init_scan_regs(dev, &local_reg, session); status = gl843_init_scan_regs(dev, &local_reg, session);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)