genesys: Replace ccd_size_divisor with explicit optical resolution

merge-requests/463/merge
Povilas Kanapickas 2020-05-18 06:35:20 +03:00
rodzic b5430cc039
commit e62f130523
10 zmienionych plików z 196 dodań i 292 usunięć

Wyświetl plik

@ -1524,12 +1524,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
if (should_calibrate_only_active_area(dev, dev.settings)) {
float offset = dev.model->x_offset_ta;
offset /= calib_sensor->get_ccd_size_divisor_for_dpi(resolution);
start_pixel = static_cast<int>((offset * resolution) / MM_PER_INCH);
start_pixel = static_cast<int>((offset * calib_sensor->get_optical_resolution()) / MM_PER_INCH);
float size = dev.model->x_size_ta;
size /= calib_sensor->get_ccd_size_divisor_for_dpi(resolution);
target_pixels = static_cast<int>((size * resolution) / MM_PER_INCH);
target_pixels = static_cast<int>((size * calib_sensor->get_optical_resolution()) / MM_PER_INCH);
}
if (dev.model->model_id == ModelId::CANON_4400F &&
@ -2867,8 +2865,7 @@ compute_averaged_planar (Genesys_Device * dev, const Genesys_Sensor& sensor,
*/
res = dev->settings.xres;
if (sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres) > 1)
{
if (sensor.full_resolution > sensor.get_optical_resolution()) {
res *= 2;
}
@ -3158,7 +3155,7 @@ compute_shifted_coefficients (Genesys_Device * dev,
auto cmat = color_order_to_cmat(color_order);
x = dev->settings.xres;
if (sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres) > 1) {
if (sensor.full_resolution > sensor.get_optical_resolution()) {
x *= 2; // scanner is using half-ccd mode
}
basepixels = sensor.full_resolution / x; // this should be evenly dividable

Wyświetl plik

@ -609,22 +609,6 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
reg->set16(REG_FMOVDEC, fast_table.table.size());
}
/** @brief setup optical related registers
* start and pixels are expressed in optical sensor resolution coordinate
* space.
* @param dev scanner device to use
* @param reg registers to set up
* @param exposure_time exposure time to use
* @param used_res scanning resolution used, may differ from
* scan's one
* @param start logical start pixel coordinate
* @param pixels logical number of pixels to use
* @param channels number of color channels (currently 1 or 3)
* @param depth bit depth of the scan (1, 8 or 16)
* @param ccd_size_divisor whether sensor's timings are such that x coordinates must be halved
* @param color_filter color channel to use as gray data
* @param flags optical flags (@see )
*/
static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set* reg, unsigned int exposure_time,
const ScanSession& session)
@ -743,7 +727,8 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
// MAXWD is expressed in 2 words unit
// BUG: we shouldn't multiply by channels here
reg->set24(REG_MAXWD, session.output_line_bytes_raw / session.ccd_size_divisor * session.params.channels);
reg->set24(REG_MAXWD, session.output_line_bytes_raw * session.params.channels *
session.optical_resolution / session.full_resolution);
reg->set24(REG_LPERIOD, exposure_time);
reg->set16(REG_DUMMY, sensor.dummy_pixel);
}
@ -819,7 +804,7 @@ ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev,
float start = dev->model->x_offset;
start += settings.tl_x;
start /= sensor.get_ccd_size_divisor_for_dpi(settings.xres);
start /= sensor.full_resolution / sensor.get_optical_resolution();
start = static_cast<float>((start * settings.xres) / MM_PER_INCH);
ScanSession session;

Wyświetl plik

