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

genesys: Simplify desegmentation state (part 5)

See merge request sane-project/backends!169
merge-requests/170/head
Povilas Kanapickas 2019-09-27 19:44:15 +00:00
commit 3618a244af
11 zmienionych plików z 89 dodań i 111 usunięć

Wyświetl plik

@ -3424,17 +3424,17 @@ static void genesys_fill_line_interp_buffer(Genesys_Device* dev, uint8_t* work_b
// dev->line_interp holds the number of lines scanned for one line of data sent
if (((dev->line_count / dev->session.params.channels) % dev->line_interp) == 0) {
/* copy pixel when line matches */
work_buffer_dst[count] = dev->oe_buffer.get_read_pos()[dev->deseg.curr_byte];
work_buffer_dst[count] = dev->oe_buffer.get_read_pos()[dev->deseg_curr_byte];
count++;
}
// always update pointer so we skip uncopied data
dev->deseg.curr_byte++;
dev->deseg_curr_byte++;
/* go to next line if needed */
if (dev->deseg.curr_byte == dev->deseg.pixel_groups) {
dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->deseg.raw_channel_bytes);
dev->deseg.curr_byte = 0;
if (dev->deseg_curr_byte == dev->session.output_segment_pixel_group_count) {
dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->session.output_line_bytes_raw);
dev->deseg_curr_byte = 0;
dev->line_count++;
}
@ -3475,7 +3475,7 @@ static void genesys_fill_segmented_buffer(Genesys_Device* dev, uint8_t* work_buf
while (count < size)
{
if (depth==1) {
while (dev->deseg.curr_byte < dev->deseg.pixel_groups && count < size) {
while (dev->deseg_curr_byte < dev->session.output_segment_pixel_group_count && count < size) {
for (unsigned n = 0; n < dev->session.segment_count; n++) {
work_buffer_dst[count+n] = 0;
}
@ -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->session.conseq_pixel_dist_bytes * dev->segment_order[n]])&(128>>i)) {
if ((dev->oe_buffer.get_read_pos()[dev->deseg_curr_byte + dev->session.output_segment_start_offset + dev->session.conseq_pixel_dist_bytes * dev->segment_order[n]])&(128>>i)) {
work_buffer_dst[k] |= 1;
}
}
@ -3492,35 +3492,35 @@ static void genesys_fill_segmented_buffer(Genesys_Device* dev, uint8_t* work_buf
/* update counter and pointer */
count += dev->session.segment_count;
dev->deseg.curr_byte++;
dev->deseg_curr_byte++;
}
}
if (depth==8) {
while (dev->deseg.curr_byte < dev->deseg.pixel_groups && count < size) {
while (dev->deseg_curr_byte < dev->session.output_segment_pixel_group_count && 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->session.conseq_pixel_dist_bytes *dev->segment_order[n]];
work_buffer_dst[count+n] = dev->oe_buffer.get_read_pos()[dev->deseg_curr_byte + dev->session.output_segment_start_offset + dev->session.conseq_pixel_dist_bytes *dev->segment_order[n]];
}
/* update counter and pointer */
count += dev->session.segment_count;
dev->deseg.curr_byte++;
dev->deseg_curr_byte++;
}
}
if (depth==16) {
while (dev->deseg.curr_byte < dev->deseg.pixel_groups && count < size) {
while (dev->deseg_curr_byte < dev->session.output_segment_pixel_group_count && 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->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];
work_buffer_dst[count+n*2] = dev->oe_buffer.get_read_pos()[dev->deseg_curr_byte + dev->session.output_segment_start_offset + 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->session.output_segment_start_offset + dev->session.conseq_pixel_dist_bytes * dev->segment_order[n] + 1];
}
/* update counter and pointer */
count += dev->session.segment_count * 2;
dev->deseg.curr_byte += 2;
dev->deseg_curr_byte += 2;
}
}
/* go to next line if needed */
if (dev->deseg.curr_byte == dev->deseg.pixel_groups) {
dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->deseg.raw_channel_bytes);
dev->deseg.curr_byte = 0;
if (dev->deseg_curr_byte == dev->session.output_segment_pixel_group_count) {
dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->session.output_line_bytes_raw);
dev->deseg_curr_byte = 0;
}
/* read a new buffer if needed */

Wyświetl plik

