Refactoring the ADF mode.

merge-requests/213/head^2
Thierry HUCHARD 2020-03-22 16:14:23 +01:00
rodzic 7caf928797
commit 79f7463366
7 zmienionych plików z 139 dodań i 65 usunięć

Wyświetl plik

@ -404,22 +404,31 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
static SANE_Status
init_options(SANE_String_Const name, escl_sane_t *s)
{
SANE_Range xrange, yrange;
DBG (10, "escl init_options\n");
SANE_Status status = SANE_STATUS_GOOD;
int i = 0;
if (!s->scanner) return SANE_STATUS_INVAL;
if (name) {
for (i = 0; i < s->scanner->SourcesSize; i++)
{
if (!strcmp(s->scanner->Sources[i], name))
s->scanner->source = i;
}
int source = s->scanner->source;
DBG (10, "escl init_options name [%s]\n", name);
if (!strcmp(name, SANE_I18N ("ADF Duplex")))
s->scanner->source = ADFSIMPLEX;
else if (!strncmp(name, "AD", 2) ||
!strcmp(name, SANE_I18N ("ADF Duplex")))
s->scanner->source = ADFSIMPLEX;
else
s->scanner->source = PLATEN;
if (source == s->scanner->source) return status;
}
else
s->scanner->source = PLATEN;
memset (s->opt, 0, sizeof (s->opt));
memset (s->val, 0, sizeof (s->val));
for (i = 0; i < NUM_OPTIONS; ++i) {
s->opt[i].size = sizeof (SANE_Word);
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
s->opt[i].size = sizeof (SANE_Word);
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
}
s->x_range.min = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MinWidth, 300.0);
s->x_range.max = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MaxWidth, 300.0);
@ -496,7 +505,7 @@ init_options(SANE_String_Const name, escl_sane_t *s)
s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_TL_X].constraint.range = &s->x_range;
s->val[OPT_TL_X].w = 0;
s->val[OPT_TL_X].w = s->x_range.min;
s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
@ -507,7 +516,7 @@ init_options(SANE_String_Const name, escl_sane_t *s)
s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_TL_Y].constraint.range = &s->y_range;
s->val[OPT_TL_Y].w = 0;
s->val[OPT_TL_Y].w = s->y_range.min;
s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
@ -542,10 +551,7 @@ init_options(SANE_String_Const name, escl_sane_t *s)
s->opt[OPT_SCAN_SOURCE].constraint.string_list = s->scanner->Sources;
if (s->val[OPT_SCAN_SOURCE].s)
free (s->val[OPT_SCAN_SOURCE].s);
if (name)
s->val[OPT_SCAN_SOURCE].s = strdup (name);
else
s->val[OPT_SCAN_SOURCE].s = strdup (s->scanner->Sources[0]);
s->val[OPT_SCAN_SOURCE].s = strdup (s->scanner->Sources[s->scanner->source]);
return (status);
}
@ -580,7 +586,7 @@ sane_open(SANE_String_Const name, SANE_Handle *h)
return (status);
status = init_options(NULL, handler);
if (status != SANE_STATUS_GOOD)
return (status);
return (status);
handler->ps.depth = 8;
handler->ps.last_frame = SANE_TRUE;
handler->ps.format = SANE_FRAME_RGB;
@ -589,7 +595,7 @@ sane_open(SANE_String_Const name, SANE_Handle *h)
handler->ps.bytes_per_line = handler->ps.pixels_per_line * 3;
status = sane_get_parameters(handler, 0);
if (status != SANE_STATUS_GOOD)
return (status);
return (status);
handler->cancel = SANE_FALSE;
handler->write_scan_data = SANE_FALSE;
handler->decompress_scan_data = SANE_FALSE;
@ -806,8 +812,8 @@ sane_start(SANE_Handle h)
DBG(10, "Calculate Size Image [%dx%d|%dx%d]\n",
handler->scanner->caps[handler->scanner->source].pos_x,
handler->scanner->caps[handler->scanner->source].pos_y,
handler->scanner->caps[handler->scanner->source].height,
handler->scanner->caps[handler->scanner->source].width);
handler->scanner->caps[handler->scanner->source].width,
handler->scanner->caps[handler->scanner->source].height);
if (!handler->scanner->caps[handler->scanner->source].default_color) {
DBG (10, "Default Color allocation failure.\n");
return (SANE_STATUS_NO_MEM);
@ -840,7 +846,7 @@ sane_start(SANE_Handle h)
return SANE_STATUS_INVAL;
}
DBG(10, "2-Size Image [%dx%d|%dx%d]\n", 0, 0, w, he);
DBG(10, "2-Size Image (%d)[%dx%d|%dx%d]\n", handler->scanner->img_size, 0, 0, w, he);
if (status != SANE_STATUS_GOOD)
return (status);
@ -849,8 +855,10 @@ sane_start(SANE_Handle h)
handler->ps.lines = he;
handler->ps.bytes_per_line = w * bps;
if (handler->scanner->source != PLATEN) {
SANE_Status st = escl_status(handler->name, handler->scanner->source);
DBG(10, "eSCL : command returned status %s\n", sane_strstatus(st));
SANE_Bool next_page =
(SANE_STATUS_GOOD == escl_status(handler->name, handler->scanner->source) ?
(SANE_STATUS_GOOD == st ?
SANE_TRUE :
SANE_FALSE);
handler->scanner->work = next_page;
@ -860,7 +868,9 @@ sane_start(SANE_Handle h)
handler->scanner->work = SANE_FALSE;
handler->ps.last_frame = SANE_TRUE;
}
handler->ps.format = SANE_FRAME_RGB;
DBG(10, "NEXT Frame [%s]\n", (handler->ps.last_frame ? "Non" : "Oui"));
DBG(10, "Real Size Image [%dx%d|%dx%d]\n", 0, 0, w, he);
return (status);
}
@ -913,6 +923,7 @@ sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len)
if (!handler | !buf | !len)
return (SANE_STATUS_INVAL);
if (handler->cancel)
return (SANE_STATUS_CANCELLED);
if (!handler->write_scan_data)