@ -1803,8 +1803,6 @@ void CommandSetGl646::move_back_home(Genesys_Device* dev, bool wait_until_home)
* init registers for shading calibration
* we assume that scanner's head is on an area suiting shading calibration.
* We scan a full scan width area by the shading line number for the device
* at either at full sensor's resolution or half depending upon ccd_size_divisor
* @param dev scanner's device
*/
void CommandSetGl646::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set& regs) const
@ -1815,10 +1813,9 @@ void CommandSetGl646::init_regs_for_shading(Genesys_Device* dev, const Genesys_S
/* fill settings for scan : always a color scan */
int channels = 3;
unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
unsigned cksel = get_cksel(dev->model->sensor_id, dev->settings.xres, channels);
unsigned resolution = sensor.full_resolution / ccd_size_divisor / cksel;
unsigned resolution = sensor.get_optical_resolution() / cksel;
// FIXME: we select wrong calibration sensor
const auto& calib_sensor = sanei_genesys_find_sensor(dev, dev->settings.xres, channels,
dev->settings.scan_method);

Wyświetl plik

@ -871,7 +871,6 @@ static void gl843_init_motor_regs_scan(Genesys_Device* dev,
* @param pixels logical number of pixels to use
* @param channels number of color channles used (1 or 3)
* @param depth bit depth of the scan (1, 8 or 16 bits)
* @param ccd_size_divisor true specifies how much x coordinates must be shrunk
* @param color_filter to choose the color channel used in gray scans
* @param flags to drive specific settings such no calibration, XPA use ...
*/
@ -1006,8 +1005,9 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
/* MAXWD is expressed in 2 words unit */
/* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */
// BUG: the division by ccd_size_divisor likely does not make sense
reg->set24(REG_MAXWD, (session.output_line_bytes / session.ccd_size_divisor) >> 1);
// BUG: the division by optical and full resolution factor likely does not make sense
reg->set24(REG_MAXWD, (session.output_line_bytes *
session.optical_resolution / session.full_resolution) >> 1);
reg->set16(REG_LPERIOD, exposure / tgtime);
reg->set8(REG_DUMMY, sensor.dummy_pixel);
}

Wyświetl plik

@ -809,7 +809,7 @@ void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
{
if (dev->model->asic_type == AsicType::GL646) {
s.pixel_startx += s.output_startx * sensor.full_resolution / 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.full_resolution / s.optical_resolution;
} else if (dev->model->asic_type == AsicType::GL841 ||
dev->model->asic_type == AsicType::GL842 ||
@ -896,13 +896,12 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
}
// compute optical and output resolutions
s.ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(s.params.xres);
s.pixel_count_ratio = sensor.pixel_count_ratio;
s.optical_resolution = sensor.full_resolution / s.ccd_size_divisor;
s.full_resolution = sensor.full_resolution;
s.optical_resolution = sensor.get_optical_resolution();
s.output_resolution = s.params.xres;
s.pixel_count_ratio = sensor.pixel_count_ratio;
if (s.output_resolution > s.optical_resolution) {
throw std::runtime_error("output resolution higher than optical resolution");
}
@ -923,7 +922,8 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
if (dev->model->asic_type == AsicType::GL843) {
// ensure the number of optical pixels is divisible by 2.
// In quarter-CCD mode optical_pixels is 4x larger than the actual physical number
s.optical_pixels = align_int_up(s.optical_pixels, 2 * s.ccd_size_divisor);
s.optical_pixels = align_int_up(s.optical_pixels,
2 * s.full_resolution / s.optical_resolution);
if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200 ||
dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I ||
@ -1019,7 +1019,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
if (dev->model->is_cis) {
s.output_line_bytes_raw = s.output_channel_bytes;
}
s.conseq_pixel_dist = s.output_pixels / s.ccd_size_divisor / s.segment_count;
s.conseq_pixel_dist = s.output_pixels / (s.full_resolution / s.optical_resolution) / s.segment_count;
}
if (dev->model->asic_type == AsicType::GL842 ||
@ -1034,7 +1034,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
dev->model->asic_type == AsicType::GL843)
{
s.output_segment_pixel_group_count = s.output_pixels /
(s.ccd_size_divisor * s.segment_count);
(s.full_resolution / s.optical_resolution * s.segment_count);
}
if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
@ -1086,8 +1086,9 @@ static std::size_t get_usb_buffer_read_size(AsicType asic, const ScanSession& se
return 1;
case AsicType::GL124:
// BUG: we shouldn't multiply by channels here nor divide by ccd_size_divisor
return session.output_line_bytes_raw / session.ccd_size_divisor * session.params.channels;
// BUG: we shouldn't multiply by channels here nor adjuct by resolution factor
return session.output_line_bytes_raw * session.optical_resolution / session.full_resolution
* session.params.channels;
case AsicType::GL845:
case AsicType::GL846:

Wyświetl plik

@ -122,12 +122,12 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Sensor& sensor)
out << "Genesys_Sensor{\n"
<< " sensor_id: " << static_cast<unsigned>(sensor.sensor_id) << '\n'
<< " full_resolution: " << sensor.full_resolution << '\n'
<< " optical_resolution: " << sensor.get_optical_resolution() << '\n'
<< " resolutions: " << format_indent_braced_list(4, sensor.resolutions) << '\n'
<< " channels: " << format_vector_unsigned(4, sensor.channels) << '\n'
<< " method: " << sensor.method << '\n'
<< " register_dpihw: " << sensor.register_dpihw << '\n'
<< " register_dpiset: " << sensor.register_dpiset << '\n'
<< " ccd_size_divisor: " << sensor.ccd_size_divisor << '\n'
<< " shading_factor: " << sensor.shading_factor << '\n'
<< " shading_pixel_offset: " << sensor.shading_pixel_offset << '\n'
<< " pixel_count_ratio: " << sensor.pixel_count_ratio << '\n'

Wyświetl plik

@ -260,6 +260,11 @@ struct Genesys_Sensor {
// pixel, see ccd_pixels_per_system_pixel()
unsigned full_resolution = 0;
// sensor resolution in pixel values that are read by the chip. Many scanners make low
// resolutions faster by configuring the timings in such a way that 1/2 or 1/4 of pixel values
// that are read. If zero, then it is equal to `full_resolution`.
unsigned optical_resolution = 0;
// the resolution list that the sensor is usable at.
ValueFilterAny<unsigned> resolutions = VALUE_FILTER_ANY;
@ -277,9 +282,6 @@ struct Genesys_Sensor {
// resolution. The value zero does not set the override.
unsigned register_dpiset = 0;
// CCD may present itself as half or quarter-size CCD on certain resolutions
int ccd_size_divisor = 1;
// The resolution to use for shading calibration
unsigned shading_resolution = 0;
@ -331,11 +333,11 @@ struct Genesys_Sensor {
// red, green and blue gamma coefficient for default gamma tables
AssignableArray<float, 3> gamma;
std::function<unsigned(const Genesys_Sensor&, unsigned)> get_ccd_size_divisor_fun;
unsigned get_ccd_size_divisor_for_dpi(unsigned xres) const
unsigned get_optical_resolution() const
{
return get_ccd_size_divisor_fun(*this, xres);
if (optical_resolution != 0)
return optical_resolution;
return full_resolution;
}
// how many CCD pixels are processed per system pixel time. This corresponds to CKSEL + 1
@ -362,10 +364,10 @@ struct Genesys_Sensor {
{
return sensor_id == other.sensor_id &&
full_resolution == other.full_resolution &&
optical_resolution == other.optical_resolution &&
resolutions == other.resolutions &&
method == other.method &&
shading_resolution == other.shading_resolution &&
ccd_size_divisor == other.ccd_size_divisor &&
shading_factor == other.shading_factor &&
shading_pixel_offset == other.shading_pixel_offset &&
pixel_count_ratio == other.pixel_count_ratio &&
@ -394,7 +396,6 @@ void serialize(Stream& str, Genesys_Sensor& x)
serialize(str, x.resolutions);
serialize(str, x.method);
serialize(str, x.shading_resolution);
serialize(str, x.ccd_size_divisor);
serialize(str, x.shading_factor);
serialize(str, x.shading_pixel_offset);
serialize(str, x.output_pixel_offset);

Wyświetl plik

@ -97,7 +97,7 @@ bool ScanSession::operator==(const ScanSession& other) const
{
return params == other.params &&
computed == other.computed &&
ccd_size_divisor == other.ccd_size_divisor &&
full_resolution == other.full_resolution &&
optical_resolution == other.optical_resolution &&
optical_pixels == other.optical_pixels &&
optical_pixels_raw == other.optical_pixels_raw &&
@ -136,7 +136,7 @@ std::ostream& operator<<(std::ostream& out, const ScanSession& session)
{
out << "ScanSession{\n"
<< " computed: " << session.computed << '\n'
<< " ccd_size_divisor: " << session.ccd_size_divisor << '\n'
<< " full_resolution: " << session.full_resolution << '\n'
<< " optical_resolution: " << session.optical_resolution << '\n'
<< " optical_pixels: " << session.optical_pixels << '\n'
<< " optical_pixels_raw: " << session.optical_pixels_raw << '\n'

Wyświetl plik

@ -212,11 +212,10 @@ struct ScanSession {
// whether the session setup has been computed via compute_session()
bool computed = false;
// specifies the reduction (if any) of CCD effective dpi which is performed by latching the
// data coming from CCD in such a way that 1/2 or 3/4 of pixel data is ignored.
unsigned ccd_size_divisor = 1;
// specifies the full resolution of the sensor that is being used.
unsigned full_resolution = 0;
// the optical resolution of the scanner.
// the optical resolution of the sensor that is being used.
unsigned optical_resolution = 0;
// the number of pixels at the optical resolution, not including segmentation overhead.
@ -230,7 +229,6 @@ struct ScanSession {
unsigned optical_line_count = 0;
// the resolution of the output data.
// gl843-only
unsigned output_resolution = 0;
// the offset in pixels from the beginning of output data
@ -343,7 +341,7 @@ void serialize(Stream& str, ScanSession& x)
serialize(str, x.params);
serialize_newline(str);
serialize(str, x.computed);
serialize(str, x.ccd_size_divisor);
serialize(str, x.full_resolution);
serialize(str, x.optical_resolution);
serialize(str, x.optical_pixels);
serialize(str, x.optical_pixels_raw);