@ -192,26 +192,6 @@ struct Genesys_Model
}
};
// Describes the geometry of the raw data coming out of the scanner for desegmentation.
struct DesegmentationState
{
// The number of bytes to skip at start of line. Currently it's always zero.
unsigned skip_bytes = 0;
// The number of "even" pixels to scan. This corresponds to the number of pixels that will be
// scanned from a single segment
unsigned pixel_groups = 0;
// Total bytes in a channel received from a scanner
unsigned raw_channel_bytes = 0;
// Total bytes in a line received from a scanner
unsigned raw_line_bytes = 0;
// The current byte during desegmentation process
unsigned curr_byte = 0;
};
/**
* Describes the current device status for the backend
* session. This should be more accurately called
@ -303,7 +283,7 @@ struct Genesys_Device
Genesys_Buffer local_buffer;
// bytes to read from desegmentation step. This is not the same as physical bytes read from
// scanners, see `deseg.raw_line_bytes` which corresponds to this information on certain
// scanners, see `session.output_line_bytes_raw` which corresponds to this information on certain
// scanners.
size_t read_bytes_left_after_deseg = 0;
@ -312,7 +292,8 @@ struct Genesys_Device
// total bytes read to be sent to frontend
size_t total_bytes_to_read = 0;
DesegmentationState deseg;
// The current byte during desegmentation process
size_t deseg_curr_byte = 0;
// contains the real used values
Genesys_Current_Setup current_setup;

Wyświetl plik

@ -945,33 +945,22 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set24(REG_ENDPIXEL, endx / session.segment_count);
DBG(DBG_io2, "%s: endpixel used=%d\n", __func__, endx / session.segment_count);
// words(16bit) before gamma, conversion to 8 bit or lineart
dev->deseg.raw_channel_bytes =
multiply_by_depth_ceil(session.output_pixels / session.ccd_size_divisor,
session.params.depth);
dev->deseg.curr_byte = 0;
dev->deseg.skip_bytes = 0;
dev->deseg.pixel_groups = 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->deseg_curr_byte = 0;
dev->line_count = 0;
dev->line_interp = 0;
DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
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->line_interp=%lu\n", __func__, (unsigned long)dev->line_interp);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;
/* allocate buffer for odd/even pixels handling */
// BUG: we shouldn't multiply by channels here
dev->oe_buffer.clear();
dev->oe_buffer.alloc(dev->deseg.raw_line_bytes);
dev->oe_buffer.alloc(session.output_line_bytes_raw * session.params.channels);
// MAXWD is expressed in 2 words unit
reg->set24(REG_MAXWD, dev->deseg.raw_line_bytes);
DBG (DBG_io2, "%s: words_per_line used=%d\n", __func__, dev->deseg.raw_line_bytes);
// BUG: we shouldn't multiply by channels here
reg->set24(REG_MAXWD, session.output_line_bytes_raw * session.params.channels);
reg->set24(REG_LPERIOD, exposure_time);
DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time);

Wyświetl plik