Wyświetl plik

@ -182,45 +182,51 @@ static int
find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
{
const char *name = (const char *)node->name;
if (strcmp(name, "ColorMode") == 0)
scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, &scanner->caps[type].ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1);
if (strcmp(name, "ColorMode") == 0) {
const char *color = (SANE_String_Const)xmlNodeGetContent(node);
if (type == PLATEN || strcmp(color, "BlackAndWhite1"))
scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, &scanner->caps[type].ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1);
}
else if (strcmp(name, "ContentType") == 0)
scanner->caps[type].ContentTypes = char_to_array(scanner->caps[type].ContentTypes, &scanner->caps[type].ContentTypesSize, (SANE_String_Const)xmlNodeGetContent(node), 0);
else if (strcmp(name, "DocumentFormat") == 0)
{
int i = 0;
SANE_Bool have_jpeg = SANE_FALSE, have_png = SANE_FALSE, have_tiff = SANE_FALSE, have_pdf = SANE_FALSE;
scanner->caps[type].DocumentFormats = char_to_array(scanner->caps[type].DocumentFormats, &scanner->caps[type].DocumentFormatsSize, (SANE_String_Const)xmlNodeGetContent(node), 0);
for(; i < scanner->caps[type].DocumentFormatsSize; i++)
{
if (scanner->caps[type].default_format == NULL && !strcmp(scanner->caps[type].DocumentFormats[i], "image/jpeg"))
if (!strcmp(scanner->caps[type].DocumentFormats[i], "image/jpeg"))
{
scanner->caps[type].default_format = strdup("image/jpeg");
have_jpeg = SANE_TRUE;
}
#if(defined HAVE_LIBPNG)
else if(!strcmp(scanner->caps[type].DocumentFormats[i], "image/png") && (scanner->caps[type].default_format == NULL || strcmp(scanner->caps[type].default_format, "image/tiff")))
else if(!strcmp(scanner->caps[type].DocumentFormats[i], "image/png"))
{
if (scanner->caps[type].default_format)
free(scanner->caps[type].default_format);
scanner->caps[type].default_format = strdup("image/png");
have_png = SANE_TRUE;
}
#endif
#if(defined HAVE_TIFFIO_H)
else if(!strcmp(scanner->caps[type].DocumentFormats[i], "image/tiff"))
else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "image/tiff"))
{
if (scanner->caps[type].default_format)
free(scanner->caps[type].default_format);
scanner->caps[type].default_format = strdup("image/tiff");
have_tiff = SANE_TRUE;
}
#endif
#if(defined HAVE_POPPLER_GLIB)
else if(!strcmp(scanner->caps[scanner->source].DocumentFormats[i], "application/pdf"))
else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "application/pdf"))
{
if (scanner->caps[scanner->source].default_format)
free(scanner->caps[scanner->source].default_format);
scanner->caps[scanner->source].default_format = strdup("application/pdf");
have_pdf = SANE_TRUE;
}
#endif
}
if (have_pdf)
scanner->caps[type].default_format = strdup("application/pdf");
else if (have_tiff)
scanner->caps[type].default_format = strdup("image/tiff");
else if (have_png)
scanner->caps[type].default_format = strdup("image/png");
else if (have_jpeg)
scanner->caps[type].default_format = strdup("image/jpeg");
}
else if (strcmp(name, "DocumentFormatExt") == 0)
scanner->caps[type].format_ext = 1;
@ -324,22 +330,34 @@ print_xml_c(xmlNode *node, capabilities_t *scanner, int type)
find_true_variables(node, scanner, type);
}
if (!strcmp((const char *)node->name, "PlatenInputCaps")) {
scanner->Sources = char_to_array(scanner->Sources, &scanner->SourcesSize, (SANE_String_Const)"Platen", 0);
scanner->Sources =
char_to_array(scanner->Sources,
&scanner->SourcesSize,
(SANE_String_Const)SANE_I18N ("Flatbed"),
0);
scanner->source = PLATEN;
print_xml_c(node->children, scanner, PLATEN);
scanner->caps[scanner->source].duplex = 0;
scanner->caps[PLATEN].duplex = 0;
}
else if (!strcmp((const char *)node->name, "AdfSimplexInputCaps")) {
scanner->Sources = char_to_array(scanner->Sources, &scanner->SourcesSize, (SANE_String_Const)"Feeder", 0);
scanner->Sources =
char_to_array(scanner->Sources,
&scanner->SourcesSize,
(SANE_String_Const)SANE_I18N("ADF"),
0);
if (scanner->source == -1) scanner->source = ADFSIMPLEX;
print_xml_c(node->children, scanner, ADFSIMPLEX);
scanner->caps[scanner->source].duplex = 0;
scanner->caps[ADFSIMPLEX].duplex = 0;
}
else if (!strcmp((const char *)node->name, "AdfDuplexInputCaps")) {
scanner->Sources = char_to_array(scanner->Sources, &scanner->SourcesSize, (SANE_String_Const)"Feeder", 0);
scanner->Sources =
char_to_array(scanner->Sources,
&scanner->SourcesSize,
(SANE_String_Const)SANE_I18N ("ADF Duplex"),
0);
if (scanner->source == -1) scanner->source = ADFDUPLEX;
print_xml_c(node->children, scanner, ADFDUPLEX);
scanner->caps[scanner->source].duplex = 1;
scanner->caps[ADFDUPLEX].duplex = 1;
}
else
print_xml_c(node->children, scanner, type);

