genesys: Return std::vector from GL646 simple_scan()

merge-requests/76/head
Povilas Kanapickas 2019-05-25 11:15:35 +03:00
rodzic e48b6c4e2d
commit 247658f23e
2 zmienionych plików z 61 dodań i 119 usunięć

Wyświetl plik

@ -1342,10 +1342,6 @@ gl646_send_slope_table (Genesys_Device * dev, int table_nr,
int dpihw;
int start_address;
SANE_Status status;
uint8_t *table;
#ifdef WORDS_BIGENDIAN
int i;
#endif
DBG(DBG_proc, "%s (table_nr = %d, steps = %d)=%d .. %d\n", __func__, table_nr, steps,
slope_table[0], slope_table[steps - 1]);
@ -1362,7 +1358,7 @@ gl646_send_slope_table (Genesys_Device * dev, int table_nr,
return SANE_STATUS_INVAL;
std::vector<uint8_t> table(steps * 2);
for (i = 0; i < steps; i++)
for (int i = 0; i < steps; i++)
{
table[i * 2] = slope_table[i] & 0xff;
table[i * 2 + 1] = slope_table[i] >> 8;
@ -2670,7 +2666,6 @@ static SANE_Status
gl646_search_start_position (Genesys_Device * dev)
{
SANE_Status status;
unsigned char *data = NULL;
Genesys_Settings settings;
unsigned int resolution, x, y;
@ -2697,8 +2692,8 @@ gl646_search_start_position (Genesys_Device * dev)
settings.dynamic_lineart = SANE_FALSE;
/* scan the desired area */
status =
simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, &data);
std::vector<uint8_t> data;
status = simple_scan(dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, data);
/* process data if scan is OK */
if (status == SANE_STATUS_GOOD)
@ -2722,21 +2717,20 @@ gl646_search_start_position (Genesys_Device * dev)
}
if (DBG_LEVEL >= DBG_data)
{
sanei_genesys_write_pnm_file("gl646_search_position.pnm", data, settings.depth, 1,
sanei_genesys_write_pnm_file("gl646_search_position.pnm", data.data(), settings.depth, 1,
settings.pixels, settings.lines);
}
}
else
{
DBG(DBG_error, "%s: simple_scan failed\n", __func__);
free (data);
DBGCOMPLETED;
return status;
}
/* now search reference points on the data */
status =
sanei_genesys_search_reference_point (dev, data,
sanei_genesys_search_reference_point (dev, data.data(),
dev->sensor.CCD_start_xoffset,
resolution, settings.pixels,
settings.lines);
@ -2746,7 +2740,6 @@ gl646_search_start_position (Genesys_Device * dev)
sane_strstatus(status));
}
free (data);
DBGCOMPLETED;
return status;
}
@ -3181,7 +3174,6 @@ static SANE_Status
gl646_led_calibration (Genesys_Device * dev)
{
int total_size;
uint8_t *line;
unsigned int i, j;
SANE_Status status = SANE_STATUS_GOOD;
int val;
@ -3239,12 +3231,7 @@ gl646_led_calibration (Genesys_Device * dev)
/* colors * bytes_per_color * scan lines */
total_size = settings.pixels * channels * 2 * 1;
line = (uint8_t*) malloc(total_size);
if (!line)
{
DBG(DBG_error, "%s: failed to allocate %d bytes\n", __func__, total_size);
return SANE_STATUS_NO_MEM;
}
std::vector<uint8_t> line(total_size);
/*
we try to get equal bright leds here:
@ -3274,11 +3261,9 @@ gl646_led_calibration (Genesys_Device * dev)
DBG(DBG_info, "%s: starting first line reading\n", __func__);
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line);
status = simple_scan(dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line);
if (status != SANE_STATUS_GOOD)
{
free(line);
DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status));
return status;
}
@ -3287,7 +3272,7 @@ gl646_led_calibration (Genesys_Device * dev)
{
char fn[30];
snprintf(fn, 30, "gl646_led_%02d.pnm", turn);
sanei_genesys_write_pnm_file(fn, line, 16, channels, settings.pixels, 1);
sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, settings.pixels, 1);
}
acceptable = SANE_TRUE;
@ -3345,9 +3330,6 @@ gl646_led_calibration (Genesys_Device * dev)
DBG(DBG_info,"%s: acceptable exposure: 0x%04x,0x%04x,0x%04x\n", __func__, expr, expg, expb);
/* cleanup before return */
free (line);
DBGCOMPLETED;
return status;
}
@ -3398,7 +3380,6 @@ static SANE_Status
ad_fe_offset_calibration (Genesys_Device * dev)
{
SANE_Status status = SANE_STATUS_GOOD;
uint8_t *line;
unsigned int channels;
int pass = 0;
SANE_Int resolution;
@ -3437,6 +3418,8 @@ ad_fe_offset_calibration (Genesys_Device * dev)
dev->frontend.gain[1] = 0;
dev->frontend.gain[2] = 0;
std::vector<uint8_t> line;
/* scan with no move */
bottom = 1;
do
@ -3446,10 +3429,9 @@ ad_fe_offset_calibration (Genesys_Device * dev)
dev->frontend.offset[1] = bottom;
dev->frontend.offset[2] = bottom;
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line);
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line);
if (status != SANE_STATUS_GOOD)
{
free(line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3457,7 +3439,7 @@ ad_fe_offset_calibration (Genesys_Device * dev)
{
char title[30];
snprintf(title, 30, "gl646_offset%03d.pnm", (int)bottom);
sanei_genesys_write_pnm_file (title, line, 8, channels,
sanei_genesys_write_pnm_file (title, line.data(), 8, channels,
settings.pixels, settings.lines);
}
@ -3476,7 +3458,6 @@ ad_fe_offset_calibration (Genesys_Device * dev)
}
}
free (line);
DBG(DBG_io2, "%s: pass=%d, min=%d\n", __func__, pass, min);
bottom++;
}
@ -3506,7 +3487,6 @@ static SANE_Status
gl646_offset_calibration (Genesys_Device * dev)
{
SANE_Status status = SANE_STATUS_GOOD;
uint8_t *first_line, *second_line;
unsigned int channels;
int pass = 0, avg;
SANE_Int resolution;
@ -3569,12 +3549,12 @@ gl646_offset_calibration (Genesys_Device * dev)
dev->frontend.offset[0] = bottom;
dev->frontend.offset[1] = bottom;
dev->frontend.offset[2] = bottom;
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE,
&first_line);
std::vector<uint8_t> first_line, second_line;
status = simple_scan(dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, first_line);
if (status != SANE_STATUS_GOOD)
{
free(first_line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3582,13 +3562,11 @@ gl646_offset_calibration (Genesys_Device * dev)
{
char title[30];
snprintf(title, 30, "gl646_offset%03d.pnm", bottom);
sanei_genesys_write_pnm_file(title, first_line, 8, channels,
sanei_genesys_write_pnm_file(title, first_line.data(), 8, channels,
settings.pixels, settings.lines);
}
bottomavg =
dark_average (first_line, settings.pixels, settings.lines, channels,
black_pixels);
free (first_line);
bottomavg = dark_average(first_line.data(), settings.pixels, settings.lines, channels,
black_pixels);
DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg);
/* now top value */
@ -3596,12 +3574,9 @@ gl646_offset_calibration (Genesys_Device * dev)
dev->frontend.offset[0] = top;
dev->frontend.offset[1] = top;
dev->frontend.offset[2] = top;
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE,
&second_line);
status = simple_scan(dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line);
if (status != SANE_STATUS_GOOD)
{
free(second_line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3610,13 +3585,11 @@ gl646_offset_calibration (Genesys_Device * dev)
{
char title[30];
snprintf(title, 30, "gl646_offset%03d.pnm", top);
sanei_genesys_write_pnm_file (title, second_line, 8, channels,
sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels,
settings.pixels, settings.lines);
}
topavg =
dark_average (second_line, settings.pixels, settings.lines, channels,
black_pixels);
free (second_line);
topavg = dark_average(second_line.data(), settings.pixels, settings.lines, channels,
black_pixels);
DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg);
/* loop until acceptable level */
@ -3630,12 +3603,9 @@ gl646_offset_calibration (Genesys_Device * dev)
dev->frontend.offset[2] = (top + bottom) / 2;
/* scan with no move */
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE,
&second_line);
status = simple_scan(dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line);
if (status != SANE_STATUS_GOOD)
{
free(second_line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3644,15 +3614,14 @@ gl646_offset_calibration (Genesys_Device * dev)
{
char title[30];
snprintf(title, 30, "gl646_offset%03d.pnm", dev->frontend.offset[1]);
sanei_genesys_write_pnm_file (title, second_line, 8, channels,
sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels,
settings.pixels, settings.lines);
}
avg =
dark_average (second_line, settings.pixels, settings.lines, channels,
dark_average (second_line.data(), settings.pixels, settings.lines, channels,
black_pixels);
DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.offset[1]);
free (second_line);
/* compute new boundaries */
if (topavg == avg)
@ -3670,18 +3639,14 @@ gl646_offset_calibration (Genesys_Device * dev)
/* in case of debug do a final scan to get result */
if (DBG_LEVEL >= DBG_data)
{
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE,
&second_line);
status = simple_scan(dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line);
if (status != SANE_STATUS_GOOD)
{
free(second_line);
DBG(DBG_error, "%s: failed to scan final line\n", __func__);
return status;
}
sanei_genesys_write_pnm_file("gl646_offset-final.pnm", second_line, 8, channels,
sanei_genesys_write_pnm_file("gl646_offset-final.pnm", second_line.data(), 8, channels,
settings.pixels, settings.lines);
free (second_line);
}
DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, dev->frontend.offset[0],
@ -3696,7 +3661,6 @@ gl646_offset_calibration (Genesys_Device * dev)
static SANE_Status
ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi)
{
uint8_t *line;
unsigned int i, channels, val;
unsigned int size, count, resolution, pass;
SANE_Status status = SANE_STATUS_GOOD;
@ -3738,15 +3702,16 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi)
average = 0;
pass = 0;
std::vector<uint8_t> line;
/* loop until each channel raises to acceptable level */
while ((average < dev->sensor.gain_white_ref) && (pass < 30))
{
/* scan with no move */
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line);
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line);
if (status != SANE_STATUS_GOOD)
{
free(line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3755,7 +3720,8 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi)
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "gl646_alternative_coarse%02d.pnm", (int)pass);
sanei_genesys_write_pnm_file(title, line, 8, channels, settings.pixels, settings.lines);
sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels,
settings.lines);
}
pass++;
@ -3777,7 +3743,6 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi)
dev->frontend.gain[2] = dev->frontend.gain[0];
DBG(DBG_proc, "%s: average = %.2f, gain = %d\n", __func__, average, dev->frontend.gain[0]);
free (line);
}
DBG(DBG_info, "%s: gains=(%d,%d,%d)\n", __func__, dev->frontend.gain[0], dev->frontend.gain[1],
@ -3796,7 +3761,6 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi)
static SANE_Status
gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
{
uint8_t *line;
unsigned int i, j, k, channels, val, maximum, idx;
unsigned int count, resolution, pass;
SANE_Status status = SANE_STATUS_GOOD;
@ -3872,6 +3836,8 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
}
pass = 0;
std::vector<uint8_t> line;
/* loop until each channel raises to acceptable level */
while (((average[0] < dev->sensor.gain_white_ref)
|| (average[1] < dev->sensor.gain_white_ref)
@ -3879,10 +3845,9 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
{
/* scan with no move */
status =
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line);
simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line);
if (status != SANE_STATUS_GOOD)
{
free(line);
DBG(DBG_error, "%s: failed to scan first line\n", __func__);
return status;
}
@ -3891,7 +3856,8 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "gl646_coarse_gain%02d.pnm", (int)pass);
sanei_genesys_write_pnm_file(title, line, 8, channels, settings.pixels, settings.lines);
sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels,
settings.lines);
}
pass++;
@ -3941,7 +3907,6 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
DBG(DBG_proc, "%s: channel %d, average = %.2f, gain = %d\n", __func__, k, average[k],
dev->frontend.gain[k]);
}
free (line);
}
if (channels < 3)
@ -4394,7 +4359,7 @@ gl646_move_to_ta (Genesys_Device * dev)
*/
static SANE_Status
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
SANE_Bool forward, SANE_Bool shading, unsigned char **data)
SANE_Bool forward, SANE_Bool shading, std::vector<uint8_t>& data)
{
SANE_Status status = SANE_STATUS_INVAL;
unsigned int size, lines, x, y, bpp;
@ -4448,12 +4413,9 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
size *= bpp;
if (settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
size *= 3;
*data = (uint8_t*) malloc(size);
if (!*data)
{
DBG(DBG_error, "%s: failed to allocate %d bytes of memory\n", __func__, size);
return SANE_STATUS_NO_MEM;
}
data.clear();
data.resize(size);
DBG(DBG_io, "%s: allocated %d bytes of memory for %d lines\n", __func__, size, lines);
/* put back real line number in settings */
@ -4463,7 +4425,6 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
status = gl646_set_fe (dev, AFE_SET, settings.xres);
if (status != SANE_STATUS_GOOD)
{
free (*data);
DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status));
return status;
}
@ -4510,7 +4471,6 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status));
free (*data);
return status;
}
@ -4518,7 +4478,6 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
status = gl646_begin_scan (dev, dev->reg, move);
if (status != SANE_STATUS_GOOD)
{
free (*data);
DBG(DBG_error, "%s: failed to begin scan: \n", __func__);
return status;
}
@ -4539,16 +4498,14 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
while (empty && count < 1000);
if (count == 1000)
{
free (*data);
DBG(DBG_error, "%s: failed toread data\n", __func__);
return SANE_STATUS_IO_ERROR;
}
/* now we're on target, we can read data */
status = sanei_genesys_read_data_from_scanner (dev, *data, size);
status = sanei_genesys_read_data_from_scanner (dev, data.data(), size);
if (status != SANE_STATUS_GOOD)
{
free (*data);
DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status));
return status;
}
@ -4568,15 +4525,12 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
/* reorder line */
for (x = 0; x < settings.pixels; x++)
{
buffer[x * 3] = (*data)[y * settings.pixels * 3 + x];
buffer[x * 3 + 1] =
(*data)[y * settings.pixels * 3 + settings.pixels + x];
buffer[x * 3 + 2] =
(*data)[y * settings.pixels * 3 + 2 * settings.pixels +
x];
buffer[x * 3] = data[y * settings.pixels * 3 + x];
buffer[x * 3 + 1] = data[y * settings.pixels * 3 + settings.pixels + x];
buffer[x * 3 + 2] = data[y * settings.pixels * 3 + 2 * settings.pixels + x];
}
/* copy line back */
memcpy ((*data) + settings.pixels * 3 * y, buffer.data(),
memcpy (data.data() + settings.pixels * 3 * y, buffer.data(),
settings.pixels * 3);
}
}
@ -4587,24 +4541,15 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
/* reorder line */
for (x = 0; x < settings.pixels; x++)
{
buffer[x * 6] = (*data)[y * settings.pixels * 6 + x * 2];
buffer[x * 6 + 1] =
(*data)[y * settings.pixels * 6 + x * 2 + 1];
buffer[x * 6 + 2] =
(*data)[y * settings.pixels * 6 + 2 * settings.pixels +
x * 2];
buffer[x * 6 + 3] =
(*data)[y * settings.pixels * 6 + 2 * settings.pixels +
x * 2 + 1];
buffer[x * 6 + 4] =
(*data)[y * settings.pixels * 6 + 4 * settings.pixels +
x * 2];
buffer[x * 6 + 5] =
(*data)[y * settings.pixels * 6 + 4 * settings.pixels +
x * 2 + 1];
buffer[x * 6] = data[y * settings.pixels * 6 + x * 2];
buffer[x * 6 + 1] = data[y * settings.pixels * 6 + x * 2 + 1];
buffer[x * 6 + 2] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2];
buffer[x * 6 + 3] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2 + 1];
buffer[x * 6 + 4] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2];
buffer[x * 6 + 5] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2 + 1];
}
/* copy line back */
memcpy ((*data) + settings.pixels * 6 * y, buffer.data(),
memcpy (data.data() + settings.pixels * 6 * y, buffer.data(),
settings.pixels * 6);
}
}
@ -4614,7 +4559,6 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
status = end_scan (dev, dev->reg, SANE_TRUE, SANE_FALSE);
if (status != SANE_STATUS_GOOD)
{
free (*data);
DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status));
return status;
}
@ -4634,7 +4578,6 @@ static SANE_Status
simple_move (Genesys_Device * dev, SANE_Int distance)
{
SANE_Status status;
unsigned char *data = NULL;
Genesys_Settings settings;
DBG(DBG_proc, "%s: %d mm\n", __func__, distance);
@ -4657,13 +4600,13 @@ simple_move (Genesys_Device * dev, SANE_Int distance)
settings.exposure_time = 0;
settings.dynamic_lineart = SANE_FALSE;
status = simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, &data);
std::vector<uint8_t> data;
status = simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, data);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: simple_scan failed\n", __func__);
}
free (data);
DBGCOMPLETED
return status;
}
@ -4990,7 +4933,6 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
SANE_Bool half_ccd = SANE_FALSE;
Genesys_Settings settings;
int res = get_closest_resolution (dev->model->ccd_type, 75, SANE_FALSE);
unsigned char *data = NULL;
unsigned int pass, count, found, x, y;
char title[80];
@ -5034,23 +4976,24 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
/* detection pass done */
pass = 0;
std::vector<uint8_t> data;
/* loop until strip is found or maximum pass number done */
while (pass < 20 && !found)
{
/* scan a full width strip */
status =
simple_scan (dev, settings, SANE_TRUE, forward, SANE_FALSE, &data);
simple_scan (dev, settings, SANE_TRUE, forward, SANE_FALSE, data);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: simple_scan failed\n", __func__);
free (data);
return status;
}
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "gl646_search_strip_%s%02d.pnm", forward ? "fwd" : "bwd",
(int)pass);
sanei_genesys_write_pnm_file (title, data, settings.depth, 1,
sanei_genesys_write_pnm_file (title, data.data(), settings.depth, 1,
settings.pixels, settings.lines);
}
@ -5129,7 +5072,6 @@ gl646_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
}
pass++;
}
free (data);
if (found)
{
status = SANE_STATUS_GOOD;

Wyświetl plik

@ -328,7 +328,7 @@ simple_move (Genesys_Device * dev, SANE_Int distance);
*/
static SANE_Status
simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, SANE_Bool forward,
SANE_Bool shading, unsigned char **data);
SANE_Bool shading, std::vector<uint8_t>& data);
/**
* Send the stop scan command