diff options
Diffstat (limited to 'backend/escl')
-rw-r--r-- | backend/escl/escl.c | 587 | ||||
-rw-r--r-- | backend/escl/escl.h | 120 | ||||
-rw-r--r-- | backend/escl/escl_capabilities.c | 111 | ||||
-rw-r--r-- | backend/escl/escl_crop.c | 4 | ||||
-rw-r--r-- | backend/escl/escl_devices.c | 31 | ||||
-rw-r--r-- | backend/escl/escl_jpeg.c | 4 | ||||
-rw-r--r-- | backend/escl/escl_mupdf.c | 4 | ||||
-rw-r--r-- | backend/escl/escl_newjob.c | 156 | ||||
-rw-r--r-- | backend/escl/escl_pdf.c | 8 | ||||
-rw-r--r-- | backend/escl/escl_png.c | 8 | ||||
-rw-r--r-- | backend/escl/escl_reset.c | 6 | ||||
-rw-r--r-- | backend/escl/escl_scan.c | 8 | ||||
-rw-r--r-- | backend/escl/escl_status.c | 5 | ||||
-rw-r--r-- | backend/escl/escl_tiff.c | 4 |
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 = ⦥ + 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 = ⦥ + 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 = ⦥ + 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 = ⦥ + 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. */ |