kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-remove-image-enhancement' into 'master'
genesys: Remove image enhancement functionality See merge request sane-project/backends!460merge-requests/463/merge
commit
3cd0914f67
|
|
@ -578,7 +578,10 @@ libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
|
|||
nodist_libsane_genesys_la_SOURCES = genesys-s.cpp
|
||||
libsane_genesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
|
||||
libsane_genesys_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
|
||||
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la ../sanei/sanei_magic.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo $(MATH_LIB) $(USB_LIBS) $(RESMGR_LIBS)
|
||||
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la \
|
||||
../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \
|
||||
../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo \
|
||||
$(MATH_LIB) $(USB_LIBS) $(RESMGR_LIBS)
|
||||
EXTRA_DIST += genesys.conf.in
|
||||
|
||||
libgphoto2_i_la_SOURCES = gphoto2.c gphoto2.h
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#define DEBUG_DECLARE_ONLY
|
||||
|
||||
#include "conv.h"
|
||||
#include "sane/sanei_magic.h"
|
||||
|
||||
namespace genesys {
|
||||
|
||||
|
|
@ -155,82 +154,4 @@ void genesys_gray_lineart(Genesys_Device* dev,
|
|||
}
|
||||
}
|
||||
|
||||
/** Look in image for likely left/right/bottom paper edges, then crop image.
|
||||
*/
|
||||
void genesys_crop(Genesys_Scanner* s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Device *dev = s->dev;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
|
||||
// first find edges if any
|
||||
TIE(sanei_magic_findEdges(&s->params, dev->img_buffer.data(),
|
||||
dev->settings.xres, dev->settings.yres,
|
||||
&top, &bottom, &left, &right));
|
||||
|
||||
DBG (DBG_io, "%s: t:%d b:%d l:%d r:%d\n", __func__, top, bottom, left,
|
||||
right);
|
||||
|
||||
// now crop the image
|
||||
TIE(sanei_magic_crop (&(s->params), dev->img_buffer.data(), top, bottom, left, right));
|
||||
|
||||
/* update counters to new image size */
|
||||
dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines;
|
||||
}
|
||||
|
||||
/** Look in image for likely upper and left paper edges, then rotate
|
||||
* image so that upper left corner of paper is upper left of image.
|
||||
*/
|
||||
void genesys_deskew(Genesys_Scanner *s, const Genesys_Sensor& sensor)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Device *dev = s->dev;
|
||||
|
||||
int x = 0, y = 0, bg;
|
||||
double slope = 0;
|
||||
|
||||
bg=0;
|
||||
if(s->params.format==SANE_FRAME_GRAY && s->params.depth == 1)
|
||||
{
|
||||
bg=0xff;
|
||||
}
|
||||
TIE(sanei_magic_findSkew(&s->params, dev->img_buffer.data(),
|
||||
sensor.full_resolution, sensor.full_resolution,
|
||||
&x, &y, &slope));
|
||||
|
||||
DBG(DBG_info, "%s: slope=%f => %f\n", __func__, slope, slope * 180 / M_PI);
|
||||
|
||||
// rotate image slope is in [-PI/2,PI/2]. Positive values rotate trigonometric direction wise
|
||||
TIE(sanei_magic_rotate(&s->params, dev->img_buffer.data(),
|
||||
x, y, slope, bg));
|
||||
}
|
||||
|
||||
/** remove lone dots
|
||||
*/
|
||||
void genesys_despeck(Genesys_Scanner* s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
TIE(sanei_magic_despeck(&s->params, s->dev->img_buffer.data(), s->despeck));
|
||||
}
|
||||
|
||||
/** Look if image needs rotation and apply it
|
||||
* */
|
||||
void genesys_derotate(Genesys_Scanner* s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
int angle = 0;
|
||||
|
||||
TIE(sanei_magic_findTurn(&s->params, s->dev->img_buffer.data(),
|
||||
s->resolution, s->resolution, &angle));
|
||||
|
||||
// apply rotation angle found
|
||||
TIE(sanei_magic_turn(&s->params, s->dev->img_buffer.data(), angle));
|
||||
|
||||
// update counters to new image size
|
||||
s->dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines;
|
||||
}
|
||||
|
||||
} // namespace genesys
|
||||
|
|
|
|||
|
|
@ -56,14 +56,6 @@ void genesys_gray_lineart(Genesys_Device* dev,
|
|||
std::uint8_t* src_data, std::uint8_t* dst_data,
|
||||
std::size_t pixels, size_t lines, std::uint8_t threshold);
|
||||
|
||||
void genesys_crop(Genesys_Scanner* s);
|
||||
|
||||
void genesys_deskew(Genesys_Scanner *s, const Genesys_Sensor& sensor);
|
||||
|
||||
void genesys_despeck(Genesys_Scanner* s);
|
||||
|
||||
void genesys_derotate(Genesys_Scanner* s);
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
#endif // BACKEND_GENESYS_CONV_H
|
||||
|
|
|
|||
|
|
@ -270,7 +270,6 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev)
|
|||
<< " line_count: " << dev.line_count << '\n'
|
||||
<< " segment_order: "
|
||||
<< format_indent_braced_list(4, format_vector_unsigned(4, dev.segment_order)) << '\n'
|
||||
<< " buffer_image: " << dev.buffer_image << '\n'
|
||||
<< " img_buffer.size(): " << dev.img_buffer.size() << '\n'
|
||||
<< '}';
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -353,9 +353,6 @@ struct Genesys_Device
|
|||
// an buffer that allows reading from `pipeline` in chunks of any size
|
||||
ImageBuffer pipeline_buffer;
|
||||
|
||||
// when true the scanned picture is first buffered to allow software image enhancements
|
||||
bool buffer_image = false;
|
||||
|
||||
// image buffer where the scanned picture is stored
|
||||
std::vector<std::uint8_t> img_buffer;
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@
|
|||
#include "test_scanner_interface.h"
|
||||
#include "test_settings.h"
|
||||
#include "../include/sane/sanei_config.h"
|
||||
#include "../include/sane/sanei_magic.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
|
@ -132,12 +131,6 @@ static SANE_String_Const cis_color_filter_list[] = {
|
|||
nullptr
|
||||
};
|
||||
|
||||
static SANE_Range swdespeck_range = {
|
||||
1,
|
||||
9,
|
||||
1
|
||||
};
|
||||
|
||||
static SANE_Range time_range = {
|
||||
0, /* minimum */
|
||||
60, /* maximum */
|
||||
|
|
@ -4449,20 +4442,6 @@ static void calc_parameters(Genesys_Scanner* s)
|
|||
// threshold curve for dynamic rasterization
|
||||
s->dev->settings.threshold_curve = s->threshold_curve;
|
||||
|
||||
/* some digital processing requires the whole picture to be buffered */
|
||||
/* no digital processing takes place when doing preview, or when bit depth is
|
||||
* higher than 8 bits */
|
||||
if ((s->swdespeck || s->swcrop || s->swdeskew || s->swderotate ||(fixed_to_float(s->swskip)>0))
|
||||
&& (!s->preview)
|
||||
&& (s->bit_depth <= 8))
|
||||
{
|
||||
s->dev->buffer_image = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->dev->buffer_image = false;
|
||||
}
|
||||
|
||||
/* brigthness and contrast only for for 8 bit scans */
|
||||
if(s->bit_depth <= 8)
|
||||
{
|
||||
|
|
@ -4853,61 +4832,6 @@ static void init_options(Genesys_Scanner* s)
|
|||
* memory than used by the full scanned image and may fail at high
|
||||
* resolution
|
||||
*/
|
||||
/* software deskew */
|
||||
s->opt[OPT_SWDESKEW].name = "swdeskew";
|
||||
s->opt[OPT_SWDESKEW].title = "Software deskew";
|
||||
s->opt[OPT_SWDESKEW].desc = "Request backend to rotate skewed pages digitally";
|
||||
s->opt[OPT_SWDESKEW].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_SWDESKEW].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
s->swdeskew = false;
|
||||
|
||||
/* software deskew */
|
||||
s->opt[OPT_SWDESPECK].name = "swdespeck";
|
||||
s->opt[OPT_SWDESPECK].title = "Software despeck";
|
||||
s->opt[OPT_SWDESPECK].desc = "Request backend to remove lone dots digitally";
|
||||
s->opt[OPT_SWDESPECK].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_SWDESPECK].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
s->swdespeck = false;
|
||||
|
||||
/* software despeckle radius */
|
||||
s->opt[OPT_DESPECK].name = "despeck";
|
||||
s->opt[OPT_DESPECK].title = "Software despeckle diameter";
|
||||
s->opt[OPT_DESPECK].desc = "Maximum diameter of lone dots to remove from scan";
|
||||
s->opt[OPT_DESPECK].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_DESPECK].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_DESPECK].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_DESPECK].constraint.range = &swdespeck_range;
|
||||
s->opt[OPT_DESPECK].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED | SANE_CAP_INACTIVE;
|
||||
s->despeck = 1;
|
||||
|
||||
/* crop by software */
|
||||
s->opt[OPT_SWCROP].name = "swcrop";
|
||||
s->opt[OPT_SWCROP].title = SANE_I18N ("Software crop");
|
||||
s->opt[OPT_SWCROP].desc = SANE_I18N ("Request backend to remove border from pages digitally");
|
||||
s->opt[OPT_SWCROP].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_SWCROP].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
s->opt[OPT_SWCROP].unit = SANE_UNIT_NONE;
|
||||
s->swcrop = false;
|
||||
|
||||
/* Software blank page skip */
|
||||
s->opt[OPT_SWSKIP].name = "swskip";
|
||||
s->opt[OPT_SWSKIP].title = SANE_I18N ("Software blank skip percentage");
|
||||
s->opt[OPT_SWSKIP].desc = SANE_I18N("Request driver to discard pages with low numbers of dark pixels");
|
||||
s->opt[OPT_SWSKIP].type = SANE_TYPE_FIXED;
|
||||
s->opt[OPT_SWSKIP].unit = SANE_UNIT_PERCENT;
|
||||
s->opt[OPT_SWSKIP].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_SWSKIP].constraint.range = &(percentage_range);
|
||||
s->opt[OPT_SWSKIP].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
s->swskip = 0; // disable by default
|
||||
|
||||
/* Software Derotate */
|
||||
s->opt[OPT_SWDEROTATE].name = "swderotate";
|
||||
s->opt[OPT_SWDEROTATE].title = SANE_I18N ("Software derotate");
|
||||
s->opt[OPT_SWDEROTATE].desc = SANE_I18N("Request driver to detect and correct 90 degree image rotation");
|
||||
s->opt[OPT_SWDEROTATE].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_SWDEROTATE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
s->opt[OPT_SWDEROTATE].unit = SANE_UNIT_NONE;
|
||||
s->swderotate = false;
|
||||
|
||||
/* Software brightness */
|
||||
s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
|
||||
|
|
@ -5446,114 +5370,6 @@ static void write_calibration(Genesys_Device::Calibration& calibration, const st
|
|||
write_calibration(str, calibration);
|
||||
}
|
||||
|
||||
/** @brief buffer scanned picture
|
||||
* In order to allow digital processing, we must be able to put all the
|
||||
* scanned picture in a buffer.
|
||||
*/
|
||||
static void genesys_buffer_image(Genesys_Scanner *s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
size_t maximum; /**> maximum bytes size of the scan */
|
||||
size_t len; /**> length of scanned data read */
|
||||
size_t total; /**> total of butes read */
|
||||
size_t size; /**> size of image buffer */
|
||||
size_t read_size; /**> size of reads */
|
||||
int lines; /** number of lines of the scan */
|
||||
Genesys_Device *dev = s->dev;
|
||||
|
||||
/* compute maximum number of lines for the scan */
|
||||
if (s->params.lines > 0)
|
||||
{
|
||||
lines = s->params.lines;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines = static_cast<int>((dev->model->y_size * dev->settings.yres) / MM_PER_INCH);
|
||||
}
|
||||
DBG(DBG_info, "%s: buffering %d lines of %d bytes\n", __func__, lines,
|
||||
s->params.bytes_per_line);
|
||||
|
||||
/* maximum bytes to read */
|
||||
maximum = s->params.bytes_per_line * lines;
|
||||
if (s->dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
maximum *= 8;
|
||||
}
|
||||
|
||||
/* initial size of the read buffer */
|
||||
size =
|
||||
((2048 * 2048) / s->params.bytes_per_line) * s->params.bytes_per_line;
|
||||
|
||||
/* read size */
|
||||
read_size = size / 2;
|
||||
|
||||
dev->img_buffer.resize(size);
|
||||
|
||||
/* loop reading data until we reach maximum or EOF */
|
||||
total = 0;
|
||||
while (total < maximum) {
|
||||
len = size - maximum;
|
||||
if (len > read_size)
|
||||
{
|
||||
len = read_size;
|
||||
}
|
||||
|
||||
try {
|
||||
genesys_read_ordered_data(dev, dev->img_buffer.data() + total, &len);
|
||||
} catch (const SaneException& e) {
|
||||
if (e.status() == SANE_STATUS_EOF) {
|
||||
// ideally we shouldn't end up here, but because computations are duplicated and
|
||||
// slightly different everywhere in the genesys backend, we have no other choice
|
||||
break;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
total += len;
|
||||
|
||||
// do we need to enlarge read buffer ?
|
||||
if (total + read_size > size) {
|
||||
size += read_size;
|
||||
dev->img_buffer.resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
/* since digital processing is going to take place,
|
||||
* issue head parking command so that the head move while
|
||||
* computing so we can save time
|
||||
*/
|
||||
if (!dev->model->is_sheetfed && !dev->parking) {
|
||||
dev->cmd_set->move_back_home(dev, has_flag(dev->model->flags, ModelFlag::MUST_WAIT));
|
||||
dev->parking = !has_flag(s->dev->model->flags, ModelFlag::MUST_WAIT);
|
||||
}
|
||||
|
||||
/* in case of dynamic lineart, we have buffered gray data which
|
||||
* must be converted to lineart first */
|
||||
if (s->dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
total/=8;
|
||||
std::vector<uint8_t> lineart(total);
|
||||
|
||||
genesys_gray_lineart (dev,
|
||||
dev->img_buffer.data(),
|
||||
lineart.data(),
|
||||
dev->settings.pixels,
|
||||
(total*8)/dev->settings.pixels,
|
||||
dev->settings.threshold);
|
||||
dev->img_buffer = lineart;
|
||||
}
|
||||
|
||||
/* update counters */
|
||||
dev->total_bytes_to_read = total;
|
||||
dev->total_bytes_read = 0;
|
||||
|
||||
/* update params */
|
||||
s->params.lines = total / s->params.bytes_per_line;
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
sanei_genesys_write_pnm_file("gl_unprocessed.pnm", dev->img_buffer.data(), s->params.depth,
|
||||
s->params.format==SANE_FRAME_RGB ? 3 : 1,
|
||||
s->params.pixels_per_line, s->params.lines);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------- SANE API functions ------------------------- */
|
||||
|
||||
void sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
|
||||
|
|
@ -5579,9 +5395,6 @@ void sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
|
|||
sanei_usb_init();
|
||||
}
|
||||
|
||||
/* init sanei_magic */
|
||||
sanei_magic_init();
|
||||
|
||||
s_scanners.init();
|
||||
s_devices.init();
|
||||
s_sane_devices.init();
|
||||
|
|
@ -5991,24 +5804,6 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
case OPT_LAMP_OFF_TIME:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->lamp_off_time;
|
||||
break;
|
||||
case OPT_SWDESKEW:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->swdeskew;
|
||||
break;
|
||||
case OPT_SWCROP:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->swcrop;
|
||||
break;
|
||||
case OPT_SWDESPECK:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->swdespeck;
|
||||
break;
|
||||
case OPT_SWDEROTATE:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->swderotate;
|
||||
break;
|
||||
case OPT_SWSKIP:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->swskip;
|
||||
break;
|
||||
case OPT_DESPECK:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->despeck;
|
||||
break;
|
||||
case OPT_CONTRAST:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->contrast;
|
||||
break;
|
||||
|
|
@ -6212,31 +6007,6 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_SWCROP:
|
||||
s->swcrop = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_SWDESKEW:
|
||||
s->swdeskew = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_DESPECK:
|
||||
s->despeck = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_SWDEROTATE:
|
||||
s->swderotate = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_SWSKIP:
|
||||
s->swskip = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_DISABLE_INTERPOLATION:
|
||||
s->disable_interpolation = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
|
|
@ -6262,38 +6032,14 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_SWDESPECK:
|
||||
s->swdespeck = *reinterpret_cast<SANE_Word*>(val);
|
||||
if (s->swdespeck) {
|
||||
ENABLE(OPT_DESPECK);
|
||||
} else {
|
||||
DISABLE(OPT_DESPECK);
|
||||
}
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
/* software enhancement functions only apply to 8 or 1 bits data */
|
||||
case OPT_BIT_DEPTH:
|
||||
s->bit_depth = *reinterpret_cast<SANE_Word*>(val);
|
||||
if(s->bit_depth>8)
|
||||
{
|
||||
DISABLE(OPT_SWDESKEW);
|
||||
DISABLE(OPT_SWDESPECK);
|
||||
DISABLE(OPT_SWCROP);
|
||||
DISABLE(OPT_DESPECK);
|
||||
DISABLE(OPT_SWDEROTATE);
|
||||
DISABLE(OPT_SWSKIP);
|
||||
DISABLE(OPT_CONTRAST);
|
||||
DISABLE(OPT_BRIGHTNESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
ENABLE(OPT_SWDESKEW);
|
||||
ENABLE(OPT_SWDESPECK);
|
||||
ENABLE(OPT_SWCROP);
|
||||
ENABLE(OPT_DESPECK);
|
||||
ENABLE(OPT_SWDEROTATE);
|
||||
ENABLE(OPT_SWSKIP);
|
||||
} else {
|
||||
ENABLE(OPT_CONTRAST);
|
||||
ENABLE(OPT_BRIGHTNESS);
|
||||
}
|
||||
|
|
@ -6586,7 +6332,7 @@ void sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
|
|||
* don't know the real document height.
|
||||
* We don't do that doing buffering image for digital processing
|
||||
*/
|
||||
if (s->dev->model->is_sheetfed && !s->dev->buffer_image &&
|
||||
if (s->dev->model->is_sheetfed &&
|
||||
s->pos_bottom_right_y == s->opt[OPT_BR_Y].constraint.range->max)
|
||||
{
|
||||
params->lines = -1;
|
||||
|
|
@ -6645,52 +6391,6 @@ void sane_start_impl(SANE_Handle handle)
|
|||
s->dev->local_buffer.clear();
|
||||
s->dev->local_buffer.alloc(s->dev->binarize_buffer.size() * 8);
|
||||
}
|
||||
|
||||
/* if one of the software enhancement option is selected,
|
||||
* we do the scan internally, process picture then put it an internal
|
||||
* buffer. Since cropping may change scan parameters, we recompute them
|
||||
* at the end */
|
||||
if (s->dev->buffer_image)
|
||||
{
|
||||
genesys_buffer_image(s);
|
||||
|
||||
/* check if we need to skip this page, sheetfed scanners
|
||||
* can go to next doc while flatbed ones can't */
|
||||
if (s->swskip > 0 && IS_ACTIVE(OPT_SWSKIP)) {
|
||||
auto status = sanei_magic_isBlank(&s->params,
|
||||
s->dev->img_buffer.data(),
|
||||
fixed_to_float(s->swskip));
|
||||
|
||||
if (status == SANE_STATUS_NO_DOCS && s->dev->model->is_sheetfed) {
|
||||
DBG(DBG_info, "%s: blank page, recurse\n", __func__);
|
||||
sane_start(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
throw SaneException(status);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->swdeskew) {
|
||||
const auto& sensor = sanei_genesys_find_sensor(s->dev, s->dev->settings.xres,
|
||||
s->dev->settings.get_channels(),
|
||||
s->dev->settings.scan_method);
|
||||
catch_all_exceptions(__func__, [&](){ genesys_deskew(s, sensor); });
|
||||
}
|
||||
|
||||
if (s->swdespeck) {
|
||||
catch_all_exceptions(__func__, [&](){ genesys_despeck(s); });
|
||||
}
|
||||
|
||||
if(s->swcrop) {
|
||||
catch_all_exceptions(__func__, [&](){ genesys_crop(s); });
|
||||
}
|
||||
|
||||
if(s->swderotate) {
|
||||
catch_all_exceptions(__func__, [&](){ genesys_derotate(s); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SANE_GENESYS_API_LINKAGE
|
||||
|
|
@ -6754,65 +6454,46 @@ void sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_
|
|||
|
||||
local_len = max_len;
|
||||
|
||||
/* in case of image processing, all data has been stored in
|
||||
* buffer_image. So read data from it if it exists, else from scanner */
|
||||
if(!dev->buffer_image)
|
||||
{
|
||||
/* dynamic lineart is another kind of digital processing that needs
|
||||
* another layer of buffering on top of genesys_read_ordered_data */
|
||||
if (dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
/* if buffer is empty, fill it with genesys_read_ordered_data */
|
||||
if(dev->binarize_buffer.avail() == 0)
|
||||
{
|
||||
/* store gray data */
|
||||
local_len=dev->local_buffer.size();
|
||||
dev->local_buffer.reset();
|
||||
genesys_read_ordered_data(dev, dev->local_buffer.get_write_pos(local_len),
|
||||
&local_len);
|
||||
dev->local_buffer.produce(local_len);
|
||||
// dynamic lineart is another kind of digital processing that needs
|
||||
// another layer of buffering on top of genesys_read_ordered_data
|
||||
if (dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
// if buffer is empty, fill it with genesys_read_ordered_data
|
||||
if (dev->binarize_buffer.avail() == 0) {
|
||||
// store gray data
|
||||
local_len=dev->local_buffer.size();
|
||||
dev->local_buffer.reset();
|
||||
genesys_read_ordered_data(dev, dev->local_buffer.get_write_pos(local_len),
|
||||
&local_len);
|
||||
dev->local_buffer.produce(local_len);
|
||||
|
||||
dev->binarize_buffer.reset();
|
||||
if (!is_testing_mode()) {
|
||||
genesys_gray_lineart(dev, dev->local_buffer.get_read_pos(),
|
||||
dev->binarize_buffer.get_write_pos(local_len / 8),
|
||||
dev->settings.pixels,
|
||||
local_len / dev->settings.pixels,
|
||||
dev->settings.threshold);
|
||||
}
|
||||
dev->binarize_buffer.produce(local_len / 8);
|
||||
dev->binarize_buffer.reset();
|
||||
if (!is_testing_mode()) {
|
||||
genesys_gray_lineart(dev, dev->local_buffer.get_read_pos(),
|
||||
dev->binarize_buffer.get_write_pos(local_len / 8),
|
||||
dev->settings.pixels,
|
||||
local_len / dev->settings.pixels,
|
||||
dev->settings.threshold);
|
||||
}
|
||||
dev->binarize_buffer.produce(local_len / 8);
|
||||
}
|
||||
|
||||
/* return data from lineart buffer if any, up to the available amount */
|
||||
local_len = max_len;
|
||||
if (static_cast<std::size_t>(max_len) > dev->binarize_buffer.avail())
|
||||
{
|
||||
local_len=dev->binarize_buffer.avail();
|
||||
}
|
||||
if(local_len)
|
||||
{
|
||||
memcpy(buf, dev->binarize_buffer.get_read_pos(), local_len);
|
||||
dev->binarize_buffer.consume(local_len);
|
||||
}
|
||||
// return data from lineart buffer if any, up to the available amount
|
||||
local_len = max_len;
|
||||
if (static_cast<std::size_t>(max_len) > dev->binarize_buffer.avail()) {
|
||||
local_len=dev->binarize_buffer.avail();
|
||||
}
|
||||
else
|
||||
{
|
||||
// most usual case, direct read of data from scanner */
|
||||
genesys_read_ordered_data(dev, buf, &local_len);
|
||||
if (local_len) {
|
||||
std::memcpy(buf, dev->binarize_buffer.get_read_pos(), local_len);
|
||||
dev->binarize_buffer.consume(local_len);
|
||||
}
|
||||
}
|
||||
else /* read data from buffer */
|
||||
{
|
||||
if(dev->total_bytes_read+local_len>dev->total_bytes_to_read)
|
||||
{
|
||||
local_len=dev->total_bytes_to_read-dev->total_bytes_read;
|
||||
}
|
||||
memcpy(buf, dev->img_buffer.data() + dev->total_bytes_read, local_len);
|
||||
dev->total_bytes_read+=local_len;
|
||||
} else {
|
||||
// most usual case, direct read of data from scanner */
|
||||
genesys_read_ordered_data(dev, buf, &local_len);
|
||||
}
|
||||
|
||||
*len = local_len;
|
||||
if (local_len > static_cast<std::size_t>(max_len)) {
|
||||
fprintf (stderr, "[genesys] sane_read: returning incorrect length!!\n");
|
||||
dbg.log(DBG_error, "error: returning incorrect length");
|
||||
}
|
||||
DBG(DBG_proc, "%s: %d bytes returned\n", __func__, *len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,12 +107,6 @@ enum Genesys_Option
|
|||
OPT_GAMMA_VECTOR_R,
|
||||
OPT_GAMMA_VECTOR_G,
|
||||
OPT_GAMMA_VECTOR_B,
|
||||
OPT_SWDESKEW,
|
||||
OPT_SWCROP,
|
||||
OPT_SWDESPECK,
|
||||
OPT_DESPECK,
|
||||
OPT_SWSKIP,
|
||||
OPT_SWDEROTATE,
|
||||
OPT_BRIGHTNESS,
|
||||
OPT_CONTRAST,
|
||||
|
||||
|
|
@ -213,18 +207,12 @@ struct Genesys_Scanner
|
|||
// Option values
|
||||
SANE_Word bit_depth = 0;
|
||||
SANE_Word resolution = 0;
|
||||
bool preview = false;
|
||||
bool preview = false; // TODO: currently not used
|
||||
SANE_Word threshold = 0;
|
||||
SANE_Word threshold_curve = 0;
|
||||
bool disable_interpolation = false;
|
||||
bool lamp_off = false;
|
||||
SANE_Word lamp_off_time = 0;
|
||||
bool swdeskew = false;
|
||||
bool swcrop = false;
|
||||
bool swdespeck = false;
|
||||
bool swderotate = false;
|
||||
SANE_Word swskip = 0;
|
||||
SANE_Word despeck = 0;
|
||||
SANE_Word contrast = 0;
|
||||
SANE_Word brightness = 0;
|
||||
SANE_Word expiration_time = 0;
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue