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

Wyświetl plik

@ -4070,11 +4070,6 @@ gl646_init (Genesys_Device * dev)
/* Set default values for registers */ /* Set default values for registers */
gl646_init_regs (dev); 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 */ /* Init shading data */
RIE (sanei_genesys_init_shading_data (dev, dev->sensor.sensor_pixels)); 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 */ /* send gamma tables */
status = gl841_send_gamma_table (dev); status = gl841_send_gamma_table (dev);
if (status != SANE_STATUS_GOOD) 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 */ /* allocate temporary gamma tables: 16 bits words, 3 channels */
std::vector<uint8_t> gamma(size * 2 * 3); std::vector<uint8_t> gamma(size * 2 * 3);
/* copy sensor specific's gamma tables */ std::vector<uint16_t> rgamma = get_gamma_table(dev, dev->sensor, GENESYS_RED);
for (i = 0; i < size; i++) 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);
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; // copy sensor specific's gamma tables
gamma[i * 2 + size * 2 + 0] = dev->sensor.gamma_table[GENESYS_GREEN][i] & 0xff; for (i = 0; i < size; i++) {
gamma[i * 2 + size * 2 + 1] = (dev->sensor.gamma_table[GENESYS_GREEN][i] >> 8) & 0xff; gamma[i * 2 + size * 0 + 0] = rgamma[i] & 0xff;
gamma[i * 2 + size * 4 + 0] = dev->sensor.gamma_table[GENESYS_BLUE][i] & 0xff; gamma[i * 2 + size * 0 + 1] = (rgamma[i] >> 8) & 0xff;
gamma[i * 2 + size * 4 + 1] = (dev->sensor.gamma_table[GENESYS_BLUE][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 */ /* 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; 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 /** @brief generates gamma buffer to transfer
* Generates gamma table buffer to send to ASIC. Applies * Generates gamma table buffer to send to ASIC. Applies
* contrast and brightness if set. * contrast and brightness if set.
@ -1247,8 +1260,9 @@ SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev,
int size, int size,
uint8_t *gamma) uint8_t *gamma)
{ {
int i; std::vector<uint16_t> rgamma = get_gamma_table(dev, dev->sensor, GENESYS_RED);
uint16_t value; 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) if(dev->settings.contrast!=0 || dev->settings.brightness!=0)
{ {
@ -1260,19 +1274,19 @@ SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev,
max, max,
dev->settings.contrast, dev->settings.contrast,
dev->settings.brightness); 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]; value=lut[value];
gamma[i * 2 + size * 0 + 0] = value & 0xff; gamma[i * 2 + size * 0 + 0] = value & 0xff;
gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff; gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_GREEN][i]; value=ggamma[i];
value=lut[value]; value=lut[value];
gamma[i * 2 + size * 2 + 0] = value & 0xff; gamma[i * 2 + size * 2 + 0] = value & 0xff;
gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff; gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff;
value=dev->sensor.gamma_table[GENESYS_BLUE][i]; value=bgamma[i];
value=lut[value]; value=lut[value];
gamma[i * 2 + size * 4 + 0] = value & 0xff; gamma[i * 2 + size * 4 + 0] = value & 0xff;
gamma[i * 2 + size * 4 + 1] = (value >> 8) & 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 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 + 0] = value & 0xff;
gamma[i * 2 + size * 0 + 1] = (value >> 8) & 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 + 0] = value & 0xff;
gamma[i * 2 + size * 2 + 1] = (value >> 8) & 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 + 0] = value & 0xff;
gamma[i * 2 + size * 4 + 1] = (value >> 8) & 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; 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 /* check if the device has already been initialized and powered up
* we read register 6 and check PWRBIT, if reset scanner has been * 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 * 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 // red, green and blue gamma coefficient for default gamma tables
AssignableArray<float, 3> gamma; AssignableArray<float, 3> gamma;
// sensor-specific gamma tables
std::vector<uint16_t> gamma_table[3];
size_t fread(FILE* fp) size_t fread(FILE* fp)
{ {
bool success = true; bool success = true;
@ -1263,6 +1260,10 @@ struct Genesys_Device
// bytes to read from USB when calibrating. If 0, this is not set // bytes to read from USB when calibrating. If 0, this is not set
size_t calib_total_bytes_to_read = 0; 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> white_average_data;
std::vector<uint8_t> dark_average_data; std::vector<uint8_t> dark_average_data;
uint16_t dark[3] = {}; uint16_t dark[3] = {};
@ -1549,14 +1550,12 @@ sanei_genesys_create_slope_table3 (Genesys_Device * dev,
unsigned int *final_exposure, unsigned int *final_exposure,
int power_mode); 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, void sanei_genesys_create_default_gamma_table(Genesys_Device* dev,
std::vector<uint16_t>& gamma_table, float gamma); 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_send_gamma_table (Genesys_Device * dev);
extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev); extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev);