kopia lustrzana https://gitlab.com/sane-project/backends
genesys: Remove support for generating lineart within the backend
rodzic
745a5c8b38
commit
a12083c8c4
|
@ -528,11 +528,9 @@ libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_deb
|
|||
EXTRA_DIST += fujitsu.conf.in
|
||||
|
||||
libgenesys_la_SOURCES = genesys/genesys.cpp genesys/genesys.h \
|
||||
genesys/buffer.h genesys/buffer.cpp \
|
||||
genesys/calibration.h \
|
||||
genesys/command_set.h \
|
||||
genesys/command_set_common.h genesys/command_set_common.cpp \
|
||||
genesys/conv.h genesys/conv.cpp \
|
||||
genesys/device.h genesys/device.cpp \
|
||||
genesys/enums.h genesys/enums.cpp \
|
||||
genesys/error.h genesys/error.cpp \
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
#include "buffer.h"
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace genesys {
|
||||
|
||||
void Genesys_Buffer::alloc(std::size_t size)
|
||||
{
|
||||
buffer_.resize(size);
|
||||
avail_ = 0;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
void Genesys_Buffer::clear()
|
||||
{
|
||||
buffer_.clear();
|
||||
avail_ = 0;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
void Genesys_Buffer::reset()
|
||||
{
|
||||
avail_ = 0;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
std::uint8_t* Genesys_Buffer::get_write_pos(std::size_t size)
|
||||
{
|
||||
if (avail_ + size > buffer_.size())
|
||||
return nullptr;
|
||||
if (pos_ + avail_ + size > buffer_.size())
|
||||
{
|
||||
std::memmove(buffer_.data(), buffer_.data() + pos_, avail_);
|
||||
pos_ = 0;
|
||||
}
|
||||
return buffer_.data() + pos_ + avail_;
|
||||
}
|
||||
|
||||
std::uint8_t* Genesys_Buffer::get_read_pos()
|
||||
{
|
||||
return buffer_.data() + pos_;
|
||||
}
|
||||
|
||||
void Genesys_Buffer::produce(std::size_t size)
|
||||
{
|
||||
if (size > buffer_.size() - avail_)
|
||||
throw std::runtime_error("buffer size exceeded");
|
||||
avail_ += size;
|
||||
}
|
||||
|
||||
void Genesys_Buffer::consume(std::size_t size)
|
||||
{
|
||||
if (size > avail_)
|
||||
throw std::runtime_error("no more data in buffer");
|
||||
avail_ -= size;
|
||||
pos_ += size;
|
||||
}
|
||||
|
||||
} // namespace genesys
|
|
@ -1,89 +0,0 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
#ifndef BACKEND_GENESYS_BUFFER_H
|
||||
#define BACKEND_GENESYS_BUFFER_H
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace genesys {
|
||||
|
||||
/* A FIFO buffer. Note, that this is _not_ a ringbuffer.
|
||||
if we need a block which does not fit at the end of our available data,
|
||||
we move the available data to the beginning.
|
||||
*/
|
||||
struct Genesys_Buffer
|
||||
{
|
||||
Genesys_Buffer() = default;
|
||||
|
||||
std::size_t size() const { return buffer_.size(); }
|
||||
std::size_t avail() const { return avail_; }
|
||||
std::size_t pos() const { return pos_; }
|
||||
|
||||
// TODO: refactor code that uses this function to no longer use it
|
||||
void set_pos(std::size_t pos) { pos_ = pos; }
|
||||
|
||||
void alloc(std::size_t size);
|
||||
void clear();
|
||||
|
||||
void reset();
|
||||
|
||||
std::uint8_t* get_write_pos(std::size_t size);
|
||||
std::uint8_t* get_read_pos(); // TODO: mark as const
|
||||
|
||||
void produce(std::size_t size);
|
||||
void consume(std::size_t size);
|
||||
|
||||
private:
|
||||
std::vector<std::uint8_t> buffer_;
|
||||
// current position in read buffer
|
||||
std::size_t pos_ = 0;
|
||||
// data bytes currently in buffer
|
||||
std::size_t avail_ = 0;
|
||||
};
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
#endif // BACKEND_GENESYS_BUFFER_H
|
|
@ -1,157 +0,0 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2005, 2006 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
#define DEBUG_DECLARE_ONLY
|
||||
|
||||
#include "conv.h"
|
||||
|
||||
namespace genesys {
|
||||
|
||||
/**
|
||||
* uses the threshold/threshold_curve to control software binarization
|
||||
* This code was taken from the epjistsu backend by m. allan noah
|
||||
* @param dev device set up for the scan
|
||||
* @param src pointer to raw data
|
||||
* @param dst pointer where to store result
|
||||
* @param width width of the processed line
|
||||
* */
|
||||
void binarize_line(Genesys_Device* dev, std::uint8_t* src, std::uint8_t* dst, int width)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
int j, windowX, sum = 0;
|
||||
int thresh;
|
||||
int offset, addCol, dropCol;
|
||||
unsigned char mask;
|
||||
|
||||
int x;
|
||||
std::uint8_t min, max;
|
||||
|
||||
/* normalize line */
|
||||
min = 255;
|
||||
max = 0;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
if (src[x] > max)
|
||||
{
|
||||
max = src[x];
|
||||
}
|
||||
if (src[x] < min)
|
||||
{
|
||||
min = src[x];
|
||||
}
|
||||
}
|
||||
|
||||
/* safeguard against dark or white areas */
|
||||
if(min>80)
|
||||
min=0;
|
||||
if(max<80)
|
||||
max=255;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
src[x] = ((src[x] - min) * 255) / (max - min);
|
||||
}
|
||||
|
||||
/* ~1mm works best, but the window needs to have odd # of pixels */
|
||||
windowX = (6 * dev->settings.xres) / 150;
|
||||
if (!(windowX % 2))
|
||||
windowX++;
|
||||
|
||||
/* second, prefill the sliding sum */
|
||||
for (j = 0; j < windowX; j++)
|
||||
sum += src[j];
|
||||
|
||||
/* third, walk the input buffer, update the sliding sum, */
|
||||
/* determine threshold, output bits */
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
/* output image location */
|
||||
offset = j % 8;
|
||||
mask = 0x80 >> offset;
|
||||
thresh = dev->settings.threshold;
|
||||
|
||||
/* move sum/update threshold only if there is a curve */
|
||||
if (dev->settings.threshold_curve)
|
||||
{
|
||||
addCol = j + windowX / 2;
|
||||
dropCol = addCol - windowX;
|
||||
|
||||
if (dropCol >= 0 && addCol < width)
|
||||
{
|
||||
sum -= src[dropCol];
|
||||
sum += src[addCol];
|
||||
}
|
||||
thresh = dev->lineart_lut[sum / windowX];
|
||||
}
|
||||
|
||||
/* use average to lookup threshold */
|
||||
if (src[j] > thresh)
|
||||
*dst &= ~mask; /* white */
|
||||
else
|
||||
*dst |= mask; /* black */
|
||||
|
||||
if (offset == 7)
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* software lineart using data from a 8 bit gray scan. We assume true gray
|
||||
* or monochrome scan as input.
|
||||
*/
|
||||
void genesys_gray_lineart(Genesys_Device* dev,
|
||||
std::uint8_t* src_data, std::uint8_t* dst_data,
|
||||
std::size_t pixels, std::size_t lines, std::uint8_t threshold)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
std::size_t y;
|
||||
(void) threshold;
|
||||
|
||||
for (y = 0; y < lines; y++)
|
||||
{
|
||||
binarize_line (dev, src_data + y * pixels, dst_data, pixels);
|
||||
dst_data += pixels / 8;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace genesys
|
|
@ -1,61 +0,0 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
#ifndef BACKEND_GENESYS_CONV_H
|
||||
#define BACKEND_GENESYS_CONV_H
|
||||
|
||||
#include "device.h"
|
||||
#include "sensor.h"
|
||||
#include "genesys.h"
|
||||
|
||||
namespace genesys {
|
||||
|
||||
void binarize_line(Genesys_Device* dev, std::uint8_t* src, std::uint8_t* dst, int width);
|
||||
|
||||
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);
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
#endif // BACKEND_GENESYS_CONV_H
|
|
@ -102,9 +102,6 @@ Genesys_Device::~Genesys_Device()
|
|||
|
||||
void Genesys_Device::clear()
|
||||
{
|
||||
binarize_buffer.clear();
|
||||
local_buffer.clear();
|
||||
|
||||
calib_file.clear();
|
||||
|
||||
calibration_cache.clear();
|
||||
|
@ -257,12 +254,9 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev)
|
|||
<< " read_active: " << dev.read_active << '\n'
|
||||
<< " parking: " << dev.parking << '\n'
|
||||
<< " document: " << dev.document << '\n'
|
||||
<< " binarize_buffer.size(): " << dev.binarize_buffer.size() << '\n'
|
||||
<< " local_buffer.size(): " << dev.local_buffer.size() << '\n'
|
||||
<< " total_bytes_read: " << dev.total_bytes_read << '\n'
|
||||
<< " total_bytes_to_read: " << dev.total_bytes_to_read << '\n'
|
||||
<< " session: " << format_indent_braced_list(4, dev.session) << '\n'
|
||||
<< " lineart_lut: (not printed)\n"
|
||||
<< " calibration_cache: (not printed)\n"
|
||||
<< " line_count: " << dev.line_count << '\n'
|
||||
<< " segment_order: "
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include "calibration.h"
|
||||
#include "command_set.h"
|
||||
#include "buffer.h"
|
||||
#include "enums.h"
|
||||
#include "image_pipeline.h"
|
||||
#include "motor.h"
|
||||
|
@ -318,11 +317,6 @@ struct Genesys_Device
|
|||
// for sheetfed scanner's, is TRUE when there is a document in the scanner
|
||||
bool document = false;
|
||||
|
||||
// buffer for digital lineart from gray data
|
||||
Genesys_Buffer binarize_buffer;
|
||||
// local buffer for gray data during dynamix lineart
|
||||
Genesys_Buffer local_buffer;
|
||||
|
||||
// total bytes read sent to frontend
|
||||
size_t total_bytes_read = 0;
|
||||
// total bytes read to be sent to frontend
|
||||
|
@ -331,9 +325,6 @@ struct Genesys_Device
|
|||
// contains computed data for the current setup
|
||||
ScanSession session;
|
||||
|
||||
// look up table used in dynamic rasterization
|
||||
unsigned char lineart_lut[256] = {};
|
||||
|
||||
Calibration calibration_cache;
|
||||
|
||||
// number of scan lines used during scan
|
||||
|
|
|
@ -46,9 +46,6 @@
|
|||
|
||||
namespace genesys {
|
||||
|
||||
// buffer.h
|
||||
struct Genesys_Buffer;
|
||||
|
||||
// calibration.h
|
||||
struct Genesys_Calibration_Cache;
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#define DEBUG_NOT_STATIC
|
||||
|
||||
#include "genesys.h"
|
||||
#include "conv.h"
|
||||
#include "gl124_registers.h"
|
||||
#include "gl841_registers.h"
|
||||
#include "gl842_registers.h"
|
||||
|
@ -111,8 +110,8 @@ namespace {
|
|||
static SANE_String_Const mode_list[] = {
|
||||
SANE_VALUE_SCAN_MODE_COLOR,
|
||||
SANE_VALUE_SCAN_MODE_GRAY,
|
||||
/* SANE_TITLE_HALFTONE, currently unused */
|
||||
SANE_VALUE_SCAN_MODE_LINEART,
|
||||
// SANE_TITLE_HALFTONE, not used
|
||||
// SANE_VALUE_SCAN_MODE_LINEART, not used
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -161,12 +160,6 @@ static const SANE_Range percentage_range = {
|
|||
float_to_fixed(1) // quantization
|
||||
};
|
||||
|
||||
static const SANE_Range threshold_curve_range = {
|
||||
0, /* minimum */
|
||||
127, /* maximum */
|
||||
1 /* quantization */
|
||||
};
|
||||
|
||||
/**
|
||||
* range for brightness and contrast
|
||||
*/
|
||||
|
@ -422,9 +415,6 @@ SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, const MotorProfile&
|
|||
/* Sends a block of shading information to the scanner.
|
||||
The data is placed at address 0x0000 for color mode, gray mode and
|
||||
unconditionally for the following CCD chips: HP2300, HP2400 and HP5345
|
||||
In the other cases (lineart, halftone on ccd chips not mentioned) the
|
||||
addresses are 0x2a00 for dpihw==0, 0x5500 for dpihw==1 and 0xa800 for
|
||||
dpihw==2. //Note: why this?
|
||||
|
||||
The data needs to be of size "size", and in little endian byte order.
|
||||
*/
|
||||
|
@ -432,7 +422,6 @@ static void genesys_send_offset_and_shading(Genesys_Device* dev, const Genesys_S
|
|||
uint8_t* data, int size)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "(size = %d)", size);
|
||||
int dpihw;
|
||||
int start_address;
|
||||
|
||||
/* ASIC higher than gl843 doesn't have register 2A/2B, so we route to
|
||||
|
@ -443,46 +432,7 @@ static void genesys_send_offset_and_shading(Genesys_Device* dev, const Genesys_S
|
|||
return;
|
||||
}
|
||||
|
||||
/* gl646, gl84[123] case */
|
||||
dpihw = dev->reg.get8(0x05) >> 6;
|
||||
|
||||
/* TODO invert the test so only the 2 models behaving like that are
|
||||
* tested instead of adding all the others */
|
||||
/* many scanners send coefficient for lineart/gray like in color mode */
|
||||
if ((dev->settings.scan_mode == ScanColorMode::LINEART ||
|
||||
dev->settings.scan_mode == ScanColorMode::HALFTONE)
|
||||
&& dev->model->sensor_id != SensorId::CCD_PLUSTEK_OPTICBOOK_3800
|
||||
&& dev->model->sensor_id != SensorId::CCD_KVSS080
|
||||
&& dev->model->sensor_id != SensorId::CCD_G4050
|
||||
&& dev->model->sensor_id != SensorId::CCD_HP_4850C
|
||||
&& dev->model->sensor_id != SensorId::CCD_CANON_4400F
|
||||
&& dev->model->sensor_id != SensorId::CCD_CANON_8400F
|
||||
&& dev->model->sensor_id != SensorId::CCD_CANON_8600F
|
||||
&& dev->model->sensor_id != SensorId::CCD_DSMOBILE600
|
||||
&& dev->model->sensor_id != SensorId::CCD_XP300
|
||||
&& dev->model->sensor_id != SensorId::CCD_DOCKETPORT_487
|
||||
&& dev->model->sensor_id != SensorId::CCD_DP665
|
||||
&& dev->model->sensor_id != SensorId::CCD_DP685
|
||||
&& dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80
|
||||
&& dev->model->sensor_id != SensorId::CCD_ROADWARRIOR
|
||||
&& dev->model->sensor_id != SensorId::CCD_HP2300
|
||||
&& dev->model->sensor_id != SensorId::CCD_HP2400
|
||||
&& dev->model->sensor_id != SensorId::CCD_HP3670
|
||||
&& dev->model->sensor_id != SensorId::CCD_5345) /* lineart, halftone */
|
||||
{
|
||||
if (dpihw == 0) { /* 600 dpi */
|
||||
start_address = 0x02a00;
|
||||
} else if (dpihw == 1) { /* 1200 dpi */
|
||||
start_address = 0x05500;
|
||||
} else if (dpihw == 2) { /* 2400 dpi */
|
||||
start_address = 0x0a800;
|
||||
} else { /* reserved */
|
||||
throw SaneException("unknown dpihw");
|
||||
}
|
||||
}
|
||||
else { // color
|
||||
start_address = 0x00;
|
||||
}
|
||||
start_address = 0x00;
|
||||
|
||||
dev->interface->write_buffer(0x3c, start_address, data, size);
|
||||
}
|
||||
|
@ -4026,18 +3976,10 @@ static void genesys_start_scan(Genesys_Device* dev, bool lamp_off)
|
|||
has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION);
|
||||
if (!shading_disabled && !dev->model->is_sheetfed) {
|
||||
genesys_scanner_calibration(dev, sensor);
|
||||
genesys_save_calibration (dev, sensor);
|
||||
}
|
||||
else
|
||||
{
|
||||
genesys_save_calibration(dev, sensor);
|
||||
} else {
|
||||
DBG(DBG_warn, "%s: no calibration done\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
/* build look up table for dynamic lineart */
|
||||
if (dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
sanei_genesys_load_lut(dev->lineart_lut, 8, 8, 50, 205, dev->settings.threshold_curve,
|
||||
dev->settings.threshold-127);
|
||||
}
|
||||
}
|
||||
|
||||
dev->cmd_set->wait_for_motor_stop(dev);
|
||||
|
@ -4236,9 +4178,13 @@ static Genesys_Settings calculate_scan_settings(Genesys_Scanner* s)
|
|||
settings.scan_mode = option_string_to_scan_color_mode(s->mode);
|
||||
|
||||
settings.depth = s->bit_depth;
|
||||
|
||||
if (settings.depth > 8) {
|
||||
settings.depth = 16;
|
||||
} else if (settings.depth < 8) {
|
||||
settings.depth = 1;
|
||||
}
|
||||
|
||||
settings.disable_interpolation = s->disable_interpolation;
|
||||
|
||||
const auto& resolutions = dev->model->get_resolution_settings(settings.scan_method);
|
||||
|
@ -4307,11 +4253,6 @@ static Genesys_Settings calculate_scan_settings(Genesys_Scanner* s)
|
|||
}
|
||||
}
|
||||
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_LINEART || settings.depth == 1) {
|
||||
// round down pixel number. This will is lossy operation, at most 7 pixels will be lost
|
||||
pixels_per_line = (pixels_per_line / 8) * 8;
|
||||
}
|
||||
|
||||
unsigned xres_factor = s->resolution / settings.xres;
|
||||
settings.pixels = pixels_per_line;
|
||||
settings.requested_pixels = pixels_per_line * xres_factor;
|
||||
|
@ -4332,11 +4273,8 @@ static Genesys_Settings calculate_scan_settings(Genesys_Scanner* s)
|
|||
settings.true_gray = 0;
|
||||
}
|
||||
|
||||
settings.threshold = static_cast<int>(2.55f * (fixed_to_float(s->threshold)));
|
||||
settings.threshold_curve = s->threshold_curve;
|
||||
|
||||
// brigthness and contrast only for for 8 bit scans
|
||||
if (s->bit_depth <= 8) {
|
||||
if (s->bit_depth == 8) {
|
||||
settings.contrast = (s->contrast * 127) / 100;
|
||||
settings.brightness = (s->brightness * 127) / 100;
|
||||
} else {
|
||||
|
@ -4359,9 +4297,7 @@ static SANE_Parameters calculate_scan_parameters(const Genesys_Device& dev,
|
|||
auto session = dev.cmd_set->calculate_scan_session(&dev, sensor, settings);
|
||||
|
||||
SANE_Parameters params;
|
||||
if (settings.scan_mode == ScanColorMode::GRAY ||
|
||||
settings.scan_mode == ScanColorMode::LINEART)
|
||||
{
|
||||
if (settings.scan_mode == ScanColorMode::GRAY) {
|
||||
params.format = SANE_FRAME_GRAY;
|
||||
} else {
|
||||
params.format = SANE_FRAME_RGB;
|
||||
|
@ -4370,9 +4306,6 @@ static SANE_Parameters calculate_scan_parameters(const Genesys_Device& dev,
|
|||
params.last_frame = true;
|
||||
|
||||
params.depth = settings.depth;
|
||||
if (settings.scan_mode == ScanColorMode::LINEART) {
|
||||
params.depth = 1;
|
||||
}
|
||||
|
||||
// FIXME: add the data needed to perform the data conversion to the format used by the user
|
||||
// to ScanSession.
|
||||
|
@ -4387,8 +4320,6 @@ static SANE_Parameters calculate_scan_parameters(const Genesys_Device& dev,
|
|||
unsigned bytes_per_line = 0;
|
||||
if (params.depth == 16) {
|
||||
bytes_per_line = 2 * pixels_per_line;
|
||||
} else if (params.depth == 1) {
|
||||
bytes_per_line = pixels_per_line / 8;
|
||||
} else {
|
||||
bytes_per_line = pixels_per_line;
|
||||
}
|
||||
|
@ -4817,26 +4748,6 @@ static void init_options(Genesys_Scanner* s)
|
|||
s->opt[OPT_EXTRAS_GROUP].size = 0;
|
||||
s->opt[OPT_EXTRAS_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
/* BW threshold */
|
||||
s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
|
||||
s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
|
||||
s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
|
||||
s->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
|
||||
s->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
|
||||
s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_THRESHOLD].constraint.range = &percentage_range;
|
||||
s->threshold = float_to_fixed(50);
|
||||
|
||||
/* BW threshold curve */
|
||||
s->opt[OPT_THRESHOLD_CURVE].name = "threshold-curve";
|
||||
s->opt[OPT_THRESHOLD_CURVE].title = SANE_I18N ("Threshold curve");
|
||||
s->opt[OPT_THRESHOLD_CURVE].desc = SANE_I18N ("Dynamic threshold curve, from light to dark, normally 50-65");
|
||||
s->opt[OPT_THRESHOLD_CURVE].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_THRESHOLD_CURVE].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_THRESHOLD_CURVE].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_THRESHOLD_CURVE].constraint.range = &threshold_curve_range;
|
||||
s->threshold_curve = 50;
|
||||
|
||||
/* disable_interpolation */
|
||||
s->opt[OPT_DISABLE_INTERPOLATION].name = "disable-interpolation";
|
||||
s->opt[OPT_DISABLE_INTERPOLATION].title =
|
||||
|
@ -5739,12 +5650,6 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
case OPT_PREVIEW:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->preview;
|
||||
break;
|
||||
case OPT_THRESHOLD:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->threshold;
|
||||
break;
|
||||
case OPT_THRESHOLD_CURVE:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->threshold_curve;
|
||||
break;
|
||||
case OPT_DISABLE_INTERPOLATION:
|
||||
*reinterpret_cast<SANE_Word*>(val) = s->disable_interpolation;
|
||||
break;
|
||||
|
@ -5948,16 +5853,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_THRESHOLD:
|
||||
s->threshold = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_THRESHOLD_CURVE:
|
||||
s->threshold_curve = *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);
|
||||
|
@ -6009,34 +5904,21 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
}
|
||||
break;
|
||||
}
|
||||
case OPT_MODE:
|
||||
s->mode = reinterpret_cast<const char*>(val);
|
||||
case OPT_MODE: {
|
||||
s->mode = reinterpret_cast<const char*>(val);
|
||||
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_LINEART)
|
||||
{
|
||||
ENABLE (OPT_THRESHOLD);
|
||||
ENABLE (OPT_THRESHOLD_CURVE);
|
||||
DISABLE (OPT_BIT_DEPTH);
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_GRAY) {
|
||||
if (dev->model->asic_type != AsicType::GL646 || !dev->model->is_cis) {
|
||||
ENABLE(OPT_COLOR_FILTER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DISABLE (OPT_THRESHOLD);
|
||||
DISABLE (OPT_THRESHOLD_CURVE);
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_GRAY) {
|
||||
if (dev->model->asic_type != AsicType::GL646 || !dev->model->is_cis) {
|
||||
ENABLE(OPT_COLOR_FILTER);
|
||||
}
|
||||
create_bpp_list(s, dev->model->bpp_gray_values);
|
||||
s->bit_depth = dev->model->bpp_gray_values[0];
|
||||
} else {
|
||||
DISABLE(OPT_COLOR_FILTER);
|
||||
create_bpp_list(s, dev->model->bpp_color_values);
|
||||
s->bit_depth = dev->model->bpp_color_values[0];
|
||||
}
|
||||
create_bpp_list(s, dev->model->bpp_gray_values);
|
||||
s->bit_depth = dev->model->bpp_gray_values[0];
|
||||
} else {
|
||||
DISABLE(OPT_COLOR_FILTER);
|
||||
create_bpp_list(s, dev->model->bpp_color_values);
|
||||
s->bit_depth = dev->model->bpp_color_values[0];
|
||||
}
|
||||
|
||||
calc_parameters(s);
|
||||
|
||||
/* if custom gamma, toggle gamma table options according to the mode */
|
||||
|
@ -6060,6 +5942,7 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
}
|
||||
case OPT_COLOR_FILTER:
|
||||
s->color_filter = reinterpret_cast<const char*>(val);
|
||||
calc_parameters(s);
|
||||
|
@ -6342,14 +6225,6 @@ void sane_start_impl(SANE_Handle handle)
|
|||
genesys_start_scan(dev, s->lamp_off);
|
||||
|
||||
s->scanning = true;
|
||||
|
||||
// allocate intermediate buffer when doing dynamic lineart
|
||||
if (dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
dev->binarize_buffer.clear();
|
||||
dev->binarize_buffer.alloc(dev->settings.pixels);
|
||||
dev->local_buffer.clear();
|
||||
dev->local_buffer.alloc(dev->binarize_buffer.size() * 8);
|
||||
}
|
||||
}
|
||||
|
||||
SANE_GENESYS_API_LINKAGE
|
||||
|
@ -6412,42 +6287,7 @@ void sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_
|
|||
|
||||
local_len = max_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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
std::memcpy(buf, dev->binarize_buffer.get_read_pos(), local_len);
|
||||
dev->binarize_buffer.consume(local_len);
|
||||
}
|
||||
} else {
|
||||
// most usual case, direct read of data from scanner */
|
||||
genesys_read_ordered_data(dev, buf, &local_len);
|
||||
}
|
||||
genesys_read_ordered_data(dev, buf, &local_len);
|
||||
|
||||
*len = local_len;
|
||||
if (local_len > static_cast<std::size_t>(max_len)) {
|
||||
|
|
|
@ -113,8 +113,6 @@ enum Genesys_Option
|
|||
OPT_EXTRAS_GROUP,
|
||||
OPT_LAMP_OFF_TIME,
|
||||
OPT_LAMP_OFF,
|
||||
OPT_THRESHOLD,
|
||||
OPT_THRESHOLD_CURVE,
|
||||
OPT_DISABLE_INTERPOLATION,
|
||||
OPT_COLOR_FILTER,
|
||||
OPT_CALIBRATION_FILE,
|
||||
|
@ -208,8 +206,6 @@ struct Genesys_Scanner
|
|||
SANE_Word bit_depth = 0;
|
||||
SANE_Word resolution = 0;
|
||||
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;
|
||||
|
|
|
@ -641,8 +641,8 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
|
||||
|
||||
// BW threshold
|
||||
dev->interface->write_register(REG_0x114, dev->settings.threshold);
|
||||
dev->interface->write_register(REG_0x115, dev->settings.threshold);
|
||||
dev->interface->write_register(REG_0x114, 0x7f);
|
||||
dev->interface->write_register(REG_0x115, 0x7f);
|
||||
|
||||
/* monochrome / color scan */
|
||||
switch (session.params.depth) {
|
||||
|
|
|
@ -853,8 +853,8 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
|
||||
|
||||
/* BW threshold */
|
||||
reg->set8(0x2e, dev->settings.threshold);
|
||||
reg->set8(0x2f, dev->settings.threshold);
|
||||
reg->set8(0x2e, 0x7f);
|
||||
reg->set8(0x2f, 0x7f);
|
||||
|
||||
|
||||
/* monochrome / color scan */
|
||||
|
|
|
@ -422,8 +422,8 @@ static void gl842_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA);
|
||||
|
||||
// BW threshold
|
||||
reg->set8(REG_0x2E, dev->settings.threshold);
|
||||
reg->set8(REG_0x2F, dev->settings.threshold);
|
||||
reg->set8(REG_0x2E, 0x7f);
|
||||
reg->set8(REG_0x2F, 0x7f);
|
||||
|
||||
// monochrome / color scan parameters
|
||||
std::uint8_t reg04 = reg->get8(REG_0x04);
|
||||
|
|
|
@ -942,8 +942,8 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA);
|
||||
|
||||
// BW threshold
|
||||
reg->set8(REG_0x2E, dev->settings.threshold);
|
||||
reg->set8(REG_0x2F, dev->settings.threshold);
|
||||
reg->set8(REG_0x2E, 0x7f);
|
||||
reg->set8(REG_0x2F, 0x7f);
|
||||
|
||||
/* monochrome / color scan */
|
||||
switch (session.params.depth) {
|
||||
|
|
|
@ -579,8 +579,8 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA);
|
||||
|
||||
// BW threshold
|
||||
reg->set8(0x2e, dev->settings.threshold);
|
||||
reg->set8(0x2f, dev->settings.threshold);
|
||||
reg->set8(0x2e, 0x7f);
|
||||
reg->set8(0x2f, 0x7f);
|
||||
|
||||
/* monochrome / color scan */
|
||||
switch (session.params.depth) {
|
||||
|
|
|
@ -457,8 +457,8 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
|
||||
|
||||
// BW threshold
|
||||
reg->set8(0x2e, dev->settings.threshold);
|
||||
reg->set8(0x2f, dev->settings.threshold);
|
||||
reg->set8(0x2e, 0x7f);
|
||||
reg->set8(0x2f, 0x7f);
|
||||
|
||||
/* monochrome / color scan */
|
||||
switch (session.params.depth) {
|
||||
|
|
|
@ -81,12 +81,6 @@ struct Genesys_Settings
|
|||
// true if scan is true gray, false if monochrome scan
|
||||
int true_gray = 0;
|
||||
|
||||
// lineart threshold
|
||||
int threshold = 0;
|
||||
|
||||
// lineart threshold curve for dynamic rasterization
|
||||
int threshold_curve = 0;
|
||||
|
||||
// Disable interpolation for xres<yres
|
||||
int disable_interpolation = 0;
|
||||
|
||||
|
|
|
@ -424,8 +424,7 @@ std::vector<TestConfig> get_all_test_configs()
|
|||
}
|
||||
model_names.insert(model.name);
|
||||
|
||||
for (auto scan_mode : { genesys::ScanColorMode::LINEART,
|
||||
genesys::ScanColorMode::GRAY,
|
||||
for (auto scan_mode : { genesys::ScanColorMode::GRAY,
|
||||
genesys::ScanColorMode::COLOR_SINGLE_PASS }) {
|
||||
|
||||
auto depth_values = model.bpp_gray_values;
|
||||
|
|
Ładowanie…
Reference in New Issue