kopia lustrzana https://gitlab.com/sane-project/backends
Proper handling of parameters (to fix xsane crash)
rodzic
6909a32587
commit
133d37e4e4
|
@ -1,4 +1,6 @@
|
||||||
2009-02-01 Alex belkin <abc@telekom.ru>
|
2009-02-01 Alex belkin <abc@telekom.ru>
|
||||||
|
* backend/xerox_mfp.c backend/xerox_mfp.h:
|
||||||
|
Proper handling of parameters (to fix xsane crash).
|
||||||
* backend/xerox_mfp.conf doc/descriptions/xerox_mfp.desc:
|
* backend/xerox_mfp.conf doc/descriptions/xerox_mfp.desc:
|
||||||
Added Dell MFP 1815dn.
|
Added Dell MFP 1815dn.
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <sane/sanei_backend.h>
|
#include <sane/sanei_backend.h>
|
||||||
#include "xerox_mfp.h"
|
#include "xerox_mfp.h"
|
||||||
|
|
||||||
#define BACKEND_BUILD 5
|
#define BACKEND_BUILD 9
|
||||||
#define XEROX_CONFIG_FILE "xerox_mfp.conf"
|
#define XEROX_CONFIG_FILE "xerox_mfp.conf"
|
||||||
|
|
||||||
static const SANE_Device **devlist = NULL; /* sane_get_devices array */
|
static const SANE_Device **devlist = NULL; /* sane_get_devices array */
|
||||||
|
@ -505,15 +505,55 @@ static void init_options(struct device *dev)
|
||||||
dev->opt[OPT_SCAN_BR_Y].constraint.range = &dev->win_y_range;
|
dev->opt[OPT_SCAN_BR_Y].constraint.range = &dev->win_y_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fill parameters from options */
|
||||||
|
static void set_parameters(struct device *dev)
|
||||||
|
{
|
||||||
|
double px_to_len;
|
||||||
|
|
||||||
|
dev->para.last_frame = SANE_TRUE;
|
||||||
|
dev->para.lines = -1;
|
||||||
|
px_to_len = 1200.0 / dev->val[OPT_RESOLUTION].w;
|
||||||
|
#define BETTER_BASEDPI 1
|
||||||
|
/* tests prove that 1200dpi base is very inexact
|
||||||
|
* so I calculated better values for each axis */
|
||||||
|
#if BETTER_BASEDPI
|
||||||
|
px_to_len = 1180.0 / dev->val[OPT_RESOLUTION].w;
|
||||||
|
#endif
|
||||||
|
dev->para.pixels_per_line = dev->win_width / px_to_len;
|
||||||
|
dev->para.bytes_per_line = dev->para.pixels_per_line;
|
||||||
|
#if BETTER_BASEDPI
|
||||||
|
px_to_len = 1213.9 / dev->val[OPT_RESOLUTION].w;
|
||||||
|
#endif
|
||||||
|
dev->para.lines = dev->win_len / px_to_len;
|
||||||
|
if (dev->composition == MODE_LINEART ||
|
||||||
|
dev->composition == MODE_HALFTONE) {
|
||||||
|
dev->para.format = SANE_FRAME_GRAY;
|
||||||
|
dev->para.depth = 1;
|
||||||
|
dev->para.bytes_per_line = (dev->para.pixels_per_line + 7) / 8;
|
||||||
|
} else if (dev->composition == MODE_GRAY8) {
|
||||||
|
dev->para.format = SANE_FRAME_GRAY;
|
||||||
|
dev->para.depth = 8;
|
||||||
|
dev->para.bytes_per_line = dev->para.pixels_per_line;
|
||||||
|
} else if (dev->composition == MODE_RGB24) {
|
||||||
|
dev->para.format = SANE_FRAME_RGB;
|
||||||
|
dev->para.depth = 8;
|
||||||
|
dev->para.bytes_per_line *= 3;
|
||||||
|
} else {
|
||||||
|
/* this will never happen */
|
||||||
|
DBG (1, "%s: impossible image composition %d\n",
|
||||||
|
__FUNCTION__, dev->composition);
|
||||||
|
dev->para.format = SANE_FRAME_GRAY;
|
||||||
|
dev->para.depth = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* resolve all options related to scan window */
|
/* resolve all options related to scan window */
|
||||||
/* called after option changed and in set_window */
|
/* called after option changed and in set_window */
|
||||||
static int fix_window(struct device *dev)
|
static int fix_window(struct device *dev)
|
||||||
{
|
{
|
||||||
int max_len = dev->max_len;
|
|
||||||
double win_width_mm, win_len_mm;
|
double win_width_mm, win_len_mm;
|
||||||
int i;
|
int i;
|
||||||
int threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);
|
int threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);
|
||||||
int thrcap = dev->opt[OPT_THRESHOLD].cap;
|
|
||||||
|
|
||||||
dev->resolution = dpi_to_code(dev->val[OPT_RESOLUTION].w);
|
dev->resolution = dpi_to_code(dev->val[OPT_RESOLUTION].w);
|
||||||
dev->composition = scan_mode_to_code[string_match_index(scan_modes, dev->val[OPT_MODE].s)];
|
dev->composition = scan_mode_to_code[string_match_index(scan_modes, dev->val[OPT_MODE].s)];
|
||||||
|
@ -524,17 +564,14 @@ static int fix_window(struct device *dev)
|
||||||
} else {
|
} else {
|
||||||
dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
|
dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
|
||||||
}
|
}
|
||||||
if (thrcap != dev->opt[OPT_THRESHOLD].cap)
|
|
||||||
dev->opt_reload++;
|
|
||||||
if (threshold < 30) {
|
if (threshold < 30) {
|
||||||
dev->val[OPT_THRESHOLD].w = SANE_FIX(30);
|
dev->val[OPT_THRESHOLD].w = SANE_FIX(30);
|
||||||
dev->opt_reload++;
|
|
||||||
} else if (threshold > 70) {
|
} else if (threshold > 70) {
|
||||||
dev->val[OPT_THRESHOLD].w = SANE_FIX(70);
|
dev->val[OPT_THRESHOLD].w = SANE_FIX(70);
|
||||||
dev->opt_reload++;
|
|
||||||
}
|
}
|
||||||
threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);
|
threshold = SANE_UNFIX(dev->val[OPT_THRESHOLD].w);
|
||||||
dev->threshold = (threshold - 30) / 10;
|
dev->threshold = (threshold - 30) / 10;
|
||||||
|
dev->val[OPT_THRESHOLD].w = dev->threshold * 10 + 30;
|
||||||
|
|
||||||
dev->doc_source = doc_source_to_code[string_match_index(doc_sources, dev->val[OPT_SOURCE].s)];
|
dev->doc_source = doc_source_to_code[string_match_index(doc_sources, dev->val[OPT_SOURCE].s)];
|
||||||
|
|
||||||
|
@ -545,24 +582,22 @@ static int fix_window(struct device *dev)
|
||||||
else
|
else
|
||||||
dev->max_len = dev->max_len_adf;
|
dev->max_len = dev->max_len_adf;
|
||||||
|
|
||||||
if (dev->max_len != max_len)
|
|
||||||
dev->opt_reload++;
|
|
||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
dev->win_y_range.max = SANE_FIX((double)dev->max_len / PNT_PER_MM);
|
dev->win_y_range.max = SANE_FIX((double)dev->max_len / PNT_PER_MM);
|
||||||
|
|
||||||
/* window sanity checking */
|
/* window sanity checking */
|
||||||
for (i = OPT_SCAN_TL_X; i <= OPT_SCAN_BR_Y; i++) {
|
for (i = OPT_SCAN_TL_X; i <= OPT_SCAN_BR_Y; i++) {
|
||||||
if (dev->val[i].w < dev->opt[i].constraint.range->min) {
|
if (dev->val[i].w < dev->opt[i].constraint.range->min)
|
||||||
dev->opt_reload++;
|
|
||||||
dev->val[i].w = dev->opt[i].constraint.range->min;
|
dev->val[i].w = dev->opt[i].constraint.range->min;
|
||||||
}
|
if (dev->val[i].w > dev->opt[i].constraint.range->max)
|
||||||
if (dev->val[i].w > dev->opt[i].constraint.range->max) {
|
|
||||||
dev->opt_reload++;
|
|
||||||
dev->val[i].w = dev->opt[i].constraint.range->max;
|
dev->val[i].w = dev->opt[i].constraint.range->max;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->val[OPT_SCAN_TL_X].w > dev->val[OPT_SCAN_BR_X].w)
|
||||||
|
SWAP_Word(dev->val[OPT_SCAN_TL_X].w, dev->val[OPT_SCAN_BR_X].w);
|
||||||
|
if (dev->val[OPT_SCAN_TL_Y].w > dev->val[OPT_SCAN_BR_Y].w)
|
||||||
|
SWAP_Word(dev->val[OPT_SCAN_TL_Y].w, dev->val[OPT_SCAN_BR_Y].w);
|
||||||
|
|
||||||
/* recalculate millimeters to inches */
|
/* recalculate millimeters to inches */
|
||||||
dev->win_off_x = SANE_UNFIX(dev->val[OPT_SCAN_TL_X].w) / MM_PER_INCH;
|
dev->win_off_x = SANE_UNFIX(dev->val[OPT_SCAN_TL_X].w) / MM_PER_INCH;
|
||||||
dev->win_off_y = SANE_UNFIX(dev->val[OPT_SCAN_TL_Y].w) / MM_PER_INCH;
|
dev->win_off_y = SANE_UNFIX(dev->val[OPT_SCAN_TL_Y].w) / MM_PER_INCH;
|
||||||
|
@ -644,9 +679,12 @@ dev_inquiry (struct device *dev)
|
||||||
*optr++ = *ptr++;
|
*optr++ = *ptr++;
|
||||||
*optr++ = 0;
|
*optr++ = 0;
|
||||||
|
|
||||||
|
for (; ptr < &dev->res[0x24] && (!*ptr || *ptr == ' '); ptr++)
|
||||||
|
/* skip spaces */;
|
||||||
|
|
||||||
dev->sane.model = optr = (SANE_Char *) malloc (33);
|
dev->sane.model = optr = (SANE_Char *) malloc (33);
|
||||||
xptr = optr; /* is last non space character + 1 */
|
xptr = optr; /* is last non space character + 1 */
|
||||||
for (ptr++; ptr < &dev->res[0x24] && *ptr;) {
|
for (; ptr < &dev->res[0x24] && *ptr;) {
|
||||||
if (*ptr != ' ')
|
if (*ptr != ' ')
|
||||||
xptr = optr + 1;
|
xptr = optr + 1;
|
||||||
*optr++ = *ptr++;
|
*optr++ = *ptr++;
|
||||||
|
@ -683,6 +721,7 @@ dev_inquiry (struct device *dev)
|
||||||
init_options(dev);
|
init_options(dev);
|
||||||
reset_options(dev);
|
reset_options(dev);
|
||||||
fix_window(dev);
|
fix_window(dev);
|
||||||
|
set_parameters(dev);
|
||||||
resolv_inq_dpi(dev);
|
resolv_inq_dpi(dev);
|
||||||
|
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
|
@ -718,21 +757,38 @@ sane_control_option (SANE_Handle h, SANE_Int opt, SANE_Action act,
|
||||||
else
|
else
|
||||||
*(SANE_Word *)val = dev->val[opt].w;
|
*(SANE_Word *)val = dev->val[opt].w;
|
||||||
} else if (act == SANE_ACTION_SET_VALUE) { /* SET */
|
} else if (act == SANE_ACTION_SET_VALUE) { /* SET */
|
||||||
dev->opt_reload = 0;
|
SANE_Parameters xpara = dev->para;
|
||||||
|
SANE_Option_Descriptor xopt[NUM_OPTIONS];
|
||||||
|
Option_Value xval[NUM_OPTIONS];
|
||||||
|
int i;
|
||||||
|
|
||||||
if (dev->opt[opt].constraint_type == SANE_CONSTRAINT_STRING_LIST)
|
if (dev->opt[opt].constraint_type == SANE_CONSTRAINT_STRING_LIST) {
|
||||||
dev->val[opt].s = string_match(dev->opt[opt].constraint.string_list, val);
|
dev->val[opt].s = string_match(dev->opt[opt].constraint.string_list, val);
|
||||||
else if (opt == OPT_RESOLUTION)
|
if (info && strcasecmp(dev->val[opt].s, val))
|
||||||
|
*info |= SANE_INFO_INEXACT;
|
||||||
|
} else if (opt == OPT_RESOLUTION)
|
||||||
dev->val[opt].w = res_dpi_codes[dpi_to_code(*(SANE_Word *)val)];
|
dev->val[opt].w = res_dpi_codes[dpi_to_code(*(SANE_Word *)val)];
|
||||||
else
|
else
|
||||||
dev->val[opt].w = *(SANE_Word *)val;
|
dev->val[opt].w = *(SANE_Word *)val;
|
||||||
|
|
||||||
|
memcpy(&xopt, &dev->opt, sizeof(xopt));
|
||||||
|
memcpy(&xval, &dev->val, sizeof(xval));
|
||||||
fix_window(dev);
|
fix_window(dev);
|
||||||
if (dev->opt_reload) {
|
set_parameters(dev);
|
||||||
dev->opt_reload = 0;
|
|
||||||
DBG (3, "SANE_INFO_RELOAD_OPTIONS\n");
|
/* check for side effects */
|
||||||
if (info)
|
if (info) {
|
||||||
*info = SANE_INFO_RELOAD_OPTIONS;
|
if (memcmp(&xpara, &dev->para, sizeof(xpara)))
|
||||||
|
*info |= SANE_INFO_RELOAD_PARAMS;
|
||||||
|
if (memcmp(&xopt, &dev->opt, sizeof(xopt)))
|
||||||
|
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
for (i = 0; i < NUM_OPTIONS; i++)
|
||||||
|
if (xval[i].w != dev->val[i].w) {
|
||||||
|
if (i == opt)
|
||||||
|
*info |= SANE_INFO_INEXACT;
|
||||||
|
else
|
||||||
|
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,7 +958,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local)
|
||||||
int dev_count;
|
int dev_count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DBG (3, "%s: %p, %d\n", __FUNCTION__, (void *)device_list, local);
|
DBG (3, "%s: %p, %d\n", __FUNCTION__, (const void *)device_list, local);
|
||||||
|
|
||||||
if (devlist) {
|
if (devlist) {
|
||||||
if (device_list)
|
if (device_list)
|
||||||
|
@ -1238,7 +1294,6 @@ SANE_Status
|
||||||
sane_start (SANE_Handle h)
|
sane_start (SANE_Handle h)
|
||||||
{
|
{
|
||||||
struct device *dev = h;
|
struct device *dev = h;
|
||||||
double px_to_len;
|
|
||||||
|
|
||||||
DBG (3, "%s: %p\n", __FUNCTION__, h);
|
DBG (3, "%s: %p\n", __FUNCTION__, h);
|
||||||
|
|
||||||
|
@ -1272,38 +1327,7 @@ sane_start (SANE_Handle h)
|
||||||
dev->bytes_per_line = 0;
|
dev->bytes_per_line = 0;
|
||||||
dev->ulines = 0;
|
dev->ulines = 0;
|
||||||
|
|
||||||
dev->para.last_frame = SANE_TRUE;
|
set_parameters(dev);
|
||||||
dev->para.lines = -1;
|
|
||||||
px_to_len = 1200.0 / dev->val[OPT_RESOLUTION].w;
|
|
||||||
#define BETTER_BASEDPI 1
|
|
||||||
/* tests prove that 1200dpi base is very inexact
|
|
||||||
* so I calculated better values for each axis */
|
|
||||||
#if BETTER_BASEDPI
|
|
||||||
px_to_len = 1180.0 / dev->val[OPT_RESOLUTION].w;
|
|
||||||
#endif
|
|
||||||
dev->para.pixels_per_line = dev->win_width / px_to_len;
|
|
||||||
dev->para.bytes_per_line = dev->para.pixels_per_line;
|
|
||||||
#if BETTER_BASEDPI
|
|
||||||
px_to_len = 1213.9 / dev->val[OPT_RESOLUTION].w;
|
|
||||||
#endif
|
|
||||||
dev->para.lines = dev->win_len / px_to_len;
|
|
||||||
if (dev->composition == MODE_LINEART ||
|
|
||||||
dev->composition == MODE_HALFTONE) {
|
|
||||||
dev->para.format = SANE_FRAME_GRAY;
|
|
||||||
dev->para.depth = 1;
|
|
||||||
} else if (dev->composition == MODE_GRAY8) {
|
|
||||||
dev->para.format = SANE_FRAME_GRAY;
|
|
||||||
dev->para.depth = 8;
|
|
||||||
} else if (dev->composition == MODE_RGB24) {
|
|
||||||
dev->para.format = SANE_FRAME_RGB;
|
|
||||||
dev->para.depth = 8;
|
|
||||||
} else {
|
|
||||||
/* this will never happen */
|
|
||||||
DBG (1, "%s: impossible image composition %d\n",
|
|
||||||
__FUNCTION__, dev->composition);
|
|
||||||
dev->para.format = SANE_FRAME_GRAY;
|
|
||||||
dev->para.depth = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dev->data && !(dev->data = malloc(DATASIZE)))
|
if (!dev->data && !(dev->data = malloc(DATASIZE)))
|
||||||
return ret_cancel(dev, SANE_STATUS_NO_MEM);
|
return ret_cancel(dev, SANE_STATUS_NO_MEM);
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#define PADDING_SIZE 16
|
#define PADDING_SIZE 16
|
||||||
|
|
||||||
|
#define SWAP_Word(x, y) { SANE_Word z = x; x = y; y = z; }
|
||||||
|
|
||||||
enum options {
|
enum options {
|
||||||
OPT_NUMOPTIONS,
|
OPT_NUMOPTIONS,
|
||||||
OPT_GROUP_STD,
|
OPT_GROUP_STD,
|
||||||
|
@ -44,9 +46,8 @@ struct device {
|
||||||
size_t reslen; /* response len */
|
size_t reslen; /* response len */
|
||||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||||
Option_Value val[NUM_OPTIONS];
|
Option_Value val[NUM_OPTIONS];
|
||||||
int opt_reload;
|
|
||||||
SANE_Bool non_blocking;
|
|
||||||
SANE_Parameters para;
|
SANE_Parameters para;
|
||||||
|
SANE_Bool non_blocking;
|
||||||
int scanning; /* scanning is started */
|
int scanning; /* scanning is started */
|
||||||
int cancel; /* cancel flag */
|
int cancel; /* cancel flag */
|
||||||
int state; /* current state */
|
int state; /* current state */
|
||||||
|
|
Ładowanie…
Reference in New Issue