kopia lustrzana https://gitlab.com/sane-project/backends
genesys: Add support for Canon 5600F
rodzic
b9e4113ef0
commit
3cca2593fc
|
@ -84,6 +84,7 @@ void CommandSetCommon::set_xpa_lamp_power(Genesys_Device& dev, bool set) const
|
|||
// turning off the lamp
|
||||
LampSettings settings[] = {
|
||||
{ ModelId::CANON_4400F, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::CANON_5600F, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, {
|
||||
{ 0xa6, 0x34, 0xf4 },
|
||||
}, {
|
||||
|
|
|
@ -174,6 +174,7 @@ std::ostream& operator<<(std::ostream& out, SensorId id)
|
|||
switch (id) {
|
||||
case SensorId::CCD_5345: out << "CCD_5345"; break;
|
||||
case SensorId::CCD_CANON_4400F: out << "CCD_CANON_4400F"; break;
|
||||
case SensorId::CCD_CANON_5600F: out << "CCD_CANON_5600F"; break;
|
||||
case SensorId::CCD_CANON_8400F: out << "CCD_CANON_8400F"; break;
|
||||
case SensorId::CCD_CANON_8600F: out << "CCD_CANON_8600F"; break;
|
||||
case SensorId::CCD_DP665: out << "CCD_DP665"; break;
|
||||
|
@ -230,6 +231,7 @@ std::ostream& operator<<(std::ostream& out, AdcId id)
|
|||
case AdcId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
|
||||
case AdcId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
|
||||
case AdcId::CANON_4400F: out << "CANON_4400F"; break;
|
||||
case AdcId::CANON_5600F: out << "CANON_5600F"; break;
|
||||
case AdcId::CANON_8400F: out << "CANON_8400F"; break;
|
||||
case AdcId::CANON_8600F: out << "CANON_8600F"; break;
|
||||
case AdcId::G4050: out << "G4050"; break;
|
||||
|
@ -270,6 +272,7 @@ std::ostream& operator<<(std::ostream& out, GpioId id)
|
|||
case GpioId::CANON_LIDE_210: out << "CANON_LIDE_210"; break;
|
||||
case GpioId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
|
||||
case GpioId::CANON_4400F: out << "CANON_4400F"; break;
|
||||
case GpioId::CANON_5600F: out << "CANON_5600F"; break;
|
||||
case GpioId::CANON_8400F: out << "CANON_8400F"; break;
|
||||
case GpioId::CANON_8600F: out << "CANON_8600F"; break;
|
||||
case GpioId::DP665: out << "DP665"; break;
|
||||
|
@ -313,6 +316,7 @@ std::ostream& operator<<(std::ostream& out, MotorId id)
|
|||
case MotorId::CANON_LIDE_700: out << "CANON_LIDE_700"; break;
|
||||
case MotorId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
|
||||
case MotorId::CANON_4400F: out << "CANON_4400F"; break;
|
||||
case MotorId::CANON_5600F: out << "CANON_5600F"; break;
|
||||
case MotorId::CANON_8400F: out << "CANON_8400F"; break;
|
||||
case MotorId::CANON_8600F: out << "CANON_8600F"; break;
|
||||
case MotorId::DP665: out << "DP665"; break;
|
||||
|
|
|
@ -245,6 +245,7 @@ enum class SensorId : unsigned
|
|||
UNKNOWN = 0,
|
||||
CCD_5345,
|
||||
CCD_CANON_4400F,
|
||||
CCD_CANON_5600F,
|
||||
CCD_CANON_8400F,
|
||||
CCD_CANON_8600F,
|
||||
CCD_DP665,
|
||||
|
@ -312,6 +313,7 @@ enum class AdcId : unsigned
|
|||
CANON_LIDE_200,
|
||||
CANON_LIDE_700F,
|
||||
CANON_4400F,
|
||||
CANON_5600F,
|
||||
CANON_8400F,
|
||||
CANON_8600F,
|
||||
G4050,
|
||||
|
@ -362,6 +364,7 @@ enum class GpioId : unsigned
|
|||
CANON_LIDE_210,
|
||||
CANON_LIDE_700F,
|
||||
CANON_4400F,
|
||||
CANON_5600F,
|
||||
CANON_8400F,
|
||||
CANON_8600F,
|
||||
DP665,
|
||||
|
@ -404,6 +407,7 @@ enum class MotorId : unsigned
|
|||
CANON_LIDE_700,
|
||||
CANON_LIDE_80,
|
||||
CANON_4400F,
|
||||
CANON_5600F,
|
||||
CANON_8400F,
|
||||
CANON_8600F,
|
||||
DP665,
|
||||
|
|
|
@ -1491,6 +1491,16 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
|||
}
|
||||
}
|
||||
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
// FIXME: use same approach as for GL843 scanners
|
||||
lines = 8;
|
||||
}
|
||||
|
||||
if (dev.model->asic_type == AsicType::GL847) {
|
||||
calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
|
||||
dev.settings.scan_method);
|
||||
}
|
||||
|
||||
ScanFlag flags = ScanFlag::DISABLE_SHADING |
|
||||
ScanFlag::DISABLE_GAMMA |
|
||||
ScanFlag::SINGLE_LINE |
|
||||
|
@ -1562,6 +1572,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
|||
scanner_stop_action_no_move(dev, regs);
|
||||
} else {
|
||||
first_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
|
||||
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
scanner_stop_action_no_move(dev, regs);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
|
@ -1598,6 +1612,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
|||
scanner_stop_action_no_move(dev, regs);
|
||||
} else {
|
||||
second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
|
||||
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
scanner_stop_action_no_move(dev, regs);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned ch = 0; ch < 3; ch++){
|
||||
|
@ -1638,6 +1656,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
|||
scanner_stop_action_no_move(dev, regs);
|
||||
} else {
|
||||
second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
|
||||
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
scanner_stop_action_no_move(dev, regs);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
|
@ -1782,7 +1804,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
|
|||
const Genesys_Sensor* calib_sensor = &sensor;
|
||||
if (dev.model->asic_type == AsicType::GL841 ||
|
||||
dev.model->asic_type == AsicType::GL842 ||
|
||||
dev.model->asic_type == AsicType::GL843)
|
||||
dev.model->asic_type == AsicType::GL843 ||
|
||||
dev.model->asic_type == AsicType::GL847)
|
||||
{
|
||||
calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
|
||||
dev.settings.scan_method);
|
||||
|
@ -1930,6 +1953,9 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
|
|||
DBG(DBG_error0, "****************************************\n");
|
||||
throw SaneException(SANE_STATUS_JAMMED, "scanning head is locked");
|
||||
}
|
||||
|
||||
dbg.vlog(DBG_info, "gain=(%d, %d, %d)", dev.frontend.get_gain(0), dev.frontend.get_gain(1),
|
||||
dev.frontend.get_gain(2));
|
||||
}
|
||||
|
||||
if (dev.model->is_cis) {
|
||||
|
@ -1942,10 +1968,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
|
|||
dev.frontend.set_gain(2, min_gain);
|
||||
}
|
||||
|
||||
DBG(DBG_info, "%s: gain=(%d,%d,%d)\n", __func__,
|
||||
dev.frontend.get_gain(0),
|
||||
dev.frontend.get_gain(1),
|
||||
dev.frontend.get_gain(2));
|
||||
dbg.vlog(DBG_info, "final gain=(%d, %d, %d)", dev.frontend.get_gain(0),
|
||||
dev.frontend.get_gain(1), dev.frontend.get_gain(2));
|
||||
|
||||
scanner_stop_action(dev);
|
||||
|
||||
|
@ -2326,10 +2350,12 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
|
|||
uint32_t pixels_per_line;
|
||||
|
||||
if (dev->model->asic_type == AsicType::GL842 ||
|
||||
dev->model->asic_type == AsicType::GL843)
|
||||
dev->model->asic_type == AsicType::GL843 ||
|
||||
dev->model->model_id == ModelId::CANON_5600F)
|
||||
{
|
||||
pixels_per_line = dev->calib_session.output_pixels;
|
||||
} else {
|
||||
// BUG: this selects incorrect pixel number
|
||||
pixels_per_line = dev->calib_session.params.pixels;
|
||||
}
|
||||
unsigned channels = dev->calib_session.params.channels;
|
||||
|
@ -2354,7 +2380,8 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
|
|||
// FIXME: the current calculation is likely incorrect on non-GL843 implementations,
|
||||
// but this needs checking. Note the extra line when computing size.
|
||||
if (dev->model->asic_type == AsicType::GL842 ||
|
||||
dev->model->asic_type == AsicType::GL843)
|
||||
dev->model->asic_type == AsicType::GL843 ||
|
||||
dev->model->model_id == ModelId::CANON_5600F)
|
||||
{
|
||||
size = dev->calib_session.output_total_bytes_raw;
|
||||
} else {
|
||||
|
@ -2407,6 +2434,12 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
|
|||
}
|
||||
}
|
||||
|
||||
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
|
||||
for (std::size_t i = 0; i < size / 2; ++i) {
|
||||
calibration_data[i] = 0xffff - calibration_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::fill(out_average_data.begin(),
|
||||
out_average_data.begin() + start_offset * channels, 0);
|
||||
|
||||
|
@ -3489,6 +3522,7 @@ static void genesys_send_shading_coefficient(Genesys_Device* dev, const Genesys_
|
|||
case SensorId::CIS_CANON_LIDE_120:
|
||||
case SensorId::CIS_CANON_LIDE_210:
|
||||
case SensorId::CIS_CANON_LIDE_220:
|
||||
case SensorId::CCD_CANON_5600F:
|
||||
/* TODO store this in a data struct so we avoid
|
||||
* growing this switch */
|
||||
switch(dev->model->sensor_id)
|
||||
|
|
|
@ -84,30 +84,49 @@ gl847_init_registers (Genesys_Device * dev)
|
|||
dev->reg.clear();
|
||||
|
||||
dev->reg.init_reg(0x01, 0x82);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x01, 0x40);
|
||||
}
|
||||
dev->reg.init_reg(0x02, 0x18);
|
||||
dev->reg.init_reg(0x03, 0x50);
|
||||
dev->reg.init_reg(0x04, 0x12);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x04, 0x20);
|
||||
}
|
||||
dev->reg.init_reg(0x05, 0x80);
|
||||
dev->reg.init_reg(0x06, 0x50); // FASTMODE + POWERBIT
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x06, 0xf8);
|
||||
}
|
||||
dev->reg.init_reg(0x08, 0x10);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x08, 0x20);
|
||||
}
|
||||
dev->reg.init_reg(0x09, 0x01);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x09, 0x00);
|
||||
}
|
||||
dev->reg.init_reg(0x0a, 0x00);
|
||||
dev->reg.init_reg(0x0b, 0x01);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x0b, 0x6b);
|
||||
}
|
||||
dev->reg.init_reg(0x0c, 0x02);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x0c, 0x00);
|
||||
}
|
||||
|
||||
// LED exposures
|
||||
dev->reg.init_reg(0x10, 0x00);
|
||||
dev->reg.init_reg(0x11, 0x00);
|
||||
dev->reg.init_reg(0x12, 0x00);
|
||||
dev->reg.init_reg(0x13, 0x00);
|
||||
dev->reg.init_reg(0x14, 0x00);
|
||||
dev->reg.init_reg(0x15, 0x00);
|
||||
dev->reg.init_reg(0x10, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
dev->reg.init_reg(0x11, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
dev->reg.init_reg(0x12, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
dev->reg.init_reg(0x13, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
dev->reg.init_reg(0x14, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
dev->reg.init_reg(0x15, 0x00); // exposure, overwritten in scanner_setup_sensor() below
|
||||
|
||||
dev->reg.init_reg(0x16, 0x10); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x17, 0x08); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF
|
||||
|
||||
// EXPDMY
|
||||
dev->reg.init_reg(0x19, 0x50); // SENSOR_DEF
|
||||
|
||||
dev->reg.init_reg(0x1a, 0x34); // SENSOR_DEF
|
||||
|
@ -115,32 +134,40 @@ gl847_init_registers (Genesys_Device * dev)
|
|||
dev->reg.init_reg(0x1c, 0x02); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x1d, 0x04); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x1e, 0x10);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x1e, 0xf0);
|
||||
}
|
||||
dev->reg.init_reg(0x1f, 0x04);
|
||||
dev->reg.init_reg(0x20, 0x02);
|
||||
dev->reg.init_reg(0x21, 0x10);
|
||||
dev->reg.init_reg(0x22, 0x7f);
|
||||
dev->reg.init_reg(0x23, 0x7f);
|
||||
dev->reg.init_reg(0x24, 0x10);
|
||||
dev->reg.init_reg(0x25, 0x00);
|
||||
dev->reg.init_reg(0x26, 0x00);
|
||||
dev->reg.init_reg(0x27, 0x00);
|
||||
dev->reg.init_reg(0x2c, 0x09);
|
||||
dev->reg.init_reg(0x2d, 0x60);
|
||||
dev->reg.init_reg(0x2e, 0x80);
|
||||
dev->reg.init_reg(0x2f, 0x80);
|
||||
dev->reg.init_reg(0x30, 0x00);
|
||||
dev->reg.init_reg(0x31, 0x10);
|
||||
dev->reg.init_reg(0x32, 0x15);
|
||||
dev->reg.init_reg(0x33, 0x0e);
|
||||
dev->reg.init_reg(0x34, 0x40);
|
||||
dev->reg.init_reg(0x35, 0x00);
|
||||
dev->reg.init_reg(0x36, 0x2a);
|
||||
dev->reg.init_reg(0x37, 0x30);
|
||||
dev->reg.init_reg(0x38, 0x2a);
|
||||
dev->reg.init_reg(0x39, 0xf8);
|
||||
dev->reg.init_reg(0x3d, 0x00);
|
||||
dev->reg.init_reg(0x3e, 0x00);
|
||||
dev->reg.init_reg(0x3f, 0x00);
|
||||
dev->reg.init_reg(0x20, 0x02); // BUFSEL: buffer full condition
|
||||
dev->reg.init_reg(0x21, 0x10); // STEPNO: set during motor setup
|
||||
dev->reg.init_reg(0x22, 0x7f); // FWDSTEP: set during motor setup
|
||||
dev->reg.init_reg(0x23, 0x7f); // BWDSTEP: set during motor setup
|
||||
dev->reg.init_reg(0x24, 0x10); // FASTNO: set during motor setup
|
||||
dev->reg.init_reg(0x25, 0x00); // LINCNT: set during motor setup
|
||||
dev->reg.init_reg(0x26, 0x00); // LINCNT: set during motor setup
|
||||
dev->reg.init_reg(0x27, 0x00); // LINCNT: set during motor setup
|
||||
|
||||
dev->reg.init_reg(0x2c, 0x09); // DPISET: set during sensor setup
|
||||
dev->reg.init_reg(0x2d, 0x60); // DPISET: set during sensor setup
|
||||
|
||||
dev->reg.init_reg(0x2e, 0x80); // BWHI: black/white low threshdold
|
||||
dev->reg.init_reg(0x2f, 0x80); // BWLOW: black/white low threshold
|
||||
|
||||
dev->reg.init_reg(0x30, 0x00); // STRPIXEL: set during sensor setup
|
||||
dev->reg.init_reg(0x31, 0x10); // STRPIXEL: set during sensor setup
|
||||
dev->reg.init_reg(0x32, 0x15); // ENDPIXEL: set during sensor setup
|
||||
dev->reg.init_reg(0x33, 0x0e); // ENDPIXEL: set during sensor setup
|
||||
|
||||
dev->reg.init_reg(0x34, 0x40); // DUMMY: SENSOR_DEF
|
||||
dev->reg.init_reg(0x35, 0x00); // MAXWD: set during scan setup
|
||||
dev->reg.init_reg(0x36, 0x2a); // MAXWD: set during scan setup
|
||||
dev->reg.init_reg(0x37, 0x30); // MAXWD: set during scan setup
|
||||
dev->reg.init_reg(0x38, 0x2a); // LPERIOD: SENSOR_DEF
|
||||
dev->reg.init_reg(0x39, 0xf8); // LPERIOD: SENSOR_DEF
|
||||
dev->reg.init_reg(0x3d, 0x00); // FEEDL: set during motor setup
|
||||
dev->reg.init_reg(0x3e, 0x00); // FEEDL: set during motor setup
|
||||
dev->reg.init_reg(0x3f, 0x00); // FEEDL: set during motor setup
|
||||
|
||||
dev->reg.init_reg(0x52, 0x03); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x53, 0x07); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x54, 0x00); // SENSOR_DEF
|
||||
|
@ -150,30 +177,27 @@ gl847_init_registers (Genesys_Device * dev)
|
|||
dev->reg.init_reg(0x58, 0x2a); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x59, 0xe1); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x5a, 0x55); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x5e, 0x41);
|
||||
dev->reg.init_reg(0x5f, 0x40);
|
||||
dev->reg.init_reg(0x60, 0x00);
|
||||
dev->reg.init_reg(0x61, 0x21);
|
||||
dev->reg.init_reg(0x62, 0x40);
|
||||
dev->reg.init_reg(0x63, 0x00);
|
||||
dev->reg.init_reg(0x64, 0x21);
|
||||
dev->reg.init_reg(0x65, 0x40);
|
||||
dev->reg.init_reg(0x67, 0x80);
|
||||
dev->reg.init_reg(0x68, 0x80);
|
||||
dev->reg.init_reg(0x69, 0x20);
|
||||
dev->reg.init_reg(0x6a, 0x20);
|
||||
|
||||
// CK1MAP
|
||||
dev->reg.init_reg(0x5e, 0x41); // DECSEL, STOPTIM
|
||||
dev->reg.init_reg(0x5f, 0x40); // FMOVDEC: set during motor setup
|
||||
|
||||
dev->reg.init_reg(0x60, 0x00); // Z1MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x61, 0x21); // Z1MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x62, 0x40); // Z1MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x63, 0x00); // Z2MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x64, 0x21); // Z2MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x65, 0x40); // Z2MOD: overwritten during motor setup
|
||||
dev->reg.init_reg(0x67, 0x80); // STEPSEL, MTRPWM: overwritten during motor setup
|
||||
dev->reg.init_reg(0x68, 0x80); // FSTPSEL, FASTPWM: overwritten during motor setup
|
||||
dev->reg.init_reg(0x69, 0x20); // FSHDEC: overwritten during motor setup
|
||||
dev->reg.init_reg(0x6a, 0x20); // FMOVNO: overwritten during motor setup
|
||||
|
||||
dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF
|
||||
|
||||
// CK3MAP
|
||||
dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF
|
||||
|
||||
// CK4MAP
|
||||
dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF
|
||||
dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF
|
||||
|
@ -181,11 +205,23 @@ gl847_init_registers (Genesys_Device * dev)
|
|||
dev->reg.init_reg(0x7d, 0x00);
|
||||
|
||||
// NOTE: autoconf is a non working option
|
||||
dev->reg.init_reg(0x87, 0x02);
|
||||
dev->reg.init_reg(0x9d, 0x06);
|
||||
dev->reg.init_reg(0xa2, 0x0f);
|
||||
dev->reg.init_reg(0xbd, 0x18);
|
||||
dev->reg.init_reg(0xfe, 0x08);
|
||||
dev->reg.init_reg(0x87, 0x02); // TODO: move to SENSOR_DEF
|
||||
dev->reg.init_reg(0x9d, 0x06); // RAMDLY, MOTLAG, CMODE, STEPTIM, IFRS
|
||||
dev->reg.init_reg(0xa2, 0x0f); // misc
|
||||
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0xab, 0x31);
|
||||
dev->reg.init_reg(0xbb, 0x00);
|
||||
dev->reg.init_reg(0xbc, 0x0f);
|
||||
}
|
||||
dev->reg.init_reg(0xbd, 0x18); // misc
|
||||
dev->reg.init_reg(0xfe, 0x08); // misc
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
dev->reg.init_reg(0x9e, 0x00); // sensor reg, but not in SENSOR_DEF
|
||||
dev->reg.init_reg(0x9f, 0x00); // sensor reg, but not in SENSOR_DEF
|
||||
dev->reg.init_reg(0xaa, 0x00); // custom data
|
||||
dev->reg.init_reg(0xff, 0x00);
|
||||
}
|
||||
|
||||
// gamma[0] and gamma[256] values
|
||||
dev->reg.init_reg(0xbe, 0x00);
|
||||
|
@ -213,6 +249,10 @@ gl847_init_registers (Genesys_Device * dev)
|
|||
const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, sensor.full_resolution,
|
||||
3, ScanMethod::FLATBED);
|
||||
sanei_genesys_set_dpihw(dev->reg, dpihw_sensor.register_dpihw);
|
||||
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
scanner_setup_sensor(*dev, sensor, dev->reg);
|
||||
}
|
||||
}
|
||||
|
||||
// Set values of analog frontend
|
||||
|
@ -224,11 +264,9 @@ void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
|
|||
|
||||
(void) sensor;
|
||||
|
||||
uint8_t val = dev->interface->read_register(REG_0x04);
|
||||
uint8_t frontend_type = val & REG_0x04_FESET;
|
||||
|
||||
if (frontend_type != 0x02) {
|
||||
throw SaneException("unsupported frontend type %d", frontend_type);
|
||||
if (dev->model->model_id != ModelId::CANON_5600F) {
|
||||
// FIXME: remove the following read
|
||||
dev->interface->read_register(REG_0x04);
|
||||
}
|
||||
|
||||
// wait for FE to be ready
|
||||
|
@ -242,14 +280,46 @@ void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
|
|||
dev->frontend = dev->frontend_initial;
|
||||
}
|
||||
|
||||
// reset DAC
|
||||
dev->interface->write_fe_register(0x00, 0x80);
|
||||
if (dev->model->model_id != ModelId::CANON_5600F) {
|
||||
// reset DAC (BUG: this does completely different thing on Analog Devices ADCs)
|
||||
dev->interface->write_fe_register(0x00, 0x80);
|
||||
} else {
|
||||
if (dev->frontend.layout.type == FrontendType::WOLFSON) {
|
||||
// reset DAC
|
||||
dev->interface->write_fe_register(0x04, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& reg : dev->frontend.regs) {
|
||||
dev->interface->write_fe_register(reg.address, reg.value);
|
||||
}
|
||||
}
|
||||
|
||||
static void gl847_write_motor_phase_table(Genesys_Device& dev, unsigned ydpi)
|
||||
{
|
||||
(void) ydpi;
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
std::vector<std::uint8_t> phase_table = {
|
||||
0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00,
|
||||
0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00,
|
||||
0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00,
|
||||
0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00,
|
||||
0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00,
|
||||
0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00,
|
||||
0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00,
|
||||
0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
|
||||
0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00,
|
||||
0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
|
||||
0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00,
|
||||
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
|
||||
0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00,
|
||||
0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00,
|
||||
};
|
||||
dev.interface->write_ahb(0x01000a00, phase_table.size(), phase_table.data());
|
||||
}
|
||||
}
|
||||
|
||||
// @brief set up motor related register for scan
|
||||
static void gl847_init_motor_regs_scan(Genesys_Device* dev,
|
||||
|
@ -326,6 +396,8 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev,
|
|||
scanner_send_slope_table(dev, sensor, FAST_TABLE, fast_table.table);
|
||||
scanner_send_slope_table(dev, sensor, HOME_TABLE, fast_table.table);
|
||||
|
||||
gl847_write_motor_phase_table(*dev, scan_yres);
|
||||
|
||||
// correct move distance by acceleration and deceleration amounts
|
||||
unsigned feedl = feed_steps;
|
||||
unsigned dist = 0;
|
||||
|
@ -441,21 +513,29 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
reg->find_reg(REG_0x01).value |= REG_0x01_SHDAREA;
|
||||
|
||||
if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) ||
|
||||
has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION))
|
||||
has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) ||
|
||||
session.use_host_side_calib)
|
||||
{
|
||||
reg->find_reg(REG_0x01).value &= ~REG_0x01_DVDSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
reg->find_reg(REG_0x01).value |= REG_0x01_DVDSET;
|
||||
}
|
||||
|
||||
reg->find_reg(REG_0x03).value &= ~REG_0x03_AVEENB;
|
||||
|
||||
reg->find_reg(REG_0x03).value &= ~REG_0x03_XPASEL;
|
||||
if (has_flag(session.params.flags, ScanFlag::USE_XPA)) {
|
||||
reg->find_reg(REG_0x03).value |= REG_0x03_XPASEL;
|
||||
}
|
||||
sanei_genesys_set_lamp_power(dev, sensor, *reg,
|
||||
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
|
||||
reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA);
|
||||
|
||||
if (has_flag(session.params.flags, ScanFlag::USE_XPA)) {
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
regs_set_exposure(dev->model->asic_type, *reg, sanei_genesys_fixup_exposure({0, 0, 0}));
|
||||
}
|
||||
}
|
||||
|
||||
// BW threshold
|
||||
reg->set8(0x2e, 0x7f);
|
||||
reg->set8(0x2f, 0x7f);
|
||||
|
@ -490,7 +570,11 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
|
|||
break; // should not happen
|
||||
}
|
||||
} else {
|
||||
reg->find_reg(REG_0x04).value |= 0x10; // mono
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
reg->find_reg(REG_0x04).value |= 0x20;
|
||||
} else {
|
||||
reg->find_reg(REG_0x04).value |= 0x10; // mono
|
||||
}
|
||||
}
|
||||
|
||||
const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, session.output_resolution,
|
||||
|
@ -545,7 +629,13 @@ void CommandSetGl847::init_regs_for_scan_session(Genesys_Device* dev, const Gene
|
|||
int slope_dpi = 0;
|
||||
int dummy = 0;
|
||||
|
||||
dummy = 3 - session.params.channels;
|
||||
if (dev->model->model_id == ModelId::CANON_LIDE_100 ||
|
||||
dev->model->model_id == ModelId::CANON_LIDE_200 ||
|
||||
dev->model->model_id == ModelId::CANON_LIDE_700F ||
|
||||
dev->model->model_id == ModelId::HP_SCANJET_N6310)
|
||||
{
|
||||
dummy = 3 - session.params.channels;
|
||||
}
|
||||
|
||||
/* slope_dpi */
|
||||
/* cis color scan is effectively a gray scan with 3 gray lines per color
|
||||
|
@ -685,11 +775,42 @@ void CommandSetGl847::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
|
|||
dev->interface->write_register(REG_0x6C, val);
|
||||
}
|
||||
|
||||
// FIXME: use scanner_clear_scan_and_feed_counts()
|
||||
val = REG_0x0D_CLRLNCNT;
|
||||
dev->interface->write_register(REG_0x0D, val);
|
||||
val = REG_0x0D_CLRMCNT;
|
||||
dev->interface->write_register(REG_0x0D, val);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
switch (dev->session.params.xres) {
|
||||
case 75:
|
||||
case 150:
|
||||
case 300:
|
||||
scanner_register_rw_bits(*dev, REG_0xA6, 0x04, 0x1c);
|
||||
break;
|
||||
case 600:
|
||||
scanner_register_rw_bits(*dev, REG_0xA6, 0x18, 0x1c);
|
||||
break;
|
||||
case 1200:
|
||||
scanner_register_rw_bits(*dev, REG_0xA6, 0x08, 0x1c);
|
||||
break;
|
||||
case 2400:
|
||||
scanner_register_rw_bits(*dev, REG_0xA6, 0x10, 0x1c);
|
||||
break;
|
||||
case 4800:
|
||||
scanner_register_rw_bits(*dev, REG_0xA6, 0x00, 0x1c);
|
||||
break;
|
||||
default:
|
||||
throw SaneException("Unexpected xres");
|
||||
}
|
||||
dev->interface->write_register(0x6c, 0xf0);
|
||||
dev->interface->write_register(0x6b, 0x87);
|
||||
dev->interface->write_register(0x6d, 0x5f);
|
||||
}
|
||||
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
scanner_clear_scan_and_feed_counts(*dev);
|
||||
} else {
|
||||
// FIXME: use scanner_clear_scan_and_feed_counts()
|
||||
val = REG_0x0D_CLRLNCNT;
|
||||
dev->interface->write_register(REG_0x0D, val);
|
||||
val = REG_0x0D_CLRMCNT;
|
||||
dev->interface->write_register(REG_0x0D, val);
|
||||
}
|
||||
|
||||
val = dev->interface->read_register(REG_0x01);
|
||||
val |= REG_0x01_SCAN;
|
||||
|
@ -823,6 +944,10 @@ void CommandSetGl847::send_shading_data(Genesys_Device* dev, const Genesys_Senso
|
|||
/* base addr of data has been written in reg D0-D4 in 4K word, so AHB address
|
||||
* is 8192*reg value */
|
||||
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* write actual color channel data */
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
|
@ -869,27 +994,35 @@ static void gl847_init_gpio(Genesys_Device* dev)
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
std::vector<std::uint16_t> order1 = { 0xa7, 0xa6, 0x6e };
|
||||
std::vector<std::uint16_t> order2 = { 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0xa8, 0xa9 };
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
apply_registers_ordered(dev->gpo.regs, {0xa6, 0xa7, 0x6f, 0x6e},
|
||||
[&](const GenesysRegisterSetting& reg)
|
||||
{
|
||||
dev->interface->write_register(reg.address, reg.value);
|
||||
});
|
||||
} else {
|
||||
std::vector<std::uint16_t> order1 = { 0xa7, 0xa6, 0x6e };
|
||||
std::vector<std::uint16_t> order2 = { 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0xa8, 0xa9 };
|
||||
|
||||
for (auto addr : order1) {
|
||||
dev->interface->write_register(addr, dev->gpo.regs.find_reg(addr).value);
|
||||
}
|
||||
|
||||
dev->interface->write_register(REG_0x6C, 0x00); // FIXME: Likely not needed
|
||||
|
||||
for (auto addr : order2) {
|
||||
dev->interface->write_register(addr, dev->gpo.regs.find_reg(addr).value);
|
||||
}
|
||||
|
||||
for (const auto& reg : dev->gpo.regs) {
|
||||
if (std::find(order1.begin(), order1.end(), reg.address) != order1.end()) {
|
||||
continue;
|
||||
for (auto addr : order1) {
|
||||
dev->interface->write_register(addr, dev->gpo.regs.find_reg(addr).value);
|
||||
}
|
||||
if (std::find(order2.begin(), order2.end(), reg.address) != order2.end()) {
|
||||
continue;
|
||||
|
||||
dev->interface->write_register(REG_0x6C, 0x00); // FIXME: Likely not needed
|
||||
|
||||
for (auto addr : order2) {
|
||||
dev->interface->write_register(addr, dev->gpo.regs.find_reg(addr).value);
|
||||
}
|
||||
|
||||
for (const auto& reg : dev->gpo.regs) {
|
||||
if (std::find(order1.begin(), order1.end(), reg.address) != order1.end()) {
|
||||
continue;
|
||||
}
|
||||
if (std::find(order2.begin(), order2.end(), reg.address) != order2.end()) {
|
||||
continue;
|
||||
}
|
||||
dev->interface->write_register(reg.address, reg.value);
|
||||
}
|
||||
dev->interface->write_register(reg.address, reg.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -900,18 +1033,17 @@ static void gl847_init_memory_layout(Genesys_Device* dev)
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
// TODO: move to initial register list
|
||||
// FIXME: move to initial register list
|
||||
switch (dev->model->model_id) {
|
||||
case ModelId::CANON_LIDE_100:
|
||||
case ModelId::CANON_LIDE_200:
|
||||
case ModelId::CANON_5600F:
|
||||
dev->interface->write_register(REG_0x0B, 0x29);
|
||||
break;
|
||||
case ModelId::CANON_LIDE_700F:
|
||||
dev->interface->write_register(REG_0x0B, 0x2a);
|
||||
break;
|
||||
default:
|
||||
throw SaneException("Unknown device");
|
||||
break;
|
||||
}
|
||||
|
||||
// prevent further writings by bulk write register
|
||||
|
@ -946,15 +1078,17 @@ void CommandSetGl847::asic_boot(Genesys_Device* dev, bool cold) const
|
|||
// Write initial registers
|
||||
dev->interface->write_registers(dev->reg);
|
||||
|
||||
/* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */
|
||||
val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL;
|
||||
val = (val | REG_0x0B_ENBDRAM);
|
||||
dev->interface->write_register(REG_0x0B, val);
|
||||
dev->reg.find_reg(0x0b).value = val;
|
||||
if (dev->model->model_id != ModelId::CANON_5600F) {
|
||||
// Enable DRAM by setting a rising edge on bit 3 of reg 0x0b
|
||||
// The initial register write also powers on SDRAM
|
||||
val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL;
|
||||
val = (val | REG_0x0B_ENBDRAM);
|
||||
dev->interface->write_register(REG_0x0B, val);
|
||||
dev->reg.find_reg(0x0b).value = val;
|
||||
|
||||
/* CIS_LINE */
|
||||
dev->reg.init_reg(0x08, REG_0x08_CIS_LINE);
|
||||
dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value);
|
||||
// TODO: remove this write
|
||||
dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value);
|
||||
}
|
||||
|
||||
// set up end access
|
||||
dev->interface->write_0x8c(0x10, 0x0b);
|
||||
|
@ -966,8 +1100,11 @@ void CommandSetGl847::asic_boot(Genesys_Device* dev, bool cold) const
|
|||
// setup internal memory layout
|
||||
gl847_init_memory_layout (dev);
|
||||
|
||||
dev->reg.init_reg(0xf8, 0x01);
|
||||
dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value);
|
||||
if (dev->model->model_id != ModelId::CANON_5600F) {
|
||||
// FIXME: move to memory layout
|
||||
dev->reg.init_reg(0xf8, 0x01);
|
||||
dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "gl646.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
|
@ -409,7 +410,7 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession&
|
|||
throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes);
|
||||
}
|
||||
if (total_bytes != max_bytes) {
|
||||
DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu\n", __func__,
|
||||
DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu)\n", __func__,
|
||||
total_bytes, max_bytes);
|
||||
}
|
||||
|
||||
|
@ -425,19 +426,120 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession&
|
|||
1, 1);
|
||||
}
|
||||
|
||||
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA) && session.params.depth == 16) {
|
||||
pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
if (session.params.depth == 16) {
|
||||
unsigned num_swaps = 0;
|
||||
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) {
|
||||
num_swaps++;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
num_swaps++;
|
||||
#endif
|
||||
if (num_swaps % 2 != 0) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
}
|
||||
}
|
||||
|
||||
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
|
||||
pipeline.push_node<ImagePipelineNodeInvert>();
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (session.params.depth == 16) {
|
||||
pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
if (dev->model->is_cis && session.params.channels == 3) {
|
||||
pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
|
||||
}
|
||||
|
||||
if (pipeline.get_output_format() == PixelFormat::BGR888) {
|
||||
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888);
|
||||
}
|
||||
|
||||
if (pipeline.get_output_format() == PixelFormat::BGR161616) {
|
||||
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
|
||||
}
|
||||
|
||||
return pipeline.get_image();
|
||||
}
|
||||
|
||||
|
||||
Image read_shuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& session)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
std::size_t total_bytes = 0;
|
||||
std::size_t pixels_per_line = 0;
|
||||
|
||||
if (dev->model->asic_type == AsicType::GL842 ||
|
||||
dev->model->asic_type == AsicType::GL843 ||
|
||||
dev->model->model_id == ModelId::CANON_5600F)
|
||||
{
|
||||
pixels_per_line = session.output_pixels;
|
||||
} else {
|
||||
// BUG: this selects incorrect pixel number
|
||||
pixels_per_line = session.params.pixels;
|
||||
}
|
||||
|
||||
// FIXME: the current calculation is likely incorrect on non-GL843 implementations,
|
||||
// but this needs checking. Note the extra line when computing size.
|
||||
if (dev->model->asic_type == AsicType::GL842 ||
|
||||
dev->model->asic_type == AsicType::GL843 ||
|
||||
dev->model->model_id == ModelId::CANON_5600F)
|
||||
{
|
||||
total_bytes = session.output_total_bytes_raw;
|
||||
} else {
|
||||
total_bytes = session.params.channels * 2 * pixels_per_line * (session.params.lines + 1);
|
||||
}
|
||||
|
||||
auto format = create_pixel_format(session.params.depth,
|
||||
dev->model->is_cis ? 1 : session.params.channels,
|
||||
dev->model->line_mode_color_order);
|
||||
|
||||
// auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw);
|
||||
auto width = pixels_per_line;
|
||||
auto height = session.params.lines + 1; // BUG: incorrect
|
||||
if (dev->model->asic_type == AsicType::GL842 ||
|
||||
dev->model->asic_type == AsicType::GL843 ||
|
||||
dev->model->model_id == ModelId::CANON_5600F)
|
||||
{
|
||||
height = session.optical_line_count;
|
||||
}
|
||||
|
||||
Image image(width, height, format);
|
||||
|
||||
auto max_bytes = image.get_row_bytes() * height;
|
||||
if (total_bytes > max_bytes) {
|
||||
throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes);
|
||||
}
|
||||
if (total_bytes != max_bytes) {
|
||||
DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu)\n", __func__,
|
||||
total_bytes, max_bytes);
|
||||
}
|
||||
|
||||
sanei_genesys_read_data_from_scanner(dev, image.get_row_ptr(0), total_bytes);
|
||||
|
||||
ImagePipelineStack pipeline;
|
||||
pipeline.push_first_node<ImagePipelineNodeImageSource>(image);
|
||||
|
||||
if (session.segment_count > 1) {
|
||||
auto output_width = session.output_segment_pixel_group_count * session.segment_count;
|
||||
pipeline.push_node<ImagePipelineNodeDesegment>(output_width, dev->segment_order,
|
||||
session.conseq_pixel_dist,
|
||||
1, 1);
|
||||
}
|
||||
|
||||
if (session.params.depth == 16) {
|
||||
unsigned num_swaps = 0;
|
||||
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) {
|
||||
num_swaps++;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
num_swaps++;
|
||||
#endif
|
||||
if (num_swaps % 2 != 0) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
}
|
||||
}
|
||||
|
||||
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
|
||||
pipeline.push_node<ImagePipelineNodeInvert>();
|
||||
}
|
||||
|
||||
if (dev->model->is_cis && session.params.channels == 3) {
|
||||
pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
|
||||
|
@ -514,6 +616,9 @@ void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sen
|
|||
regs_set_exposure(dev->model->asic_type, regs, sanei_genesys_fixup_exposure({0, 0, 0}));
|
||||
regs.set8(0x19, 0xff);
|
||||
}
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
regs_set_exposure(dev->model->asic_type, regs, sanei_genesys_fixup_exposure({0, 0, 0}));
|
||||
}
|
||||
}
|
||||
regs.state.is_lamp_on = set;
|
||||
}
|
||||
|
@ -685,7 +790,16 @@ void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
|
|||
dev->model->asic_type == AsicType::GL846 ||
|
||||
dev->model->asic_type == AsicType::GL847)
|
||||
{
|
||||
s.pixel_startx = (s.output_startx * s.optical_resolution) / s.params.xres;
|
||||
unsigned startx_xres = s.optical_resolution;
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
if (s.output_resolution == 1200) {
|
||||
startx_xres /= 2;
|
||||
}
|
||||
if (s.output_resolution >= 2400) {
|
||||
startx_xres /= 4;
|
||||
}
|
||||
}
|
||||
s.pixel_startx = (s.output_startx * startx_xres) / s.params.xres;
|
||||
s.pixel_endx = s.pixel_startx + s.optical_pixels_raw;
|
||||
|
||||
} else if (dev->model->asic_type == AsicType::GL124)
|
||||
|
@ -719,6 +833,10 @@ unsigned session_adjust_output_pixels(unsigned output_pixels,
|
|||
bool adjust_output_pixels)
|
||||
{
|
||||
bool adjust_optical_pixels = !adjust_output_pixels;
|
||||
if (dev.model->model_id == ModelId::CANON_5600F) {
|
||||
adjust_optical_pixels = true;
|
||||
adjust_output_pixels = true;
|
||||
}
|
||||
if (adjust_optical_pixels) {
|
||||
auto optical_resolution = sensor.get_optical_resolution();
|
||||
|
||||
|
@ -873,6 +991,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
|
|||
s.output_line_bytes_raw = s.output_line_bytes;
|
||||
s.conseq_pixel_dist = 0;
|
||||
|
||||
// FIXME: Use ModelFlag::SIS_SENSOR
|
||||
if ((dev->model->asic_type == AsicType::GL845 ||
|
||||
dev->model->asic_type == AsicType::GL846 ||
|
||||
dev->model->asic_type == AsicType::GL847) &&
|
||||
|
@ -882,18 +1001,47 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
|
|||
if (s.segment_count > 1) {
|
||||
s.conseq_pixel_dist = sensor.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, 2);
|
||||
extra_segment_scan_area *= s.segment_count - 1;
|
||||
extra_segment_scan_area = s.pixel_count_ratio.apply_inverse(extra_segment_scan_area);
|
||||
// in case of multi-segments sensor, we have expand the scan area to sensor boundary
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
unsigned startx_xres = s.optical_resolution;
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
if (s.output_resolution == 1200) {
|
||||
startx_xres /= 2;
|
||||
}
|
||||
if (s.output_resolution >= 2400) {
|
||||
startx_xres /= 4;
|
||||
}
|
||||
}
|
||||
unsigned optical_startx = s.output_startx * startx_xres / s.params.xres;
|
||||
unsigned optical_endx = optical_startx + s.optical_pixels;
|
||||
|
||||
s.optical_pixels_raw += extra_segment_scan_area;
|
||||
unsigned multi_segment_size_output = s.segment_count * s.conseq_pixel_dist;
|
||||
unsigned multi_segment_size_optical =
|
||||
(multi_segment_size_output * s.optical_resolution) / s.output_resolution;
|
||||
|
||||
optical_endx = align_multiple_ceil(optical_endx, multi_segment_size_optical);
|
||||
s.optical_pixels_raw = optical_endx - optical_startx;
|
||||
s.optical_pixels_raw = align_multiple_floor(s.optical_pixels_raw,
|
||||
4 * s.optical_resolution / s.output_resolution);
|
||||
} else {
|
||||
// BUG: the following code will likely scan too much. Use the CANON_5600F approach
|
||||
unsigned extra_segment_scan_area = align_multiple_ceil(s.conseq_pixel_dist, 2);
|
||||
extra_segment_scan_area *= s.segment_count - 1;
|
||||
extra_segment_scan_area = s.pixel_count_ratio.apply_inverse(extra_segment_scan_area);
|
||||
|
||||
s.optical_pixels_raw += extra_segment_scan_area;
|
||||
}
|
||||
}
|
||||
|
||||
s.output_line_bytes_raw = multiply_by_depth_ceil(
|
||||
(s.optical_pixels_raw * s.output_resolution) / sensor.full_resolution / s.segment_count,
|
||||
s.params.depth);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
auto output_pixels_raw = (s.optical_pixels_raw * s.output_resolution) / s.optical_resolution;
|
||||
auto output_channel_bytes_raw = multiply_by_depth_ceil(output_pixels_raw, s.params.depth);
|
||||
s.output_line_bytes_raw = output_channel_bytes_raw * s.params.channels;
|
||||
} else {
|
||||
s.output_line_bytes_raw = multiply_by_depth_ceil(
|
||||
(s.optical_pixels_raw * s.output_resolution) / sensor.full_resolution / s.segment_count,
|
||||
s.params.depth);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->model->asic_type == AsicType::GL841) {
|
||||
|
@ -927,7 +1075,11 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
|
|||
dev->model->asic_type == AsicType::GL846 ||
|
||||
dev->model->asic_type == AsicType::GL847)
|
||||
{
|
||||
s.output_segment_pixel_group_count = s.pixel_count_ratio.apply(s.optical_pixels);
|
||||
if (dev->model->model_id == ModelId::CANON_5600F) {
|
||||
s.output_segment_pixel_group_count = s.output_pixels / s.segment_count;
|
||||
} else {
|
||||
s.output_segment_pixel_group_count = s.pixel_count_ratio.apply(s.optical_pixels);
|
||||
}
|
||||
}
|
||||
|
||||
s.output_line_bytes_requested = multiply_by_depth_ceil(
|
||||
|
@ -977,7 +1129,13 @@ ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSes
|
|||
|
||||
auto read_data_from_usb = [&dev](std::size_t size, std::uint8_t* data)
|
||||
{
|
||||
DBG(DBG_info, "read_data_from_usb: reading %zu bytes\n", size);
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
dev.interface->bulk_read_data(0x45, data, size);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
float us = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();
|
||||
float speed = size / us; // bytes/us == MB/s
|
||||
DBG(DBG_info, "read_data_from_usb: reading %zu bytes finished %f MB/s\n", size, speed);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
|
@ -310,8 +310,7 @@ struct Genesys_Sensor {
|
|||
|
||||
int exposure_lperiod = -1;
|
||||
|
||||
// the number of pixels in a single segment.
|
||||
// only on gl843
|
||||
// the number of pixels in a single segment. This is counted in output resolution.
|
||||
unsigned segment_size = 0;
|
||||
|
||||
// the order of the segments, if any, for the sensor. If the sensor is not segmented or uses
|
||||
|
|
|
@ -583,6 +583,26 @@ void genesys_init_frontend_tables()
|
|||
s_frontends->push_back(fe);
|
||||
|
||||
|
||||
fe = Genesys_Frontend();
|
||||
fe.id = AdcId::CANON_5600F;
|
||||
fe.layout = wolfson_layout;
|
||||
fe.regs = {
|
||||
{ 0x01, 0x23 },
|
||||
{ 0x02, 0x24 },
|
||||
{ 0x03, 0x2f },
|
||||
{ 0x06, 0x00 },
|
||||
{ 0x08, 0x00 },
|
||||
{ 0x09, 0x00 },
|
||||
{ 0x20, 0x60 },
|
||||
{ 0x21, 0x60 },
|
||||
{ 0x22, 0x60 },
|
||||
{ 0x28, 0x77 },
|
||||
{ 0x29, 0x77 },
|
||||
{ 0x2a, 0x77 },
|
||||
};
|
||||
s_frontends->push_back(fe);
|
||||
|
||||
|
||||
fe = Genesys_Frontend();
|
||||
fe.id = AdcId::CANON_8400F;
|
||||
fe.layout = wolfson_layout;
|
||||
|
|
|
@ -392,6 +392,22 @@ void genesys_init_gpo_tables()
|
|||
s_gpo->push_back(gpo);
|
||||
|
||||
|
||||
gpo = Genesys_Gpo();
|
||||
gpo.id = GpioId::CANON_5600F;
|
||||
gpo.regs = {
|
||||
{ 0x6b, 0x87 },
|
||||
{ 0x6c, 0xf0 },
|
||||
{ 0x6d, 0x5f },
|
||||
{ 0x6e, 0x7f },
|
||||
{ 0x6f, 0xa0 },
|
||||
{ 0xa6, 0x07 },
|
||||
{ 0xa7, 0x1c },
|
||||
{ 0xa8, 0x00 },
|
||||
{ 0xa9, 0x04 },
|
||||
};
|
||||
s_gpo->push_back(gpo);
|
||||
|
||||
|
||||
gpo = Genesys_Gpo();
|
||||
gpo.id = GpioId::CANON_8400F;
|
||||
gpo.regs = {
|
||||
|
|
|
@ -75,6 +75,21 @@ void genesys_init_memory_layout_tables()
|
|||
On GL847 and GL124, the values of the base address for scanned data must be multiplied by
|
||||
1024*2=0x0800 to give address on AHB
|
||||
*/
|
||||
ml = MemoryLayout();
|
||||
ml.models = { ModelId::CANON_5600F };
|
||||
ml.regs = {
|
||||
{ 0xd0, 0x0a },
|
||||
{ 0xe0, 0x01 }, { 0xe1, 0x2c }, { 0xe2, 0x06 }, { 0xe3, 0x4e },
|
||||
{ 0xe4, 0x06 }, { 0xe5, 0x4f }, { 0xe6, 0x0b }, { 0xe7, 0x71 },
|
||||
{ 0xe8, 0x0b }, { 0xe9, 0x72 }, { 0xea, 0x10 }, { 0xeb, 0x94 },
|
||||
{ 0xec, 0x10 }, { 0xed, 0x95 }, { 0xee, 0x15 }, { 0xef, 0xb7 },
|
||||
{ 0xf0, 0x15 }, { 0xf1, 0xb8 }, { 0xf2, 0x1a }, { 0xf3, 0xda },
|
||||
{ 0xf4, 0x1a }, { 0xf5, 0xdb }, { 0xf6, 0x1f }, { 0xf7, 0xfd },
|
||||
{ 0xf8, 0x05 }
|
||||
};
|
||||
s_memory_layout->push_back(ml);
|
||||
|
||||
|
||||
ml = MemoryLayout();
|
||||
ml.models = { ModelId::CANON_LIDE_100 };
|
||||
ml.regs = {
|
||||
|
@ -90,8 +105,7 @@ void genesys_init_memory_layout_tables()
|
|||
|
||||
|
||||
ml = MemoryLayout();
|
||||
// BUG: we shouldn't use LIDE_200 data for 5600F
|
||||
ml.models = { ModelId::CANON_LIDE_200, ModelId::CANON_5600F };
|
||||
ml.models = { ModelId::CANON_LIDE_200 };
|
||||
ml.regs = {
|
||||
{ 0xd0, 0x0a }, { 0xd1, 0x1f }, { 0xd2, 0x34 },
|
||||
{ 0xe0, 0x01 }, { 0xe1, 0x24 }, { 0xe2, 0x02 }, { 0xe3, 0x91 },
|
||||
|
|
|
@ -894,43 +894,57 @@ void genesys_init_usb_device_tables()
|
|||
|
||||
model.resolutions = {
|
||||
{
|
||||
{ ScanMethod::FLATBED },
|
||||
{ 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 },
|
||||
{ 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 },
|
||||
{ ScanMethod::FLATBED, ScanMethod::TRANSPARENCY },
|
||||
{ 4800, 2400, 1200, 600, 300, /*150*/ },
|
||||
{ 4800, 2400, 1200, 600, 300, /*150*/ },
|
||||
}
|
||||
};
|
||||
|
||||
model.bpp_gray_values = { 8, 16 };
|
||||
model.bpp_color_values = { 8, 16 };
|
||||
|
||||
model.x_offset = 1.1;
|
||||
model.y_offset = 8.3;
|
||||
model.x_size = 216.07;
|
||||
model.y_size = 299.0;
|
||||
model.x_offset = 1.5;
|
||||
model.y_offset = 10.4;
|
||||
model.x_size = 219.00;
|
||||
model.y_size = 305.0;
|
||||
|
||||
model.y_offset_calib_white = 3.0;
|
||||
model.y_size_calib_mm = 3.0;
|
||||
model.y_offset_calib_white = 2.0;
|
||||
model.y_size_calib_mm = 2.0;
|
||||
model.x_offset_calib_black = 0.0;
|
||||
model.x_size_calib_mm = 217.4241;
|
||||
model.x_size_calib_mm = 220.5;
|
||||
|
||||
model.x_offset_ta = 93.0;
|
||||
model.y_offset_ta = 42.4;
|
||||
model.x_size_ta = 35.0;
|
||||
model.y_size_ta = 230.0;
|
||||
|
||||
model.y_offset_sensor_to_ta = 0;
|
||||
model.y_offset_calib_white_ta = 21.4;
|
||||
model.y_size_calib_ta_mm = 1.0;
|
||||
|
||||
model.post_scan = 0.0;
|
||||
model.eject_feed = 0.0;
|
||||
|
||||
model.ld_shift_r = 0;
|
||||
model.ld_shift_g = 0;
|
||||
model.ld_shift_b = 0;
|
||||
model.ld_shift_g = 32;
|
||||
model.ld_shift_b = 64;
|
||||
|
||||
model.line_mode_color_order = ColorOrder::RGB;
|
||||
|
||||
model.is_cis = true;
|
||||
model.is_cis = false;
|
||||
model.is_sheetfed = false;
|
||||
model.sensor_id = SensorId::CIS_CANON_LIDE_200;
|
||||
model.adc_id = AdcId::CANON_LIDE_200;
|
||||
model.gpio_id = GpioId::CANON_LIDE_200;
|
||||
model.motor_id = MotorId::CANON_LIDE_200;
|
||||
model.flags = ModelFlag::UNTESTED |
|
||||
ModelFlag::SIS_SENSOR |
|
||||
model.sensor_id = SensorId::CCD_CANON_5600F;
|
||||
model.adc_id = AdcId::CANON_5600F;
|
||||
model.gpio_id = GpioId::CANON_5600F;
|
||||
model.motor_id = MotorId::CANON_5600F;
|
||||
model.flags = ModelFlag::SIS_SENSOR |
|
||||
ModelFlag::INVERT_PIXEL_DATA |
|
||||
ModelFlag::DISABLE_ADC_CALIBRATION |
|
||||
ModelFlag::DISABLE_EXPOSURE_CALIBRATION |
|
||||
ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN |
|
||||
ModelFlag::DARK_CALIBRATION |
|
||||
ModelFlag::SHADING_REPARK |
|
||||
ModelFlag::UTA_NO_SECONDARY_MOTOR |
|
||||
ModelFlag::CUSTOM_GAMMA;
|
||||
model.buttons = GENESYS_HAS_SCAN_SW |
|
||||
GENESYS_HAS_COPY_SW |
|
||||
|
|
|
@ -315,6 +315,34 @@ void genesys_init_motor_tables()
|
|||
s_motors->push_back(std::move(motor));
|
||||
|
||||
|
||||
motor = Genesys_Motor();
|
||||
motor.id = MotorId::CANON_5600F;
|
||||
motor.base_ydpi = 2400;
|
||||
|
||||
// FIXME: real limit is 134, but for some reason the motor can't acquire that speed.
|
||||
profile = MotorProfile();
|
||||
profile.slope = MotorSlope::create_from_steps(2500 * 2, 134 * 2, 1000);
|
||||
profile.step_type = StepType::HALF;
|
||||
profile.motor_vref = 0;
|
||||
profile.resolutions = { 75, 150 };
|
||||
motor.profiles.push_back(std::move(profile));
|
||||
|
||||
profile = MotorProfile();
|
||||
profile.slope = MotorSlope::create_from_steps(2500 * 2, 200 * 2, 1000);
|
||||
profile.step_type = StepType::QUARTER;
|
||||
profile.motor_vref = 0;
|
||||
profile.resolutions = { 300, 600, 1200, 2400, 4800 };
|
||||
motor.profiles.push_back(std::move(profile));
|
||||
|
||||
profile = MotorProfile();
|
||||
profile.slope = MotorSlope::create_from_steps(2500 * 2, 200 * 2, 1000);
|
||||
profile.step_type = StepType::QUARTER;
|
||||
profile.motor_vref = 0;
|
||||
motor.fast_profiles.push_back(std::move(profile));
|
||||
|
||||
s_motors->push_back(std::move(motor));
|
||||
|
||||
|
||||
motor = Genesys_Motor();
|
||||
motor.id = MotorId::CANON_8400F;
|
||||
motor.base_ydpi = 1600;
|
||||
|
|
|
@ -1877,6 +1877,129 @@ void genesys_init_sensor_tables()
|
|||
}
|
||||
|
||||
|
||||
sensor = Genesys_Sensor();
|
||||
sensor.sensor_id = SensorId::CCD_CANON_5600F; // gl847
|
||||
sensor.full_resolution = 4800;
|
||||
sensor.register_dpihw = 4800;
|
||||
sensor.black_pixels = 50*8;
|
||||
sensor.dummy_pixel = 10;
|
||||
sensor.fau_gain_white_ref = 160;
|
||||
sensor.gain_white_ref = 160;
|
||||
sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
|
||||
sensor.gamma = { 1.0f, 1.0f, 1.0f };
|
||||
sensor.use_host_side_calib = true;
|
||||
{
|
||||
struct CustomSensorSettings {
|
||||
ValueFilterAny<unsigned> resolutions;
|
||||
unsigned optical_resolution;
|
||||
unsigned register_dpihw;
|
||||
unsigned register_dpiset;
|
||||
int exposure_lperiod;
|
||||
SensorExposure exposure;
|
||||
Ratio pixel_count_ratio;
|
||||
int output_pixel_offset;
|
||||
unsigned segment_size;
|
||||
std::vector<unsigned> segment_order;
|
||||
StaggerConfig stagger_x;
|
||||
StaggerConfig stagger_y;
|
||||
GenesysRegisterSettingSet custom_regs;
|
||||
};
|
||||
|
||||
CustomSensorSettings custom_settings[] = {
|
||||
{ { 150 }, 2400, 600, 300, 4288, { 3983/2, 3983/2, 3983/2 }, Ratio{1, 8}, 10,
|
||||
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
|
||||
{ 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
},
|
||||
{ { 300 }, 2400, 600, 600, 5472, { 4558/2, 4558/2, 4558/2 }, Ratio{1, 8}, 110,
|
||||
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
|
||||
{ 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
},
|
||||
{ { 600 }, 2400, 600, 600, 10944, { 8701/2, 8701/2, 8701/2 }, Ratio{1, 4}, 155,
|
||||
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
|
||||
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
},
|
||||
{ { 1200 }, 2400, 1200, 1200, 29120, { 17120/2, 17120/2, 17120/2 }, Ratio{1, 2}, 295,
|
||||
5418, { 1, 0 }, StaggerConfig{}, StaggerConfig{}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
|
||||
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
},
|
||||
{ { 2400 }, 2400, 2400, 2400, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 600,
|
||||
5418, { 0, 1, 2, 3 },
|
||||
StaggerConfig{10, 15, 4, 9, 14, 19, 8, 13}, StaggerConfig{}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
|
||||
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
},
|
||||
{ { 4800 }, 4800, 4800, 4800, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 1000,
|
||||
10784, { 0, 1, 2, 3 },
|
||||
StaggerConfig{5, 9, 6, 10, 3, 7, 16, 20, 13, 17, 14, 18, 11, 15, 24, 28},
|
||||
StaggerConfig{6, 0}, {
|
||||
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
|
||||
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
|
||||
{ 0x52, 0x0a }, { 0x53, 0x0c }, { 0x54, 0x0e }, { 0x55, 0x00 },
|
||||
{ 0x56, 0x02 }, { 0x57, 0x04 }, { 0x58, 0x32 }, { 0x59, 0x1a }, { 0x5a, 0x40 },
|
||||
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
|
||||
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
|
||||
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& setting : custom_settings) {
|
||||
for (auto method : { ScanMethod::FLATBED, ScanMethod::TRANSPARENCY }) {
|
||||
sensor.method = method;
|
||||
sensor.resolutions = setting.resolutions;
|
||||
sensor.optical_resolution = setting.optical_resolution;
|
||||
sensor.register_dpihw = setting.register_dpihw;
|
||||
sensor.register_dpiset = setting.register_dpiset;
|
||||
sensor.shading_resolution = setting.resolutions.values().front();
|
||||
sensor.exposure_lperiod = setting.exposure_lperiod;
|
||||
sensor.exposure = setting.exposure;
|
||||
sensor.pixel_count_ratio = setting.pixel_count_ratio;
|
||||
sensor.output_pixel_offset = setting.output_pixel_offset;
|
||||
sensor.segment_size = setting.segment_size;
|
||||
sensor.segment_order = setting.segment_order;
|
||||
sensor.stagger_x = setting.stagger_x;
|
||||
sensor.stagger_y = setting.stagger_y;
|
||||
sensor.custom_regs = setting.custom_regs;
|
||||
s_sensors->push_back(sensor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sensor = Genesys_Sensor();
|
||||
sensor.sensor_id = SensorId::CCD_CANON_8400F; // gl843
|
||||
sensor.full_resolution = 3200;
|
||||
|
|
Ładowanie…
Reference in New Issue