Wyświetl plik

@ -42,7 +42,7 @@ escl_crop_surface(capabilities_t *scanner,
int y_off = 0, y = 0;
int real_h = 0;
unsigned char *surface_crop = NULL;
/*
DBG( 1, "Escl Image Crop\n");
if (w < (int)scanner->caps[scanner->source].width)
scanner->caps[scanner->source].width = w;
@ -54,12 +54,27 @@ escl_crop_surface(capabilities_t *scanner,
if (scanner->caps[scanner->source].pos_x < 0)
scanner->caps[scanner->source].pos_x = 0;
DBG( 1, "Escl Image Crop [%dx%d|%dx%d]\n", scanner->caps[scanner->source].pos_x, scanner->caps[scanner->source].pos_y,
scanner->caps[scanner->source].width, scanner->caps[scanner->source].height);
x_off = scanner->caps[scanner->source].pos_x;
real_w = scanner->caps[scanner->source].width - x_off;
if (x_off >= scanner->caps[scanner->source].width) {
real_w = scanner->caps[scanner->source].width;
x_off = 0;
}
else
real_w = scanner->caps[scanner->source].width - x_off;
y_off = scanner->caps[scanner->source].pos_y;
real_h = scanner->caps[scanner->source].height - y_off;
*width = real_w;
*height = real_h;
if(y_off >= scanner->caps[scanner->source].height) {
real_h = scanner->caps[scanner->source].height;
y_off = 0;
}
else
real_h = scanner->caps[scanner->source].height - y_off;
*/
*width = w; //real_w;
*height = h; //real_h;
DBG( 1, "Escl Image Crop [%dx%d]\n", *width, *height);
/*
if (x_off > 0 || real_w < scanner->caps[scanner->source].width ||
y_off > 0 || real_h < scanner->caps[scanner->source].height) {
surface_crop = (unsigned char *)malloc (sizeof (unsigned char) * real_w
@ -80,9 +95,11 @@ escl_crop_surface(capabilities_t *scanner,
free(surface);
surface = surface_crop;
}
*/
// we don't need row pointers anymore
scanner->img_data = surface;
scanner->img_size = (int)(real_w * real_h * bps);
scanner->img_size = (int)(w * h * bps);
// scanner->img_size = (int)(real_w * real_h * bps);
scanner->img_read = 0;
finish:
return surface;

Wyświetl plik

@ -202,11 +202,30 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)
scanner->caps[scanner->source].height = cinfo.output_height;
if (scanner->caps[scanner->source].pos_y < 0)
scanner->caps[scanner->source].pos_y = 0;
DBG(10, "1-JPEF Geometry [%dx%d|%dx%d]\n",
scanner->caps[scanner->source].pos_x,
scanner->caps[scanner->source].pos_y,
scanner->caps[scanner->source].width,
scanner->caps[scanner->source].height);
x_off = scanner->caps[scanner->source].pos_x;
w = scanner->caps[scanner->source].width - x_off;
if (x_off > scanner->caps[scanner->source].width) {
w = scanner->caps[scanner->source].width;
x_off = 0;
}
else
w = scanner->caps[scanner->source].width - x_off;
y_off = scanner->caps[scanner->source].pos_y;
h = scanner->caps[scanner->source].height - y_off;
if(y_off > scanner->caps[scanner->source].height) {
h = scanner->caps[scanner->source].height;
y_off = 0;
}
else
h = scanner->caps[scanner->source].height - y_off;
DBG(10, "2-JPEF Geometry [%dx%d|%dx%d]\n",
x_off,
y_off,
w,
h);
surface = malloc(w * h * cinfo.output_components);
if (surface == NULL) {
jpeg_destroy_decompress(&cinfo);

Wyświetl plik

@ -127,6 +127,7 @@ char *
escl_newjob (capabilities_t *scanner, SANE_String_Const name, SANE_Status *status)
{
CURL *curl_handle = NULL;
int off_x = 0, off_y = 0;
struct uploading *upload = NULL;
struct downloading *download = NULL;
const char *scan_jobs = "/eSCL/ScanJobs";
@ -169,25 +170,30 @@ escl_newjob (capabilities_t *scanner, SANE_String_Const name, SANE_Status *statu
}
else
format_ext = f_ext;
if(!strcmp(scanner->Sources[scanner->source], "Feeder")) {
if(scanner->source > PLATEN) {
snprintf(duplex_mode, sizeof(duplex_mode),
" <scan:Duplex>%s</scan:Duplex>",
scanner->caps[scanner->source].duplex ? "true" : "false");
scanner->source == ADFDUPLEX ? "true" : "false");
}
DBG( 1, "Create NewJob : %s\n", scanner->caps[scanner->source].default_format);
if (scanner->caps[scanner->source].pos_x > scanner->caps[scanner->source].width)
off_x = (scanner->caps[scanner->source].pos_x > scanner->caps[scanner->source].width) / 2;
if (scanner->caps[scanner->source].pos_y > scanner->caps[scanner->source].height)
off_y = (scanner->caps[scanner->source].pos_y > scanner->caps[scanner->source].height) / 2;
if (curl_handle != NULL) {
char *source = (scanner->source == PLATEN ? "Platen" : "Feeder");
snprintf(cap_data, sizeof(cap_data), settings,
scanner->caps[scanner->source].height,
scanner->caps[scanner->source].width,
0,
0,
off_x,
off_y,
scanner->caps[scanner->source].default_format,
format_ext,
scanner->caps[scanner->source].default_color,
scanner->caps[scanner->source].default_resolution,
scanner->caps[scanner->source].default_resolution,
scanner->Sources[scanner->source],
scanner->Sources[scanner->source],
source,
source,
duplex_mode[0] == 0 ? "" : duplex_mode);
DBG( 1, "Create NewJob : %s\n", cap_data);
upload->read_data = strdup(cap_data);

Wyświetl plik

@ -76,7 +76,7 @@ escl_scan(capabilities_t __sane_unused__ *scanner, SANE_String_Const name, char
strcat(scan_cmd, scanner_start);
curl_easy_setopt(curl_handle, CURLOPT_URL, scan_cmd);
DBG( 1, "Scan : %s.\n", scan_cmd);
if (strncmp(name, "https", 5) == 0) {
if (strncmp(name, "https", 5) == 0) {
DBG( 1, "Ignoring safety certificates, use https\n");
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
@ -88,12 +88,12 @@ escl_scan(capabilities_t __sane_unused__ *scanner, SANE_String_Const name, char
if (curl_easy_perform(curl_handle) != CURLE_OK) {
status = SANE_STATUS_INVAL;
}
else
curl_easy_cleanup(curl_handle);
fseek(scanner->tmp, 0, SEEK_SET);
}
else
status = SANE_STATUS_NO_MEM;
curl_easy_cleanup(curl_handle);
}
printf ("eSCL scan : %s\n", sane_strstatus(status));
return (status);
}

Wyświetl plik

@ -115,7 +115,7 @@ print_xml_s(xmlNode *node, SANE_Status *platen_status, SANE_Status* adf_status,
} else if (!strcmp(state, "ScannerAdfDoorOpen")) {
*adf_status = SANE_STATUS_COVER_OPEN;
} else if (!strcmp(state, "ScannerAdfProcessing")) {
*adf_status = SANE_STATUS_NO_DOCS;
*adf_status = SANE_STATUS_GOOD;
} else if (!strcmp(state, "ScannerAdfEmpty")) {
*adf_status = SANE_STATUS_NO_DOCS;
} else {
@ -174,6 +174,7 @@ escl_status(SANE_String_Const name, int source)
status = SANE_STATUS_INVAL;
goto clean_data;
}
DBG( 10, "eSCL : Status : %s.\n", var->memory);
data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0);
if (data == NULL) {
status = SANE_STATUS_NO_MEM;
@ -187,14 +188,16 @@ escl_status(SANE_String_Const name, int source)
status = SANE_STATUS_DEVICE_BUSY;
print_xml_s(node, &platen_status, &adf_status, source);
/* Decode Job status */
if (platen_status != SANE_STATUS_GOOD &&
platen_status != SANE_STATUS_UNSUPPORTED) {
/* Decode Job status */
if (source == PLATEN) {
status = platen_status;
} else if (source == PLATEN) {
status = platen_status;
} else {
} else if (platen_status != SANE_STATUS_UNSUPPORTED) {
status = adf_status;
}
else
status = platen_status;
printf ("STATUS AA : %s\n", sane_strstatus(status));
clean:
xmlFreeDoc(data);
clean_data: