kopia lustrzana https://gitlab.com/sane-project/backends
Added support for Acer/Benq Scanwit 2720S film scanner by Andrew Goodbody in snapscan backend.
rodzic
a56d62356a
commit
cfecc1fbf6
|
@ -1,3 +1,9 @@
|
|||
2013-03-04 Oliver Schwartz <oliverschwartz@users.sf.net>
|
||||
* backend/snapscan-options.c backend/snapscan-scsi.c backend/snapscan.c
|
||||
backend/snapscan-sources.c backend/snapscan.h
|
||||
doc/descriptions/snapscan.desc: Added support for Acer Scanwit 2720S
|
||||
implemented by Andrew Goddbody.
|
||||
|
||||
2013-02-28 Stéphane Voltz <stef.dev@free.fr>
|
||||
* sanei/sanei_usb.c: only free devanme when reusing a device slot in
|
||||
device list
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Copyright (C) 1997, 1998, 2001, 2013 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
|
||||
Oliver Schwartz and Kevin Charter
|
||||
Andrew Goodbody, Oliver Schwartz and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -67,11 +67,15 @@
|
|||
static SANE_Int def_rgb_lpr = 4;
|
||||
static SANE_Int def_gs_lpr = 12;
|
||||
static SANE_Int def_bpp = 8;
|
||||
static SANE_Int def_frame_no = 1;
|
||||
|
||||
|
||||
/* predefined preview mode name */
|
||||
static char md_auto[] = "Auto";
|
||||
|
||||
/* predefined focus mode name */
|
||||
static char md_manual[] = "Manual";
|
||||
|
||||
/* predefined scan mode names */
|
||||
static char md_colour[] = SANE_VALUE_SCAN_MODE_COLOR;
|
||||
static char md_bilevelcolour[] = SANE_VALUE_SCAN_MODE_HALFTONE;
|
||||
|
@ -103,6 +107,15 @@ static char lpr_desc[] = SANE_I18N(
|
|||
"a scan; if it's set too high, X-based frontends may stop responding "
|
||||
"to X events and your system could bog down.");
|
||||
|
||||
static char frame_desc[] = SANE_I18N(
|
||||
"Frame number of media holder that should be scanned.");
|
||||
|
||||
static char focus_mode_desc[] = SANE_I18N(
|
||||
"Use manual or automatic selection of focus point.");
|
||||
|
||||
static char focus_desc[] = SANE_I18N(
|
||||
"Focus point for scanning.");
|
||||
|
||||
/* ranges */
|
||||
static const SANE_Range x_range_fb =
|
||||
{
|
||||
|
@ -174,6 +187,16 @@ static const SANE_Range y_range_tpo_2580 =
|
|||
SANE_FIX (0.0), SANE_FIX (80.0), 0
|
||||
}; /* mm */
|
||||
|
||||
/* TPO range for the Scanwit 2720S */
|
||||
static const SANE_Range x_range_tpo_2720s =
|
||||
{
|
||||
SANE_FIX (0.0), SANE_FIX (23.6), 0
|
||||
}; /* mm */
|
||||
static const SANE_Range y_range_tpo_2720s =
|
||||
{
|
||||
SANE_FIX (0.0), SANE_FIX (35.7), 0
|
||||
}; /* mm */
|
||||
|
||||
/* TPO range for the Epson 3490 */
|
||||
static const SANE_Range x_range_tpo_3490 =
|
||||
{
|
||||
|
@ -198,6 +221,14 @@ static const SANE_Range lpr_range =
|
|||
{
|
||||
1, 50, 1
|
||||
};
|
||||
static const SANE_Range frame_range =
|
||||
{
|
||||
1, 6, 1
|
||||
};
|
||||
static const SANE_Range focus_range =
|
||||
{
|
||||
0, 0x300, 6
|
||||
};
|
||||
|
||||
static const SANE_Range brightness_range =
|
||||
{
|
||||
|
@ -243,6 +274,8 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
{10, 50, 75, 100, 150, 200, 300, 400, 600, 800, 1600};
|
||||
static SANE_Word resolutions_2400[] =
|
||||
{10, 50, 75, 100, 150, 200, 300, 400, 600, 1200, 2400};
|
||||
static SANE_Word resolutions_2700[] =
|
||||
{4, 337, 675, 1350, 2700};
|
||||
static SANE_Word resolutions_3200[] =
|
||||
{15, 50, 150, 200, 240, 266, 300, 350, 360, 400, 600, 720, 800, 1200, 1600, 3200};
|
||||
static SANE_String_Const names_all[] =
|
||||
|
@ -253,6 +286,8 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
{md_auto, md_colour, md_bilevelcolour, md_greyscale, md_lineart, NULL};
|
||||
static SANE_String_Const preview_names_basic[] =
|
||||
{md_auto, md_colour, md_greyscale, md_lineart, NULL};
|
||||
static SANE_String_Const focus_modes[] =
|
||||
{md_auto, md_manual, NULL};
|
||||
static SANE_Int bit_depth_list[4];
|
||||
int bit_depths;
|
||||
SANE_Option_Descriptor *po = ps->options;
|
||||
|
@ -287,6 +322,10 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
y_range_tpo = y_range_tpo_2480;
|
||||
}
|
||||
break;
|
||||
case SCANWIT2720S:
|
||||
x_range_tpo = x_range_tpo_2720s;
|
||||
y_range_tpo = y_range_tpo_2720s;
|
||||
break;
|
||||
case PERFECTION3490:
|
||||
x_range_tpo = x_range_tpo_3490;
|
||||
y_range_tpo = y_range_tpo_3490;
|
||||
|
@ -318,6 +357,7 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
po[OPT_MODE_GROUP].cap = 0;
|
||||
po[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
ps->res = DEFAULT_RES;
|
||||
po[OPT_SCANRES].name = SANE_NAME_SCAN_RESOLUTION;
|
||||
po[OPT_SCANRES].title = SANE_TITLE_SCAN_RESOLUTION;
|
||||
po[OPT_SCANRES].desc = SANE_DESC_SCAN_RESOLUTION;
|
||||
|
@ -354,11 +394,17 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
case PERFECTION3490:
|
||||
po[OPT_SCANRES].constraint.word_list = resolutions_3200;
|
||||
break;
|
||||
case SCANWIT2720S:
|
||||
po[OPT_SCANRES].constraint.word_list = resolutions_2700;
|
||||
ps->val[OPT_SCANRES].w = 1350;
|
||||
ps->res = 1350;
|
||||
break;
|
||||
default:
|
||||
po[OPT_SCANRES].constraint.word_list = resolutions_600;
|
||||
break;
|
||||
}
|
||||
ps->res = DEFAULT_RES;
|
||||
DBG (DL_OPTION_TRACE,
|
||||
"sane_init_options resolution is %d\n", ps->res);
|
||||
|
||||
po[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
|
||||
po[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
|
||||
|
@ -464,7 +510,7 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
po[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
|
||||
po[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
|
||||
po[OPT_SOURCE].type = SANE_TYPE_STRING;
|
||||
po[OPT_SOURCE].cap = SANE_CAP_SOFT_SELECT
|
||||
po[OPT_SOURCE].cap = SANE_CAP_SOFT_SELECT
|
||||
| SANE_CAP_SOFT_DETECT
|
||||
| SANE_CAP_INACTIVE
|
||||
| SANE_CAP_AUTOMATIC;
|
||||
|
@ -483,12 +529,22 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
{
|
||||
source_list[i++] = src_adf;
|
||||
po[OPT_SOURCE].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
source_list[i] = 0;
|
||||
po[OPT_SOURCE].size = max_string_size(source_list);
|
||||
po[OPT_SOURCE].constraint.string_list = source_list;
|
||||
ps->source = SRC_FLATBED;
|
||||
ps->source_s = (SANE_Char *) strdup(src_flatbed);
|
||||
if (ps->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
ps->source = SRC_TPO;
|
||||
ps->source_s = (SANE_Char *) strdup(src_tpo);
|
||||
ps->pdev->x_range.max = x_range_tpo.max;
|
||||
ps->pdev->y_range.max = y_range_tpo.max;
|
||||
}
|
||||
else
|
||||
{
|
||||
ps->source = SRC_FLATBED;
|
||||
ps->source_s = (SANE_Char *) strdup(src_flatbed);
|
||||
}
|
||||
}
|
||||
|
||||
po[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
|
||||
|
@ -564,13 +620,13 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
po[OPT_ENHANCEMENT_GROUP].cap = 0;
|
||||
po[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
/* bit depth */
|
||||
/* bit depth */
|
||||
po[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
|
||||
po[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
|
||||
po[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
|
||||
po[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
|
||||
po[OPT_BIT_DEPTH].unit = SANE_UNIT_BIT;
|
||||
po[OPT_BIT_DEPTH].size = sizeof (SANE_Word);
|
||||
po[OPT_BIT_DEPTH].size = sizeof (SANE_Word);
|
||||
po[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
|
||||
po[OPT_BIT_DEPTH].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
||||
bit_depths = 0;
|
||||
|
@ -581,13 +637,25 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
case PERFECTION3490:
|
||||
bit_depth_list[++bit_depths] = 16;
|
||||
break;
|
||||
case SCANWIT2720S:
|
||||
bit_depth_list[bit_depths] = 12;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
bit_depth_list[0] = bit_depths;
|
||||
po[OPT_BIT_DEPTH].constraint.word_list = bit_depth_list;
|
||||
ps->val[OPT_BIT_DEPTH].w = def_bpp;
|
||||
|
||||
if (ps->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
ps->val[OPT_BIT_DEPTH].w = 12;
|
||||
ps->bpp_scan = 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
ps->val[OPT_BIT_DEPTH].w = def_bpp;
|
||||
ps->bpp_scan = def_bpp;
|
||||
}
|
||||
|
||||
po[OPT_QUALITY_CAL].name = SANE_NAME_QUALITY_CAL;
|
||||
po[OPT_QUALITY_CAL].title = SANE_TITLE_QUALITY_CAL;
|
||||
po[OPT_QUALITY_CAL].desc = SANE_DESC_QUALITY_CAL;
|
||||
|
@ -813,6 +881,45 @@ static void init_options (SnapScan_Scanner * ps)
|
|||
po[OPT_THRESHOLD].constraint.range = &positive_percent_range;
|
||||
ps->threshold = DEFAULT_THRESHOLD;
|
||||
|
||||
po[OPT_FRAME_NO].name = SANE_I18N("Frame");
|
||||
po[OPT_FRAME_NO].title = SANE_I18N("Frame to be scanned");
|
||||
po[OPT_FRAME_NO].desc = frame_desc;
|
||||
po[OPT_FRAME_NO].type = SANE_TYPE_INT;
|
||||
po[OPT_FRAME_NO].unit = SANE_UNIT_NONE;
|
||||
po[OPT_FRAME_NO].size = sizeof (SANE_Int);
|
||||
po[OPT_FRAME_NO].cap = SANE_CAP_SOFT_SELECT
|
||||
| SANE_CAP_SOFT_DETECT
|
||||
| SANE_CAP_INACTIVE;
|
||||
po[OPT_FRAME_NO].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
po[OPT_FRAME_NO].constraint.range = &frame_range;
|
||||
ps->frame_no = def_frame_no;
|
||||
|
||||
po[OPT_FOCUS_MODE].name = SANE_I18N("Focus-mode");
|
||||
po[OPT_FOCUS_MODE].title = SANE_I18N("Auto or manual focus");
|
||||
po[OPT_FOCUS_MODE].desc = focus_mode_desc;
|
||||
po[OPT_FOCUS_MODE].type = SANE_TYPE_STRING;
|
||||
po[OPT_FOCUS_MODE].unit = SANE_UNIT_NONE;
|
||||
po[OPT_FOCUS_MODE].size = 16;
|
||||
po[OPT_FOCUS_MODE].cap = SANE_CAP_SOFT_SELECT
|
||||
| SANE_CAP_SOFT_DETECT
|
||||
| SANE_CAP_INACTIVE;
|
||||
po[OPT_FOCUS_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||
po[OPT_FOCUS_MODE].constraint.string_list = focus_modes;
|
||||
ps->focus_mode_s= md_auto;
|
||||
ps->focus_mode = MD_AUTO;
|
||||
|
||||
po[OPT_FOCUS_POINT].name = SANE_I18N("Focus-point");
|
||||
po[OPT_FOCUS_POINT].title = SANE_I18N("Focus point");
|
||||
po[OPT_FOCUS_POINT].desc = focus_desc;
|
||||
po[OPT_FOCUS_POINT].type = SANE_TYPE_INT;
|
||||
po[OPT_FOCUS_POINT].unit = SANE_UNIT_NONE;
|
||||
po[OPT_FOCUS_POINT].size = sizeof (SANE_Int);
|
||||
po[OPT_FOCUS_POINT].cap = SANE_CAP_SOFT_SELECT
|
||||
| SANE_CAP_SOFT_DETECT
|
||||
| SANE_CAP_INACTIVE;
|
||||
po[OPT_FOCUS_POINT].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
po[OPT_FOCUS_POINT].constraint.range = &focus_range;
|
||||
|
||||
po[OPT_ADVANCED_GROUP].title = SANE_I18N("Advanced");
|
||||
po[OPT_ADVANCED_GROUP].desc = "";
|
||||
po[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
|
||||
|
@ -878,7 +985,7 @@ static void control_options(SnapScan_Scanner *pss)
|
|||
pss->options[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
|
||||
pss->options[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
|
||||
pss->options[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
||||
|
||||
|
||||
if ((pss->mode == MD_COLOUR) ||
|
||||
((pss->mode == MD_BILEVELCOLOUR) && (pss->hconfig & HCFG_HT) &&
|
||||
pss->halftone))
|
||||
|
@ -942,7 +1049,16 @@ static void control_options(SnapScan_Scanner *pss)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
pss->options[OPT_FRAME_NO].cap &= ~SANE_CAP_INACTIVE;
|
||||
pss->options[OPT_FOCUS_MODE].cap &= ~SANE_CAP_INACTIVE;
|
||||
if (pss->focus_mode == MD_MANUAL)
|
||||
{
|
||||
pss->options[OPT_FOCUS_POINT].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SANE_Status sane_control_option (SANE_Handle h,
|
||||
|
@ -1080,7 +1196,16 @@ SANE_Status sane_control_option (SANE_Handle h,
|
|||
break;
|
||||
case OPT_BIT_DEPTH:
|
||||
*(SANE_Int *) v = pss->val[OPT_BIT_DEPTH].w;
|
||||
break;
|
||||
break;
|
||||
case OPT_FRAME_NO:
|
||||
*(SANE_Int *) v = pss->frame_no;
|
||||
break;
|
||||
case OPT_FOCUS_MODE:
|
||||
strcpy ((SANE_String) v, pss->focus_mode_s);
|
||||
break;
|
||||
case OPT_FOCUS_POINT:
|
||||
*(SANE_Int *) v = pss->focus;
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: invalid option number %ld\n",
|
||||
|
@ -1495,6 +1620,31 @@ SANE_Status sane_control_option (SANE_Handle h,
|
|||
if (i)
|
||||
*i |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
case OPT_FRAME_NO:
|
||||
pss->frame_no = *(SANE_Int *) v;
|
||||
break;
|
||||
case OPT_FOCUS_MODE:
|
||||
{
|
||||
char *s = (SANE_String) v;
|
||||
if (strcmp (s, md_manual) == 0)
|
||||
{
|
||||
pss->focus_mode_s = md_manual;
|
||||
pss->focus_mode = MD_MANUAL;
|
||||
pss->options[OPT_FOCUS_POINT].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pss->focus_mode_s = md_auto;
|
||||
pss->focus_mode = MD_AUTO;
|
||||
pss->options[OPT_FOCUS_POINT].cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
if (i)
|
||||
*i = SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
}
|
||||
case OPT_FOCUS_POINT:
|
||||
pss->focus = *(SANE_Int *) v;
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: invalid option number %ld\n",
|
||||
|
@ -1526,7 +1676,14 @@ SANE_Status sane_control_option (SANE_Handle h,
|
|||
switch (n)
|
||||
{
|
||||
case OPT_SCANRES:
|
||||
pss->res = 300;
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
pss->res = 1350;
|
||||
}
|
||||
else
|
||||
{
|
||||
pss->res = 300;
|
||||
}
|
||||
if (i)
|
||||
*i |= SANE_INFO_RELOAD_PARAMS;
|
||||
break;
|
||||
|
@ -1558,13 +1715,26 @@ SANE_Status sane_control_option (SANE_Handle h,
|
|||
pss->preview_mode = MD_GREYSCALE;
|
||||
break;
|
||||
case OPT_SOURCE:
|
||||
pss->source = SRC_FLATBED;
|
||||
pss->pdev->x_range.max = x_range_fb.max;
|
||||
pss->pdev->y_range.max = y_range_fb.max;
|
||||
pss->predef_window = pdw_none;
|
||||
if (pss->source_s)
|
||||
free (pss->source_s);
|
||||
pss->source_s = (SANE_Char *) strdup(src_flatbed);
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
pss->source = SRC_TPO;
|
||||
pss->pdev->x_range.max = x_range_tpo.max;
|
||||
pss->pdev->y_range.max = y_range_tpo.max;
|
||||
pss->predef_window = pdw_none;
|
||||
if (pss->source_s)
|
||||
free (pss->source_s);
|
||||
pss->source_s = (SANE_Char *) strdup(src_tpo);
|
||||
}
|
||||
else
|
||||
{
|
||||
pss->source = SRC_FLATBED;
|
||||
pss->pdev->x_range.max = x_range_fb.max;
|
||||
pss->pdev->y_range.max = y_range_fb.max;
|
||||
pss->predef_window = pdw_none;
|
||||
if (pss->source_s)
|
||||
free (pss->source_s);
|
||||
pss->source_s = (SANE_Char *) strdup(src_flatbed);
|
||||
}
|
||||
if (i)
|
||||
*i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
|
@ -1598,7 +1768,26 @@ SANE_Status sane_control_option (SANE_Handle h,
|
|||
pss->gs_lpr = def_gs_lpr;
|
||||
break;
|
||||
case OPT_BIT_DEPTH:
|
||||
pss->val[OPT_BIT_DEPTH].w = def_bpp;
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
pss->val[OPT_BIT_DEPTH].w = 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
pss->val[OPT_BIT_DEPTH].w = def_bpp;
|
||||
}
|
||||
break;
|
||||
case OPT_FRAME_NO:
|
||||
pss->frame_no = def_frame_no;
|
||||
break;
|
||||
case OPT_FOCUS_MODE:
|
||||
pss->focus_mode_s = md_auto;
|
||||
pss->focus_mode = MD_AUTO;
|
||||
if (i)
|
||||
*i = SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
case OPT_FOCUS_POINT:
|
||||
pss->focus = 0x13e;
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Copyright (C) 1997, 1998, 2001, 2002, 2013 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
|
||||
Oliver Schwartz and Kevin Charter
|
||||
Max Ushakov, Andrew Goodbody, Oliver Schwartz and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
|
@ -289,6 +289,7 @@ static SANE_Status snapscan_cmd(SnapScan_Bus bus, int fd, const void *src,
|
|||
#define RESERVE_UNIT 0x16
|
||||
#define RELEASE_UNIT 0x17
|
||||
#define SEND_DIAGNOSTIC 0x1D
|
||||
#define OBJECT_POSITION 0x31
|
||||
#define GET_DATA_BUFFER_STATUS 0x34
|
||||
|
||||
#define SCAN_LEN 6
|
||||
|
@ -561,6 +562,7 @@ static SANE_Status inquiry (SnapScan_Scanner *pss)
|
|||
pss->bpp = 14;
|
||||
break;
|
||||
case STYLUS_CX1500:
|
||||
case SCANWIT2720S:
|
||||
pss->bpp = 12;
|
||||
break;
|
||||
default:
|
||||
|
@ -674,6 +676,10 @@ static void release_unit (SnapScan_Scanner *pss)
|
|||
#define DTCQ_GAMMA_RED14 0x96
|
||||
#define DTCQ_GAMMA_GREEN14 0x97
|
||||
#define DTCQ_GAMMA_BLUE14 0x98
|
||||
#define DTCQ_GAMMA_GRAY12_16BIT 0xa0
|
||||
#define DTCQ_GAMMA_RED12_16BIT 0xa1
|
||||
#define DTCQ_GAMMA_GREEN12_16BIT 0xa2
|
||||
#define DTCQ_GAMMA_BLUE12_16BIT 0xa3
|
||||
#define DTCQ_GAMMA_GRAY14_16BIT 0xa5 /* ? */
|
||||
#define DTCQ_GAMMA_RED14_16BIT 0xa6
|
||||
#define DTCQ_GAMMA_GREEN14_16BIT 0xa7
|
||||
|
@ -734,6 +740,12 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
|
|||
case DTCQ_GAMMA_BLUE12:
|
||||
tl = 4096;
|
||||
break;
|
||||
case DTCQ_GAMMA_GRAY12_16BIT: /* 12-bit tables with 16 bit data */
|
||||
case DTCQ_GAMMA_RED12_16BIT:
|
||||
case DTCQ_GAMMA_GREEN12_16BIT:
|
||||
case DTCQ_GAMMA_BLUE12_16BIT:
|
||||
tl = 8192;
|
||||
break;
|
||||
case DTCQ_GAMMA_GRAY14: /* 14-bit tables */
|
||||
case DTCQ_GAMMA_RED14:
|
||||
case DTCQ_GAMMA_GREEN14:
|
||||
|
@ -832,13 +844,10 @@ static SANE_Status send_calibration_5150(SnapScan_Scanner *pss)
|
|||
#define SET_WINDOW_P_BLUE_UNDER_COLOR 45
|
||||
#define SET_WINDOW_P_GREEN_UNDER_COLOR 44
|
||||
|
||||
static SANE_Status set_window (SnapScan_Scanner *pss)
|
||||
static SANE_Status prepare_set_window (SnapScan_Scanner *pss)
|
||||
{
|
||||
static const char *me = "set_window";
|
||||
SANE_Status status;
|
||||
unsigned char source;
|
||||
static const char *me = "prepare_set_window";
|
||||
u_char *pc;
|
||||
int pos_factor;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
|
||||
|
@ -860,62 +869,11 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
u_short_to_u_charp (pss->res, pc + SET_WINDOW_P_YRES);
|
||||
DBG (DL_CALL_TRACE, "%s Resolution: %d\n", me, pss->res);
|
||||
|
||||
switch (pss->pdev->model)
|
||||
{
|
||||
case PRISA5000:
|
||||
case PRISA5000E:
|
||||
case PRISA5150:
|
||||
pos_factor = (pss->res > 600) ? 1200 : 600;
|
||||
break;
|
||||
case PERFECTION1270:
|
||||
case PERFECTION1670:
|
||||
pos_factor = (pss->res > 800) ? 1600 : 800;
|
||||
break;
|
||||
case PERFECTION2480:
|
||||
pos_factor = (pss->res > 1200) ? 2400 : 1200;
|
||||
break;
|
||||
case PERFECTION3490:
|
||||
pos_factor = (pss->res > 1600) ? 3200 : 1600;
|
||||
break;
|
||||
default:
|
||||
pos_factor = pss->actual_res;
|
||||
break;
|
||||
}
|
||||
/* it's an ugly sound if the scanner drives against the rear
|
||||
wall, and with changing max values we better be sure */
|
||||
check_range(&(pss->brx), pss->pdev->x_range);
|
||||
check_range(&(pss->bry), pss->pdev->y_range);
|
||||
{
|
||||
int tlxp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->tlx));
|
||||
int tlyp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->tly));
|
||||
int brxp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->brx));
|
||||
int bryp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->bry));
|
||||
|
||||
/* Check for brx > tlx and bry > tly */
|
||||
if (brxp <= tlxp) {
|
||||
tlxp = MAX (0, brxp - 75);
|
||||
}
|
||||
if (bryp <= tlyp) {
|
||||
tlyp = MAX (0, bryp - 75);
|
||||
}
|
||||
|
||||
u_int_to_u_char4p (tlxp, pc + SET_WINDOW_P_TLX);
|
||||
u_int_to_u_char4p (tlyp, pc + SET_WINDOW_P_TLY);
|
||||
u_int_to_u_char4p (MAX (((unsigned) (brxp - tlxp)), 75),
|
||||
pc + SET_WINDOW_P_WIDTH);
|
||||
u_int_to_u_char4p (MAX (((unsigned) (bryp - tlyp)), 75),
|
||||
pc + SET_WINDOW_P_LENGTH);
|
||||
DBG (DL_INFO, "%s Width: %d\n", me, brxp-tlxp);
|
||||
DBG (DL_INFO, "%s Length: %d\n", me, bryp-tlyp);
|
||||
}
|
||||
pc[SET_WINDOW_P_BRIGHTNESS] = 128;
|
||||
pc[SET_WINDOW_P_THRESHOLD] =
|
||||
(u_char) (255.0*(pss->threshold / 100.0));
|
||||
pc[SET_WINDOW_P_CONTRAST] = 128;
|
||||
|
||||
{
|
||||
SnapScan_Mode mode = pss->mode;
|
||||
pss->bpp_scan = pss->val[OPT_BIT_DEPTH].w;
|
||||
|
@ -923,9 +881,10 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
if (pss->preview)
|
||||
{
|
||||
mode = pss->preview_mode;
|
||||
pss->bpp_scan = 8;
|
||||
if (pss->pdev->model != SCANWIT2720S)
|
||||
pss->bpp_scan = 8;
|
||||
}
|
||||
|
||||
|
||||
DBG (DL_MINOR_INFO, "%s Mode: %d\n", me, mode);
|
||||
switch (mode)
|
||||
{
|
||||
|
@ -982,6 +941,87 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded gamma table */
|
||||
}
|
||||
}
|
||||
|
||||
pc[SET_WINDOW_P_RED_UNDER_COLOR] = 0xff; /* defaults */
|
||||
pc[SET_WINDOW_P_BLUE_UNDER_COLOR] = 0xff;
|
||||
pc[SET_WINDOW_P_GREEN_UNDER_COLOR] = 0xff;
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status set_window (SnapScan_Scanner *pss)
|
||||
{
|
||||
static const char *me = "set_window";
|
||||
SANE_Status status;
|
||||
unsigned char source;
|
||||
u_char *pc;
|
||||
int pos_factor;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = prepare_set_window(pss);
|
||||
CHECK_STATUS (status, me, "prepare_set_window");
|
||||
|
||||
pc = pss->cmd;
|
||||
|
||||
/* header; we support only one window */
|
||||
pc += SET_WINDOW_LEN;
|
||||
|
||||
/* the sole window descriptor */
|
||||
pc += SET_WINDOW_HEADER_LEN;
|
||||
|
||||
switch (pss->pdev->model)
|
||||
{
|
||||
case PRISA5000:
|
||||
case PRISA5000E:
|
||||
case PRISA5150:
|
||||
pos_factor = (pss->res > 600) ? 1200 : 600;
|
||||
break;
|
||||
case PERFECTION1270:
|
||||
case PERFECTION1670:
|
||||
pos_factor = (pss->res > 800) ? 1600 : 800;
|
||||
break;
|
||||
case PERFECTION2480:
|
||||
pos_factor = (pss->res > 1200) ? 2400 : 1200;
|
||||
break;
|
||||
case PERFECTION3490:
|
||||
pos_factor = (pss->res > 1600) ? 3200 : 1600;
|
||||
break;
|
||||
default:
|
||||
pos_factor = pss->actual_res;
|
||||
break;
|
||||
}
|
||||
/* it's an ugly sound if the scanner drives against the rear
|
||||
wall, and with changing max values we better be sure */
|
||||
check_range(&(pss->brx), pss->pdev->x_range);
|
||||
check_range(&(pss->bry), pss->pdev->y_range);
|
||||
{
|
||||
int tlxp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->tlx));
|
||||
int tlyp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->tly));
|
||||
int brxp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->brx));
|
||||
int bryp =
|
||||
(int) (pos_factor*IN_PER_MM*SANE_UNFIX(pss->bry));
|
||||
|
||||
/* Check for brx > tlx and bry > tly */
|
||||
if (brxp <= tlxp) {
|
||||
tlxp = MAX (0, brxp - 75);
|
||||
}
|
||||
if (bryp <= tlyp) {
|
||||
tlyp = MAX (0, bryp - 75);
|
||||
}
|
||||
|
||||
u_int_to_u_char4p (tlxp, pc + SET_WINDOW_P_TLX);
|
||||
u_int_to_u_char4p (tlyp, pc + SET_WINDOW_P_TLY);
|
||||
u_int_to_u_char4p (MAX (((unsigned) (brxp - tlxp)), 75),
|
||||
pc + SET_WINDOW_P_WIDTH);
|
||||
u_int_to_u_char4p (MAX (((unsigned) (bryp - tlyp)), 75),
|
||||
pc + SET_WINDOW_P_LENGTH);
|
||||
DBG (DL_INFO, "%s Width: %d\n", me, brxp-tlxp);
|
||||
DBG (DL_INFO, "%s Length: %d\n", me, bryp-tlyp);
|
||||
}
|
||||
|
||||
source = 0x0;
|
||||
if (pss->preview) {
|
||||
source |= 0x80; /* no high quality in preview */
|
||||
|
@ -1003,9 +1043,6 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
}
|
||||
pc[SET_WINDOW_P_OPERATION_MODE] = source;
|
||||
DBG (DL_MINOR_INFO, "%s: operation mode set to 0x%02x\n", me, (int) source);
|
||||
pc[SET_WINDOW_P_RED_UNDER_COLOR] = 0xff; /* defaults */
|
||||
pc[SET_WINDOW_P_BLUE_UNDER_COLOR] = 0xff;
|
||||
pc[SET_WINDOW_P_GREEN_UNDER_COLOR] = 0xff;
|
||||
|
||||
do {
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
|
||||
|
@ -1020,6 +1057,90 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
return status;
|
||||
}
|
||||
|
||||
static SANE_Status set_window_autofocus (SnapScan_Scanner *copy)
|
||||
{
|
||||
static char me[] = "set_window_autofocus";
|
||||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%p)\n", me, (void*)copy);
|
||||
|
||||
copy->res = copy->actual_res;
|
||||
status = prepare_set_window (copy);
|
||||
CHECK_STATUS (status, me, "prepare_set_window");
|
||||
|
||||
u_int_to_u_char4p (1700, copy->cmd + SET_WINDOW_DESC + SET_WINDOW_P_TLY);
|
||||
/* fill in width & height */
|
||||
u_int_to_u_char4p (2550, copy->cmd + SET_WINDOW_DESC + SET_WINDOW_P_WIDTH);
|
||||
u_int_to_u_char4p (128, copy->cmd + SET_WINDOW_DESC + SET_WINDOW_P_LENGTH);
|
||||
|
||||
copy->cmd[SET_WINDOW_DESC + SET_WINDOW_P_BITS_PER_PIX] = 12;
|
||||
copy->cmd[SET_WINDOW_DESC + SET_WINDOW_P_OPERATION_MODE] = 0x49; /* focusing mode */
|
||||
return snapscan_cmd (copy->pdev->bus, copy->fd, copy->cmd,
|
||||
SET_WINDOW_TOTAL_LEN, NULL, NULL);
|
||||
}
|
||||
|
||||
#define SET_FRAME_LEN 10
|
||||
|
||||
static SANE_Status set_frame (SnapScan_Scanner *pss, SANE_Byte frame_no)
|
||||
{
|
||||
static const char *me = "set_frame";
|
||||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
DBG (DL_VERBOSE, "%s setting frame to %d\n", me, frame_no);
|
||||
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
|
||||
pss->cmd[0] = OBJECT_POSITION;
|
||||
pss->cmd[1] = 2; /* Absolute position used here to select the frame */
|
||||
pss->cmd[4] = frame_no;
|
||||
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd, SET_FRAME_LEN, NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static SANE_Status set_focus (SnapScan_Scanner *pss, SANE_Int focus)
|
||||
{
|
||||
static const char *me = "set_focus";
|
||||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d)\n", me, focus);
|
||||
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
|
||||
pss->cmd[0] = OBJECT_POSITION;
|
||||
pss->cmd[1] = 4; /* Rotate object but here it sets the focus point */
|
||||
pss->cmd[3] = (focus >> 8) & 0xFF;
|
||||
pss->cmd[4] = focus & 0xFF;
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd, SET_FRAME_LEN, NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
static SANE_Int get_8 (u_char *p)
|
||||
{
|
||||
SANE_Int b;
|
||||
b = p[0] | (p[1] << 8);
|
||||
return b;
|
||||
}
|
||||
|
||||
static double get_val (u_char *p, SANE_Int len, SANE_Int x)
|
||||
{
|
||||
return get_8 (p + ((x + len) << 1)) / 255.0;
|
||||
}
|
||||
|
||||
static double sum_pixel_differences (u_char *p, int len)
|
||||
{
|
||||
double v, m, s;
|
||||
SANE_Int i;
|
||||
|
||||
s = 0;
|
||||
for (i = 0; i < len-1; i++) {
|
||||
v = get_val (p, len, i);
|
||||
m = get_val (p, len, i+1);
|
||||
s += fabs (v - m);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static SANE_Status scan (SnapScan_Scanner *pss)
|
||||
{
|
||||
static const char *me = "scan";
|
||||
|
@ -1061,6 +1182,60 @@ static SANE_Status scsi_read (SnapScan_Scanner *pss, u_char read_type)
|
|||
return status;
|
||||
}
|
||||
|
||||
static SANE_Status get_focus (SnapScan_Scanner *pss)
|
||||
{
|
||||
static const char *me = "get_focus";
|
||||
SANE_Int focus_point, max_focus_point;
|
||||
double sum, max;
|
||||
SANE_Status status;
|
||||
SnapScan_Scanner copy;
|
||||
|
||||
copy = *pss;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
reserve_unit(©);
|
||||
|
||||
status = set_window_autofocus (©);
|
||||
CHECK_STATUS (status, me, "set_window_autofocus");
|
||||
|
||||
status = inquiry (©);
|
||||
CHECK_STATUS (status, me, "inquiry");
|
||||
|
||||
status = scan (©);
|
||||
CHECK_STATUS (status, me, "scan");
|
||||
|
||||
status = set_frame (©, copy.frame_no);
|
||||
CHECK_STATUS (status, me, "set_frame");
|
||||
|
||||
DBG (DL_VERBOSE, "%s: Expected number of bytes for each read %d\n", me, (int)copy.bytes_per_line);
|
||||
DBG (DL_VERBOSE, "%s: Expected number of pixels per line %d\n", me, (int)copy.pixels_per_line);
|
||||
max_focus_point = -1;
|
||||
max = -1;
|
||||
for (focus_point = 0; focus_point <= 0x300; focus_point += 6) {
|
||||
status = set_focus (©, focus_point);
|
||||
CHECK_STATUS (status, me, "set_focus");
|
||||
|
||||
copy.expected_read_bytes = copy.bytes_per_line;
|
||||
status = scsi_read (©, READ_IMAGE);
|
||||
CHECK_STATUS (status, me, "scsi_read");
|
||||
|
||||
sum = sum_pixel_differences (copy.buf, copy.pixels_per_line);
|
||||
|
||||
if (sum > max) {
|
||||
max = sum;
|
||||
max_focus_point = focus_point;
|
||||
}
|
||||
}
|
||||
pss->focus = max_focus_point;
|
||||
DBG (DL_VERBOSE, "%s: Focus point found to be at 0x%x\n", me, max_focus_point);
|
||||
release_unit (©);
|
||||
|
||||
wait_scanner_ready (©);
|
||||
CHECK_STATUS (status, me, "wait_scanner_ready");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
static SANE_Status request_sense (SnapScan_Scanner *pss)
|
||||
{
|
||||
|
@ -1100,6 +1275,8 @@ static SANE_Status send_diagnostic (SnapScan_Scanner *pss)
|
|||
||
|
||||
pss->pdev->model == SNAPSCAN1236
|
||||
||
|
||||
pss->pdev->model == SCANWIT2720S
|
||||
||
|
||||
pss->pdev->model == ARCUS1200)
|
||||
{
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -1373,12 +1550,14 @@ static SANE_Status calibrate (SnapScan_Scanner *pss)
|
|||
(pss->pdev->model == PERFECTION3490)) {
|
||||
return calibrate_epson (pss);
|
||||
}
|
||||
|
||||
|
||||
if (pss->pdev->model == PRISA5150)
|
||||
{
|
||||
return send_calibration_5150(pss);
|
||||
return send_calibration_5150(pss);
|
||||
}
|
||||
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
|
||||
if (line_length) {
|
||||
int num_lines = pss->phys_buf_sz / line_length;
|
||||
if (num_lines > NUM_CALIBRATION_LINES)
|
||||
|
@ -1425,7 +1604,6 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss)
|
|||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
char cModelName[8], cModel[255];
|
||||
unsigned char bModelNo;
|
||||
int readByte;
|
||||
|
||||
bModelNo =*(pss->buf + INQUIRY_HWMI);
|
||||
zero_buf((unsigned char *)cModel, 255);
|
||||
|
@ -1512,7 +1690,7 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss)
|
|||
pCDB = (unsigned char *)malloc(bufLength + cdbLength);
|
||||
pFwBuf = pCDB + cdbLength;
|
||||
zero_buf (pCDB, cdbLength);
|
||||
readByte = fread(pFwBuf,1,bufLength,fd);
|
||||
(void)fread(pFwBuf,1,bufLength,fd);
|
||||
|
||||
*pCDB = SEND;
|
||||
*(pCDB + 2) = 0x87;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
Copyright (C) 1997, 1998, 2002, 2013 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Oliver Schwartz
|
||||
and Kevin Charter
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Max Ushakov,
|
||||
Andrew Goodbody, Oliver Schwartz and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -932,6 +932,13 @@ typedef struct
|
|||
SANE_Int round_read;
|
||||
} RGBRouter;
|
||||
|
||||
static void put_int16r (int n, u_char *p)
|
||||
{
|
||||
p[0] = (n & 0x00ff);
|
||||
p[1] = (n & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Int RGBRouter_remaining (Source *pself)
|
||||
{
|
||||
RGBRouter *ps = (RGBRouter *) pself;
|
||||
|
@ -951,7 +958,7 @@ static SANE_Status RGBRouter_get (Source *pself,
|
|||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Int remaining = *plen;
|
||||
SANE_Byte *s;
|
||||
SANE_Int i;
|
||||
SANE_Int i, t;
|
||||
SANE_Int r, g, b;
|
||||
SANE_Int run_req;
|
||||
SANE_Int org_len = *plen;
|
||||
|
@ -998,6 +1005,22 @@ static SANE_Status RGBRouter_get (Source *pself,
|
|||
*s++ = ps->cbuf[g++];
|
||||
*s++ = ps->cbuf[b++];
|
||||
}
|
||||
else if (pself->pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
t = (((ps->cbuf[r+1] << 8) | ps->cbuf[r]) & 0xfff) << 4;
|
||||
put_int16r (t, s);
|
||||
s += 2;
|
||||
r += 2;
|
||||
t = (((ps->cbuf[g+1] << 8) | ps->cbuf[g]) & 0xfff) << 4;
|
||||
put_int16r (t, s);
|
||||
s += 2;
|
||||
g += 2;
|
||||
t = (((ps->cbuf[b+1] << 8) | ps->cbuf[b]) & 0xfff) << 4;
|
||||
put_int16r (t, s);
|
||||
s += 2;
|
||||
b += 2;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*s++ = ps->cbuf[r++];
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997-2005 Franck Schnefra, Michel Roelofs, Emmanuel Blot,
|
||||
Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller, Simon Munton,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
|
||||
Oliver Schwartz and Kevin Charter
|
||||
Copyright (C) 1997-2005, 2013 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Simon Munton, Petter Reinholdtsen, Gary Plewa, Sebastien Sable,
|
||||
Mikael Magnusson, Max Ushakov, Andrew Goodbody, Oliver Schwartz
|
||||
and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -133,6 +134,10 @@ if ((s) != SANE_STATUS_GOOD) { DBG(DL_MAJOR_ERROR, "%s: %s command failed: %s\n"
|
|||
#define MM_PER_IN 25.4 /* # millimetres per inch */
|
||||
#define IN_PER_MM 0.03937 /* # inches per millimetre */
|
||||
|
||||
#define GAMMA_8BIT 0
|
||||
#define GAMMA_16BIT 1
|
||||
#define GAMMA_12_16BIT 2
|
||||
|
||||
#ifndef SANE_I18N
|
||||
#define SANE_I18N(text) text
|
||||
#endif
|
||||
|
@ -147,7 +152,7 @@ static SANE_Char password[SANE_MAX_PASSWORD_LEN];
|
|||
/* function prototypes */
|
||||
|
||||
static void gamma_n (double gamma, int brightness, int contrast,
|
||||
u_char *buf, int length, int gamma_16bit);
|
||||
u_char *buf, int length, int gamma_mode);
|
||||
static void gamma_to_sane (int length, u_char *in, SANE_Int *out);
|
||||
|
||||
static size_t max_string_size(SANE_String_Const strings[]);
|
||||
|
@ -181,11 +186,16 @@ static inline int calibration_line_length(SnapScan_Scanner *pss)
|
|||
case PERFECTION2480:
|
||||
case PERFECTION3490:
|
||||
pos_factor = pss->actual_res / 2;
|
||||
pixel_length = pos_factor * 8.5;
|
||||
break;
|
||||
case SCANWIT2720S:
|
||||
pixel_length = 2550;
|
||||
break;
|
||||
default:
|
||||
pos_factor = pss->actual_res;
|
||||
pixel_length = pos_factor * 8.5;
|
||||
break;
|
||||
}
|
||||
pixel_length = pos_factor * 8.5;
|
||||
|
||||
if(is_colour_mode(actual_mode(pss))) {
|
||||
return 3 * pixel_length;
|
||||
|
@ -285,7 +295,7 @@ static size_t max_string_size (SANE_String_Const strings[])
|
|||
|
||||
/* gamma table computation */
|
||||
static void gamma_n (double gamma, int brightness, int contrast,
|
||||
u_char *buf, int bpp, int gamma_16bit)
|
||||
u_char *buf, int bpp, int gamma_mode)
|
||||
{
|
||||
int i;
|
||||
double i_gamma = 1.0/gamma;
|
||||
|
@ -295,27 +305,37 @@ static void gamma_n (double gamma, int brightness, int contrast,
|
|||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
int x;
|
||||
double val = (i - mid) * (1.0 + contrast / 100.0)
|
||||
+ (1.0 + brightness / 100.0) * mid;
|
||||
val = LIMIT(val, 0, max);
|
||||
if (gamma_16bit)
|
||||
switch (gamma_mode)
|
||||
{
|
||||
int x = LIMIT(65535*pow ((double) val/max, i_gamma) + 0.5, 0, 65535);
|
||||
case GAMMA_16BIT:
|
||||
x = LIMIT(65535*pow ((double) val/max, i_gamma) + 0.5, 0, 65535);
|
||||
|
||||
buf[2*i] = (u_char) x;
|
||||
buf[2*i + 1] = (u_char) (x >> 8);
|
||||
}
|
||||
else
|
||||
break;
|
||||
case GAMMA_12_16BIT:
|
||||
buf[2*i] = (u_char) i;
|
||||
buf[2*i + 1] = (u_char) (i >> 8);
|
||||
break;
|
||||
case GAMMA_8BIT:
|
||||
buf[i] =
|
||||
(u_char) LIMIT(255*pow ((double) val/max, i_gamma) + 0.5, 0, 255);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gamma_from_sane (int length, SANE_Int *in, u_char *out, int gamma_16bit)
|
||||
static void gamma_from_sane (int length, SANE_Int *in, u_char *out, int gamma_mode)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < length; i++)
|
||||
if (gamma_16bit)
|
||||
if (gamma_mode != GAMMA_8BIT)
|
||||
{
|
||||
out[2*i] = (u_char) LIMIT(in[i], 0, 65535);
|
||||
out[2*i + 1] = (u_char) (LIMIT(in[i], 0, 65535) >> 8);
|
||||
|
@ -468,7 +488,14 @@ static SANE_Status snapscani_init_device_structure(
|
|||
(*pd)->dev.vendor = strdup (vendor);
|
||||
}
|
||||
(*pd)->dev.model = strdup (model);
|
||||
(*pd)->dev.type = strdup (SNAPSCAN_TYPE);
|
||||
if (model_num == SCANWIT2720S)
|
||||
{
|
||||
(*pd)->dev.type = strdup (SNAPSCAN_FS_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*pd)->dev.type = strdup (SNAPSCAN_TYPE);
|
||||
}
|
||||
(*pd)->bus = bus_type;
|
||||
(*pd)->model = model_num;
|
||||
|
||||
|
@ -569,7 +596,7 @@ static SANE_Status add_usb_device (SANE_String_Const full_name) {
|
|||
sanei_config_get_string(full_name, &name);
|
||||
if (!name)
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/* Avoid adding the same device more then once */
|
||||
if (device_already_in_list (first_device, name)) {
|
||||
|
@ -585,7 +612,7 @@ static SANE_Status add_usb_device (SANE_String_Const full_name) {
|
|||
status = snapscani_usb_shm_init();
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
status = snapscani_usb_open (name, &fd, sense_handler, NULL);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
|
@ -623,7 +650,7 @@ static SANE_Status add_usb_device (SANE_String_Const full_name) {
|
|||
snapscani_usb_close(fd);
|
||||
}
|
||||
/* deinit shared memory, will be initialized again in open_scanner */
|
||||
snapscani_usb_shm_exit();
|
||||
snapscani_usb_shm_exit();
|
||||
if (status == SANE_STATUS_GOOD) {
|
||||
status = snapscani_init_device_structure(
|
||||
&pd,
|
||||
|
@ -832,7 +859,7 @@ SANE_Status sane_open (SANE_String_Const name, SANE_Handle * h)
|
|||
DBG (DL_CALL_TRACE, "%s (%s, %p)\n", me, name, (void *) h);
|
||||
|
||||
/* possible authorization required */
|
||||
|
||||
|
||||
/* no device name: use first device */
|
||||
if ((strlen(name) == 0) && (first_device != NULL))
|
||||
{
|
||||
|
@ -963,7 +990,7 @@ SANE_Status sane_open (SANE_String_Const name, SANE_Handle * h)
|
|||
{
|
||||
char vendor[8];
|
||||
char model[17];
|
||||
|
||||
|
||||
status = download_firmware(pss);
|
||||
CHECK_STATUS (status, me, "download_firmware");
|
||||
/* send inquiry command again, wait for scanner to initialize */
|
||||
|
@ -978,7 +1005,7 @@ SANE_Status sane_open (SANE_String_Const name, SANE_Handle * h)
|
|||
model);
|
||||
/* Check if it is one of our supported models */
|
||||
pss->pdev->model = snapscani_get_model_id(model, pss->fd, pss->pdev->bus);
|
||||
|
||||
|
||||
if (pss->pdev->model == UNKNOWN) {
|
||||
DBG (DL_MINOR_ERROR,
|
||||
"%s (after firmware upload): \"%s\" is not a supported scanner\n",
|
||||
|
@ -1111,9 +1138,11 @@ SANE_Status sane_get_parameters (SANE_Handle h,
|
|||
p->format = (is_colour_mode(mode)) ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
|
||||
if (mode == MD_LINEART)
|
||||
p->depth = 1;
|
||||
else if (pss->pdev->model == SCANWIT2720S)
|
||||
p->depth = 16;
|
||||
else if (pss->preview)
|
||||
p->depth = 8;
|
||||
else
|
||||
else
|
||||
p->depth = pss->val[OPT_BIT_DEPTH].w;
|
||||
|
||||
DBG (DL_DATA_TRACE, "%s: depth = %ld\n", me, (long) p->depth);
|
||||
|
@ -1212,7 +1241,7 @@ static int reader_process( void *args )
|
|||
if( sanei_thread_is_forked()) {
|
||||
DBG( DL_MINOR_INFO, "reader_process started (forked)\n" );
|
||||
/* child process - close read side, make stdout the write side of the pipe */
|
||||
close( pss->rpipe[0] );
|
||||
close( pss->rpipe[0] );
|
||||
pss->rpipe[0] = -1;
|
||||
} else {
|
||||
DBG( DL_MINOR_INFO, "reader_process started (as thread)\n" );
|
||||
|
@ -1247,8 +1276,8 @@ static int reader_process( void *args )
|
|||
pss->preadersrc->done(pss->preadersrc);
|
||||
free(pss->preadersrc);
|
||||
pss->preadersrc = 0;
|
||||
close( pss->rpipe[1] );
|
||||
pss->rpipe[1] = -1;
|
||||
close( pss->rpipe[1] );
|
||||
pss->rpipe[1] = -1;
|
||||
DBG( DL_MINOR_INFO, "reader_process: finished reading data\n" );
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -1269,9 +1298,9 @@ static SANE_Status start_reader (SnapScan_Scanner *pss)
|
|||
{
|
||||
pss->orig_rpipe_flags = fcntl (pss->rpipe[0], F_GETFL, 0);
|
||||
pss->child = sanei_thread_begin(reader_process, (void *) pss);
|
||||
|
||||
|
||||
cancelRead = SANE_FALSE;
|
||||
|
||||
|
||||
if (pss->child == -1)
|
||||
{
|
||||
/* we'll have to read in blocking mode */
|
||||
|
@ -1333,7 +1362,7 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
int dtcq_gamma_red;
|
||||
int dtcq_gamma_green;
|
||||
int dtcq_gamma_blue;
|
||||
int gamma_16bit = 0;
|
||||
int gamma_mode = GAMMA_8BIT;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
switch (mode)
|
||||
|
@ -1357,32 +1386,47 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
break;
|
||||
}
|
||||
|
||||
DBG (DL_DATA_TRACE, "%s: Sending gamma table for %d bpp\n", me, pss->bpp);
|
||||
switch (pss->bpp)
|
||||
{
|
||||
case 10:
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 8bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY10;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED10;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN10;
|
||||
dtcq_gamma_blue = DTCQ_GAMMA_BLUE10;
|
||||
break;
|
||||
case 12:
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY12;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED12;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN12;
|
||||
dtcq_gamma_blue = DTCQ_GAMMA_BLUE12;
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 16bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY12_16BIT;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED12_16BIT;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN12_16BIT;
|
||||
dtcq_gamma_blue = DTCQ_GAMMA_BLUE12_16BIT;
|
||||
gamma_mode = GAMMA_12_16BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 8bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY12;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED12;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN12;
|
||||
dtcq_gamma_blue = DTCQ_GAMMA_BLUE12;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
if (pss->bpp_scan == 16)
|
||||
{
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 16bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY14_16BIT;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED14_16BIT;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN14_16BIT;
|
||||
dtcq_gamma_blue = DTCQ_GAMMA_BLUE14_16BIT;
|
||||
gamma_16bit = 1;
|
||||
gamma_mode = GAMMA_16BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 8bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY14;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED14;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN14;
|
||||
|
@ -1390,6 +1434,7 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
DBG (DL_DATA_TRACE, "%s: Sending 8bit gamma table for %d bpp\n", me, pss->bpp);
|
||||
dtcq_gamma_gray = DTCQ_GAMMA_GRAY8;
|
||||
dtcq_gamma_red = DTCQ_GAMMA_RED8;
|
||||
dtcq_gamma_green = DTCQ_GAMMA_GREEN8;
|
||||
|
@ -1405,34 +1450,34 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
{
|
||||
/* Use greyscale gamma for all rgb channels */
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_gs,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_gs,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_gs,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
else
|
||||
{
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_r,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_g,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_b,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
|
@ -1443,34 +1488,34 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
{
|
||||
/* Use greyscale gamma for all rgb channels */
|
||||
gamma_n (gamma_gs, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_n (gamma_gs, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_n (gamma_gs, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
else
|
||||
{
|
||||
gamma_n (gamma_r, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_red);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_n (gamma_g, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_green);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
|
||||
gamma_n (gamma_b, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_blue);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
|
@ -1481,14 +1526,14 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss)
|
|||
if(pss->val[OPT_CUSTOM_GAMMA].b)
|
||||
{
|
||||
gamma_from_sane (pss->gamma_length, pss->gamma_table_gs,
|
||||
pss->buf + SEND_LENGTH, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_gray);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
else
|
||||
{
|
||||
gamma_n (gamma_gs, pss->bright, pss->contrast,
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_16bit);
|
||||
pss->buf + SEND_LENGTH, pss->bpp, gamma_mode);
|
||||
status = send_gamma_table(pss, DTC_GAMMA, dtcq_gamma_gray);
|
||||
CHECK_STATUS (status, me, "send");
|
||||
}
|
||||
|
@ -1631,8 +1676,22 @@ SANE_Status sane_start (SANE_Handle h)
|
|||
|
||||
pss->state = ST_SCAN_INIT;
|
||||
|
||||
if ((pss->pdev->model == SCANWIT2720S) && (pss->focus_mode == MD_AUTO))
|
||||
{
|
||||
status = get_focus(pss);
|
||||
CHECK_STATUS (status, me, "get_focus");
|
||||
}
|
||||
|
||||
reserve_unit(pss);
|
||||
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
status = set_frame(pss, 0);
|
||||
CHECK_STATUS (status, me, "set_frame");
|
||||
status = set_focus(pss, pss->focus);
|
||||
CHECK_STATUS (status, me, "set_focus");
|
||||
}
|
||||
|
||||
/* set up the window and fetch the resulting scanner parameters */
|
||||
status = set_window(pss);
|
||||
CHECK_STATUS (status, me, "set_window");
|
||||
|
@ -1644,7 +1703,7 @@ SANE_Status sane_start (SANE_Handle h)
|
|||
|
||||
status = download_gamma_tables(pss);
|
||||
CHECK_STATUS (status, me, "download_gamma_tables");
|
||||
|
||||
|
||||
status = download_halftone_matrices(pss);
|
||||
CHECK_STATUS (status, me, "download_halftone_matrices");
|
||||
|
||||
|
@ -1698,6 +1757,12 @@ SANE_Status sane_start (SANE_Handle h)
|
|||
return status;
|
||||
}
|
||||
|
||||
if (pss->pdev->model == SCANWIT2720S)
|
||||
{
|
||||
status = set_frame(pss, pss->frame_no);
|
||||
CHECK_STATUS (status, me, "set_frame");
|
||||
}
|
||||
|
||||
if (pss->source == SRC_ADF)
|
||||
{
|
||||
/* Wait for scanner ready again (e.g. until paper is loaded from an ADF) */
|
||||
|
@ -1829,7 +1894,7 @@ void sane_cancel (SANE_Handle h)
|
|||
{
|
||||
cancelRead = SANE_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* give'em 10 seconds 'til done...*/
|
||||
alarm(10);
|
||||
res = sanei_thread_waitpid( pss->child, 0 );
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
|
||||
Oliver Schwartz and Kevin Charter
|
||||
Copyright (C) 1997, 1998, 1999, 2001, 2002, 2013 Franck Schnefra,
|
||||
Michel Roelofs, Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang,
|
||||
Wolfgang Goeller, Petter Reinholdtsen, Gary Plewa, Sebastien Sable,
|
||||
Mikael Magnusson, Andrew Goodbody, Oliver Schwartz and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
@ -60,6 +60,7 @@
|
|||
|
||||
#define DEFAULT_DEVICE "/dev/scanner" /* Check this if config is missing */
|
||||
#define SNAPSCAN_TYPE "flatbed scanner"
|
||||
#define SNAPSCAN_FS_TYPE "film scanner"
|
||||
#define TMP_FILE_PREFIX "/var/tmp/snapscan"
|
||||
#define SNAPSCAN_CONFIG_FILE "snapscan.conf"
|
||||
#define FIRMWARE_KW "firmware"
|
||||
|
@ -107,7 +108,8 @@ typedef enum
|
|||
PERFECTION2480, /* Epson Perfection 2480 - 2400 DPI */
|
||||
PERFECTION3490, /* Epson Perfection 3490 - 3200 DPI */
|
||||
STYLUS_CX1500, /* Epson Stylus CX 1500 - 600 DPI */
|
||||
ARCUS1200 /* Agfa Arcus 1200 - 1200 DPI (rebadged Acer?) */
|
||||
ARCUS1200, /* Agfa Arcus 1200 - 1200 DPI (rebadged Acer?) */
|
||||
SCANWIT2720S /* BenQ ScanWit 2720S film scanner 2700 DPI */
|
||||
} SnapScan_Model;
|
||||
|
||||
struct SnapScan_Driver_desc {
|
||||
|
@ -146,7 +148,8 @@ static struct SnapScan_Driver_desc drivers[] =
|
|||
{PERFECTION1670, "Perfection 1670"},
|
||||
{PERFECTION2480, "Perfection 2480"},
|
||||
{PERFECTION3490, "Perfection 3490"},
|
||||
{STYLUS_CX1500, "Stylus CX 1500"}
|
||||
{STYLUS_CX1500, "Stylus CX 1500"},
|
||||
{SCANWIT2720S, "BenQ ScanWit 2720S"}
|
||||
};
|
||||
|
||||
#define known_drivers ((int) (sizeof(drivers)/sizeof(drivers[0])))
|
||||
|
@ -200,7 +203,8 @@ static struct SnapScan_Model_desc scanners[] =
|
|||
{"EPSON Scanner1", PERFECTION2480}, /* dummy entry to detect scanner */
|
||||
{"EPSON Scanner2", PERFECTION3490}, /* dummy entry to detect scanner */
|
||||
{"EPSON MFP00", STYLUS_CX1500},
|
||||
{"ARCUS 1200", ARCUS1200}
|
||||
{"ARCUS 1200", ARCUS1200},
|
||||
{"FilmScanner____1", SCANWIT2720S}
|
||||
};
|
||||
|
||||
#define known_scanners ((int) (sizeof(scanners)/sizeof(scanners[0])))
|
||||
|
@ -271,6 +275,9 @@ typedef enum
|
|||
OPT_PREVIEW_MODE, /* preview mode */
|
||||
OPT_HIGHQUALITY, /* scan quality (fast / high) */
|
||||
OPT_SOURCE, /* scan source (flatbed / TPO) */
|
||||
OPT_FRAME_NO, /* frame number for film scanner */
|
||||
OPT_FOCUS_MODE, /* manual or auto focus for film scanner */
|
||||
OPT_FOCUS_POINT, /* focus point for film scanner */
|
||||
OPT_GEOMETRY_GROUP, /* geometry group */
|
||||
OPT_TLX, /* top left x */
|
||||
OPT_TLY, /* top left y */
|
||||
|
@ -338,6 +345,9 @@ typedef struct snapscan_device
|
|||
}
|
||||
SnapScan_Device;
|
||||
|
||||
#define MD_AUTO 0
|
||||
#define MD_MANUAL 1
|
||||
|
||||
#define MAX_SCSI_CMD_LEN 256 /* not that large */
|
||||
#define DEFAULT_SCANNER_BUF_SZ 1024*63
|
||||
|
||||
|
@ -418,6 +428,10 @@ struct snapscan_scanner
|
|||
SANE_Bool firmware_loaded; /* true if firmware was downloaded */
|
||||
SANE_Word usb_vendor; /* USB vendor id */
|
||||
SANE_Word usb_product; /* USB product id */
|
||||
SANE_Byte frame_no; /* frame number for film scanner */
|
||||
SANE_Int focus_mode; /* focus mode value */
|
||||
SANE_String focus_mode_s; /* focus mode string */
|
||||
SANE_Word focus; /* focus point */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -146,6 +146,10 @@
|
|||
:interface "SCSI"
|
||||
:status :good
|
||||
|
||||
:model "ScanWit 2720s"
|
||||
:interface "SCSI"
|
||||
:status :good
|
||||
|
||||
:model "310U"
|
||||
:interface "USB"
|
||||
:usbid "0x04a5" "0x1a20"
|
||||
|
|
Ładowanie…
Reference in New Issue