Merge branch 'genesys-desegmentation-refactor' into 'master'

genesys: Simplify desegmentation state (part 4)

See merge request sane-project/backends!168
merge-requests/169/merge
Povilas Kanapickas 2019-09-27 19:22:08 +00:00
commit 86b9768dd3
9 zmienionych plików z 70 dodań i 48 usunięć

Wyświetl plik

@ -3484,7 +3484,7 @@ static void genesys_fill_segmented_buffer(Genesys_Device* dev, uint8_t* work_buf
k = count + (i * dev->session.segment_count) / 8;
for (unsigned n = 0; n < dev->session.segment_count; n++) {
work_buffer_dst[k] = work_buffer_dst[k] << 1;
if ((dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->deseg.conseq_pixel_dist_bytes * dev->segment_order[n]])&(128>>i)) {
if ((dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->session.conseq_pixel_dist_bytes * dev->segment_order[n]])&(128>>i)) {
work_buffer_dst[k] |= 1;
}
}
@ -3498,7 +3498,7 @@ static void genesys_fill_segmented_buffer(Genesys_Device* dev, uint8_t* work_buf
if (depth==8) {
while (dev->deseg.curr_byte < dev->deseg.pixel_groups && count < size) {
for (unsigned n = 0; n < dev->session.segment_count; n++) {
work_buffer_dst[count+n] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->deseg.conseq_pixel_dist_bytes *dev->segment_order[n]];
work_buffer_dst[count+n] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->session.conseq_pixel_dist_bytes *dev->segment_order[n]];
}
/* update counter and pointer */
count += dev->session.segment_count;
@ -3508,8 +3508,8 @@ static void genesys_fill_segmented_buffer(Genesys_Device* dev, uint8_t* work_buf
if (depth==16) {
while (dev->deseg.curr_byte < dev->deseg.pixel_groups && count < size) {
for (unsigned n = 0; n < dev->session.segment_count; n++) {
work_buffer_dst[count+n*2] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->deseg.conseq_pixel_dist_bytes * dev->segment_order[n]];
work_buffer_dst[count+n*2+1] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->deseg.conseq_pixel_dist_bytes * dev->segment_order[n] + 1];
work_buffer_dst[count+n*2] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->session.conseq_pixel_dist_bytes * dev->segment_order[n]];
work_buffer_dst[count+n*2+1] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte + dev->deseg.skip_bytes + dev->session.conseq_pixel_dist_bytes * dev->segment_order[n] + 1];
}
/* update counter and pointer */
count += dev->session.segment_count * 2;

Wyświetl plik

@ -202,10 +202,6 @@ struct DesegmentationState
// scanned from a single segment
unsigned pixel_groups = 0;
// Distance in bytes between consecutive pixels, e.g. between odd and even pixels. Note that
// the number of segments can be large.
unsigned conseq_pixel_dist_bytes = 0;
// Total bytes in a channel received from a scanner
unsigned raw_channel_bytes = 0;

Wyświetl plik

@ -953,7 +953,7 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
dev->deseg.curr_byte = 0;
dev->deseg.skip_bytes = 0;
dev->deseg.pixel_groups = dev->deseg.raw_channel_bytes / session.segment_count;
dev->deseg.conseq_pixel_dist_bytes = dev->deseg.raw_channel_bytes / session.segment_count;
const_cast<ScanSession&>(session).conseq_pixel_dist_bytes = dev->deseg.raw_channel_bytes / session.segment_count;
dev->line_count = 0;
dev->line_interp = 0;
@ -961,7 +961,6 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long) dev->deseg.raw_channel_bytes);
DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long) dev->deseg.pixel_groups);
DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long) dev->deseg.conseq_pixel_dist_bytes);
DBG (DBG_io2, "%s: dev->line_interp=%lu\n", __func__, (unsigned long)dev->line_interp);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;

Wyświetl plik

@ -1164,7 +1164,6 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG(DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);
DBG(DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long) dev->deseg.raw_channel_bytes);
DBG(DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long) dev->deseg.pixel_groups);
DBG(DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long) dev->deseg.conseq_pixel_dist_bytes);
/* MAXWD is expressed in 2 words unit */
/* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */

Wyświetl plik

@ -708,24 +708,15 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
start |= 1;
}
unsigned startx = start + sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel;
unsigned endx = startx + session.optical_pixels;
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;
dev->deseg.pixel_groups = (endx - startx) / ccd_pixels_per_system_pixel;
dev->deseg.conseq_pixel_dist_bytes = 0;
dev->deseg.pixel_groups = session.optical_pixels /
(session.hwdpi_divisor * session.segment_count * ccd_pixels_per_system_pixel);
dev->deseg.skip_bytes = 0;
/* in cas of multi-segments sensor, we have to add the witdh
* of the sensor crossed by the scan area */
if (session.segment_count > 1) {
dev->deseg.conseq_pixel_dist_bytes = sensor_profile.segment_size;
}
/* use a segcnt rounded to next even number */
endx += ((dev->deseg.conseq_pixel_dist_bytes + 1) & 0xfffe) * (session.segment_count - 1) * ccd_pixels_per_system_pixel;
gl846_set_fe(dev, sensor, AFE_SET);
/* enable shading */
@ -824,7 +815,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
words_per_line = ((endx - startx) * session.params.xres) / sensor.get_register_hwdpi(session.params.xres * ccd_pixels_per_system_pixel);
dev->deseg.raw_channel_bytes = multiply_by_depth_ceil(words_per_line, session.params.depth);
dev->deseg.pixel_groups = multiply_by_depth_ceil(dev->deseg.pixel_groups, session.params.depth);
dev->deseg.conseq_pixel_dist_bytes = multiply_by_depth_ceil(dev->deseg.conseq_pixel_dist_bytes, session.params.depth);
dev->deseg.curr_byte = 0;
dev->line_interp = 0;
@ -842,7 +832,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long) dev->deseg.raw_channel_bytes);
DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long) dev->deseg.pixel_groups);
DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long) dev->deseg.conseq_pixel_dist_bytes);
DBG (DBG_io2, "%s: dev->segnb =%lu\n", __func__, (unsigned long) dev->session.segment_count);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;

Wyświetl plik

@ -724,27 +724,15 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
// 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;
/* sensors are built from 600 dpi segments for LiDE 100/200
* and 1200 dpi for the 700F */
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;
dev->deseg.pixel_groups = (endx - startx) / ccd_pixels_per_system_pixel;
dev->deseg.conseq_pixel_dist_bytes = 0;
dev->deseg.pixel_groups = session.optical_pixels /
(session.hwdpi_divisor * session.segment_count * ccd_pixels_per_system_pixel);
dev->deseg.skip_bytes = 0;
/* in cas of multi-segments sensor, we have to add the witdh
* of the sensor crossed by the scan area */
if (session.segment_count > 1) {
dev->deseg.conseq_pixel_dist_bytes = sensor_profile.segment_size;
}
/* use a segcnt rounded to next even number */
endx += ((dev->deseg.conseq_pixel_dist_bytes + 1) & 0xfffe) * (session.segment_count - 1) * ccd_pixels_per_system_pixel;
gl847_set_fe(dev, sensor, AFE_SET);
/* enable shading */
@ -843,7 +831,6 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
dev->deseg.raw_channel_bytes = multiply_by_depth_ceil(((endx - startx) * session.params.xres) / dpihw,
session.params.depth);
dev->deseg.pixel_groups = multiply_by_depth_ceil(dev->deseg.pixel_groups, session.params.depth);
dev->deseg.conseq_pixel_dist_bytes = multiply_by_depth_ceil(dev->deseg.conseq_pixel_dist_bytes, session.params.depth);
dev->deseg.curr_byte = 0;
dev->line_interp = 0;
@ -861,7 +848,6 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth);
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long) dev->deseg.raw_channel_bytes);
DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long) dev->deseg.pixel_groups);
DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long) dev->deseg.conseq_pixel_dist_bytes);
DBG (DBG_io2, "%s: dev->segnb =%lu\n", __func__, (unsigned long) dev->session.segment_count);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;

Wyświetl plik

@ -1303,19 +1303,52 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor&
s.output_channel_bytes = multiply_by_depth_ceil(s.output_pixels, s.params.depth);
s.output_line_bytes = s.output_channel_bytes * s.params.channels;
s.segment_count = 1;
if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR || dev->model->asic_type == AsicType::GL124) {
const SensorProfile* sensor_profile = nullptr;
if (dev->model->asic_type == AsicType::GL124 ||
dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
{
unsigned ccd_size_divisor_for_profile = 1;
if (dev->model->asic_type == AsicType::GL124) {
ccd_size_divisor_for_profile = s.ccd_size_divisor;
}
unsigned dpihw = sensor.get_register_hwdpi(s.output_resolution * ccd_pixels_per_system_pixel);
const auto& sensor_profile = get_sensor_profile(dev->model->asic_type, sensor, dpihw,
ccd_size_divisor_for_profile);
s.segment_count = sensor_profile.get_segment_count();
sensor_profile = &get_sensor_profile(dev->model->asic_type, sensor, dpihw,
ccd_size_divisor_for_profile);
}
s.segment_count = 1;
if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR || dev->model->asic_type == AsicType::GL124) {
s.segment_count = sensor_profile->get_segment_count();
}
s.optical_pixels_raw = s.optical_pixels;
s.conseq_pixel_dist_bytes = 0;
if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
{
if (s.segment_count > 1) {
s.conseq_pixel_dist_bytes = sensor_profile->segment_size;
// in case of multi-segments sensor, we have to add the width of the sensor crossed by
// the scan area
unsigned extra_segment_scan_area = align_multiple_ceil(s.conseq_pixel_dist_bytes, 2);
extra_segment_scan_area *= s.segment_count - 1;
extra_segment_scan_area *= s.hwdpi_divisor * s.segment_count;
extra_segment_scan_area *= ccd_pixels_per_system_pixel;
s.optical_pixels_raw += extra_segment_scan_area;
s.conseq_pixel_dist_bytes = multiply_by_depth_ceil(s.conseq_pixel_dist_bytes,
s.params.depth);
}
}
// TODO: gl124 conseq_pixel_dist_bytes
compute_session_buffer_sizes(dev->model->asic_type, s);
}
@ -1992,6 +2025,7 @@ void debug_dump(unsigned level, const ScanSession& session)
DBG(level, " ccd_size_divisor : %d\n", session.ccd_size_divisor);
DBG(level, " optical_resolution : %d\n", session.optical_resolution);
DBG(level, " optical_pixels : %d\n", session.optical_pixels);
DBG(level, " optical_pixels_raw : %d\n", session.optical_pixels_raw);
DBG(level, " output_resolution : %d\n", session.output_resolution);
DBG(level, " output_pixels : %d\n", session.output_pixels);
DBG(level, " output_line_bytes : %d\n", session.output_line_bytes);

Wyświetl plik

@ -649,6 +649,16 @@ inline T abs_diff(T a, T b)
}
}
inline uint64_t align_multiple_floor(uint64_t x, uint64_t multiple)
{
return (x / multiple) * multiple;
}
inline uint64_t align_multiple_ceil(uint64_t x, uint64_t multiple)
{
return ((x + multiple - 1) / multiple) * multiple;
}
inline unsigned multiply_by_depth_ceil(unsigned pixels, unsigned depth)
{
if (depth == 1) {

Wyświetl plik

@ -227,9 +227,13 @@ struct ScanSession {
// the optical resolution of the scanner.
unsigned optical_resolution = 0;
// the number of pixels at the optical resolution.
// the number of pixels at the optical resolution, not including segmentation overhead.
unsigned optical_pixels = 0;
// the number of pixels at the optical resolution, including segmentation overhead.
// only on gl846, g847
unsigned optical_pixels_raw = 0;
// the resolution of the output data.
// gl843-only
unsigned output_resolution = 0;
@ -263,6 +267,11 @@ struct ScanSession {
unsigned pixel_startx = 0;
unsigned pixel_endx = 0;
// Distance in bytes between consecutive pixels, e.g. between odd and even pixels. Note that
// the number of segments can be large.
// only on gl124, gl846, gl847
unsigned conseq_pixel_dist_bytes = 0;
// the sizes of the corresponding buffers
size_t buffer_size_read = 0;
size_t buffer_size_lines = 0;