@ -563,9 +563,6 @@ static void gl646_setup_registers(Genesys_Device* dev,
DBG(DBG_info, "%s: startx=%d, endx=%d, ccd_size_divisor=%d\n", __func__, sx, ex,
session.ccd_size_divisor);
dev->deseg.raw_channel_bytes = session.output_channel_bytes;
dev->deseg.raw_line_bytes = session.output_line_bytes;
regs->set24(REG_MAXWD, session.output_line_bytes);
regs->set16(REG_DPISET, session.output_resolution * session.ccd_size_divisor *
@ -1511,7 +1508,7 @@ static void gl646_detect_document_end(Genesys_Device* dev)
/* we add the number of lines needed to read the last part of the document in */
lines = (SANE_UNFIX(dev->model->y_offset) * dev->session.params.yres) / MM_PER_INCH;
DBG(DBG_io, "%s: adding %d line to flush\n", __func__, lines);
bytes_left += lines * dev->deseg.raw_line_bytes;
bytes_left += lines * dev->session.output_line_bytes_raw;
if (dev->session.params.depth > 8) {
bytes_left = 2 * bytes_left;

Wyświetl plik

@ -1604,9 +1604,6 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_ENDPIXEL, end);
DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d\n", __func__, start, end);
dev->deseg.raw_line_bytes = session.output_line_bytes;
dev->deseg.raw_channel_bytes = session.output_line_bytes;
reg->set24(REG_MAXWD, session.output_line_bytes);
reg->set16(REG_LPERIOD, exposure_time);
@ -2441,7 +2438,7 @@ static void gl841_detect_document_end(Genesys_Device* dev)
/* the current scancnt is also the final one, so we use it to
* compute total bytes to read. We also add the line count to eject document */
total_bytes_to_read=(scancnt+postcnt) * dev->deseg.raw_line_bytes;
total_bytes_to_read=(scancnt+postcnt) * dev->session.output_line_bytes_raw;
DBG(DBG_io, "%s: old total_bytes_to_read=%u\n", __func__,
(unsigned int)dev->total_bytes_to_read);

Wyświetl plik

@ -1157,13 +1157,8 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx);
dev->deseg.raw_line_bytes = session.output_channel_bytes; // FIXME: this is not currently used
dev->deseg.raw_channel_bytes = session.output_channel_bytes; // FIXME: this is not currently used
DBG(DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
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);
/* MAXWD is expressed in 2 words unit */
/* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */
@ -1583,7 +1578,7 @@ static void gl843_detect_document_end(Genesys_Device* dev)
// number of bytes to read from scanner to get document out of it after
// end of document dectected by hardware sensor */
bytes_to_flush = lines * dev->deseg.raw_line_bytes;
bytes_to_flush = lines * dev->session.output_line_bytes_raw;
/* if we are already close to end of scan, flushing isn't needed */
if (bytes_to_flush < read_bytes_left)

Wyświetl plik

@ -684,7 +684,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
const ScanSession& session)
{
DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time);
unsigned int words_per_line;
unsigned int dpihw;
GenesysRegister *r;
@ -713,9 +712,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
// 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 = session.optical_pixels /
(session.hwdpi_divisor * session.segment_count * ccd_pixels_per_system_pixel);
dev->deseg.skip_bytes = 0;
gl846_set_fe(dev, sensor, AFE_SET);
@ -811,12 +807,7 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
}*/
}
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
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.curr_byte = 0;
dev->deseg_curr_byte = 0;
dev->line_interp = 0;
unsigned dpiset = session.params.xres * ccd_pixels_per_system_pixel;
@ -830,18 +821,14 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
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->segnb =%lu\n", __func__, (unsigned long) dev->session.segment_count);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;
// BUG: we shouldn't multiply by channels here
dev->oe_buffer.clear();
dev->oe_buffer.alloc(dev->deseg.raw_line_bytes);
dev->oe_buffer.alloc(session.output_line_bytes_raw * session.params.channels);
/* MAXWD is expressed in 4 words unit */
reg->set24(REG_MAXWD, (dev->deseg.raw_line_bytes >> 2));
DBG(DBG_io2, "%s: words_per_line used=%d\n", __func__, dev->deseg.raw_line_bytes);
// BUG: we shouldn't multiply by channels here
reg->set24(REG_MAXWD, (session.output_line_bytes_raw * session.params.channels >> 2));
reg->set16(REG_LPERIOD, exposure_time);
DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time);

Wyświetl plik

@ -729,9 +729,6 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
// 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 = session.optical_pixels /
(session.hwdpi_divisor * session.segment_count * ccd_pixels_per_system_pixel);
dev->deseg.skip_bytes = 0;
gl847_set_fe(dev, sensor, AFE_SET);
@ -827,12 +824,7 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
}*/
}
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
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.curr_byte = 0;
dev->deseg_curr_byte = 0;
dev->line_interp = 0;
unsigned dpiset = session.params.xres * ccd_pixels_per_system_pixel;
@ -846,18 +838,14 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels);
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->segnb =%lu\n", __func__, (unsigned long) dev->session.segment_count);
dev->deseg.raw_line_bytes = dev->deseg.raw_channel_bytes * session.params.channels;
// BUG: we shouldn't multiply by channels here
dev->oe_buffer.clear();
dev->oe_buffer.alloc(dev->deseg.raw_line_bytes);
dev->oe_buffer.alloc(session.output_line_bytes_raw * session.params.channels);
/* MAXWD is expressed in 4 words unit */
reg->set24(REG_MAXWD, (dev->deseg.raw_line_bytes >> 2));
DBG(DBG_io2, "%s: words_per_line used=%d\n", __func__, dev->deseg.raw_line_bytes);
// BUG: we shouldn't multiply by channels here
reg->set24(REG_MAXWD, (session.output_line_bytes_raw * session.params.channels >> 2));
reg->set16(REG_LPERIOD, exposure_time);
DBG(DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time);

Wyświetl plik

