genesys: Don't modify sensor with gamma data

merge-requests/81/head
Povilas Kanapickas 2019-06-02 11:47:50 +03:00
rodzic dafd2a150b
commit f8e8243b78
6 zmienionych plików z 114 dodań i 112 usunięć

Wyświetl plik

@ -746,7 +746,6 @@ void sanei_genesys_create_default_gamma_table(Genesys_Device* dev,
sanei_genesys_create_gamma_table(gamma_table, size, max, max, gamma);
}
/* computes the exposure_time on the basis of the given vertical dpi,
the number of pixels the ccd needs to send,
the step_type and the corresponding maximum speed from the motor struct */
@ -6562,14 +6561,15 @@ sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
return ret;
}
/* gets an option , called by sane_control_option */
static SANE_Status
get_option_value (Genesys_Scanner * s, int option, void *val)
{
unsigned int i;
SANE_Word *table ,tmp;
uint16_t *gamma;
SANE_Word tmp;
SANE_Word* table = nullptr;
std::vector<uint16_t> gamma_table;
unsigned option_size = 0;
SANE_Status status = SANE_STATUS_GOOD;
switch (option)
@ -6631,43 +6631,53 @@ get_option_value (Genesys_Scanner * s, int option, void *val)
/* word array options */
case OPT_GAMMA_VECTOR:
table = (SANE_Word *) val;
if (strcmp (s->val[OPT_COLOR_FILTER].s, "Red") == 0)
{
gamma = s->dev->sensor.gamma_table[GENESYS_RED].data();
}
else if (strcmp (s->val[OPT_COLOR_FILTER].s, "Blue") == 0)
{
gamma = s->dev->sensor.gamma_table[GENESYS_BLUE].data();
}
else
{
gamma = s->dev->sensor.gamma_table[GENESYS_GREEN].data();
}
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = gamma[i];
}
break;
if (strcmp (s->val[OPT_COLOR_FILTER].s, "Red") == 0) {
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_RED);
} else if (strcmp (s->val[OPT_COLOR_FILTER].s, "Blue") == 0) {
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_BLUE);
} else {
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_GREEN);
}
option_size = s->opt[option].size / sizeof (SANE_Word);
if (gamma_table.size() != option_size) {
throw std::runtime_error("The size of the gamma tables does not match");
}
for (i = 0; i < option_size; i++) {
table[i] = gamma_table[i];
}
break;
case OPT_GAMMA_VECTOR_R:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.gamma_table[GENESYS_RED][i];
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_RED);
option_size = s->opt[option].size / sizeof (SANE_Word);
if (gamma_table.size() != option_size) {
throw std::runtime_error("The size of the gamma tables does not match");
}
for (i = 0; i < option_size; i++) {
table[i] = gamma_table[i];
}
break;
case OPT_GAMMA_VECTOR_G:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.gamma_table[GENESYS_GREEN][i];
}
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_GREEN);
option_size = s->opt[option].size / sizeof (SANE_Word);
if (gamma_table.size() != option_size) {
throw std::runtime_error("The size of the gamma tables does not match");
}
for (i = 0; i < option_size; i++) {
table[i] = gamma_table[i];
}
break;
case OPT_GAMMA_VECTOR_B:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.gamma_table[GENESYS_BLUE][i];
}
gamma_table = get_gamma_table(s->dev, s->dev->sensor, GENESYS_BLUE);
option_size = s->opt[option].size / sizeof (SANE_Word);
if (gamma_table.size() != option_size) {
throw std::runtime_error("The size of the gamma tables does not match");
}
for (i = 0; i < option_size; i++) {
table[i] = gamma_table[i];
}
break;
/* sensors */
case OPT_SCAN_SW:
@ -6746,6 +6756,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
SANE_Word *table;
unsigned int i;
SANE_Range *x_range, *y_range;
unsigned option_size = 0;
switch (option)
{
@ -6964,56 +6975,48 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
DISABLE (OPT_GAMMA_VECTOR_R);
DISABLE (OPT_GAMMA_VECTOR_G);
DISABLE (OPT_GAMMA_VECTOR_B);
/* restore default sensor gamma table */
/* currently there is no sensor's specific gamma table,
* tables are built by sanei_genesys_create_gamma_table */
sanei_genesys_create_gamma_table (s->dev->sensor.gamma_table[GENESYS_RED],
s->opt[OPT_GAMMA_VECTOR_R].size / sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_R].constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_R].constraint.range->max,
s->dev->sensor.gamma[GENESYS_RED]);
sanei_genesys_create_gamma_table (s->dev->sensor.gamma_table[GENESYS_GREEN],
s->opt[OPT_GAMMA_VECTOR_G].size / sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_G].constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_G].constraint.range->max,
s->dev->sensor.gamma[GENESYS_GREEN]);
sanei_genesys_create_gamma_table (s->dev->sensor.gamma_table[GENESYS_BLUE],
s->opt[OPT_GAMMA_VECTOR_B].size / sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_B].constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_B].constraint.range->max,
s->dev->sensor.gamma[GENESYS_BLUE]);
for (auto& table : s->dev->gamma_override_tables) {
table.clear();
}
}
break;
case OPT_GAMMA_VECTOR:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.gamma_table[GENESYS_RED][i] = table[i];
s->dev->sensor.gamma_table[GENESYS_GREEN][i] = table[i];
s->dev->sensor.gamma_table[GENESYS_BLUE][i] = table[i];
}
option_size = s->opt[option].size / sizeof (SANE_Word);
s->dev->gamma_override_tables[GENESYS_RED].resize(option_size);
s->dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
s->dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
for (i = 0; i < option_size; i++) {
s->dev->gamma_override_tables[GENESYS_RED][i] = table[i];
s->dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
s->dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_R:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.gamma_table[GENESYS_RED][i] = table[i];
}
option_size = s->opt[option].size / sizeof (SANE_Word);
s->dev->gamma_override_tables[GENESYS_RED].resize(option_size);
for (i = 0; i < option_size; i++) {
s->dev->gamma_override_tables[GENESYS_RED][i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_G:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.gamma_table[GENESYS_GREEN][i] = table[i];
}
option_size = s->opt[option].size / sizeof (SANE_Word);
s->dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
for (i = 0; i < option_size; i++) {
s->dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_B:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.gamma_table[GENESYS_BLUE][i] = table[i];
}
option_size = s->opt[option].size / sizeof (SANE_Word);
s->dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
for (i = 0; i < option_size; i++) {
s->dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
}
break;
case OPT_CALIBRATE:
status = s->dev->model->cmd_set->save_power (s->dev, SANE_FALSE);

Wyświetl plik

@ -4070,11 +4070,6 @@ gl646_init (Genesys_Device * dev)
/* Set default values for registers */
gl646_init_regs (dev);
for(int i=0; i < 3; i++) {
sanei_genesys_create_default_gamma_table(dev, dev->sensor.gamma_table[i],
dev->sensor.gamma[i]);
}
/* Init shading data */
RIE (sanei_genesys_init_shading_data (dev, dev->sensor.sensor_pixels));

Wyświetl plik

@ -5102,12 +5102,6 @@ gl841_init (Genesys_Device * dev)
}
}
// initalize sensor gamma tables
for (int i = 0; i<3; i++) {
sanei_genesys_create_default_gamma_table(dev, dev->sensor.gamma_table[i],
dev->sensor.gamma[i]);
}
/* send gamma tables */
status = gl841_send_gamma_table (dev);
if (status != SANE_STATUS_GOOD)

