summaryrefslogtreecommitdiff
path: root/backend/escl
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2021-05-18 07:43:35 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2021-05-18 07:43:35 +0200
commit9f8889f928ce86ba4a78659d378c6ba29bc9f735 (patch)
treec9567cb0d015b68ce3da8d03472b6443f1cb1ca9 /backend/escl
parent446e9454b8cbe5b689149415d11d36e88442ca88 (diff)
parent154785ab2d5df7ddc8c2cf813b773c340e5e2aea (diff)
Merge branch 'release/debian/1.0.32-1'debian/1.0.32-1
Diffstat (limited to 'backend/escl')
-rw-r--r--backend/escl/escl.c587
-rw-r--r--backend/escl/escl.h120
-rw-r--r--backend/escl/escl_capabilities.c111
-rw-r--r--backend/escl/escl_crop.c4
-rw-r--r--backend/escl/escl_devices.c31
-rw-r--r--backend/escl/escl_jpeg.c4
-rw-r--r--backend/escl/escl_mupdf.c4
-rw-r--r--backend/escl/escl_newjob.c156
-rw-r--r--backend/escl/escl_pdf.c8
-rw-r--r--backend/escl/escl_png.c8
-rw-r--r--backend/escl/escl_reset.c6
-rw-r--r--backend/escl/escl_scan.c8
-rw-r--r--backend/escl/escl_status.c5
-rw-r--r--backend/escl/escl_tiff.c4
14 files changed, 907 insertions, 149 deletions
diff --git a/backend/escl/escl.c b/backend/escl/escl.c
index c40fd98..bb62219 100644
--- a/backend/escl/escl.c
+++ b/backend/escl/escl.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -29,15 +29,32 @@
#include <setjmp.h>
-#include <curl/curl.h>
-
#include "../include/sane/saneopts.h"
#include "../include/sane/sanei.h"
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_config.h"
+
+#ifndef SANE_NAME_SHARPEN
+# define SANE_NAME_SHARPEN "sharpen"
+# define SANE_TITLE_SHARPEN SANE_I18N("Sharpen")
+# define SANE_DESC_SHARPEN SANE_I18N("Set sharpen value.")
+#endif
+
+#ifndef SANE_NAME_THRESHOLD
+# define SANE_NAME_THRESHOLD "threshold"
+#endif
+#ifndef SANE_TITLE_THRESHOLD
+# define SANE_TITLE_THRESHOLD SANE_I18N("Threshold")
+#endif
+#ifndef SANE_DESC_THRESHOLD
+# define SANE_DESC_THRESHOLD \
+ SANE_I18N("Set threshold for line-art scans.")
+#endif
+
#define min(A,B) (((A)<(B)) ? (A) : (B))
#define max(A,B) (((A)>(B)) ? (A) : (B))
+#define IS_ACTIVE(OPTION) (((handler->opt[OPTION].cap) & SANE_CAP_INACTIVE) == 0)
#define INPUT_BUFFER_SIZE 4096
static const SANE_Device **devlist = NULL;
@@ -56,6 +73,10 @@ typedef struct Handled {
SANE_Range x_range2;
SANE_Range y_range1;
SANE_Range y_range2;
+ SANE_Range brightness_range;
+ SANE_Range contrast_range;
+ SANE_Range sharpen_range;
+ SANE_Range thresold_range;
SANE_Bool cancel;
SANE_Bool write_scan_data;
SANE_Bool decompress_scan_data;
@@ -70,7 +91,10 @@ escl_free_device(ESCL_Device *current)
free((void*)current->ip_address);
free((void*)current->model_name);
free((void*)current->type);
- free(current->unix_socket);
+ free((void*)current->is);
+ free((void*)current->uuid);
+ free((void*)current->unix_socket);
+ curl_slist_free_all(current->hack);
free(current);
return NULL;
}
@@ -110,6 +134,10 @@ escl_check_and_add_device(ESCL_Device *current)
DBG (10, "Scanner Type allocation failure.\n");
return (SANE_STATUS_NO_MEM);
}
+ if (!current->is) {
+ DBG (10, "Scanner Is allocation failure.\n");
+ return (SANE_STATUS_NO_MEM);
+ }
++num_devices;
current->next = list_devices_primary;
list_devices_primary = current;
@@ -150,14 +178,20 @@ escl_add_in_list(ESCL_Device *current)
* \return escl_add_in_list(current)
*/
SANE_Status
-escl_device_add(int port_nb, const char *model_name, char *ip_address, char *type)
+escl_device_add(int port_nb,
+ const char *model_name,
+ char *ip_address,
+ const char *is,
+ const char *uuid,
+ char *type)
{
char tmp[PATH_MAX] = { 0 };
char *model = NULL;
ESCL_Device *current = NULL;
DBG (10, "escl_device_add\n");
for (current = list_devices_primary; current; current = current->next) {
- if (strcmp(current->ip_address, ip_address) == 0)
+ if ((strcmp(current->ip_address, ip_address) == 0) ||
+ (uuid && current->uuid && !strcmp(current->uuid, uuid)))
{
if (strcmp(current->type, type))
{
@@ -166,6 +200,10 @@ escl_device_add(int port_nb, const char *model_name, char *ip_address, char *typ
{
free (current->type);
current->type = strdup(type);
+ if (strcmp(current->ip_address, ip_address)) {
+ free (current->ip_address);
+ current->ip_address = strdup(ip_address);
+ }
current->port_nb = port_nb;
current->https = SANE_TRUE;
}
@@ -191,7 +229,12 @@ escl_device_add(int port_nb, const char *model_name, char *ip_address, char *typ
model = (char*)(tmp[0] != 0 ? tmp : model_name);
current->model_name = strdup(model);
current->ip_address = strdup(ip_address);
+ memset(tmp, 0, PATH_MAX);
+ snprintf(tmp, sizeof(tmp), "%s scanner", (is ? is : "flatbed or ADF"));
+ current->is = strdup(tmp);
current->type = strdup(type);
+ if (uuid)
+ current->uuid = strdup(uuid);
return escl_add_in_list(current);
}
@@ -259,7 +302,7 @@ get_vendor(char *search)
* \brief Function that checks if the url of the received scanner is secured or not (http / https).
* --> if the url is not secured, our own url will be composed like "http://'ip':'port'".
* --> else, our own url will be composed like "https://'ip':'port'".
- * AND, it's in this function that we gather all the informations of the url (that were in our list) :
+ * AND, it's in this function that we gather all the information of the url (that were in our list) :
* the model_name, the port, the ip, and the type of url.
* SO, leaving this function, we have in memory the complete url.
*
@@ -308,7 +351,7 @@ convertFromESCLDev(ESCL_Device *cdev)
DBG (10, "Model allocation failure.\n");
goto freename;
}
- sdev->type = strdup("flatbed scanner");
+ sdev->type = strdup(cdev->is);
if (!sdev->type) {
DBG (10, "Scanner Type allocation failure.\n");
goto freevendor;
@@ -383,7 +426,8 @@ sane_exit(void)
* \return escl_add_in_list(escl_device) if the parsing worked, SANE_STATUS_GOOD otherwise.
*/
static SANE_Status
-attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
+attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,
+ void __sane_unused__ *data)
{
int port = 0;
SANE_Status status;
@@ -392,6 +436,7 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
if (strncmp(line, "device", 6) == 0) {
char *name_str = NULL;
char *opt_model = NULL;
+ char *opt_hack = NULL;
line = sanei_config_get_string(line + 6, &name_str);
DBG (10, "New Escl_Device URL [%s].\n", (name_str ? name_str : "VIDE"));
@@ -403,6 +448,10 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
line = sanei_config_get_string(line, &opt_model);
DBG (10, "New Escl_Device model [%s].\n", opt_model);
}
+ if (*line) {
+ line = sanei_config_get_string(line, &opt_hack);
+ DBG (10, "New Escl_Device hack [%s].\n", opt_hack);
+ }
escl_free_device(escl_device);
escl_device = (ESCL_Device*)calloc(1, sizeof(ESCL_Device));
@@ -419,7 +468,9 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
return status;
}
escl_device->model_name = opt_model ? opt_model : strdup("Unknown model");
- escl_device->type = strdup("flatbed scanner");
+ escl_device->is = strdup("flatbed or ADF scanner");
+ escl_device->type = strdup("In url");
+ escl_device->uuid = NULL;
}
if (strncmp(line, "[device]", 8) == 0) {
@@ -430,7 +481,7 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
return (SANE_STATUS_NO_MEM);
}
}
- if (strncmp(line, "ip", 2) == 0) {
+ else if (strncmp(line, "ip", 2) == 0) {
const char *ip_space = sanei_config_skip_whitespace(line + 2);
DBG (10, "New Escl_Device IP [%s].", (ip_space ? ip_space : "VIDE"));
if (escl_device != NULL && ip_space != NULL) {
@@ -438,14 +489,14 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
escl_device->ip_address = strdup(ip_space);
}
}
- if (sscanf(line, "port %i", &port) == 1 && port != 0) {
+ else if (sscanf(line, "port %i", &port) == 1 && port != 0) {
DBG (10, "New Escl_Device PORT [%d].", port);
if (escl_device != NULL) {
DBG (10, "New Escl_Device PORT Affected.");
escl_device->port_nb = port;
}
}
- if (strncmp(line, "model", 5) == 0) {
+ else if (strncmp(line, "model", 5) == 0) {
const char *model_space = sanei_config_skip_whitespace(line + 5);
DBG (10, "New Escl_Device MODEL [%s].", (model_space ? model_space : "VIDE"));
if (escl_device != NULL && model_space != NULL) {
@@ -453,7 +504,7 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
escl_device->model_name = strdup(model_space);
}
}
- if (strncmp(line, "type", 4) == 0) {
+ else if (strncmp(line, "type", 4) == 0) {
const char *type_space = sanei_config_skip_whitespace(line + 4);
DBG (10, "New Escl_Device TYPE [%s].", (type_space ? type_space : "VIDE"));
if (escl_device != NULL && type_space != NULL) {
@@ -461,6 +512,8 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
escl_device->type = strdup(type_space);
}
}
+ escl_device->is = strdup("flatbed or ADF scanner");
+ escl_device->uuid = NULL;
status = escl_check_and_add_device(escl_device);
if (status == SANE_STATUS_GOOD)
escl_device = NULL;
@@ -487,7 +540,8 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
if (device_list == NULL)
return (SANE_STATUS_INVAL);
- status = sanei_configure_attach(ESCL_CONFIG_FILE, NULL, attach_one_config);
+ status = sanei_configure_attach(ESCL_CONFIG_FILE, NULL,
+ attach_one_config, NULL);
if (status != SANE_STATUS_GOOD)
return (status);
escl_devices(&status);
@@ -526,10 +580,156 @@ _source_size_max (SANE_String_Const * sources)
return size;
}
+static int
+_get_resolution(escl_sane_t *handler, int resol)
+{
+ int x = 1;
+ int n = handler->scanner->caps[handler->scanner->source].SupportedResolutions[0] + 1;
+ int old = -1;
+ for (; x < n; x++) {
+ DBG(10, "SEARCH RESOLUTION [ %d | %d]\n", resol, (int)handler->scanner->caps[handler->scanner->source].SupportedResolutions[x]);
+ if (resol == handler->scanner->caps[handler->scanner->source].SupportedResolutions[x])
+ return resol;
+ else if (resol < handler->scanner->caps[handler->scanner->source].SupportedResolutions[x])
+ {
+ if (old == -1)
+ return handler->scanner->caps[handler->scanner->source].SupportedResolutions[1];
+ else
+ return old;
+ }
+ else
+ old = handler->scanner->caps[handler->scanner->source].SupportedResolutions[x];
+ }
+ return old;
+}
+
+
+/**
+ * \fn static SANE_Status init_options(SANE_String_Const name, escl_sane_t *s)
+ * \brief Function thzt initializes all the needed options of the received scanner
+ * (the resolution / the color / the margins) thanks to the information received with
+ * the 'escl_capabilities' function, called just before.
+ *
+ * \return status (if everything is OK, status = SANE_STATUS_GOOD)
+ */
+static SANE_Status
+init_options_small(SANE_String_Const name_source, escl_sane_t *s)
+{
+ int found = 0;
+ DBG (10, "escl init_options\n");
+
+ SANE_Status status = SANE_STATUS_GOOD;
+ if (!s->scanner) return SANE_STATUS_INVAL;
+ if (name_source) {
+ int source = s->scanner->source;
+ if (!strcmp(name_source, SANE_I18N ("ADF Duplex")))
+ s->scanner->source = ADFDUPLEX;
+ else if (!strncmp(name_source, "A", 1) ||
+ !strcmp(name_source, SANE_I18N ("ADF")))
+ s->scanner->source = ADFSIMPLEX;
+ else
+ s->scanner->source = PLATEN;
+ if (source == s->scanner->source) return status;
+ s->scanner->caps[s->scanner->source].default_color =
+ strdup(s->scanner->caps[source].default_color);
+ s->scanner->caps[s->scanner->source].default_resolution =
+ _get_resolution(s, s->scanner->caps[source].default_resolution);
+ }
+ if (s->scanner->caps[s->scanner->source].ColorModes == NULL) {
+ if (s->scanner->caps[PLATEN].ColorModes)
+ s->scanner->source = PLATEN;
+ else if (s->scanner->caps[ADFSIMPLEX].ColorModes)
+ s->scanner->source = ADFSIMPLEX;
+ else if (s->scanner->caps[ADFDUPLEX].ColorModes)
+ s->scanner->source = ADFDUPLEX;
+ else
+ return SANE_STATUS_INVAL;
+ }
+ if (s->scanner->source == PLATEN) {
+ DBG (10, "SOURCE PLATEN.\n");
+ }
+ else if (s->scanner->source == ADFDUPLEX) {
+ DBG (10, "SOURCE ADFDUPLEX.\n");
+ }
+ else if (s->scanner->source == ADFSIMPLEX) {
+ DBG (10, "SOURCE ADFSIMPLEX.\n");
+ }
+ s->x_range1.min = 0;
+ s->x_range1.max =
+ PIXEL_TO_MM((s->scanner->caps[s->scanner->source].MaxWidth -
+ s->scanner->caps[s->scanner->source].MinWidth),
+ 300.0);
+ s->x_range1.quant = 0;
+ s->x_range2.min = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MinWidth, 300.0);
+ s->x_range2.max = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MaxWidth, 300.0);
+ s->x_range2.quant = 0;
+ s->y_range1.min = 0;
+ s->y_range1.max =
+ PIXEL_TO_MM((s->scanner->caps[s->scanner->source].MaxHeight -
+ s->scanner->caps[s->scanner->source].MinHeight),
+ 300.0);
+ s->y_range1.quant = 0;
+ s->y_range2.min = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MinHeight, 300.0);
+ s->y_range2.max = PIXEL_TO_MM(s->scanner->caps[s->scanner->source].MaxHeight, 300.0);
+ s->y_range2.quant = 0;
+
+ s->opt[OPT_MODE].constraint.string_list = s->scanner->caps[s->scanner->source].ColorModes;
+ if (s->val[OPT_MODE].s)
+ free(s->val[OPT_MODE].s);
+ s->val[OPT_MODE].s = NULL;
+
+ if (s->scanner->caps[s->scanner->source].default_color) {
+ int x = 0;
+ if (!strcmp(s->scanner->caps[s->scanner->source].default_color, "Grayscale8"))
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_GRAY);
+ else if (!strcmp(s->scanner->caps[s->scanner->source].default_color, "BlackAndWhite1"))
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_LINEART);
+ else
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_COLOR);
+ for (x = 0; s->scanner->caps[s->scanner->source].ColorModes[x]; x++) {
+ if (s->scanner->caps[s->scanner->source].ColorModes[x] &&
+ !strcasecmp(s->scanner->caps[s->scanner->source].ColorModes[x], s->val[OPT_MODE].s)) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (!s->scanner->caps[s->scanner->source].default_color || found == 0) {
+ if (s->scanner->caps[s->scanner->source].default_color)
+ free(s->scanner->caps[s->scanner->source].default_color);
+ s->val[OPT_MODE].s = strdup(s->scanner->caps[s->scanner->source].ColorModes[0]);
+ if (!strcasecmp(s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
+ s->scanner->caps[s->scanner->source].default_color = strdup("Grayscale8");
+ else if (!strcasecmp(s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART))
+ s->scanner->caps[s->scanner->source].default_color = strdup("BlackAndWhite1");
+ else
+ s->scanner->caps[s->scanner->source].default_color = strdup("RGB24");
+ }
+ if (!s->val[OPT_MODE].s) {
+ DBG (10, "Color Mode Default allocation failure.\n");
+ return (SANE_STATUS_NO_MEM);
+ }
+ if (!s->scanner->caps[s->scanner->source].default_color) {
+ DBG (10, "Color Mode Default allocation failure.\n");
+ return (SANE_STATUS_NO_MEM);
+ }
+ s->val[OPT_RESOLUTION].w = s->scanner->caps[s->scanner->source].default_resolution;
+ s->opt[OPT_TL_X].constraint.range = &s->x_range1;
+ s->opt[OPT_TL_Y].constraint.range = &s->y_range1;
+ s->opt[OPT_BR_X].constraint.range = &s->x_range2;
+ s->opt[OPT_BR_Y].constraint.range = &s->y_range2;
+
+ if (s->val[OPT_SCAN_SOURCE].s)
+ free (s->val[OPT_SCAN_SOURCE].s);
+ s->val[OPT_SCAN_SOURCE].s = strdup (s->scanner->Sources[s->scanner->source]);
+
+ return (SANE_STATUS_GOOD);
+}
+
/**
* \fn static SANE_Status init_options(SANE_String_Const name, escl_sane_t *s)
* \brief Function thzt initializes all the needed options of the received scanner
- * (the resolution / the color / the margins) thanks to the informations received with
+ * (the resolution / the color / the margins) thanks to the information received with
* the 'escl_capabilities' function, called just before.
*
* \return status (if everything is OK, status = SANE_STATUS_GOOD)
@@ -554,8 +754,25 @@ init_options(SANE_String_Const name_source, escl_sane_t *s)
s->scanner->source = PLATEN;
if (source == s->scanner->source) return status;
}
- else
- s->scanner->source = PLATEN;
+ if (s->scanner->caps[s->scanner->source].ColorModes == NULL) {
+ if (s->scanner->caps[PLATEN].ColorModes)
+ s->scanner->source = PLATEN;
+ else if (s->scanner->caps[ADFSIMPLEX].ColorModes)
+ s->scanner->source = ADFSIMPLEX;
+ else if (s->scanner->caps[ADFDUPLEX].ColorModes)
+ s->scanner->source = ADFDUPLEX;
+ else
+ return SANE_STATUS_INVAL;
+ }
+ if (s->scanner->source == PLATEN) {
+ DBG (10, "SOURCE PLATEN.\n");
+ }
+ else if (s->scanner->source == ADFDUPLEX) {
+ DBG (10, "SOURCE ADFDUPLEX.\n");
+ }
+ else if (s->scanner->source == ADFSIMPLEX) {
+ DBG (10, "SOURCE ADFSIMPLEX.\n");
+ }
memset (s->opt, 0, sizeof (s->opt));
memset (s->val, 0, sizeof (s->val));
for (i = 0; i < NUM_OPTIONS; ++i) {
@@ -590,6 +807,7 @@ init_options(SANE_String_Const name_source, escl_sane_t *s)
s->opt[OPT_MODE_GROUP].desc = "";
s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_MODE_GROUP].cap = 0;
+ s->opt[OPT_MODE_GROUP].size = 0;
s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
@@ -599,17 +817,39 @@ init_options(SANE_String_Const name_source, escl_sane_t *s)
s->opt[OPT_MODE].unit = SANE_UNIT_NONE;
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
s->opt[OPT_MODE].constraint.string_list = s->scanner->caps[s->scanner->source].ColorModes;
- s->val[OPT_MODE].s = (char *)strdup(s->scanner->caps[s->scanner->source].ColorModes[0]);
+ if (s->scanner->caps[s->scanner->source].default_color) {
+ if (!strcasecmp(s->scanner->caps[s->scanner->source].default_color, "Grayscale8"))
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_GRAY);
+ else if (!strcasecmp(s->scanner->caps[s->scanner->source].default_color, "BlackAndWhite1"))
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_LINEART);
+ else
+ s->val[OPT_MODE].s = (char *)strdup(SANE_VALUE_SCAN_MODE_COLOR);
+ }
+ else {
+ s->val[OPT_MODE].s = (char *)strdup(s->scanner->caps[s->scanner->source].ColorModes[0]);
+ if (!strcasecmp(s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY)) {
+ s->scanner->caps[s->scanner->source].default_color = strdup("Grayscale8");
+ }
+ else if (!strcasecmp(s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART)) {
+ s->scanner->caps[s->scanner->source].default_color =
+ strdup("BlackAndWhite1");
+ }
+ else {
+ s->scanner->caps[s->scanner->source].default_color =
+ strdup("RGB24");
+ }
+ }
if (!s->val[OPT_MODE].s) {
DBG (10, "Color Mode Default allocation failure.\n");
return (SANE_STATUS_NO_MEM);
}
+ DBG (10, "++ Color Mode Default allocation [%s].\n", s->scanner->caps[s->scanner->source].default_color);
s->opt[OPT_MODE].size = max_string_size(s->scanner->caps[s->scanner->source].ColorModes);
- s->scanner->caps[s->scanner->source].default_color = (char *)strdup(s->scanner->caps[s->scanner->source].ColorModes[0]);
if (!s->scanner->caps[s->scanner->source].default_color) {
DBG (10, "Color Mode Default allocation failure.\n");
return (SANE_STATUS_NO_MEM);
}
+ DBG (10, "Color Mode Default allocation (%s).\n", s->scanner->caps[s->scanner->source].default_color);
s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
@@ -638,6 +878,7 @@ init_options(SANE_String_Const name_source, escl_sane_t *s)
s->opt[OPT_GEOMETRY_GROUP].desc = SANE_DESC_GEOMETRY;
s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
+ s->opt[OPT_GEOMETRY_GROUP].size = 0;
s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
@@ -696,6 +937,113 @@ init_options(SANE_String_Const name_source, escl_sane_t *s)
if (s->val[OPT_SCAN_SOURCE].s)
free (s->val[OPT_SCAN_SOURCE].s);
s->val[OPT_SCAN_SOURCE].s = strdup (s->scanner->Sources[s->scanner->source]);
+
+ /* "Enhancement" group: */
+ s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
+ s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; /* not valid for a group */
+ s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
+ s->opt[OPT_ENHANCEMENT_GROUP].cap = SANE_CAP_ADVANCED;
+ s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
+ s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
+
+
+ s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
+ s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
+ s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
+ s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
+ s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
+ s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
+ if (s->scanner->brightness) {
+ s->opt[OPT_BRIGHTNESS].constraint.range = &s->brightness_range;
+ s->val[OPT_BRIGHTNESS].w = s->scanner->brightness->normal;
+ s->brightness_range.quant=1;
+ s->brightness_range.min=s->scanner->brightness->min;
+ s->brightness_range.max=s->scanner->brightness->max;
+ }
+ else{
+ SANE_Range range = { 0, 255, 0 };
+ s->opt[OPT_BRIGHTNESS].constraint.range = &range;
+ s->val[OPT_BRIGHTNESS].w = 0;
+ s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
+ }
+ s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
+ s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
+ s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
+ s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
+ s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
+ s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
+ if (s->scanner->contrast) {
+ s->opt[OPT_CONTRAST].constraint.range = &s->contrast_range;
+ s->val[OPT_CONTRAST].w = s->scanner->contrast->normal;
+ s->contrast_range.quant=1;
+ s->contrast_range.min=s->scanner->contrast->min;
+ s->contrast_range.max=s->scanner->contrast->max;
+ }
+ else{
+ SANE_Range range = { 0, 255, 0 };
+ s->opt[OPT_CONTRAST].constraint.range = &range;
+ s->val[OPT_CONTRAST].w = 0;
+ s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
+ }
+ s->opt[OPT_SHARPEN].name = SANE_NAME_SHARPEN;
+ s->opt[OPT_SHARPEN].title = SANE_TITLE_SHARPEN;
+ s->opt[OPT_SHARPEN].desc = SANE_DESC_SHARPEN;
+ s->opt[OPT_SHARPEN].type = SANE_TYPE_INT;
+ s->opt[OPT_SHARPEN].unit = SANE_UNIT_NONE;
+ s->opt[OPT_SHARPEN].constraint_type = SANE_CONSTRAINT_RANGE;
+ if (s->scanner->sharpen) {
+ s->opt[OPT_SHARPEN].constraint.range = &s->sharpen_range;
+ s->val[OPT_SHARPEN].w = s->scanner->sharpen->normal;
+ s->sharpen_range.quant=1;
+ s->sharpen_range.min=s->scanner->sharpen->min;
+ s->sharpen_range.max=s->scanner->sharpen->max;
+ }
+ else{
+ SANE_Range range = { 0, 255, 0 };
+ s->opt[OPT_SHARPEN].constraint.range = &range;
+ s->val[OPT_SHARPEN].w = 0;
+ s->opt[OPT_SHARPEN].cap |= SANE_CAP_INACTIVE;
+ }
+ /*threshold*/
+ s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
+ s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
+ s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
+ s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
+ s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
+ s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
+ if (s->scanner->threshold) {
+ s->opt[OPT_THRESHOLD].constraint.range = &s->thresold_range;
+ s->val[OPT_THRESHOLD].w = s->scanner->threshold->normal;
+ s->thresold_range.quant=1;
+ s->thresold_range.min= s->scanner->threshold->min;
+ s->thresold_range.max=s->scanner->threshold->max;
+ }
+ else{
+ SANE_Range range = { 0, 255, 0 };
+ s->opt[OPT_THRESHOLD].constraint.range = &range;
+ s->val[OPT_THRESHOLD].w = 0;
+ s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
+ }
+ if (!strcasecmp(s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART)) {
+ if (s->scanner->threshold)
+ s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
+ if (s->scanner->brightness)
+ s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
+ if (s->scanner->contrast)
+ s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
+ if (s->scanner->sharpen)
+ s->opt[OPT_SHARPEN].cap |= SANE_CAP_INACTIVE;
+ }
+ else {
+ if (s->scanner->threshold)
+ s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
+ if (s->scanner->brightness)
+ s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
+ if (s->scanner->contrast)
+ s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
+ if (s->scanner->sharpen)
+ s->opt[OPT_SHARPEN].cap &= ~SANE_CAP_INACTIVE;
+ }
return (status);
}
@@ -745,6 +1093,50 @@ escl_parse_name(SANE_String_Const name, ESCL_Device *device)
return SANE_STATUS_GOOD;
}
+static void
+_get_hack(SANE_String_Const name, ESCL_Device *device)
+{
+ FILE *fp;
+ SANE_Char line[PATH_MAX];
+ DBG (3, "_get_hack: start\n");
+ if (device->model_name &&
+ (strcasestr(device->model_name, "LaserJet FlowMFP M578") ||
+ strcasestr(device->model_name, "LaserJet MFP M630"))) {
+ device->hack = curl_slist_append(NULL, "Host: localhost");
+ DBG (3, "_get_hack: finish\n");
+ return;
+ }
+
+ /* open configuration file */
+ fp = sanei_config_open (ESCL_CONFIG_FILE);
+ if (!fp)
+ {
+ DBG (2, "_get_hack: couldn't access %s\n", ESCL_CONFIG_FILE);
+ DBG (3, "_get_hack: exit\n");
+ }
+
+ /* loop reading the configuration file, all line beginning by "option " are
+ * parsed for value to store in configuration structure, other line are
+ * used are device to try to attach
+ */
+ while (sanei_config_read (line, PATH_MAX, fp))
+ {
+ if (strstr(line, name)) {
+ DBG (3, "_get_hack: idevice found\n");
+ if (strstr(line, "hack=localhost")) {
+ DBG (3, "_get_hack: device found\n");
+ device->hack = curl_slist_append(NULL, "Host: localhost");
+ }
+ goto finish_hack;
+ }
+ }
+finish_hack:
+ DBG (3, "_get_hack: finish\n");
+ fclose(fp);
+}
+
+
+
/**
* \fn SANE_Status sane_open(SANE_String_Const name, SANE_Handle *h)
* \brief Function that establishes a connection with the device named by 'name',
@@ -786,6 +1178,8 @@ sane_open(SANE_String_Const name, SANE_Handle *h)
escl_free_handler(handler);
return (status);
}
+ _get_hack(name, device);
+
status = init_options(NULL, handler);
if (status != SANE_STATUS_GOOD) {
escl_free_handler(handler);
@@ -897,9 +1291,12 @@ sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int
case OPT_BR_X:
case OPT_BR_Y:
case OPT_NUM_OPTS:
- case OPT_RESOLUTION:
case OPT_PREVIEW:
case OPT_GRAY_PREVIEW:
+ case OPT_RESOLUTION:
+ case OPT_BRIGHTNESS:
+ case OPT_CONTRAST:
+ case OPT_SHARPEN:
*(SANE_Word *) v = handler->val[n].w;
break;
case OPT_SCAN_SOURCE:
@@ -919,16 +1316,18 @@ sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int
case OPT_BR_X:
case OPT_BR_Y:
case OPT_NUM_OPTS:
- case OPT_RESOLUTION:
case OPT_PREVIEW:
case OPT_GRAY_PREVIEW:
+ case OPT_BRIGHTNESS:
+ case OPT_CONTRAST:
+ case OPT_SHARPEN:
handler->val[n].w = *(SANE_Word *) v;
if (i)
*i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
break;
case OPT_SCAN_SOURCE:
DBG(10, "SET OPT_SCAN_SOURCE(%s)\n", (SANE_String_Const)v);
- init_options((SANE_String_Const)v, handler);
+ init_options_small((SANE_String_Const)v, handler);
if (i)
*i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
break;
@@ -940,6 +1339,48 @@ sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int
DBG (10, "OPT_MODE allocation failure.\n");
return (SANE_STATUS_NO_MEM);
}
+ DBG(10, "SET OPT_MODE(%s)\n", (SANE_String_Const)v);
+
+ if (!strcasecmp(handler->val[n].s, SANE_VALUE_SCAN_MODE_GRAY)) {
+ handler->scanner->caps[handler->scanner->source].default_color = strdup("Grayscale8");
+ DBG(10, "SET OPT_MODE(Grayscale8)\n");
+ }
+ else if (!strcasecmp(handler->val[n].s, SANE_VALUE_SCAN_MODE_LINEART)) {
+ handler->scanner->caps[handler->scanner->source].default_color =
+ strdup("BlackAndWhite1");
+ DBG(10, "SET OPT_MODE(BlackAndWhite1)\n");
+ }
+ else {
+ handler->scanner->caps[handler->scanner->source].default_color =
+ strdup("RGB24");
+ DBG(10, "SET OPT_MODE(RGB24)\n");
+ }
+ DBG (10, "Color Mode allocation (%s).\n", handler->scanner->caps[handler->scanner->source].default_color);
+ if (i)
+ *i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
+ if (handler->scanner->brightness)
+ handler->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
+ if (handler->scanner->contrast)
+ handler->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
+ if (handler->scanner->threshold)
+ handler->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
+ if (handler->scanner->sharpen)
+ handler->opt[OPT_SHARPEN].cap |= SANE_CAP_INACTIVE;
+ if (!strcasecmp(handler->val[n].s, SANE_VALUE_SCAN_MODE_LINEART)) {
+ if (handler->scanner->threshold)
+ handler->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
+ }
+ else {
+ if (handler->scanner->brightness)
+ handler->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
+ if (handler->scanner->contrast)
+ handler->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
+ if (handler->scanner->sharpen)
+ handler->opt[OPT_SHARPEN].cap &= ~SANE_CAP_INACTIVE;
+ }
+ break;
+ case OPT_RESOLUTION:
+ handler->val[n].w = _get_resolution(handler, (int)(*(SANE_Word *) v));
if (i)
*i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;
break;
@@ -975,7 +1416,7 @@ _go_next_page(SANE_Status status,
/**
* \fn SANE_Status sane_start(SANE_Handle h)
- * \brief Function that initiates aquisition of an image from the device represented by handle 'h'.
+ * \brief Function that initiates acquisition of an image from the device represented by handle 'h'.
* This function calls the "escl_newjob" function and the "escl_scan" function.
*
* \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)
@@ -1005,11 +1446,13 @@ sane_start(SANE_Handle h)
NULL);
if (st != SANE_STATUS_GOOD)
return st;
- if(handler->scanner->caps[handler->scanner->source].default_color)
- free(handler->scanner->caps[handler->scanner->source].default_color);
if (handler->val[OPT_PREVIEW].w == SANE_TRUE)
{
- int i = 0, val = 9999;;
+ int i = 0, val = 9999;
+
+ if(handler->scanner->caps[handler->scanner->source].default_color)
+ free(handler->scanner->caps[handler->scanner->source].default_color);
+
if (handler->val[OPT_GRAY_PREVIEW].w == SANE_TRUE ||
!strcasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
handler->scanner->caps[handler->scanner->source].default_color =
@@ -1032,15 +1475,18 @@ sane_start(SANE_Handle h)
{
handler->scanner->caps[handler->scanner->source].default_resolution =
handler->val[OPT_RESOLUTION].w;
- if (!strcasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
- handler->scanner->caps[handler->scanner->source].default_color = strdup("Grayscale8");
- else if (!strcasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART))
- handler->scanner->caps[handler->scanner->source].default_color =
- strdup("BlackAndWhite1");
- else
- handler->scanner->caps[handler->scanner->source].default_color =
- strdup("RGB24");
+ if (!handler->scanner->caps[handler->scanner->source].default_color) {
+ if (!strcasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
+ handler->scanner->caps[handler->scanner->source].default_color = strdup("Grayscale8");
+ else if (!strcasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART))
+ handler->scanner->caps[handler->scanner->source].default_color =
+ strdup("BlackAndWhite1");
+ else
+ handler->scanner->caps[handler->scanner->source].default_color =
+ strdup("RGB24");
+ }
}
+ DBG (10, "Before newjob Color Mode allocation (%s).\n", handler->scanner->caps[handler->scanner->source].default_color);
handler->scanner->caps[handler->scanner->source].height =
MM_TO_PIXEL(handler->val[OPT_BR_Y].w, 300.0);
handler->scanner->caps[handler->scanner->source].width =
@@ -1066,6 +1512,67 @@ sane_start(SANE_Handle h)
DBG (10, "Default Color allocation failure.\n");
return (SANE_STATUS_NO_MEM);
}
+
+ if (handler->scanner->threshold) {
+ DBG(10, "Have Thresold\n");
+ if (IS_ACTIVE(OPT_THRESHOLD)) {
+ DBG(10, "Use Thresold [%d]\n", handler->val[OPT_THRESHOLD].w);
+ handler->scanner->val_threshold = handler->val[OPT_THRESHOLD].w;
+ handler->scanner->use_threshold = 1;
+ }
+ else {
+ DBG(10, "Not use Thresold\n");
+ handler->scanner->use_threshold = 0;
+ }
+ }
+ else
+ DBG(10, "Don't have Thresold\n");
+
+ if (handler->scanner->sharpen) {
+ DBG(10, "Have Sharpen\n");
+ if (IS_ACTIVE(OPT_SHARPEN)) {
+ DBG(10, "Use Sharpen [%d]\n", handler->val[OPT_SHARPEN].w);
+ handler->scanner->val_sharpen = handler->val[OPT_SHARPEN].w;
+ handler->scanner->use_sharpen = 1;
+ }
+ else {
+ DBG(10, "Not use Sharpen\n");
+ handler->scanner->use_sharpen = 0;
+ }
+ }
+ else
+ DBG(10, "Don't have Sharpen\n");
+
+ if (handler->scanner->contrast) {
+ DBG(10, "Have Contrast\n");
+ if (IS_ACTIVE(OPT_CONTRAST)) {
+ DBG(10, "Use Contrast [%d]\n", handler->val[OPT_CONTRAST].w);
+ handler->scanner->val_contrast = handler->val[OPT_CONTRAST].w;
+ handler->scanner->use_contrast = 1;
+ }
+ else {
+ DBG(10, "Not use Contrast\n");
+ handler->scanner->use_contrast = 0;
+ }
+ }
+ else
+ DBG(10, "Don't have Contrast\n");
+
+ if (handler->scanner->brightness) {
+ DBG(10, "Have Brightness\n");
+ if (IS_ACTIVE(OPT_BRIGHTNESS)) {
+ DBG(10, "Use Brightness [%d]\n", handler->val[OPT_BRIGHTNESS].w);
+ handler->scanner->val_brightness = handler->val[OPT_BRIGHTNESS].w;
+ handler->scanner->use_brightness = 1;
+ }
+ else {
+ DBG(10, "Not use Brightness\n");
+ handler->scanner->use_brightness = 0;
+ }
+ }
+ else
+ DBG(10, "Don't have Brightness\n");
+
handler->result = escl_newjob(handler->scanner, handler->device, &status);
if (status != SANE_STATUS_GOOD)
return (status);
@@ -1104,7 +1611,7 @@ sane_start(SANE_Handle h)
status = get_PDF_data(handler->scanner, &w, &he, &bps);
}
else {
- DBG(10, "Unknow image format\n");
+ DBG(10, "Unknown image format\n");
return SANE_STATUS_INVAL;
}
@@ -1257,6 +1764,12 @@ escl_curl_url(CURL *handle, const ESCL_Device *device, SANE_String_Const path)
DBG( 1, "escl_curl_url: URL: %s\n", url );
curl_easy_setopt(handle, CURLOPT_URL, url);
free(url);
+ DBG( 1, "Before use hack\n");
+ if (device->hack) {
+ DBG( 1, "Use hack\n");
+ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, device->hack);
+ }
+ DBG( 1, "After use hack\n");
if (device->https) {
DBG( 1, "Ignoring safety certificates, use https\n");
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
diff --git a/backend/escl/escl.h b/backend/escl/escl.h
index 53ce7c7..67b11c7 100644
--- a/backend/escl/escl.h
+++ b/backend/escl/escl.h
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -27,10 +27,13 @@
#include "../include/sane/config.h"
+
#if !(HAVE_LIBCURL && defined(WITH_AVAHI) && defined(HAVE_LIBXML2))
#error "The escl backend requires libcurl, libavahi and libxml2"
#endif
+
+
#ifndef HAVE_LIBJPEG
/* FIXME: Make JPEG support optional.
Support for PNG and PDF is to be added later but currently only
@@ -45,6 +48,8 @@
#include <stdio.h>
#include <math.h>
+#include <curl/curl.h>
+
#ifndef BACKEND_NAME
#define BACKEND_NAME escl
#endif
@@ -87,12 +92,15 @@ typedef struct {
typedef struct ESCL_Device {
struct ESCL_Device *next;
- char *model_name;
- int port_nb;
- char *ip_address;
- char *type;
+ char *model_name;
+ int port_nb;
+ char *ip_address;
+ char *is;
+ char *uuid;
+ char *type;
SANE_Bool https;
- char *unix_socket;
+ struct curl_slist *hack;
+ char *unix_socket;
} ESCL_Device;
typedef struct capst
@@ -127,8 +135,20 @@ typedef struct capst
int RiskyTopMargin;
int RiskyBottomMargin;
int duplex;
+ int have_jpeg;
+ int have_png;
+ int have_tiff;
+ int have_pdf;
} caps_t;
+typedef struct support
+{
+ int min;
+ int max;
+ int normal;
+ int step;
+} support_t;
+
typedef struct capabilities
{
caps_t caps[3];
@@ -141,6 +161,18 @@ typedef struct capabilities
long img_read;
size_t real_read;
SANE_Bool work;
+ support_t *brightness;
+ support_t *contrast;
+ support_t *sharpen;
+ support_t *threshold;
+ int use_brightness;
+ int val_brightness;
+ int use_contrast;
+ int val_contrast;
+ int use_sharpen;
+ int val_sharpen;
+ int use_threshold;
+ int val_threshold;
} capabilities_t;
typedef struct {
@@ -162,8 +194,7 @@ enum
OPT_MODE_GROUP,
OPT_MODE,
OPT_RESOLUTION,
- OPT_PREVIEW,
- OPT_GRAY_PREVIEW,
+ OPT_SCAN_SOURCE,
OPT_GEOMETRY_GROUP,
OPT_TL_X,
@@ -171,7 +202,13 @@ enum
OPT_BR_X,
OPT_BR_Y,
- OPT_SCAN_SOURCE,
+ OPT_ENHANCEMENT_GROUP,
+ OPT_PREVIEW,
+ OPT_GRAY_PREVIEW,
+ OPT_BRIGHTNESS,
+ OPT_CONTRAST,
+ OPT_SHARPEN,
+ OPT_THRESHOLD,
NUM_OPTIONS
};
@@ -180,35 +217,68 @@ enum
#define MM_TO_PIXEL(millimeters, dpi) (SANE_Word)round(SANE_UNFIX(millimeters) * (dpi) / 25.4)
ESCL_Device *escl_devices(SANE_Status *status);
-SANE_Status escl_device_add(int port_nb, const char *model_name,
- char *ip_address, char *type);
+SANE_Status escl_device_add(int port_nb,
+ const char *model_name,
+ char *ip_address,
+ const char *is,
+ const char *uuid,
+ char *type);
+
SANE_Status escl_status(const ESCL_Device *device,
int source,
const char* jobId,
SANE_Status *job);
-capabilities_t *escl_capabilities(const ESCL_Device *device, SANE_Status *status);
-char *escl_newjob(capabilities_t *scanner, const ESCL_Device *device,
- SANE_Status *status);
-SANE_Status escl_scan(capabilities_t *scanner, const ESCL_Device *device,
- char *result);
-void escl_scanner(const ESCL_Device *device, char *result);
+
+capabilities_t *escl_capabilities(ESCL_Device *device,
+ SANE_Status *status);
+
+char *escl_newjob(capabilities_t *scanner,
+ const ESCL_Device *device,
+ SANE_Status *status);
+
+SANE_Status escl_scan(capabilities_t *scanner,
+ const ESCL_Device *device,
+ char *result);
+
+void escl_scanner(const ESCL_Device *device,
+ char *result);
typedef void CURL;
-void escl_curl_url(CURL *handle, const ESCL_Device *device, SANE_String_Const path);
-unsigned char *escl_crop_surface(capabilities_t *scanner, unsigned char *surface,
- int w, int h, int bps, int *width, int *height);
+void escl_curl_url(CURL *handle,
+ const ESCL_Device *device,
+ SANE_String_Const path);
+
+unsigned char *escl_crop_surface(capabilities_t *scanner,
+ unsigned char *surface,
+ int w,
+ int h,
+ int bps,
+ int *width,
+ int *height);
// JPEG
-SANE_Status get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps);
+SANE_Status get_JPEG_data(capabilities_t *scanner,
+ int *width,
+ int *height,
+ int *bps);
// PNG
-SANE_Status get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps);
+SANE_Status get_PNG_data(capabilities_t *scanner,
+ int *width,
+ int *height,
+ int *bps);
// TIFF
-SANE_Status get_TIFF_data(capabilities_t *scanner, int *width, int *height, int *bps);
+SANE_Status get_TIFF_data(capabilities_t *scanner,
+ int *width,
+ int *height,
+ int *bps);
// PDF
-SANE_Status get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps);
+SANE_Status get_PDF_data(capabilities_t *scanner,
+ int *width,
+ int *height,
+ int *bps);
#endif
diff --git a/backend/escl/escl_capabilities.c b/backend/escl/escl_capabilities.c
index fdd5cfe..db194f9 100644
--- a/backend/escl/escl_capabilities.c
+++ b/backend/escl/escl_capabilities.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -30,7 +30,6 @@
#include <stdlib.h>
#include <string.h>
-#include <curl/curl.h>
#include <libxml/parser.h>
#include "../include/sane/saneopts.h"
@@ -90,9 +89,9 @@ char_to_array(SANE_String_Const *tab, int *tabsize, SANE_String_Const mode, int
}
(*tabsize)++;
if (*tabsize == 1)
- board = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * (*tabsize) + 1);
+ board = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * ((*tabsize) + 1));
else
- board = (SANE_String_Const *)realloc(tab, sizeof(SANE_String_Const) * (*tabsize) + 1);
+ board = (SANE_String_Const *)realloc(tab, sizeof(SANE_String_Const) * ((*tabsize) + 1));
board[*tabsize - 1] = (SANE_String_Const)strdup(convert);
board[*tabsize] = NULL;
return (board);
@@ -173,7 +172,7 @@ find_nodes_c(xmlNode *node)
/**
* \fn static int find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner)
- * \brief Function that searchs in the xml file if a scanner capabilitie stocked
+ * \brief Function that searches in the xml file if a scanner capabilitie stocked
* in one of the created array (character/integer array) is found.
*
* \return 0
@@ -194,32 +193,40 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
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);
+ scanner->caps[type].have_jpeg = -1;
+ scanner->caps[type].have_png = -1;
+ scanner->caps[type].have_tiff = -1;
+ scanner->caps[type].have_pdf = -1;
for(; i < scanner->caps[type].DocumentFormatsSize; i++)
{
if (!strcmp(scanner->caps[type].DocumentFormats[i], "image/jpeg"))
{
have_jpeg = SANE_TRUE;
+ scanner->caps[type].have_jpeg = i;
}
#if(defined HAVE_LIBPNG)
else if(!strcmp(scanner->caps[type].DocumentFormats[i], "image/png"))
{
have_png = SANE_TRUE;
+ scanner->caps[type].have_png = i;
}
#endif
#if(defined HAVE_TIFFIO_H)
else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "image/tiff"))
{
have_tiff = SANE_TRUE;
+ scanner->caps[type].have_tiff = i;
}
#endif
#if(defined HAVE_POPPLER_GLIB)
else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "application/pdf"))
{
have_pdf = SANE_TRUE;
+ scanner->caps[type].have_pdf = i;
}
#endif
}
- if (have_pdf)
+ if (have_pdf)
scanner->caps[type].default_format = strdup("application/pdf");
else if (have_tiff)
scanner->caps[type].default_format = strdup("image/tiff");
@@ -239,7 +246,7 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
/**
* \fn static int find_value_of_int_variables(xmlNode *node, capabilities_t *scanner)
- * \brief Function that searchs in the xml file if a integer scanner capabilitie is found.
+ * \brief Function that searches in the xml file if a integer scanner capabilitie is found.
* The integer scanner capabilities that are interesting are :
* MinWidth, MaxWidth, MaxHeight, MinHeight, MaxScanRegions, MaxOpticalXResolution,
* RiskyLeftMargin, RiskyRightMargin, RiskyTopMargin, RiskyBottomMargin.
@@ -283,11 +290,74 @@ find_value_of_int_variables(xmlNode *node, capabilities_t *scanner, int type)
return (0);
}
+static support_t*
+print_support(xmlNode *node)
+{
+ support_t *sup = (support_t*)calloc(1, sizeof(support_t));
+ int cpt = 0;
+ int have_norm = 0;
+ while (node) {
+ if (!strcmp((const char *)node->name, "Min")){
+ sup->min = atoi((const char *)xmlNodeGetContent(node));
+ cpt++;
+ }
+ else if (!strcmp((const char *)node->name, "Max")) {
+ sup->max = atoi((const char *)xmlNodeGetContent(node));
+ cpt++;
+ }
+ else if (!strcmp((const char *)node->name, "Normal")) {
+ sup->normal = atoi((const char *)xmlNodeGetContent(node));
+ cpt++;
+ have_norm = 1;
+ }
+ else if (!strcmp((const char *)node->name, "Step")) {
+ sup->step = atoi((const char *)xmlNodeGetContent(node));
+ cpt++;
+ }
+ node = node->next;
+ }
+ if (cpt == 4)
+ return sup;
+ if (cpt == 3 && have_norm == 0) {
+ sup->normal = (sup->max / 2 );
+ return sup;
+ }
+ free(sup);
+ return NULL;
+}
+
+static int
+find_struct_variables(xmlNode *node, capabilities_t *scanner)
+{
+ const char *name = (const char *)node->name;
+ if (strcmp(name, "BrightnessSupport") == 0) {
+ scanner->brightness =
+ print_support(node->children);
+ return 1;
+ }
+ else if (strcmp(name, "ContrastSupport") == 0) {
+ scanner->contrast =
+ print_support(node->children);
+ return 1;
+ }
+ else if (strcmp(name, "SharpenSupport") == 0) {
+ scanner->sharpen =
+ print_support(node->children);
+ return 1;
+ }
+ else if (strcmp(name, "ThresholdSupport") == 0) {
+ scanner->threshold =
+ print_support(node->children);
+ return 1;
+ }
+ return (0);
+}
+
/**
* \fn static int find_true_variables(xmlNode *node, capabilities_t *scanner)
- * \brief Function that searchs in the xml file if we find a scanner capabilitie stocked
+ * \brief Function that searches in the xml file if we find a scanner capability stored
* in one of the created array (character/integer array),
- * or, if we find a integer scanner capabilitie.
+ * or, if we find a integer scanner capability.
*
* \return 0
*/
@@ -322,36 +392,39 @@ find_true_variables(xmlNode *node, capabilities_t *scanner, int type)
* \return 0
*/
static int
-print_xml_c(xmlNode *node, capabilities_t *scanner, int type)
+print_xml_c(xmlNode *node, ESCL_Device *device, capabilities_t *scanner, int type)
{
while (node) {
if (node->type == XML_ELEMENT_NODE) {
if (find_nodes_c(node) && type != -1)
find_true_variables(node, scanner, type);
}
- if (!strcmp((const char *)node->name, "PlatenInputCaps")) {
+ if (!strcmp((const char *)node->name, "MakeAndModel")){
+ device->model_name = strdup((const char *)xmlNodeGetContent(node));
+ }
+ else if (!strcmp((const char *)node->name, "PlatenInputCaps")) {
scanner->Sources[PLATEN] = (SANE_String_Const)strdup(SANE_I18N ("Flatbed"));
scanner->SourcesSize++;
scanner->source = PLATEN;
- print_xml_c(node->children, scanner, PLATEN);
+ print_xml_c(node->children, device, scanner, PLATEN);
scanner->caps[PLATEN].duplex = 0;
}
else if (!strcmp((const char *)node->name, "AdfSimplexInputCaps")) {
scanner->Sources[ADFSIMPLEX] = (SANE_String_Const)strdup(SANE_I18N("ADF"));
scanner->SourcesSize++;
if (scanner->source == -1) scanner->source = ADFSIMPLEX;
- print_xml_c(node->children, scanner, ADFSIMPLEX);
+ print_xml_c(node->children, device, scanner, ADFSIMPLEX);
scanner->caps[ADFSIMPLEX].duplex = 0;
}
else if (!strcmp((const char *)node->name, "AdfDuplexInputCaps")) {
scanner->Sources[ADFDUPLEX] = (SANE_String_Const)strdup(SANE_I18N ("ADF Duplex"));
scanner->SourcesSize++;
if (scanner->source == -1) scanner->source = ADFDUPLEX;
- print_xml_c(node->children, scanner, ADFDUPLEX);
+ print_xml_c(node->children, device, scanner, ADFDUPLEX);
scanner->caps[ADFDUPLEX].duplex = 1;
}
- else
- print_xml_c(node->children, scanner, type);
+ else if (find_struct_variables(node, scanner) == 0)
+ print_xml_c(node->children, device, scanner, type);
node = node->next;
}
return (0);
@@ -390,7 +463,7 @@ _reduce_color_modes(capabilities_t *scanner)
* \return scanner (the structure that stocks all the capabilities elements)
*/
capabilities_t *
-escl_capabilities(const ESCL_Device *device, SANE_Status *status)
+escl_capabilities(ESCL_Device *device, SANE_Status *status)
{
capabilities_t *scanner = (capabilities_t*)calloc(1, sizeof(capabilities_t));
CURL *curl_handle = NULL;
@@ -434,7 +507,7 @@ escl_capabilities(const ESCL_Device *device, SANE_Status *status)
scanner->Sources = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * 4);
for (i = 0; i < 4; i++)
scanner->Sources[i] = NULL;
- print_xml_c(node, scanner, -1);
+ print_xml_c(node, device, scanner, -1);
_reduce_color_modes(scanner);
clean:
xmlFreeDoc(data);
diff --git a/backend/escl/escl_crop.c b/backend/escl/escl_crop.c
index 8740d22..59284ac 100644
--- a/backend/escl/escl_crop.c
+++ b/backend/escl/escl_crop.c
@@ -15,8 +15,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
diff --git a/backend/escl/escl_devices.c b/backend/escl/escl_devices.c
index 7ecbe31..3ca28de 100644
--- a/backend/escl/escl_devices.c
+++ b/backend/escl/escl_devices.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -38,6 +38,7 @@
#include "../include/sane/sanei.h"
static AvahiSimplePoll *simple_poll = NULL;
+static int count_finish = 0;
/**
* \fn static void resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED
@@ -62,6 +63,9 @@ resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interfac
void __sane_unused__ *userdata)
{
char a[AVAHI_ADDRESS_STR_MAX], *t;
+ const char *is;
+ const char *uuid;
+ AvahiStringList *s;
assert(r);
switch (event) {
case AVAHI_RESOLVER_FAILURE:
@@ -69,8 +73,19 @@ resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interfac
case AVAHI_RESOLVER_FOUND:
avahi_address_snprint(a, sizeof(a), address);
t = avahi_string_list_to_string(txt);
- if (strstr(t, "\"rs=eSCL\"") || strstr(t, "\"rs=/eSCL\""))
- escl_device_add(port, name, a, (char*)type);
+ if (strstr(t, "\"rs=eSCL\"") || strstr(t, "\"rs=/eSCL\"")) {
+ s = avahi_string_list_find(txt, "is");
+ if (s && s->size > 3)
+ is = (const char*)s->text + 3;
+ else
+ is = (const char*)NULL;
+ s = avahi_string_list_find(txt, "uuid");
+ if (s && s->size > 5)
+ uuid = (const char*)s->text + 5;
+ else
+ uuid = (const char*)NULL;
+ escl_device_add(port, name, a, is, uuid, (char*)type);
+ }
}
}
@@ -107,7 +122,11 @@ browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface,
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED:
if (event != AVAHI_BROWSER_CACHE_EXHAUSTED)
- avahi_simple_poll_quit(simple_poll);
+ {
+ count_finish++;
+ if (count_finish == 2)
+ avahi_simple_poll_quit(simple_poll);
+ }
break;
}
}
@@ -143,6 +162,8 @@ escl_devices(SANE_Status *status)
AvahiServiceBrowser *sb = NULL;
int error;
+ count_finish = 0;
+
*status = SANE_STATUS_GOOD;
if (!(simple_poll = avahi_simple_poll_new())) {
DBG( 1, "Failed to create simple poll object.\n");
diff --git a/backend/escl/escl_jpeg.c b/backend/escl/escl_jpeg.c
index 8d6b6b6..651e7c5 100644
--- a/backend/escl/escl_jpeg.c
+++ b/backend/escl/escl_jpeg.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
diff --git a/backend/escl/escl_mupdf.c b/backend/escl/escl_mupdf.c
index 9399218..dd23482 100644
--- a/backend/escl/escl_mupdf.c
+++ b/backend/escl/escl_mupdf.c
@@ -15,8 +15,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
diff --git a/backend/escl/escl_newjob.c b/backend/escl/escl_newjob.c
index ee8c03c..24bfbc9 100644
--- a/backend/escl/escl_newjob.c
+++ b/backend/escl/escl_newjob.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -29,8 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
-#include <curl/curl.h>
+#include <unistd.h>
#ifdef PATH_MAX
# undef PATH_MAX
@@ -38,12 +37,6 @@
#define PATH_MAX 4096
-struct uploading
-{
- const char *read_data;
- size_t size;
-};
-
struct downloading
{
char *memory;
@@ -71,6 +64,7 @@ static const char settings[] =
" <pwg:InputSource>%s</pwg:InputSource>" \
" <scan:InputSource>%s</scan:InputSource>" \
"%s" \
+ "%s" \
"</scan:ScanSettings>";
/**
@@ -114,6 +108,15 @@ download_callback(void *str, size_t size, size_t nmemb, void *userp)
return (realsize);
}
+static char*
+add_support_option(char *key, int val)
+{
+ int size = (strlen(key) * 3) + 10;
+ char *tmp = (char*)calloc(1, size);
+ snprintf (tmp, size, "<scan:%s>%d</scan:%s>\n", key, val, key);
+ return tmp;
+}
+
/**
* \fn char *escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *status)
* \brief Function that, using curl, uploads the data (composed by the scanner capabilities) to the
@@ -128,7 +131,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
{
CURL *curl_handle = NULL;
int off_x = 0, off_y = 0;
- struct uploading *upload = NULL;
+ struct downloading *upload = NULL;
struct downloading *download = NULL;
const char *scan_jobs = "/eSCL/ScanJobs";
char cap_data[PATH_MAX] = { 0 };
@@ -138,6 +141,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
char *f_ext = "";
char *format_ext = NULL;
char duplex_mode[1024] = { 0 };
+ int wakup_count = 0;
*status = SANE_STATUS_GOOD;
if (device == NULL || scanner == NULL) {
@@ -145,7 +149,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
DBG( 1, "Create NewJob : the name or the scan are invalid.\n");
return (NULL);
}
- upload = (struct uploading *)calloc(1, sizeof(struct uploading));
+ upload = (struct downloading *)calloc(1, sizeof(struct downloading));
if (upload == NULL) {
*status = SANE_STATUS_NO_MEM;
DBG( 1, "Create NewJob : memory allocation failure\n");
@@ -158,7 +162,33 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
*status = SANE_STATUS_NO_MEM;
return (NULL);
}
- curl_handle = curl_easy_init();
+ if (scanner->caps[scanner->source].default_format)
+ free(scanner->caps[scanner->source].default_format);
+ scanner->caps[scanner->source].default_format = NULL;
+ int have_png = scanner->caps[scanner->source].have_png;
+ int have_jpeg = scanner->caps[scanner->source].have_jpeg;
+ int have_tiff = scanner->caps[scanner->source].have_tiff;
+ int have_pdf = scanner->caps[scanner->source].have_pdf;
+
+ if ((scanner->source == PLATEN && have_pdf == -1) ||
+ (scanner->source > PLATEN)) {
+ if (have_tiff != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_tiff]);
+ }
+ else if (have_png != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_png]);
+ }
+ else if (have_jpeg != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_jpeg]);
+ }
+ }
+ else {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_pdf]);
+ }
if (scanner->caps[scanner->source].format_ext == 1)
{
char f_ext_tmp[1024];
@@ -179,29 +209,71 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
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;
+
+ char support_options[1024];
+ memset(support_options, 0, 1024);
+ char *source = (scanner->source == PLATEN ? "Platen" : "Feeder");
+ if (scanner->use_threshold)
+ {
+ char *tmp = add_support_option("ThresholdSupport", scanner->val_threshold);
+ if (support_options[0])
+ strcat(support_options, tmp);
+ else
+ strcpy(support_options, tmp);
+ free(tmp);
+ }
+ if (scanner->use_sharpen)
+ {
+ char *tmp = add_support_option("SharpenSupport", scanner->val_sharpen);
+ if (support_options[0])
+ strcat(support_options, tmp);
+ else
+ strcpy(support_options, tmp);
+ free(tmp);
+ }
+ if (scanner->use_contrast)
+ {
+ char *tmp = add_support_option("ContrastSupport", scanner->val_contrast);
+ if (support_options[0])
+ strcat(support_options, tmp);
+ else
+ strcpy(support_options, tmp);
+ free(tmp);
+ }
+ if (scanner->use_brightness)
+ {
+ char *tmp = add_support_option("BrightnessSupport", scanner->val_brightness);
+ if (support_options[0])
+ strcat(support_options, tmp);
+ else
+ strcpy(support_options, tmp);
+ free(tmp);
+ }
+ snprintf(cap_data, sizeof(cap_data), settings,
+ scanner->caps[scanner->source].height,
+ scanner->caps[scanner->source].width,
+ 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,
+ source,
+ source,
+ duplex_mode[0] == 0 ? " " : duplex_mode,
+ support_options[0] == 0 ? " " : support_options);
+ upload->memory = strdup(cap_data);
+ upload->size = strlen(cap_data);
+wake_up_device:
+ DBG( 1, "Create NewJob : %s\n", cap_data);
+ download->memory = malloc(1);
+ download->size = 0;
+ curl_handle = curl_easy_init();
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,
- 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,
- source,
- source,
- duplex_mode[0] == 0 ? "" : duplex_mode);
- DBG( 1, "Create NewJob : %s\n", cap_data);
- upload->read_data = strdup(cap_data);
- upload->size = strlen(cap_data);
- download->memory = malloc(1);
- download->size = 0;
escl_curl_url(curl_handle, device, scan_jobs);
curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);
- curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, upload->read_data);
+ curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, (const char*)upload->memory);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, upload->size);
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, download_callback);
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)download);
@@ -224,6 +296,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
result = strdup(location);
DBG( 1, "Create NewJob : %s\n", result);
*temporary = '\n';
+ wakup_count = 0;
}
}
if (result == NULL) {
@@ -231,6 +304,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
*status = SANE_STATUS_INVAL;
}
free(download->memory);
+ download->memory = NULL;
}
else {
DBG( 1, "Create NewJob : The creation of the failed job: %s\n", download->memory);
@@ -238,8 +312,10 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
if (strstr(download->memory, "409 Conflict") != NULL)
*status = SANE_STATUS_NO_DOCS;
// If "503 Service Unavailable" appear, it means that device is busy (scanning in progress)
- else if (strstr(download->memory, "503 Service Unavailable") != NULL)
+ else if (strstr(download->memory, "503 Service Unavailable") != NULL) {
+ wakup_count += 1;
*status = SANE_STATUS_DEVICE_BUSY;
+ }
else
*status = SANE_STATUS_INVAL;
}
@@ -252,8 +328,18 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
}
curl_easy_cleanup(curl_handle);
}
- if (upload != NULL)
+ if (wakup_count > 0 && wakup_count < 4) {
+ free(download->memory);
+ download->memory = NULL;
+ download->size = 0;
+ *status = SANE_STATUS_GOOD;
+ usleep(250);
+ goto wake_up_device;
+ }
+ if (upload != NULL) {
+ free(upload->memory);
free(upload);
+ }
if (download != NULL)
free(download);
return (result);
diff --git a/backend/escl/escl_pdf.c b/backend/escl/escl_pdf.c
index ae85a3a..02dce66 100644
--- a/backend/escl/escl_pdf.c
+++ b/backend/escl/escl_pdf.c
@@ -15,8 +15,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -35,14 +35,14 @@
#include <errno.h>
-#if(defined HAVE_POPPLER_GLIB)
+#if HAVE_POPPLER_GLIB
#include <poppler/glib/poppler.h>
#endif
#include <setjmp.h>
-#if(defined HAVE_POPPLER_GLIB)
+#if HAVE_POPPLER_GLIB
#define INPUT_BUFFER_SIZE 4096
diff --git a/backend/escl/escl_png.c b/backend/escl/escl_png.c
index cf92449..294ec00 100644
--- a/backend/escl/escl_png.c
+++ b/backend/escl/escl_png.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -87,7 +87,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
goto close_file;
}
// initialize the setjmp for returning properly after a libpng
- // error occured
+ // error occurred
if (setjmp (png_jmpbuf (png_ptr)))
{
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
@@ -107,7 +107,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
png_read_info (png_ptr, info_ptr);
int bit_depth, color_type;
- // get some usefull information from header
+ // get some useful information from header
bit_depth = png_get_bit_depth (png_ptr, info_ptr);
color_type = png_get_color_type (png_ptr, info_ptr);
// convert index color images to RGB images
diff --git a/backend/escl/escl_reset.c b/backend/escl/escl_reset.c
index 64d779a..7494dda 100644
--- a/backend/escl/escl_reset.c
+++ b/backend/escl/escl_reset.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -29,8 +29,6 @@
#include <stdlib.h>
#include <string.h>
-#include <curl/curl.h>
-
static size_t
write_callback(void __sane_unused__*str,
size_t __sane_unused__ size,
diff --git a/backend/escl/escl_scan.c b/backend/escl/escl_scan.c
index 9fce801..53bd438 100644
--- a/backend/escl/escl_scan.c
+++ b/backend/escl/escl_scan.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -30,15 +30,13 @@
#include <stdlib.h>
#include <string.h>
-#include <curl/curl.h>
-
#include "../include/sane/sanei.h"
/**
* \fn static size_t write_callback(void *str, size_t size, size_t nmemb, void *userp)
* \brief Callback function that writes the image scanned into the temporary file.
*
- * \return to_write (the result of the fwrite fonction)
+ * \return to_write (the result of the fwrite function)
*/
static size_t
write_callback(void *str, size_t size, size_t nmemb, void *userp)
diff --git a/backend/escl/escl_status.c b/backend/escl/escl_status.c
index 7b98566..a68f6ea 100644
--- a/backend/escl/escl_status.c
+++ b/backend/escl/escl_status.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */
@@ -30,7 +30,6 @@
#include <stdlib.h>
#include <string.h>
-#include <curl/curl.h>
#include <libxml/parser.h>
struct idle
diff --git a/backend/escl/escl_tiff.c b/backend/escl/escl_tiff.c
index 98bc5f3..e33498c 100644
--- a/backend/escl/escl_tiff.c
+++ b/backend/escl/escl_tiff.c
@@ -16,8 +16,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with sane; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with sane; see the file COPYING.
+ If not, see <https://www.gnu.org/licenses/>.
This file implements a SANE backend for eSCL scanners. */