@ -1325,8 +1325,14 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor&
}
s.optical_pixels_raw = s.optical_pixels;
s.output_line_bytes_raw = s.output_line_bytes;
s.conseq_pixel_dist_bytes = 0;
if (dev->model->asic_type == AsicType::GL646) {
// BUG: most likely segmented sensors were never used, so incorrect value was supplied
s.output_line_bytes_raw = s.output_channel_bytes;
}
if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
@ -1345,9 +1351,30 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor&
s.conseq_pixel_dist_bytes = multiply_by_depth_ceil(s.conseq_pixel_dist_bytes,
s.params.depth);
}
s.output_line_bytes_raw = multiply_by_depth_ceil(
(s.optical_pixels_raw * s.output_resolution) / sensor.optical_res / s.segment_count,
s.params.depth);
}
// TODO: gl124 conseq_pixel_dist_bytes
if (dev->model->asic_type == AsicType::GL124) {
s.output_line_bytes_raw = multiply_by_depth_ceil(s.output_pixels / s.ccd_size_divisor,
s.params.depth);
s.conseq_pixel_dist_bytes = s.output_line_bytes_raw / s.segment_count;
}
s.output_segment_pixel_group_count = 0;
if (dev->model->asic_type == AsicType::GL124) {
s.output_segment_pixel_group_count = s.output_line_bytes_raw / s.segment_count;
}
if (dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847)
{
s.output_segment_pixel_group_count = multiply_by_depth_ceil(
s.optical_pixels / (s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel),
s.params.depth);
}
compute_session_buffer_sizes(dev->model->asic_type, s);
}
@ -2029,6 +2056,7 @@ void debug_dump(unsigned level, const ScanSession& session)
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);
DBG(level, " output_line_bytes_raw : %d\n", session.output_line_bytes_raw);
DBG(level, " output_line_count : %d\n", session.output_line_count);
DBG(level, " num_staggered_lines : %d\n", session.num_staggered_lines);
DBG(level, " max_color_shift_lines : %d\n", session.max_color_shift_lines);
@ -2036,6 +2064,9 @@ void debug_dump(unsigned level, const ScanSession& session)
DBG(level, " segment_count : %d\n", session.segment_count);
DBG(level, " pixel_startx : %d\n", session.pixel_startx);
DBG(level, " pixel_endx : %d\n", session.pixel_endx);
DBG(level, " conseq_pixel_dist_bytes : %d\n", session.conseq_pixel_dist_bytes);
DBG(level, " output_segment_pixel_group_count : %d\n",
session.output_segment_pixel_group_count);
DBG(level, " buffer_size_read : %zu\n", session.buffer_size_read);
DBG(level, " buffer_size_read : %zu\n", session.buffer_size_lines);
DBG(level, " buffer_size_shrink : %zu\n", session.buffer_size_shrink);

Wyświetl plik

@ -659,7 +659,7 @@ 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)
inline uint64_t multiply_by_depth_ceil(uint64_t pixels, uint64_t depth)
{
if (depth == 1) {
return (pixels / 8) + ((pixels % 8) ? 1 : 0);

Wyświetl plik

@ -238,15 +238,19 @@ struct ScanSession {
// gl843-only
unsigned output_resolution = 0;
// the number of pixels in output data
// the number of pixels in output data (after desegmentation)
unsigned output_pixels = 0;
// the number of bytes in the output of a channel of a single line
// the number of bytes in the output of a channel of a single line (after desegmentation)
unsigned output_channel_bytes = 0;
// the number of bytes in the output of a single line
// the number of bytes in the output of a single line (after desegmentation)
unsigned output_line_bytes = 0;
// the number of bytes per line in the output data from the scanner (before desegmentation)
// Equal to output_line_bytes if sensor does not have segments
unsigned output_line_bytes_raw = 0;
// 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.
unsigned output_line_count = 0;
@ -272,6 +276,15 @@ struct ScanSession {
// only on gl124, gl846, gl847
unsigned conseq_pixel_dist_bytes = 0;
// The number of "even" pixels to scan. This corresponds to the number of pixels that will be
// scanned from a single segment
// only on gl124, gl846, gl847
unsigned output_segment_pixel_group_count = 0;
// The number of bytes to skip at start of line during desegmentation.
// Currently it's always zero.
unsigned output_segment_start_offset = 0;
// the sizes of the corresponding buffers
size_t buffer_size_read = 0;
size_t buffer_size_lines = 0;