genesys: Use new image pipeline for CCD line shifts and unstagger

merge-requests/183/head
Povilas Kanapickas 2019-09-13 17:04:01 +03:00
rodzic 0b1bfa3f12
commit bf7e890fa4
11 zmienionych plików z 12 dodań i 161 usunięć

Wyświetl plik

@ -3439,9 +3439,8 @@ static void genesys_fill_read_buffer(Genesys_Device* dev)
static void genesys_read_ordered_data(Genesys_Device* dev, SANE_Byte* destination, size_t* len)
{
DBG_HELPER(dbg);
size_t bytes, extra;
size_t bytes;
unsigned int channels, depth, src_pixels;
unsigned int ccd_shift[12], shift_count;
uint8_t *work_buffer_src;
uint8_t *work_buffer_dst;
unsigned int dst_lines;
@ -3489,31 +3488,6 @@ static void genesys_read_ordered_data(Genesys_Device* dev, SANE_Byte* destinatio
((dev->read_bytes_left_after_deseg + dev->read_buffer.avail()) * 8UL) /
(src_pixels * channels * depth));
if (channels == 1)
{
ccd_shift[0] = 0;
ccd_shift[1] = dev->current_setup.stagger;
shift_count = 2;
}
else
{
ccd_shift[0] =
((dev->ld_shift_r * dev->settings.yres) /
dev->motor.base_ydpi);
ccd_shift[1] =
((dev->ld_shift_g * dev->settings.yres) /
dev->motor.base_ydpi);
ccd_shift[2] =
((dev->ld_shift_b * dev->settings.yres) /
dev->motor.base_ydpi);
ccd_shift[3] = ccd_shift[0] + dev->current_setup.stagger;
ccd_shift[4] = ccd_shift[1] + dev->current_setup.stagger;
ccd_shift[5] = ccd_shift[2] + dev->current_setup.stagger;
shift_count = 6;
}
/* convert data */
/*
@ -3546,56 +3520,6 @@ Problems with the first approach:
src_buffer = &(dev->read_buffer);
// maybe reverse effects of ccd layout
if (dev->session.pipeline_needs_ccd)
{
// should not happen with depth == 1.
if (depth == 1) {
throw SaneException("Can't reverse ccd single bit data\n");
}
dst_buffer = &(dev->shrink_buffer);
work_buffer_src = src_buffer->get_read_pos();
bytes = src_buffer->avail();
extra =
(dev->current_setup.max_shift * src_pixels * channels * depth) / 8;
/*extra bytes are reserved, and should not be consumed*/
if (bytes < extra)
bytes = 0;
else
bytes -= extra;
/*how many bytes can be processed here?*/
/*we are greedy. we work as much as possible*/
if (bytes > dst_buffer->size() - dst_buffer->avail())
bytes = dst_buffer->size() - dst_buffer->avail();
dst_lines = (bytes * 8) / (src_pixels * channels * depth);
bytes = (dst_lines * src_pixels * channels * depth) / 8;
work_buffer_dst = dst_buffer->get_write_pos(bytes);
DBG(DBG_info, "%s: un-ccd-ing %d lines\n", __func__, dst_lines);
if (dst_lines != 0)
{
if (depth == 8) {
genesys_reverse_ccd_8(work_buffer_src, work_buffer_dst, dst_lines,
src_pixels * channels, ccd_shift, shift_count);
} else {
genesys_reverse_ccd_16(work_buffer_src, work_buffer_dst, dst_lines,
src_pixels * channels, ccd_shift, shift_count);
}
dst_buffer->produce(bytes);
src_buffer->consume(bytes);
}
src_buffer = dst_buffer;
}
// maybe shrink(or enlarge) lines
if (dev->session.pipeline_needs_shrink) {

Wyświetl plik

@ -45,70 +45,6 @@
* Conversion filters for genesys backend
*/
static void FUNC_NAME(genesys_reverse_ccd) (uint8_t* src_data, uint8_t* dst_data,
unsigned int lines, unsigned int components_per_line,
unsigned int *ccd_shift, unsigned int component_count)
{
DBG_HELPER(dbg);
unsigned int x, y, c;
COMPONENT_TYPE *src = (COMPONENT_TYPE *)src_data;
COMPONENT_TYPE *dst = (COMPONENT_TYPE *)dst_data;
COMPONENT_TYPE *srcp;
COMPONENT_TYPE *dstp;
unsigned int pitch = components_per_line;
unsigned int ccd_shift_pitch[12];
unsigned int *csp;
for (c = 0; c < component_count; c++)
ccd_shift_pitch[c] = ccd_shift[c] * pitch;
/*
* cache efficiency:
we are processing a single line component_count times, so it should fit
into the cpu cache for maximum efficiency. our lines take
maximum 252kb(3 channels, 16bit, 2400dpi, full gl841 shading range)
* instruction efficiency:
the innermost loop runs long and consists of 3 adds, one compare,
2 derefences.
*/
/*
for (y = 0; y < lines; y++) {
csp = ccd_shift_pitch;
for (c = 0; c < component_count; c++) {
srcp = src + c + *csp++;
dstp = dst + c;
for (x = 0; x < pitch; x += component_count) {
*dstp = *srcp;
srcp += component_count;
dstp += component_count;
}
}
dst += pitch;
src += pitch;
}
*/
/*
* cache efficency:
here only line_dist_pitch needs to stay in cache. 12*4 = 48 bytes
* instruction efficiency:
we have a short running inner loop, consisting of 4 incs, 2 compare, 1 add,
2 dereference and 1 indexed dereference.
the enclosing loop is long running, consisting of 1 add, 1 compare.
*/
srcp = src;
dstp = dst;
for (y = 0; y < lines; y++) {
for (x = 0; x < pitch; x += component_count) {
csp = ccd_shift_pitch;
for (c = 0; c < component_count && c + x < pitch; c++) {
*dstp = srcp[*csp++];
dstp++;
srcp++;
}
}
}
}
static void FUNC_NAME(genesys_shrink_lines) (uint8_t* src_data, uint8_t* dst_data,
unsigned int lines,
unsigned int src_pixels, unsigned int dst_pixels,

Wyświetl plik

@ -55,7 +55,6 @@ Genesys_Device::~Genesys_Device()
void Genesys_Device::clear()
{
read_buffer.clear();
shrink_buffer.clear();
out_buffer.clear();
binarize_buffer.clear();
local_buffer.clear();

Wyświetl plik

@ -282,7 +282,6 @@ struct Genesys_Device
SANE_Bool needs_home_ta = 0;
Genesys_Buffer read_buffer;
Genesys_Buffer shrink_buffer;
Genesys_Buffer out_buffer;
// buffer for digital lineart from gray data

Wyświetl plik

@ -1053,9 +1053,6 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -718,9 +718,6 @@ static void gl646_setup_registers(Genesys_Device* dev,
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -1875,9 +1875,6 @@ dummy \ scanned lines
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -1292,9 +1292,6 @@ static void gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -918,9 +918,6 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -928,9 +928,6 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
dev->read_buffer.clear();
dev->read_buffer.alloc(session.buffer_size_read);
dev->shrink_buffer.clear();
dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear();
dev->out_buffer.alloc(session.buffer_size_out);

Wyświetl plik

@ -1519,6 +1519,17 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
}
if (session.max_color_shift_lines > 0 && session.params.channels == 3) {
std::size_t shift_r = (dev->ld_shift_r * session.params.yres) / dev->motor.base_ydpi;
std::size_t shift_g = (dev->ld_shift_g * session.params.yres) / dev->motor.base_ydpi;
std::size_t shift_b = (dev->ld_shift_b * session.params.yres) / dev->motor.base_ydpi;
dev->pipeline.push_node<ImagePipelineNodeComponentShiftLines>(shift_r, shift_g, shift_b);
}
if (session.num_staggered_lines > 0) {
std::vector<std::size_t> shifts{0, session.num_staggered_lines};
dev->pipeline.push_node<ImagePipelineNodePixelShiftLines>(shifts);
}
auto read_from_pipeline = [dev](std::size_t size, std::uint8_t* out_data)
{