kopia lustrzana https://gitlab.com/sane-project/backends
epsonds: dynamically size ADF area based on DPI selection
The Epson ES-50 (and friends) supports a larger scanning area when used at its lowest DPI setting. This adds support for switching to the larger reported scan area when the DPI setting is at its lowest value. The scanner does not directly report the DPI to scan area relationship, so this code is based on some educated guesses and experimentation. It's been tested to work on the ES-50 with both scanimage and xsane. Hopefully it does not interfere with any other scanners using this backend.merge-requests/753/head
rodzic
f79b04e8ff
commit
a1c58d5d82
|
@ -465,6 +465,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
|
|||
int max = decode_value(value + 4 + 8, 8);
|
||||
|
||||
DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max);
|
||||
eds_set_adf_area_large(s->hw, min, max, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -493,6 +494,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
|
|||
int max = decode_value(value + 4 + 4, 8);
|
||||
|
||||
DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max);
|
||||
eds_set_adf_area_large(s->hw, min, max, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,25 @@ eds_set_adf_area(struct epsonds_device *dev, int x, int y, int unit)
|
|||
SANE_UNFIX(dev->adf_y_range.max), unit);
|
||||
}
|
||||
|
||||
void
|
||||
eds_set_adf_area_large(struct epsonds_device *dev, int x, int y, int unit)
|
||||
{
|
||||
dev->adf_x_range_large.min = 0;
|
||||
dev->adf_x_range_large.max = SANE_FIX(x * MM_PER_INCH / unit);
|
||||
dev->adf_x_range_large.quant = 0;
|
||||
|
||||
dev->adf_y_range_large.min = 0;
|
||||
dev->adf_y_range_large.max = SANE_FIX(y * MM_PER_INCH / unit);
|
||||
dev->adf_y_range_large.quant = 0;
|
||||
|
||||
DBG(5, "%s: %f,%f %f,%f %d [mm]\n",
|
||||
__func__,
|
||||
SANE_UNFIX(dev->adf_x_range_large.min),
|
||||
SANE_UNFIX(dev->adf_y_range_large.min),
|
||||
SANE_UNFIX(dev->adf_x_range_large.max),
|
||||
SANE_UNFIX(dev->adf_y_range_large.max), unit);
|
||||
}
|
||||
|
||||
void
|
||||
eds_set_tpu_area(struct epsonds_device *dev, int x, int y, int unit)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ extern SANE_Status eds_add_resolution(epsonds_device *dev, int r);
|
|||
extern SANE_Status eds_set_resolution_range(epsonds_device *dev, int min, int max);
|
||||
extern void eds_set_fbf_area(epsonds_device *dev, int x, int y, int unit);
|
||||
extern void eds_set_adf_area(epsonds_device *dev, int x, int y, int unit);
|
||||
extern void eds_set_adf_area_large(epsonds_device *dev, int x, int y, int unit);
|
||||
extern void eds_set_tpu_area(epsonds_device *dev, int x, int y, int unit);
|
||||
|
||||
extern SANE_Status eds_add_depth(epsonds_device *dev, SANE_Word depth);
|
||||
|
|
|
@ -1597,11 +1597,16 @@ device_detect(const char *name, int type, SANE_Status *status)
|
|||
dev->alignment = dev->fbf_alignment;
|
||||
|
||||
} else if (s->hw->has_adf) {
|
||||
if (dev->adf_x_range_large.max > 0) {
|
||||
dev->x_range = &dev->adf_x_range_large;
|
||||
dev->y_range = &dev->adf_y_range_large;
|
||||
} else {
|
||||
DBG(17, "ADF AMAX was not sent by scanner, using AREA instead\n");
|
||||
dev->x_range = &dev->adf_x_range;
|
||||
dev->y_range = &dev->adf_y_range;
|
||||
}
|
||||
|
||||
dev->x_range = &dev->adf_x_range;
|
||||
dev->y_range = &dev->adf_y_range;
|
||||
dev->alignment = dev->adf_alignment;
|
||||
|
||||
} else {
|
||||
DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n");
|
||||
}
|
||||
|
@ -2209,9 +2214,21 @@ change_source(epsonds_scanner *s, SANE_Int optindex, char *value)
|
|||
force_max = SANE_TRUE;
|
||||
}
|
||||
|
||||
SANE_Word min_resolution =
|
||||
(s->hw->dpi_range.quant) ? s->hw->dpi_range.min : s->hw->res_list[1];
|
||||
SANE_Bool in_min_resolution = (s->val[OPT_RESOLUTION].w == min_resolution);
|
||||
|
||||
if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) {
|
||||
s->hw->x_range = &s->hw->adf_x_range;
|
||||
s->hw->y_range = &s->hw->adf_y_range;
|
||||
if (s->hw->adf_x_range_large.max > 0 && in_min_resolution) {
|
||||
s->hw->x_range = &s->hw->adf_x_range_large;
|
||||
s->hw->y_range = &s->hw->adf_y_range_large;
|
||||
} else {
|
||||
if(!in_min_resolution) DBG(17, "ADF AMAX was not sent by scanner, using AREA instead\n");
|
||||
else DBG(17, "Not allowed to use AMAX due to DPI, using AREA instead\n");
|
||||
s->hw->x_range = &s->hw->adf_x_range;
|
||||
s->hw->y_range = &s->hw->adf_y_range;
|
||||
}
|
||||
|
||||
s->hw->alignment = s->hw->adf_alignment;
|
||||
|
||||
|
||||
|
@ -2317,8 +2334,37 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
|
|||
|
||||
switch (option) {
|
||||
|
||||
case OPT_ADF_SKEW:
|
||||
case OPT_RESOLUTION:
|
||||
/* Note: this includes an assumption that only the lowest DPI supports
|
||||
* the large ADF area. This assumption holds true on at least the ES-50
|
||||
* and friends, but other scanners need to be tested to see if this is
|
||||
* universally true or not.
|
||||
*/
|
||||
if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
|
||||
SANE_Word min_resolution =
|
||||
(s->hw->dpi_range.quant) ? s->hw->dpi_range.min : s->hw->res_list[1];
|
||||
|
||||
if (*((SANE_Word *) value) == min_resolution) {
|
||||
DBG(17, "DPI change, setting ADF to large area\n");
|
||||
s->hw->x_range = &s->hw->adf_x_range_large;
|
||||
s->hw->y_range = &s->hw->adf_y_range_large;
|
||||
} else {
|
||||
DBG(17, "DPI change, setting ADF to normal area\n");
|
||||
s->hw->x_range = &s->hw->adf_x_range;
|
||||
s->hw->y_range = &s->hw->adf_y_range;
|
||||
}
|
||||
|
||||
s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
|
||||
s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
|
||||
|
||||
if (s->val[OPT_BR_X].w > s->hw->x_range->max)
|
||||
s->val[OPT_BR_X].w = s->hw->x_range->max;
|
||||
|
||||
if (s->val[OPT_BR_Y].w > s->hw->y_range->max)
|
||||
s->val[OPT_BR_Y].w = s->hw->y_range->max;
|
||||
}
|
||||
// fall through
|
||||
case OPT_ADF_SKEW:
|
||||
case OPT_ADF_CRP:
|
||||
sval->w = *((SANE_Word *) value);
|
||||
reload = SANE_TRUE;
|
||||
|
|
|
@ -140,6 +140,8 @@ struct epsonds_device
|
|||
SANE_Bool has_adf; /* adf */
|
||||
SANE_Range adf_x_range; /* x range */
|
||||
SANE_Range adf_y_range; /* y range */
|
||||
SANE_Range adf_x_range_large; /* x range in largest scan mode (low DPI) */
|
||||
SANE_Range adf_y_range_large; /* y range in largest scan mode (low DPI) */
|
||||
SANE_Bool adf_is_duplex; /* supports duplex mode */
|
||||
SANE_Bool adf_singlepass; /* supports single pass duplex */
|
||||
SANE_Bool adf_has_skew; /* supports skew correction */
|
||||
|
|
Ładowanie…
Reference in New Issue