Wyświetl plik

@ -3198,15 +3198,18 @@ gl843_send_gamma_table (Genesys_Device * dev)
/* allocate temporary gamma tables: 16 bits words, 3 channels */
std::vector<uint8_t> gamma(size * 2 * 3);
/* copy sensor specific's gamma tables */
for (i = 0; i < size; i++)
{
gamma[i * 2 + size * 0 + 0] = dev->sensor.gamma_table[GENESYS_RED][i] & 0xff;
gamma[i * 2 + size * 0 + 1] = (dev->sensor.gamma_table[GENESYS_RED][i] >> 8) & 0xff;
gamma[i * 2 + size * 2 + 0] = dev->sensor.gamma_table[GENESYS_GREEN][i] & 0xff;
gamma[i * 2 + size * 2 + 1] = (dev->sensor.gamma_table[GENESYS_GREEN][i] >> 8) & 0xff;
gamma[i * 2 + size * 4 + 0] = dev->sensor.gamma_table[GENESYS_BLUE][i] & 0xff;
gamma[i * 2 + size * 4 + 1] = (dev->sensor.gamma_table[GENESYS_BLUE][i] >> 8) & 0xff;
std::vector<uint16_t> rgamma = get_gamma_table(dev, dev->sensor, GENESYS_RED);
std::vector<uint16_t> ggamma = get_gamma_table(dev, dev->sensor, GENESYS_GREEN);
std::vector<uint16_t> bgamma = get_gamma_table(dev, dev->sensor, GENESYS_BLUE);
// copy sensor specific's gamma tables
for (i = 0; i < size; i++) {
gamma[i * 2 + size * 0 + 0] = rgamma[i] & 0xff;
gamma[i * 2 + size * 0 + 1] = (rgamma[i] >> 8) & 0xff;
gamma[i * 2 + size * 2 + 0] = ggamma[i] & 0xff;
gamma[i * 2 + size * 2 + 1] = (ggamma[i] >> 8) & 0xff;
gamma[i * 2 + size * 4 + 0] = bgamma[i] & 0xff;
gamma[i * 2 + size * 4 + 1] = (bgamma[i] >> 8) & 0xff;
}
/* send address */

Wyświetl plik

@ -1231,6 +1231,19 @@ sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, uint8
return status;
}
std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor,
int color)
{
if (!dev->gamma_override_tables[color].empty()) {
return dev->gamma_override_tables[color];
} else {
std::vector<uint16_t> ret;
sanei_genesys_create_default_gamma_table(dev, ret, sensor.gamma[color]);
return ret;
}
}
/** @brief generates gamma buffer to transfer
* Generates gamma table buffer to send to ASIC. Applies
* contrast and brightness if set.
@ -1247,8 +1260,9 @@ SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev,
int size,
uint8_t *gamma)
{
int i;
uint16_t value;
std::vector<uint16_t> rgamma = get_gamma_table(dev, dev->sensor, GENESYS_RED);
std::vector<uint16_t> ggamma = get_gamma_table(dev, dev->sensor, GENESYS_GREEN);
std::vector<uint16_t> bgamma = get_gamma_table(dev, dev->sensor, GENESYS_BLUE);
if(dev->settings.contrast!=0 || dev->settings.brightness!=0)
{
@ -1260,19 +1274,19 @@ SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev,
max,
dev->settings.contrast,
dev->settings.brightness);
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
value=dev->sensor.gamma_table[GENESYS_RED][i];
uint16_t value=rgamma[i];
value=lut[value];
gamma[i * 2 + size * 0 + 0] = value & 0xff;
gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_GREEN][i];
value=ggamma[i];
value=lut[value];
gamma[i * 2 + size * 2 + 0] = value & 0xff;
gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_BLUE][i];
value=bgamma[i];
value=lut[value];
gamma[i * 2 + size * 4 + 0] = value & 0xff;
gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff;
@ -1280,17 +1294,17 @@ SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev,
}
else
{
for (i = 0; i < size; i++)
for (int i = 0; i < size; i++)
{
value=dev->sensor.gamma_table[GENESYS_RED][i];
uint16_t value=rgamma[i];
gamma[i * 2 + size * 0 + 0] = value & 0xff;
gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_GREEN][i];
value=ggamma[i];
gamma[i * 2 + size * 2 + 0] = value & 0xff;
gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_BLUE][i];
value=bgamma[i];
gamma[i * 2 + size * 4 + 0] = value & 0xff;
gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff;
}
@ -1398,12 +1412,6 @@ sanei_genesys_asic_init (Genesys_Device * dev, int /*max_regs*/)
dev->usb_mode = 2;
}
// initalize sensor gamma tables
for (int i = 0; i<3; i++) {
sanei_genesys_create_default_gamma_table(dev, dev->sensor.gamma_table[i],
dev->sensor.gamma[i]);
}
/* check if the device has already been initialized and powered up
* we read register 6 and check PWRBIT, if reset scanner has been
* freshly powered up. This bit will be set to later so that following

Wyświetl plik

@ -536,9 +536,6 @@ struct Genesys_Sensor {
// red, green and blue gamma coefficient for default gamma tables
AssignableArray<float, 3> gamma;
// sensor-specific gamma tables
std::vector<uint16_t> gamma_table[3];
size_t fread(FILE* fp)
{
bool success = true;
@ -1263,6 +1260,10 @@ struct Genesys_Device
// bytes to read from USB when calibrating. If 0, this is not set
size_t calib_total_bytes_to_read = 0;
// gamma overrides. If a respective array is not empty then it means that the gamma for that
// color is overridden.
std::vector<uint16_t> gamma_override_tables[3];
std::vector<uint8_t> white_average_data;
std::vector<uint8_t> dark_average_data;
uint16_t dark[3] = {};
@ -1549,14 +1550,12 @@ sanei_genesys_create_slope_table3 (Genesys_Device * dev,
unsigned int *final_exposure,
int power_mode);
extern void
sanei_genesys_create_gamma_table (std::vector<uint16_t>& gamma_table, int size,
float maximum, float gamma_max,
float gamma);
void sanei_genesys_create_default_gamma_table(Genesys_Device* dev,
std::vector<uint16_t>& gamma_table, float gamma);
std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor,
int color);
extern SANE_Status sanei_genesys_send_gamma_table (Genesys_Device * dev);
extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev);