Added sm3840 backend (from "Earle F. Philhower, III"

<earlephilhower@yahoo.com>).
merge-requests/1/head
Henning Geinitz 2005-02-20 20:08:04 +00:00
rodzic 46d59a14aa
commit 316d7553e4
16 zmienionych plików z 3189 dodań i 18 usunięć

Wyświetl plik

@ -65,6 +65,7 @@ Backends:
sceptre: Frank Zago (*)
sharp: Kazuya Fukuda and Abel Deuring (*)
sm3600: Marian Eichholz (*) and Glenn Ramsey
sm3840: Earle F. Philhower III
snapscan: Kevin Charter, Franck Schneider, Michel Roelofs, Sebastien
Sable, Henrik Johansson, Chris Bagwell, and Oliver Schwartz (*)
sp15c: Randolph Bentson
@ -131,6 +132,7 @@ David Huggins-Daines <bn711@freenet.carleton.ca>
David Mosberger <David.Mosberger@acm.org>
David Stevenson <david.stevenson@zoom.co.uk>
Didier Carlier <didier@sema.be>
Earle F. Philhower III <earle@ziplabel.com>
Eddy De Greef <eddy_de_greef at tiscali dot be>
Eugene S. Weiss <yossarian@users.sourceforge.net>
Feico W. Dillema <dillema@acm.org>

Wyświetl plik

@ -150,7 +150,10 @@ DISTFILES = abaton.c abaton.conf abaton.h agfafocus.c agfafocus.conf \
umax_pp_low.c umax_pp_low.h umax_pp_mid.c umax_pp_mid.h umax-scanner.c \
umax-scanner.h umax-scsidef.h umax-uc1200s.c umax-uc1200se.c umax-uc1260.c \
umax-uc630.c umax-uc840.c umax-ug630.c umax-ug80.c umax-usb.c v4l.c \
v4l.conf v4l-frequencies.h v4l.h
v4l.conf v4l-frequencies.h v4l.h \
sm3840.c sm3840_lib.c sm3840_params.h sm3840_scan.c sm3840.h \
sm3840_lib.h sm3840-s.c
.PHONY: all clean depend dist distclean install uninstall
@ -394,6 +397,9 @@ libsane-sharp.la: ../sanei/sanei_config2.lo
libsane-sharp.la: ../sanei/sanei_constrain_value.lo
libsane-sharp.la: ../sanei/sanei_scsi.lo
libsane-sm3600.la: ../sanei/sanei_constrain_value.lo
libsane-sm3840.la: ../sanei/sanei_config2.lo
libsane-sm3840.la: ../sanei/sanei_constrain_value.lo
libsane-sm3840.la: ../sanei/sanei_usb.lo
libsane-snapscan.la: ../sanei/sanei_config2.lo
libsane-snapscan.la: ../sanei/sanei_constrain_value.lo
libsane-snapscan.la: ../sanei/sanei_scsi.lo

Wyświetl plik

@ -46,6 +46,7 @@ s9036
sceptre
sharp
sm3600
sm3840
snapscan
sp15c
#st400

747
backend/sm3840.c 100755
Wyświetl plik

@ -0,0 +1,747 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#include "../include/sane/config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include "../include/sane/sane.h"
#include "../include/sane/saneopts.h"
#define BACKENDNAME sm3840
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_usb.h"
#include "../include/sane/sanei_config.h"
#include "sm3840.h"
#include "sm3840_scan.c"
#include "sm3840_lib.c"
static double sm3840_unit_convert (SANE_Int val);
static int num_devices;
static SM3840_Device *first_dev;
static SM3840_Scan *first_handle;
static const SANE_Device **devlist = 0;
static const SANE_String_Const mode_list[] = {
SANE_I18N ("Gray"), SANE_I18N ("Color"),
0
};
static const SANE_Word resolution_list[] = {
4, 1200, 600, 300, 150
};
static const SANE_Word bpp_list[] = {
2, 8, 16
};
static const SANE_Range x_range = {
SANE_FIX (0),
SANE_FIX (215.91), /* 8.5 inches */
SANE_FIX (0)
};
static const SANE_Range y_range = {
SANE_FIX (0),
SANE_FIX (297.19), /* 11.7 inches */
SANE_FIX (0)
};
static const SANE_Range brightness_range = {
1,
4096,
1.0
};
static const SANE_Range contrast_range = {
SANE_FIX (0.1),
SANE_FIX (9.9),
SANE_FIX (0.1)
};
static const SANE_Range lamp_range = {
1,
15,
1
};
/*--------------------------------------------------------------------------*/
static int
min (int a, int b)
{
if (a < b)
return a;
else
return b;
}
SANE_Status
sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
SANE_Int * len)
{
SM3840_Scan *s = handle;
DBG (2, "+sane-read:%p %p %d %p\n", (unsigned char *) s, buf, max_len,
(unsigned char *) len);
DBG (2,
"+sane-read:remain:%d offset:%d linesleft:%d linebuff:%p linesread:%d\n",
s->remaining, s->offset, s->linesleft, s->line_buffer, s->linesread);
if (!s->scanning)
return SANE_STATUS_INVAL;
if (!s->remaining)
{
if (!s->linesleft)
{
*len = 0;
s->scanning = 0;
/* Move to home position */
reset_scanner ((usb_dev_handle *) s->udev);
/* Send lamp timeout */
set_lamp_timer ((usb_dev_handle *) s->udev, s->sm3840_params.lamp);
/* Free memory */
if (s->save_scan_line)
free (s->save_scan_line);
s->save_scan_line = NULL;
if (s->save_dpi1200_remap)
free (s->save_dpi1200_remap);
s->save_dpi1200_remap = NULL;
if (s->save_color_remap)
free (s->save_color_remap);
s->save_color_remap = NULL;
return SANE_STATUS_EOF;
}
record_line ((s->linesread == 0) ? 1 : 0,
(usb_dev_handle *) s->udev,
s->line_buffer,
s->sm3840_params.dpi,
s->sm3840_params.scanpix,
s->sm3840_params.gray,
(s->sm3840_params.bpp == 16) ? 1 : 0,
&s->save_i,
&s->save_scan_line,
&s->save_dpi1200_remap, &s->save_color_remap);
s->remaining = s->sm3840_params.linelen;
s->offset = 0;
s->linesread++;
s->linesleft--;
}
memcpy (buf, s->offset + s->line_buffer, min (max_len, s->remaining));
*len = min (max_len, s->remaining);
s->offset += min (max_len, s->remaining);
s->remaining -= min (max_len, s->remaining);
DBG (2, "-sane_read\n");
return SANE_STATUS_GOOD;
}
/*--------------------------------------------------------------------------*/
void
sane_cancel (SANE_Handle h)
{
SM3840_Scan *s = h;
DBG (2, "trying to cancel...\n");
if (s->scanning)
{
if (!s->cancelled)
{
/* Move to home position */
reset_scanner ((usb_dev_handle *) s->udev);
/* Send lamp timeout */
set_lamp_timer ((usb_dev_handle *) s->udev, s->sm3840_params.lamp);
/* Free memory */
if (s->save_scan_line)
free (s->save_scan_line);
s->save_scan_line = NULL;
if (s->save_dpi1200_remap)
free (s->save_dpi1200_remap);
s->save_dpi1200_remap = NULL;
if (s->save_color_remap)
free (s->save_color_remap);
s->save_color_remap = NULL;
s->scanning = 0;
s->cancelled = SANE_TRUE;
}
}
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_start (SANE_Handle handle)
{
SM3840_Scan *s = handle;
SANE_Status status;
/* First make sure we have a current parameter set. Some of the
* parameters will be overwritten below, but that's OK. */
DBG (2, "sane_start\n");
status = sane_get_parameters (s, 0);
if (status != SANE_STATUS_GOOD)
return status;
DBG (1, "Got params again...\n");
s->scanning = SANE_TRUE;
s->cancelled = 0;
s->line_buffer = malloc (s->sm3840_params.linelen);
s->remaining = 0;
s->offset = 0;
s->linesleft = s->sm3840_params.scanlines;
s->linesread = 0;
s->save_i = 0;
s->save_scan_line = NULL;
s->save_dpi1200_remap = NULL;
s->save_color_remap = NULL;
setup_scan ((usb_dev_handle *) s->udev, &(s->sm3840_params));
return (SANE_STATUS_GOOD);
}
static double
sm3840_unit_convert (SANE_Int val)
{
double d;
d = SANE_UNFIX (val);
d /= MM_PER_INCH;
return d;
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
SM3840_Scan *s = handle;
DBG (2, "sane_get_parameters\n");
if (!s->scanning)
{
memset (&s->sane_params, 0, sizeof (s->sane_params));
/* Copy from options to sm3840_params */
s->sm3840_params.gray =
(!strcasecmp (s->value[OPT_MODE].s, SANE_I18N ("Gray"))) ? 1 : 0;
s->sm3840_params.dpi = s->value[OPT_RESOLUTION].w;
s->sm3840_params.bpp = s->value[OPT_BIT_DEPTH].w;
s->sm3840_params.gain = SANE_UNFIX (s->value[OPT_CONTRAST].w);
s->sm3840_params.offset = s->value[OPT_BRIGHTNESS].w;
s->sm3840_params.lamp = s->value[OPT_LAMP_TIMEOUT].w;
s->sm3840_params.top = sm3840_unit_convert (s->value[OPT_TL_Y].w);
s->sm3840_params.left = sm3840_unit_convert (s->value[OPT_TL_X].w);
s->sm3840_params.width =
sm3840_unit_convert (s->value[OPT_BR_X].w) - s->sm3840_params.left;
s->sm3840_params.height =
sm3840_unit_convert (s->value[OPT_BR_Y].w) - s->sm3840_params.top;
/* Legalize and calculate pixel sizes */
prepare_params (&(s->sm3840_params));
/* Copy into sane_params */
s->sane_params.pixels_per_line = s->sm3840_params.scanpix;
s->sane_params.lines = s->sm3840_params.scanlines;
s->sane_params.format =
s->sm3840_params.gray ? SANE_FRAME_GRAY : SANE_FRAME_RGB;
s->sane_params.bytes_per_line = s->sm3840_params.linelen;
s->sane_params.depth = s->sm3840_params.bpp;
s->sane_params.last_frame = SANE_TRUE;
} /*!scanning */
if (params)
*params = s->sane_params;
return (SANE_STATUS_GOOD);
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
{
SM3840_Scan *s = handle;
SANE_Status status = 0;
SANE_Word cap;
DBG (2, "sane_control_option\n");
if (info)
*info = 0;
if (s->scanning)
return SANE_STATUS_DEVICE_BUSY;
if (option >= NUM_OPTIONS)
return SANE_STATUS_INVAL;
cap = s->options_list[option].cap;
if (!SANE_OPTION_IS_ACTIVE (cap))
return SANE_STATUS_INVAL;
if (action == SANE_ACTION_GET_VALUE)
{
DBG (1, "sane_control_option %d, get value\n", option);
switch (option)
{
/* word options: */
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
case OPT_NUM_OPTS:
case OPT_CONTRAST:
case OPT_BRIGHTNESS:
case OPT_LAMP_TIMEOUT:
*(SANE_Word *) val = s->value[option].w;
return (SANE_STATUS_GOOD);
/* string options: */
case OPT_MODE:
strcpy (val, s->value[option].s);
return (SANE_STATUS_GOOD);
}
}
else if (action == SANE_ACTION_SET_VALUE)
{
DBG (1, "sane_control_option %d, set value\n", option);
if (!SANE_OPTION_IS_SETTABLE (cap))
return (SANE_STATUS_INVAL);
if (status != SANE_STATUS_GOOD)
return (status);
status = sanei_constrain_value (s->options_list + option, val, info);
switch (option)
{
/* (mostly) side-effect-free word options: */
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_BR_X:
case OPT_BR_Y:
case OPT_TL_X:
case OPT_TL_Y:
if (info)
*info |= SANE_INFO_RELOAD_PARAMS;
/* fall through */
case OPT_NUM_OPTS:
case OPT_CONTRAST:
case OPT_BRIGHTNESS:
case OPT_LAMP_TIMEOUT:
s->value[option].w = *(SANE_Word *) val;
DBG (1, "set brightness to\n");
return (SANE_STATUS_GOOD);
case OPT_MODE:
if (s->value[option].s)
free (s->value[option].s);
s->value[option].s = strdup (val);
if (info)
*info |= SANE_INFO_RELOAD_PARAMS;
return (SANE_STATUS_GOOD);
}
}
return (SANE_STATUS_INVAL);
}
/*--------------------------------------------------------------------------*/
const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{
SM3840_Scan *s = handle;
DBG (2, "sane_get_option_descriptor\n");
if ((unsigned) option >= NUM_OPTIONS)
return (0);
return (&s->options_list[option]);
}
/*--------------------------------------------------------------------------*/
void
sane_close (SANE_Handle handle)
{
SM3840_Scan *prev, *s;
DBG (2, "sane_close\n");
/* remove handle from list of open handles: */
prev = 0;
for (s = first_handle; s; s = s->next)
{
if (s == handle)
break;
prev = s;
}
if (!s)
{
DBG (1, "close: invalid handle %p\n", handle);
return; /* oops, not a handle we know about */
}
if (s->scanning)
{
sane_cancel (handle);
}
sanei_usb_close (s->udev);
if (s->line_buffer)
free (s->line_buffer);
if (s->save_scan_line)
free (s->save_scan_line);
if (s->save_dpi1200_remap)
free (s->save_dpi1200_remap);
if (s->save_color_remap)
free (s->save_color_remap);
if (prev)
prev->next = s->next;
else
first_handle = s;
free (handle);
}
/*--------------------------------------------------------------------------*/
void
sane_exit (void)
{
SM3840_Device *next;
DBG (2, "sane_exit\n");
while (first_dev != NULL)
{
next = first_dev->next;
free (first_dev);
first_dev = next;
}
if (devlist)
free (devlist);
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
DBG_INIT ();
if (version_code)
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
if (authorize)
DBG(2, "Unused authorize\n");
sanei_usb_init ();
return (SANE_STATUS_GOOD);
}
/*--------------------------------------------------------------------------*/
static SANE_Status
add_sm3840_device (SANE_String_Const devname)
{
SM3840_Device *dev;
dev = calloc (sizeof (*dev), 1);
if (!dev)
return (SANE_STATUS_NO_MEM);
memset (dev, 0, sizeof (*dev));
dev->sane.name = strdup (devname);
dev->sane.model = "ScanMaker 3840";
dev->sane.vendor = "Microtek";
dev->sane.type = "flatbed scanner";
++num_devices;
dev->next = first_dev;
first_dev = dev;
return (SANE_STATUS_GOOD);
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
static const SANE_Device **devlist = 0;
SM3840_Device *dev;
int i;
DBG (3, "sane_get_devices (local_only = %d)\n", local_only);
while (first_dev)
{
dev = first_dev->next;
free (first_dev);
first_dev = dev;
}
first_dev = NULL;
num_devices = 0;
sanei_usb_find_devices (0x05da, 0x30d4, add_sm3840_device);
if (devlist)
free (devlist);
devlist = calloc ((num_devices + 1) * sizeof (devlist[0]), 1);
if (!devlist)
return SANE_STATUS_NO_MEM;
i = 0;
for (dev = first_dev; i < num_devices; dev = dev->next)
devlist[i++] = &dev->sane;
devlist[i++] = 0;
if (device_list)
*device_list = devlist;
return (SANE_STATUS_GOOD);
}
/*--------------------------------------------------------------------------*/
static size_t
max_string_size (const SANE_String_Const strings[])
{
size_t size, max_size = 0;
int i;
for (i = 0; strings[i]; ++i)
{
size = strlen (strings[i]) + 1;
if (size > max_size)
max_size = size;
}
return (max_size);
}
/*--------------------------------------------------------------------------*/
static void
initialize_options_list (SM3840_Scan * s)
{
SANE_Int option;
DBG (2, "initialize_options_list\n");
for (option = 0; option < NUM_OPTIONS; ++option)
{
s->options_list[option].size = sizeof (SANE_Word);
s->options_list[option].cap =
SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
}
s->options_list[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
s->options_list[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
s->options_list[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
s->options_list[OPT_NUM_OPTS].type = SANE_TYPE_INT;
s->options_list[OPT_NUM_OPTS].unit = SANE_UNIT_NONE;
s->options_list[OPT_NUM_OPTS].size = sizeof (SANE_Word);
s->options_list[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
s->options_list[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;
s->value[OPT_NUM_OPTS].w = NUM_OPTIONS;
s->options_list[OPT_MODE].name = SANE_NAME_SCAN_MODE;
s->options_list[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
s->options_list[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
s->options_list[OPT_MODE].type = SANE_TYPE_STRING;
s->options_list[OPT_MODE].size = max_string_size (mode_list);
s->options_list[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
s->options_list[OPT_MODE].constraint.string_list = mode_list;
s->value[OPT_MODE].s = strdup (mode_list[1]);
s->options_list[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
s->options_list[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
s->options_list[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
s->options_list[OPT_RESOLUTION].type = SANE_TYPE_INT;
s->options_list[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
s->options_list[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
s->options_list[OPT_RESOLUTION].constraint.word_list = resolution_list;
s->value[OPT_RESOLUTION].w = 300;
s->options_list[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
s->options_list[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
s->options_list[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
s->options_list[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
s->options_list[OPT_BIT_DEPTH].unit = SANE_UNIT_NONE;
s->options_list[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
s->options_list[OPT_BIT_DEPTH].constraint.word_list = bpp_list;
s->value[OPT_BIT_DEPTH].w = 8;
s->options_list[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
s->options_list[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
s->options_list[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
s->options_list[OPT_TL_X].type = SANE_TYPE_FIXED;
s->options_list[OPT_TL_X].unit = SANE_UNIT_MM;
s->options_list[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_TL_X].constraint.range = &x_range;
s->value[OPT_TL_X].w = s->options_list[OPT_TL_X].constraint.range->min;
s->options_list[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
s->options_list[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
s->options_list[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
s->options_list[OPT_TL_Y].type = SANE_TYPE_FIXED;
s->options_list[OPT_TL_Y].unit = SANE_UNIT_MM;
s->options_list[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_TL_Y].constraint.range = &y_range;
s->value[OPT_TL_Y].w = s->options_list[OPT_TL_Y].constraint.range->min;
s->options_list[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
s->options_list[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
s->options_list[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
s->options_list[OPT_BR_X].type = SANE_TYPE_FIXED;
s->options_list[OPT_BR_X].unit = SANE_UNIT_MM;
s->options_list[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_BR_X].constraint.range = &x_range;
s->value[OPT_BR_X].w = s->options_list[OPT_BR_X].constraint.range->max;
s->options_list[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
s->options_list[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
s->options_list[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
s->options_list[OPT_BR_Y].type = SANE_TYPE_FIXED;
s->options_list[OPT_BR_Y].unit = SANE_UNIT_MM;
s->options_list[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_BR_Y].constraint.range = &y_range;
s->value[OPT_BR_Y].w = s->options_list[OPT_BR_Y].constraint.range->max;
s->options_list[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
s->options_list[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
s->options_list[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
s->options_list[OPT_CONTRAST].type = SANE_TYPE_FIXED;
s->options_list[OPT_CONTRAST].unit = SANE_UNIT_NONE;
s->options_list[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_CONTRAST].constraint.range = &contrast_range;
s->value[OPT_CONTRAST].w = SANE_FIX (3.5);
s->options_list[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
s->options_list[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
s->options_list[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
s->options_list[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
s->options_list[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
s->options_list[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_BRIGHTNESS].constraint.range = &brightness_range;
s->value[OPT_BRIGHTNESS].w = 1800;
s->options_list[OPT_LAMP_TIMEOUT].name = "lamp-timeout";
s->options_list[OPT_LAMP_TIMEOUT].title = SANE_I18N ("Lamp timeout");
s->options_list[OPT_LAMP_TIMEOUT].desc =
SANE_I18N ("Minutes until lamp is turned off after scan");
s->options_list[OPT_LAMP_TIMEOUT].type = SANE_TYPE_INT;
s->options_list[OPT_LAMP_TIMEOUT].unit = SANE_UNIT_NONE;
s->options_list[OPT_LAMP_TIMEOUT].constraint_type = SANE_CONSTRAINT_RANGE;
s->options_list[OPT_LAMP_TIMEOUT].constraint.range = &lamp_range;
s->value[OPT_LAMP_TIMEOUT].w = 15;
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{
SANE_Status status;
SM3840_Device *dev;
SM3840_Scan *s;
DBG (2, "sane_open\n");
/* Make sure we have first_dev */
sane_get_devices (NULL, 0);
if (devicename[0])
{
for (dev = first_dev; dev; dev = dev->next)
if (strcmp (dev->sane.name, devicename) == 0)
break;
}
else
{
/* empty devicename -> use first device */
dev = first_dev;
}
DBG (2, "using device: %s %p\n", dev->sane.name, (unsigned char *)dev);
if (!dev)
return SANE_STATUS_INVAL;
s = calloc (sizeof (*s), 1);
if (!s)
return SANE_STATUS_NO_MEM;
status = sanei_usb_open (dev->sane.name, &(s->udev));
initialize_options_list (s);
s->scanning = 0;
/* insert newly opened handle into list of open handles: */
s->next = first_handle;
first_handle = s;
*handle = s;
return (SANE_STATUS_GOOD);
}
/*--------------------------------------------------------------------------*/
SANE_Status
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
SM3840_Scan *s = handle;
DBG (2, "sane_set_io_mode( %p, %d )\n", handle, non_blocking);
if (s->scanning)
{
if (non_blocking == SANE_FALSE)
return SANE_STATUS_GOOD;
else
return (SANE_STATUS_UNSUPPORTED);
}
else
return SANE_STATUS_INVAL;
}
/*---------------------------------------------------------------------------*/
SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
{
DBG (2, "sane_get_select_fd( %p, %p )\n", (void *) handle, (void *) fd);
return SANE_STATUS_UNSUPPORTED;
}

Wyświetl plik

@ -0,0 +1,3 @@
# usb vendor product
# Microtek ScanMaker 3840 ID
usb 0x05da 0x30d4

123
backend/sm3840.h 100755
Wyświetl plik

@ -0,0 +1,123 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef sm3840_h
#define sm3840_h
#include <sys/stat.h>
#include <sys/types.h>
#include <sane/sane.h>
typedef enum SM3840_Option
{
OPT_NUM_OPTS = 0,
OPT_MODE,
OPT_RESOLUTION,
OPT_BIT_DEPTH,
OPT_TL_X, /* top-left x */
OPT_TL_Y, /* top-left y */
OPT_BR_X, /* bottom-right x */
OPT_BR_Y, /* bottom-right y */
OPT_BRIGHTNESS,
OPT_CONTRAST,
OPT_LAMP_TIMEOUT,
/* must come last */
NUM_OPTIONS
} SM3840_Option;
#include "sm3840_params.h"
typedef struct SM3840_Device
{
struct SM3840_Device *next;
SANE_Device sane;
} SM3840_Device;
typedef struct SM3840_Scan
{
struct SM3840_Scan *next;
SANE_Option_Descriptor options_list[NUM_OPTIONS];
Option_Value value[NUM_OPTIONS];
SANE_Int udev;
SANE_Bool scanning;
SANE_Bool cancelled;
SANE_Parameters sane_params;
SM3840_Params sm3840_params;
SANE_Byte *line_buffer; /* One remapped/etc line */
size_t remaining; /* How much of line_buffer is still good? */
size_t offset; /* Offset in line_buffer where unread data lives */
int linesleft; /* How many lines to read from scanner? */
int linesread; /* Total lines returned to SANE */
/* record_line state parameters */
int save_i;
unsigned char *save_scan_line;
unsigned char *save_dpi1200_remap;
unsigned char *save_color_remap;
} SM3840_Scan;
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#define SM3840_CONFIG_FILE "sm3840.conf"
#define MM_PER_INCH 25.4
#define SCAN_BUF_SIZE 65536
#endif /* sm3840_h */

Wyświetl plik

@ -0,0 +1,996 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include "sm3840_lib.h"
#ifndef BACKENDNAME
/* For standalone compilation */
static void
DBG (int ignored, const char *fmt, ...)
{
va_list a;
va_start (a, fmt);
vfprintf (stderr, fmt, a);
va_end (a);
}
#else
/* For SANE compilation, convert libusb to sanei_usb */
static int
my_usb_bulk_write (usb_dev_handle * dev, int ep,
unsigned char *bytes, int size, int timeout)
{
SANE_Status status;
size_t my_size;
timeout = timeout;
ep = ep;
my_size = size;
status =
sanei_usb_write_bulk ((SANE_Int) dev, (SANE_Byte *) bytes, &my_size);
if (status != SANE_STATUS_GOOD)
my_size = -1;
return my_size;
}
static int
my_usb_bulk_read (usb_dev_handle * dev, int ep,
unsigned char *bytes, int size, int timeout)
{
SANE_Status status;
size_t my_size;
timeout = timeout;
ep = ep;
my_size = size;
status =
sanei_usb_read_bulk ((SANE_Int) dev, (SANE_Byte *) bytes, &my_size);
if (status != SANE_STATUS_GOOD)
my_size = -1;
return my_size;
}
static int
my_usb_control_msg (usb_dev_handle * dev, int requesttype,
int request, int value, int index,
unsigned char *bytes, int size, int timeout)
{
SANE_Status status;
timeout = timeout;
status = sanei_usb_control_msg ((SANE_Int) dev, (SANE_Int) requesttype,
(SANE_Int) request, (SANE_Int) value,
(SANE_Int) index, (SANE_Int) size,
(SANE_Byte *) bytes);
return status;
}
#endif
/* Sanitize and convert scan parameters from inches to pixels */
static void
prepare_params (SM3840_Params * params)
{
if (params->gray)
params->gray = 1;
if (params->dpi != 1200 && params->dpi != 600 && params->dpi != 300
&& params->dpi != 150)
params->dpi = 150;
if (params->bpp != 8 && params->bpp != 16)
params->bpp = 8;
/* Sanity check input sizes */
if (params->top < 0)
params->top = 0;
if (params->left < 0)
params->left = 0;
if (params->width < 0)
params->width = 0;
if (params->height < 0)
params->height = 0;
if ((params->top + params->height) > 11.7)
params->height = 11.7 - params->top;
if ((params->left + params->width) > 8.5)
params->width = 8.5 - params->left;
params->topline = params->top * params->dpi;
params->scanlines = params->height * params->dpi;
params->leftpix = params->left * params->dpi;
params->leftpix &= ~1; /* Always start on even pixel boundary for remap */
/* Scanpix always a multiple of 128 */
params->scanpix = params->width * params->dpi;
params->scanpix = (params->scanpix + 127) & ~127;
/* Sanity check outputs... */
if (params->topline < 0)
params->topline = 0;
if (params->scanlines < 1)
params->scanlines = 1;
if (params->leftpix < 0)
params->leftpix = 0;
if (params->scanpix < 128)
params->scanpix = 128;
/* Some handy calculations */
params->linelen =
params->scanpix * (params->bpp / 8) * (params->gray ? 1 : 3);
}
#ifndef BACKENDNAME
usb_dev_handle *
find_device (unsigned int idVendor, unsigned int idProduct)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_init ();
usb_find_busses ();
usb_find_devices ();
for (bus = usb_get_busses (); bus; bus = bus->next)
for (dev = bus->devices; dev; dev = dev->next)
if (dev->descriptor.idVendor == idVendor &&
dev->descriptor.idProduct == idProduct)
return usb_open (dev);
return NULL;
}
#endif
static void
idle_ab (usb_dev_handle * udev)
{
int len, i;
unsigned char buff[8] = { 0x64, 0x65, 0x16, 0x17, 0x64, 0x65, 0x44, 0x45 };
for (i = 0; i < 8; i++)
{
len = usb_control_msg (udev, 0x40, 0x0c, 0x0090, 0x0000, buff + i,
0x0001, wr_timeout);
}
}
/* CW: 40 04 00b0 0000 <len> : <reg1> <value1> <reg2> <value2> ... */
static void
write_regs (usb_dev_handle * udev, int regs, unsigned char reg1,
unsigned char val1,
... /*unsigned char reg, unsigned char val, ... */ )
{
unsigned char buff[512];
va_list marker;
int len, i;
va_start (marker, val1);
buff[0] = reg1;
buff[1] = val1;
for (i = 1; i < regs; i++)
{
buff[i * 2] = va_arg (marker, int);
buff[i * 2 + 1] = va_arg (marker, int);
}
va_end (marker);
len = usb_control_msg (udev, 0x40, 0x04, 0x00b0, 0x0000, buff,
regs * 2, wr_timeout);
}
static int
write_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char byte)
{
return usb_control_msg (udev, 0x40, request, value, index,
&byte, 1, wr_timeout);
}
static int
read_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char *byte)
{
return usb_control_msg (udev, 0xc0, request, value, index,
byte, 1, wr_timeout);
}
#ifndef BACKENDNAME
/* Copy from a USB data pipe to a file with optional header */
static void
record_head (usb_dev_handle * udev, char *fname, int bytes, char *header)
{
FILE *fp;
unsigned char buff[65536];
int len;
int toread;
fp = fopen (fname, "wb");
if (header)
fprintf (fp, "%s", header);
do
{
toread = (bytes > 65536) ? 65536 : bytes;
len = usb_bulk_read (udev, 1, buff, toread, rd_timeout);
if (len > 0)
{
fwrite (buff, len, 1, fp);
bytes -= len;
}
else
{
DBG (2, "TIMEOUT\n");
}
}
while (bytes);
fclose (fp);
}
/* Copy from a USB data pipe to a file without header */
static void
record (usb_dev_handle * udev, char *fname, int bytes)
{
record_head (udev, fname, bytes, "");
}
#endif
static int
max (int a, int b)
{
return (a > b) ? a : b;
}
#define DPI1200SHUFFLE 6
static void
record_line (int reset,
usb_dev_handle * udev,
unsigned char *storeline,
int dpi, int scanpix, int gray, int bpp16,
int *save_i,
unsigned char **save_scan_line,
unsigned char **save_dpi1200_remap,
unsigned char **save_color_remap)
{
int len;
unsigned char *scan_line, *dpi1200_remap;
unsigned char *color_remap;
int i;
int red_delay, blue_delay, green_delay;
int j;
int linelen;
int pixsize;
unsigned char *ptrcur, *ptrprev;
unsigned char *savestoreline;
int lineptr, outline, bufflines;
i = *save_i;
scan_line = *save_scan_line;
dpi1200_remap = *save_dpi1200_remap;
color_remap = *save_color_remap;
pixsize = (gray ? 1 : 3) * (bpp16 ? 2 : 1);
linelen = scanpix * pixsize;
if (gray)
{
red_delay = 0;
blue_delay = 0;
green_delay = 0;
}
else if (dpi == 150)
{
red_delay = 0;
blue_delay = 6;
green_delay = 3;
}
else if (dpi == 300)
{
red_delay = 0;
blue_delay = 12;
green_delay = 6;
}
else if (dpi == 600)
{
red_delay = 0;
blue_delay = 24;
green_delay = 12;
}
else /*(dpi==1200) */
{
red_delay = 0;
blue_delay = 48;
green_delay = 24;
}
bufflines = max (max (red_delay, blue_delay), green_delay) + 1;
if (reset)
{
if (dpi1200_remap)
free (dpi1200_remap);
if (scan_line)
free (scan_line);
if (color_remap)
free (color_remap);
*save_color_remap = color_remap =
(unsigned char *) malloc (bufflines * linelen);
*save_scan_line = scan_line = (unsigned char *) calloc (linelen, 1);
if (dpi == 1200)
*save_dpi1200_remap = dpi1200_remap =
(unsigned char *) calloc (linelen, DPI1200SHUFFLE);
else
*save_dpi1200_remap = dpi1200_remap = NULL;
*save_i = i = 0; /* i is our linenumber */
}
while (1)
{ /* We'll exit inside the loop... */
len = usb_bulk_read (udev, 1, scan_line, linelen, rd_timeout);
if (dpi == 1200)
{
ptrcur = dpi1200_remap + (linelen * (i % DPI1200SHUFFLE));
ptrprev =
dpi1200_remap +
(linelen * ((i - (DPI1200SHUFFLE - 2)) % DPI1200SHUFFLE));
}
else
{
ptrcur = scan_line;
ptrprev = NULL;
}
if (gray)
{
memcpy (ptrcur, scan_line, linelen);
}
else
{
int pixsize = bpp16 ? 2 : 1;
int pix = linelen / (3 * pixsize);
unsigned char *outbuff = ptrcur;
outline = i;
lineptr = i % bufflines;
memcpy (color_remap + linelen * lineptr, scan_line, linelen);
outline++;
if (outline > bufflines)
{
int redline = (outline + red_delay) % bufflines;
int greenline = (outline + green_delay) % bufflines;
int blueline = (outline + blue_delay) % bufflines;
unsigned char *rp, *gp, *bp;
rp = color_remap + linelen * redline;
gp = color_remap + linelen * greenline + 1 * pixsize;
bp = color_remap + linelen * blueline + 2 * pixsize;
for (j = 0; j < pix; j++)
{
if (outbuff)
{
*(outbuff++) = *rp;
if (pixsize == 2)
*(outbuff++) = *(rp + 1);
*(outbuff++) = *gp;
if (pixsize == 2)
*(outbuff++) = *(gp + 1);
*(outbuff++) = *bp;
if (pixsize == 2)
*(outbuff++) = *(bp + 1);
}
rp += 3 * pixsize;
gp += 3 * pixsize;
bp += 3 * pixsize;
}
}
lineptr = (lineptr + 1) % bufflines;
}
if (dpi != 1200)
{
if (i > blue_delay)
{
savestoreline = storeline;
for (j = 0; j < scanpix; j++)
{
memcpy (storeline, ptrcur + linelen - (j + 1) * pixsize,
pixsize);
storeline += pixsize;
}
if (dpi == 150)
{
/* 150 DPI skips every 4th returned line */
if (i % 4)
{
i++;
*save_i = i;
if (bpp16)
fix_endian_short ((unsigned short *) storeline,
scanpix);
return;
}
storeline = savestoreline;
}
else
{
i++;
*save_i = i;
if (bpp16)
fix_endian_short ((unsigned short *) storeline, scanpix);
return;
}
}
}
else /* dpi==1200 */
{
if (i > (DPI1200SHUFFLE + blue_delay))
{
for (j = 0; j < scanpix; j++)
{
if (1 == (j & 1))
memcpy (storeline, ptrcur + linelen - (j + 1) * pixsize,
pixsize);
else
memcpy (storeline, ptrprev + linelen - (j + 1) * pixsize,
pixsize);
storeline += pixsize;
} /* end for */
i++;
*save_i = i;
if (bpp16)
fix_endian_short ((unsigned short *) storeline, scanpix);
return;
} /* end if >dpi1200shuffle */
} /* end if dpi1200 */
i++;
} /* end for */
}
#ifndef BACKENDNAME
/* Record an image to a file with remapping/reordering/etc. */
void
record_image (usb_dev_handle * udev, char *fname, int dpi,
int scanpix, int scanlines, int gray, char *head, int bpp16)
{
FILE *fp;
int i;
int save_i;
unsigned char *save_scan_line;
unsigned char *save_dpi1200_remap;
unsigned char *save_color_remap;
unsigned char *storeline;
save_i = 0;
save_scan_line = save_dpi1200_remap = save_color_remap = NULL;
storeline =
(unsigned char *) malloc (scanpix * (gray ? 1 : 3) * (bpp16 ? 2 : 1));
fp = fopen (fname, "wb");
if (head)
fprintf (fp, "%s", head);
for (i = 0; i < scanlines; i++)
{
record_line ((i == 0) ? 1 : 0, udev, storeline, dpi, scanpix, gray,
bpp16, &save_i, &save_scan_line, &save_dpi1200_remap,
&save_color_remap);
fwrite (storeline, scanpix * (gray ? 1 : 3) * (bpp16 ? 2 : 1), 1, fp);
}
fclose (fp);
if (save_scan_line)
free (save_scan_line);
if (save_dpi1200_remap)
free (save_dpi1200_remap);
if (save_color_remap)
free (save_color_remap);
free (storeline);
}
#endif
static void
record_mem (usb_dev_handle * udev, unsigned char **dest, int bytes)
{
unsigned char *mem;
unsigned char buff[65536];
int len;
mem = (unsigned char *) malloc (bytes);
*dest = mem;
do
{
len =
usb_bulk_read (udev, 1, buff, bytes > 65536 ? 65536 : bytes,
rd_timeout);
if (len > 0)
{
memcpy (mem, buff, len);
bytes -= len;
mem += len;
}
}
while (bytes);
}
static void
reset_scanner (usb_dev_handle * udev)
{
unsigned char rd_byte;
DBG (2, "+reset_scanner\n");
write_regs (udev, 5, 0x83, 0x00, 0xa3, 0xff, 0xa4, 0xff, 0xa1, 0xff,
0xa2, 0xff);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
write_regs (udev, 2, 0xbe, 0x00, 0x84, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00,
0x88, 0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00,
0xc2, 0x00, 0xc3, 0x00, 0xc4, 0x00, 0xc5, 0x00,
0xc6, 0x00, 0xc7, 0x00, 0xc8, 0x00, 0xc0, 0x00);
write_regs (udev, 16, 0x84, 0x94, 0x80, 0xd1, 0x80, 0xc1, 0x82, 0x7f,
0xcf, 0x04, 0xc1, 0x02, 0xc2, 0x00, 0xc3, 0x06,
0xc4, 0xff, 0xc5, 0x40, 0xc6, 0x8c, 0xc7, 0xdc,
0xc8, 0x20, 0xc0, 0x72, 0x89, 0xff, 0x86, 0xff);
write_regs (udev, 7, 0xa8, 0x80, 0x83, 0xa2, 0x85, 0xc8, 0x83, 0x82,
0x85, 0xaf, 0x83, 0x00, 0x93, 0x00);
write_regs (udev, 3, 0xa8, 0x0a, 0x8c, 0x08, 0x94, 0x00);
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
DBG (2, "-reset_scanner\n");
}
static void
poll1 (usb_dev_handle * udev)
{
unsigned char rd_byte;
DBG (2, "+poll1\n");
do
{
write_regs (udev, 1, 0x97, 0x00);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
}
while (0 == (rd_byte & 0x40));
DBG (2, "-poll1\n");
}
static void
poll2 (usb_dev_handle * udev)
{
unsigned char rd_byte;
DBG (2, "+poll2\n");
do
{
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
}
while (0 == (rd_byte & 0x02));
DBG (2, "-poll2\n");
}
#ifndef BACKENDNAME
static void
check_buttons (usb_dev_handle * udev, int *scan, int *print, int *mail)
{
unsigned char rd_byte;
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
if (scan)
{
if (0 == (rd_byte & 1))
*scan = 1;
else
*scan = 0;
}
if (print)
{
if (0 == (rd_byte & 2))
*print = 1;
else
*print = 0;
}
if (mail)
{
if (0 == (rd_byte & 4))
*mail = 1;
else
*mail = 0;
}
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
idle_ab (udev);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
idle_ab (udev);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
idle_ab (udev);
}
#endif
static int
lut (int val, double gain, int offset)
{
/* int offset = 1800; */
/* double exponent = 3.5; */
return (offset + 8192.0 * (pow ((8192.0 - val) / 8192.0, gain)));
}
static void
calc_lightmap (unsigned short *buff,
unsigned short *storage, int index, int dpi,
double gain, int offset)
{
int val, line;
int px = 5632;
int i;
line = px * 3;
for (i = 0; i < px; i++)
{
if ((i >= 2) && (i <= (px - 2)))
{
val = 0;
val += 1 * buff[i * 3 + index - 3 * 2];
val += 3 * buff[i * 3 + index - 3 * 1];
val += 5 * buff[i * 3 + index + 3 * 0];
val += 3 * buff[i * 3 + index + 3 * 1];
val += 1 * buff[i * 3 + index + 3 * 2];
val += 2 * buff[i * 3 + index - 3 * 1 + line];
val += 3 * buff[i * 3 + index + 3 * 0 + line];
val += 2 * buff[i * 3 + index + 3 * 1 + line];
val += 1 * buff[i * 3 + index + 3 * 0 + 2 * line];
val /= 21;
}
else
{
val = 1 * buff[i * 3 + index];
}
val = val >> 3;
if (val > 8191)
val = 8191;
val = lut (val, gain, offset);
if (val > 8191)
val = 8191;
if (val < 0)
val = 0;
storage[i * (dpi == 1200 ? 2 : 1)] = val;
if (dpi == 1200)
storage[i * 2 + 1] = val;
}
fix_endian_short (storage, (dpi == 1200) ? i * 2 : i);
}
/*#define VALMAP 0x1fff */
/*#define SCANMAP 0x2000*/
#define RAWPIXELS600 7320
#define RAWPIXELS1200 14640
static void
select_pixels (unsigned short *map, int dpi, int start, int end)
{
int i;
int skip, offset;
unsigned short VALMAP = 0x1fff;
unsigned short SCANMAP = 0x2000;
fix_endian_short (&VALMAP, 1);
fix_endian_short (&SCANMAP, 1);
/* Clear the pixel-on flags for all bits */
for (i = 0; i < ((dpi == 1200) ? RAWPIXELS1200 : RAWPIXELS600); i++)
map[i] &= VALMAP;
/* 300 and 150 have subsampling */
if (dpi == 300)
skip = -2;
else if (dpi == 150)
skip = -4;
else
skip = -1;
/* 1200 has 2x pixels so start at 2x the offset */
if (dpi == 1200)
offset = 234 + (8.5 * 1200);
else
offset = 117 + (8.5 * 600);
if (0 == (offset & 1))
offset++;
DBG (2, "offset=%d start=%d skip=%d\n", offset, start, skip);
for (i = 0; i < end; i++)
{
int x;
x = offset + (start * skip) + (i * skip);
if (x < 0 || x > ((dpi == 1200) ? RAWPIXELS1200 : RAWPIXELS600))
DBG (2, "ERR %d\n", x);
else
map[x] |= SCANMAP;
}
}
static void
set_lightmap_white (unsigned short *map, int dpi, int color)
{
int i;
unsigned short VALMAP = 0x1fff;
unsigned short SCANMAP = 0x2000;
fix_endian_short (&VALMAP, 1);
fix_endian_short (&SCANMAP, 1);
if (dpi != 1200)
{
memset (map, 0, RAWPIXELS600 * 2);
if (color != 0)
return; /* Only 1st has enables... */
for (i = 0; i < 22; i++)
map[7 + i] = SCANMAP; /* Get some black... */
for (i = 0; i < 1024; i++)
map[2048 + i] = SCANMAP; /* And some white... */
}
else
{
memset (map, 0, RAWPIXELS1200 * 2);
if (color != 0)
return;
for (i = 16; i < 61; i++)
map[i] = SCANMAP;
for (i = 4076; i < 6145; i++)
map[i] = SCANMAP;
/* 3rd is all clear */
}
}
static void
set_lamp_timer (usb_dev_handle * udev, int timeout_in_mins)
{
write_regs (udev, 7, 0xa8, 0x80, 0x83, 0xa2, 0x85, 0xc8, 0x83, 0x82,
0x85, 0xaf, 0x83, 0x00, 0x93, 0x00);
write_regs (udev, 3, 0xa8, timeout_in_mins * 2, 0x8c, 0x08, 0x94, 0x00);
idle_ab (udev);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0x26, 0x83, 0x00, 0x8d, 0xff);
}
static void
calculate_lut8 (double *poly, int skip, unsigned char *dest)
{
int i;
double sum, x;
if (!poly || !dest)
return;
for (i = 0; i < 8192; i += skip)
{
sum = poly[0];
x = (double) i;
sum += poly[1] * x;
x = x * i;
sum += poly[2] * x;
x = x * i;
sum += poly[3] * x;
x = x * i;
sum += poly[4] * x;
x = x * i;
sum += poly[5] * x;
x = x * i;
sum += poly[6] * x;
x = x * i;
sum += poly[7] * x;
x = x * i;
sum += poly[8] * x;
x = x * i;
sum += poly[9] * x;
x = x * i;
if (sum < 0)
sum = 0;
if (sum > 255)
sum = 255;
*dest = (unsigned char) sum;
dest++;
}
}
static void
download_lut8 (usb_dev_handle * udev, int dpi, int incolor)
{
double color[10] = { 0.0, 1.84615261590892E-01, -2.19613868292657E-04,
1.79549523214101E-07, -8.69378513113239E-11,
2.56694911984996E-14, -4.67288886157239E-18,
5.11622894146250E-22, -3.08729724411991E-26,
7.88581670873938E-31
};
double gray[10] = { 0.0, 1.73089945056694E-01, -1.39794924306080E-04,
9.70266873814926E-08, -4.57503008236968E-11,
1.37092321631794E-14, -2.54395068387198E-18,
2.82432084125966E-22, -1.71787408822688E-26,
4.40306800664567E-31
};
unsigned char *lut;
int len;
DBG (2, "+download_lut8\n");
switch (dpi)
{
case 150:
case 300:
case 600:
lut = (unsigned char *) malloc (4096);
if (!lut)
return;
if (!incolor)
{
calculate_lut8 (gray, 2, lut);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x20, 0xb2, 0x07, 0xb3, 0xff,
0xb4, 0x2f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, 0x1000, 0x00);
len = usb_bulk_write (udev, 2, lut, 4096, wr_timeout);
}
else
{
calculate_lut8 (color, 2, lut);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x10, 0xb2, 0x07, 0xb3, 0xff,
0xb4, 0x1f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, 0x1000, 0x00);
len = usb_bulk_write (udev, 2, lut, 4096, wr_timeout);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x20, 0xb2, 0x07, 0xb3, 0xff,
0xb4, 0x2f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, 0x1000, 0x00);
len = usb_bulk_write (udev, 2, lut, 4096, wr_timeout);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x30, 0xb2, 0x07, 0xb3, 0xff,
0xb4, 0x3f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, 0x1000, 0x00);
len = usb_bulk_write (udev, 2, lut, 4096, wr_timeout);
}
break;
case 1200:
default:
lut = (unsigned char *) malloc (8192);
if (!lut)
return;
if (!incolor)
{
calculate_lut8 (gray, 1, lut);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x40, 0xb2, 0x06, 0xb3, 0xff,
0xb4, 0x5f, 0xb5, 0x06);
write_vctl (udev, 0x0c, 0x0002, 0x2000, 0x00);
len = usb_bulk_write (udev, 2, lut, 8192, wr_timeout);
}
else
{
calculate_lut8 (color, 1, lut);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x20, 0xb2, 0x06, 0xb3, 0xff,
0xb4, 0x3f, 0xb5, 0x06);
write_vctl (udev, 0x0c, 0x0002, 0x2000, 0x00);
len = usb_bulk_write (udev, 2, lut, 8192, wr_timeout);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x40, 0xb2, 0x06, 0xb3, 0xff,
0xb4, 0x5f, 0xb5, 0x06);
write_vctl (udev, 0x0c, 0x0002, 0x2000, 0x00);
len = usb_bulk_write (udev, 2, lut, 8192, wr_timeout);
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x60, 0xb2, 0x06, 0xb3, 0xff,
0xb4, 0x7f, 0xb5, 0x06);
write_vctl (udev, 0x0c, 0x0002, 0x2000, 0x00);
len = usb_bulk_write (udev, 2, lut, 8192, wr_timeout);
}
break;
}
free (lut);
DBG (2, "-download_lut8\n");
}
static void
set_gain_black (usb_dev_handle * udev,
int r_gain, int g_gain, int b_gain,
int r_black, int g_black, int b_black)
{
write_regs (udev, 1, 0x80, 0x00);
write_regs (udev, 1, 0x80, 0x01);
write_regs (udev, 1, 0x04, 0x80);
write_regs (udev, 1, 0x04, 0x00);
write_regs (udev, 1, 0x00, 0x00);
write_regs (udev, 1, 0x01, 0x03);
write_regs (udev, 1, 0x02, 0x04);
write_regs (udev, 1, 0x03, 0x11);
write_regs (udev, 1, 0x05, 0x00);
write_regs (udev, 1, 0x28, r_gain);
write_regs (udev, 1, 0x29, g_gain);
write_regs (udev, 1, 0x2a, b_gain);
write_regs (udev, 1, 0x20, r_black);
write_regs (udev, 1, 0x21, g_black);
write_regs (udev, 1, 0x22, b_black);
write_regs (udev, 1, 0x24, 0x00);
write_regs (udev, 1, 0x25, 0x00);
write_regs (udev, 1, 0x26, 0x00);
}
/* Handle short endianness issues */
static void
fix_endian_short (unsigned short *data, int count)
{
unsigned short testvalue = 255;
unsigned char *firstbyte = (unsigned char *) &testvalue;
int i;
if (*firstbyte == 255)
return; /* INTC endianness */
DBG (2, "swapping endiannes...\n");
for (i = 0; i < count; i++)
data[i] = ((data[i] >> 8) & 0x00ff) | ((data[i] << 8) & 0xff00);
}

Wyświetl plik

@ -0,0 +1,146 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#include <stdio.h>
#include <stdarg.h>
#ifndef BACKENDNAME
#include <usb.h>
static usb_dev_handle *find_device (unsigned int idVendor,
unsigned int idProduct);
#else
#include "../include/sane/sanei_usb.h"
#ifndef USBWRAPPER
#define USBWRAPPER
#define usb_dev_handle SANE_Int
#define usb_control_msg my_usb_control_msg
#define usb_bulk_read my_usb_bulk_read
#define usb_bulk_write my_usb_bulk_write
static int my_usb_bulk_write (usb_dev_handle * dev, int ep,
unsigned char *bytes,
int size, int timeout);
static int my_usb_bulk_read (usb_dev_handle * dev, int ep,
unsigned char *bytes,
int size, int timeout);
static int my_usb_control_msg (usb_dev_handle * dev, int requesttype,
int request, int value, int index,
unsigned char *bytes,
int size, int timeout);
#endif /* USBWRAPPER */
#endif
#include "sm3840_params.h"
static void idle_ab (usb_dev_handle * udev);
static void write_regs (usb_dev_handle * udev, int regs, unsigned char reg1,
unsigned char val1,
... /*unsigned char reg, unsigned char val, ... */ );
static int write_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char byte);
static int read_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char *byte);
#ifndef BACKENDNAME
static void record (usb_dev_handle * udev, char *fname, int bytes);
static void record_image (usb_dev_handle * udev, char *fname, int dpi,
int scanpix, int scanlines, int gray, char *head,
int bpp16);
static void check_buttons (usb_dev_handle * udev, int *scan, int *print,
int *mail);
static void record_head (usb_dev_handle * udev, char *fname, int bytes,
char *header);
#endif
static void poll1 (usb_dev_handle * udev);
static void poll2 (usb_dev_handle * udev);
static void reset_scanner (usb_dev_handle * udev);
static void set_lightmap_white (unsigned short *map, int dpi, int color);
static void calc_lightmap (unsigned short *buff,
unsigned short *storage, int index, int dpi,
double gain, int offset);
static void select_pixels (unsigned short *map, int dpi, int start, int end);
static void record_mem (usb_dev_handle * udev, unsigned char **dest,
int bytes);
static void set_lamp_timer (usb_dev_handle * udev, int timeout_in_mins);
static void set_gain_black (usb_dev_handle * udev,
int r_gain, int g_gain, int b_gain,
int r_black, int g_black, int b_black);
static void idle_ab (usb_dev_handle * udev);
static void write_regs (usb_dev_handle * udev, int regs, unsigned char reg1,
unsigned char val1,
... /*unsigned char reg, unsigned char val, ... */ );
static int write_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char byte);
static int read_vctl (usb_dev_handle * udev, int request, int value,
int index, unsigned char *byte);
static void download_lut8 (usb_dev_handle * udev, int dpi, int incolor);
static void record_line (int reset,
usb_dev_handle * udev,
unsigned char *storeline,
int dpi, int scanpix, int gray, int bpp16,
int *save_i,
unsigned char **save_scan_line,
unsigned char **save_dpi1200_remap,
unsigned char **save_color_remap);
static void prepare_params (SM3840_Params * params);
static void fix_endian_short (unsigned short *data, int count);
#define rd_timeout 10000
#define wr_timeout 10000

Wyświetl plik

@ -0,0 +1,69 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef _SM3840_Params
#define _SM3840_Params
typedef struct SM3840_Params
{
int gray; /* 0, 1 */
int dpi; /* 150, 300, 600, 1200 */
int bpp; /* 8, 16 */
double gain; /* 0.01...9.9 */
int offset; /* 0..4095 */
int lamp; /* 1..15 mins */
/* Input to configure(), in inches */
double top, left;
double width, height;
/* Output from configure(), in pixels */
int topline;
int scanlines;
int leftpix;
int scanpix;
int linelen; /* bytes per line */
} SM3840_Params;
#endif

Wyświetl plik

@ -0,0 +1,938 @@
/* sane - Scanner Access Now Easy.
ScanMaker 3840 Backend
Copyright (C) 2005 Earle F. Philhower, III
earle@ziplabel.com - http://www.ziplabel.com
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.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#include <stdio.h>
#include <stdarg.h>
#include "sm3840_lib.h"
#ifndef BACKENDNAME
static void setup_scan (usb_dev_handle * udev, SM3840_Params * p,
char *stname, int raw, int nohead);
#else
static void setup_scan (usb_dev_handle * udev, SM3840_Params * p);
#endif
#ifndef BACKENDNAME
#include "sm3840_lib.c"
int
main (int argc, char *argv[])
{
int i;
int gray = 0;
int dpi = 1200;
int bpp16 = 0;
int raw = 0;
int nohead = 0;
double gain = 3.5;
int offset = 1800;
usb_dev_handle *udev;
char *stname;
double topin, botin, leftin, rightin;
int topline, scanlines, leftpix, scanpix;
stname = NULL;
topin = 0.0;
botin = 11.7;
leftin = 0.0;
rightin = 8.5;
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "-300"))
dpi = 300;
else if (!strcmp (argv[i], "-600"))
dpi = 600;
else if (!strcmp (argv[i], "-1200"))
dpi = 1200;
else if (!strcmp (argv[i], "-150"))
dpi = 150;
else if (!strcmp (argv[i], "-top"))
topin = atof (argv[++i]);
else if (!strcmp (argv[i], "-bot"))
botin = atof (argv[++i]);
else if (!strcmp (argv[i], "-left"))
leftin = atof (argv[++i]);
else if (!strcmp (argv[i], "-right"))
rightin = atof (argv[++i]);
else if (!strcmp (argv[i], "-gain"))
gain = atof (argv[++i]);
else if (!strcmp (argv[i], "-offset"))
offset = atoi (argv[++i]);
else if (!strcmp (argv[i], "-gray"))
gray = 1;
else if (!strcmp (argv[i], "-16bpp"))
bpp16 = 1;
else if (!strcmp (argv[i], "-raw"))
raw = 1;
else if (!strcmp (argv[i], "-nohead"))
nohead = 1;
else
stname = argv[i];
}
SM3840_Params params;
params.gray = gray;
params.dpi = dpi;
params.bpp = bpp16 ? 16 : 8;
params.gain = gain;
params.offset = offset;
params.lamp = 15;
params.top = topin;
params.left = leftin;
params.height = botin - topin;
params.width = rightin - leftin;
prepare_params (&params);
udev = find_device (0x05da, 0x30d4);
if (!udev)
fprintf (stderr, "Unable to open scanner.\n");
else
setup_scan (udev, &params, stname, raw, nohead);
return 0;
}
#endif
#ifndef BACKENDNAME
static void
setup_scan (usb_dev_handle * udev, SM3840_Params * p,
char *stname, int raw, int nohead)
#else
static void
setup_scan (usb_dev_handle * udev, SM3840_Params * p)
#endif
{
int gray = p->gray ? 1 : 0;
int dpi = p->dpi;
int bpp16 = (p->bpp == 16) ? 1 : 0;
double gain = p->gain;
int offset = p->offset;
int topline = p->topline;
int scanlines = p->scanlines;
int leftpix = p->leftpix;
int scanpix = p->scanpix;
int len;
unsigned char hello[2] = { 0x55, 0xaa };
unsigned char howdy[3];
unsigned short *whitebalance;
int whitebalancesize = (dpi == 1200) ? 12672 : 6528;
unsigned short *whitemap;
int whitemapsize = (dpi == 1200) ? 29282 : 14642;
unsigned short *whitescan;
unsigned short *lightmap;
unsigned int topreg, botreg;
int redreg, greenreg, bluereg, donered, donegreen, doneblue;
int rgreg = 0x00;
int ggreg = 0x00;
int bgreg = 0x00;
int i, j;
int red, green, blue;
unsigned char rd_byte;
#ifndef BACKENDNAME
char fname[64];
char head[128];
len = usb_set_configuration (udev, 1);
len = usb_claim_interface (udev, 0);
len = usb_clear_halt (udev, 1);
len = usb_clear_halt (udev, 2);
len = usb_clear_halt (udev, 3);
#endif
DBG (2, "params.gray = %d;\n", p->gray);
DBG (2, "params.dpi = %d\n", p->dpi);
DBG (2, "params.bpp = %d\n", p->bpp);
DBG (2, "params.gain = %f\n", p->gain);
DBG (2, "params.offset = %d\n", p->offset);
DBG (2, "params.lamp = %d\n", p->lamp);
DBG (2, "params.top = %f\n", p->top);
DBG (2, "params.left = %f\n", p->left);
DBG (2, "params.height = %f\n", p->height);
DBG (2, "params.width = %f\n", p->width);
DBG (2, "params.topline = %d\n", p->topline);
DBG (2, "params.scanlines = %d\n", p->scanlines);
DBG (2, "params.leftpix = %d\n", p->leftpix);
DBG (2, "params.scanpix = %d\n", p->scanpix);
DBG (2, "params.linelen = %d\n", p->linelen);
reset_scanner (udev);
idle_ab (udev);
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0b, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 7, 0xa8, 0x80, 0x83, 0xa2, 0x85, 0x01, 0x83, 0x82, 0x85,
0x00, 0x83, 0x00, 0x93, 0x00);
write_regs (udev, 1, 0xa8, 0x80);
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xfe, 0x83, 0x00, 0x8d, 0xff);
write_regs (udev, 1, 0x97, 0x00);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 8, 0x80, 0x00, 0x84, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0x86,
0x00, 0x89, 0x00, 0x94, 0x00, 0x01, 0x02);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 1, 0x94, 0x51);
write_regs (udev, 1, 0xb0, 0x00);
write_regs (udev, 1, 0xb1, 0x00);
write_regs (udev, 1, 0xb2, 0x00);
write_regs (udev, 1, 0xb3, 0x00);
write_regs (udev, 1, 0xb4, 0x10);
write_regs (udev, 1, 0xb5, 0x1f);
write_regs (udev, 1, 0xb0, 0x00);
write_regs (udev, 1, 0xb1, 0x00);
write_regs (udev, 1, 0xb2, 0x00);
write_vctl (udev, 0x0c, 0x0002, 0x0002, 0x00);
len = usb_bulk_write (udev, 2, hello, 2, wr_timeout);
write_regs (udev, 1, 0xb0, 0x00);
write_regs (udev, 1, 0xb1, 0x00);
write_regs (udev, 1, 0xb2, 0x00);
write_vctl (udev, 0x0c, 0x0003, 0x0003, 0x00);
len = usb_bulk_read (udev, 1, howdy, 3, rd_timeout);
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xfe, 0x83, 0x00, 0x8d, 0xff);
write_regs (udev, 1, 0x97, 0x00);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 8, 0x80, 0x00, 0x84, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0x86,
0x00, 0x89, 0x00, 0x94, 0x00, 0x01, 0x02);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xff, 0x83, 0x00, 0x8d, 0xff);
write_regs (udev, 5, 0x83, 0x00, 0xa3, 0xff, 0xa4, 0xff, 0xa1, 0xff, 0xa2,
0xf7);
write_regs (udev, 4, 0x83, 0x22, 0x87, 0x01, 0x83, 0x02, 0x87, 0x16);
write_regs (udev, 11, 0xa0, 0x00, 0x9c, 0x00, 0x9f, 0x00, 0x9d, 0x00, 0x9e,
0x00, 0xa0, 0x00, 0xce, 0x0c, 0x83, 0x20, 0xa5, 0x00, 0xa6,
0x00, 0xa7, 0x00);
set_gain_black (udev, 0x01, 0x01, 0x01, 0xaa, 0xaa, 0xaa);
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x02, 0x98,
0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x03, 0x98, 0x00, 0x99,
0x00, 0x9a, 0x00);
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x98, 0x83, 0x82, 0x85, 0x3a);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (dpi == 1200)
write_regs (udev, 1, 0x94, 0x51);
else
write_regs (udev, 1, 0x94, 0x61);
whitemap = (unsigned short *) malloc (whitemapsize);
set_lightmap_white (whitemap, dpi, 0);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x06, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x06);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x40, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0x7f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
len =
usb_bulk_write (udev, 2, (unsigned char *) whitemap, whitemapsize,
wr_timeout);
set_lightmap_white (whitemap, dpi, 1);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0x7f, 0xb5, 0x07);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xbf, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
len =
usb_bulk_write (udev, 2, (unsigned char *) whitemap, whitemapsize,
wr_timeout);
set_lightmap_white (whitemap, dpi, 2);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x07);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0xc0, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
len =
usb_bulk_write (udev, 2, (unsigned char *) whitemap, whitemapsize,
wr_timeout);
free (whitemap);
/* Move to head... */
idle_ab (udev);
write_regs (udev, 1, 0x97, 0x00);
idle_ab (udev);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
idle_ab (udev);
write_regs (udev, 16, 0x84, 0x94, 0x80, 0xd1, 0x80, 0xc1, 0x82, 0x7f, 0xcf,
0x04, 0xc1, 0x02, 0xc2, 0x00, 0xc3, 0x06, 0xc4, 0xff, 0xc5,
0x40, 0xc6, 0x8c, 0xc7, 0xdc, 0xc8, 0x20, 0xc0, 0x72, 0x89,
0xff, 0x86, 0xff);
poll1 (udev);
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x01, 0x83, 0x82, 0x85, 0x00);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (dpi == 1200)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8, 0x77,
0xb9, 0x1e);
else
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8, 0x3b,
0xb9, 0x1f);
write_regs (udev, 5, 0xc0, 0x00, 0x84, 0x00, 0x80, 0xa1, 0xcf, 0x04, 0x82,
0x00);
if (dpi == 1200)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x02, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x01, 0xbd, 0x01, 0x88, 0xa4, 0xc1, 0x02, 0xc2, 0x00,
0xc3, 0x02, 0xc4, 0x01, 0xc5, 0x01, 0xc6, 0xa3, 0xc7, 0xa4,
0xc8, 0x04, 0xc0, 0xd2, 0x89, 0x05, 0x86, 0x00);
else
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x01, 0xbd, 0x01, 0x88, 0xd0, 0xc1, 0x01, 0xc2, 0x00,
0xc3, 0x04, 0xc4, 0x01, 0xc5, 0x01, 0xc6, 0xcf, 0xc7, 0xd0,
0xc8, 0x14, 0xc0, 0xd1, 0x89, 0x0a, 0x86, 0x00);
write_regs (udev, 8, 0xbb, 0x01, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80, 0xbf,
0x00, 0x90, 0x40, 0x91, 0x00, 0x83, 0x82);
write_regs (udev, 1, 0xbe, 0x0d);
write_vctl (udev, 0x0c, 0x0003, 0x0001, 0x00);
whitebalance = (unsigned short *) malloc (whitebalancesize);
len = usb_bulk_read (udev, 1, &rd_byte, 1, rd_timeout);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
len =
usb_bulk_read (udev, 1, (unsigned char *) whitebalance, whitebalancesize,
rd_timeout);
write_regs (udev, 2, 0xbe, 0x00, 0x84, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
redreg = greenreg = bluereg = 0x80;
red = green = blue = 0;
donered = donegreen = doneblue = 0;
DBG (2, "setting blackpoint\n");
for (j = 0; (j < 16) && !(donered && donegreen && doneblue); j++)
{
set_gain_black (udev, 0x01, 0x01, 0x01, redreg, greenreg, bluereg);
if (dpi == 1200)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x77, 0xb9, 0x1e);
else
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x3b, 0xb9, 0x1f);
write_regs (udev, 8, 0xbb, 0x01, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x40, 0x91, 0x00, 0x83, 0x82);
write_regs (udev, 1, 0xbe, 0x0d);
write_vctl (udev, 0x0c, 0x0003, 0x0001, 0x00);
len = usb_bulk_read (udev, 1, &rd_byte, 1, rd_timeout);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
len =
usb_bulk_read (udev, 1, (unsigned char *) whitebalance,
whitebalancesize, rd_timeout);
if (!donered)
{
red = (whitebalance[0] + whitebalance[3] + whitebalance[6]) / 3;
if (red > 0x1000)
redreg += 0x10;
else if (red > 0x500)
redreg += 0x08;
else if (red > 0x0010)
redreg++;
else
donered = 1;
}
if (!donegreen)
{
green = (whitebalance[1] + whitebalance[4] + whitebalance[7]) / 3;
if (green > 0x1000)
greenreg += 0x10;
else if (green > 0x0500)
greenreg += 0x08;
else if (green > 0x0010)
greenreg++;
else
donegreen = 1;
}
if (!doneblue)
{
blue = (whitebalance[2] + whitebalance[5] + whitebalance[8]) / 3;
if (blue > 0x1000)
bluereg += 0x10;
else if (blue > 0x0500)
bluereg += 0x08;
else if (blue > 0x0010)
bluereg++;
else
doneblue = 1;
}
DBG (2, "red=%d(%d)%02x, green=%d(%d)%02x, blue=%d(%d)%02x\n",
red, donered, redreg, green, donegreen, greenreg,
blue, doneblue, bluereg);
write_regs (udev, 2, 0xbe, 0x00, 0x84, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
}
DBG (2, "setting whitepoint\n");
donegreen = donered = doneblue = 0;
for (j = 0; (j < 16) && !(donered && donegreen && doneblue); j++)
{
set_gain_black (udev, rgreg, ggreg, bgreg, redreg, greenreg, bluereg);
if (dpi == 1200)
idle_ab (udev);
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8, 0x3b,
0xb9, 0x1f);
if (dpi == 1200)
idle_ab (udev);
write_regs (udev, 8, 0xbb, 0x01, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x40, 0x91, 0x00, 0x83, 0x82);
write_regs (udev, 1, 0xbe, 0x0d);
write_vctl (udev, 0x0c, 0x0003, 0x0001, 0x00);
len = usb_bulk_read (udev, 1, &rd_byte, 1, rd_timeout);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
len =
usb_bulk_read (udev, 1, (unsigned char *) whitebalance,
whitebalancesize, rd_timeout);
if (!donered)
{
red =
(whitebalance[180 * 3 + 0] + whitebalance[180 * 3 + 3] +
whitebalance[180 * 3 + 6]) / 3;
if (red < 0x5000)
rgreg += 0x02;
else if (red < 0x8000)
rgreg += 0x01;
else
donered = 1;
}
if (!donegreen)
{
green =
(whitebalance[180 * 3 + 1] + whitebalance[180 * 3 + 4] +
whitebalance[180 * 3 + 7]) / 3;
if (green < 0x5000)
ggreg += 0x02;
else if (green < 0x8000)
ggreg += 0x01;
else
donegreen = 1;
}
if (!doneblue)
{
blue =
(whitebalance[180 * 3 + 2] + whitebalance[180 * 3 + 5] +
whitebalance[180 * 3 + 8]) / 3;
if (blue < 0x5000)
bgreg += 0x02;
else if (blue < 0x8000)
bgreg += 0x01;
else
doneblue = 1;
}
DBG (2, "red=%d(%d)%02x, green=%d(%d)%02x, blue=%d(%d)%02x\n",
red, donered, rgreg, green, donegreen, ggreg, blue, doneblue,
bgreg);
write_regs (udev, 2, 0xbe, 0x00, 0x84, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
}
free (whitebalance);
/* One step down for optimal contrast... */
if (rgreg)
rgreg--;
if (bgreg)
bgreg--;
if (ggreg)
ggreg--;
write_regs (udev, 8, 0x80, 0x00, 0x84, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0x86,
0x00, 0x89, 0x00, 0x94, 0x00, 0x01, 0x02);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xff, 0x83, 0x00, 0x8d, 0xff);
write_regs (udev, 5, 0x83, 0x00, 0xa3, 0xff, 0xa4, 0xff, 0xa1, 0xff, 0xa2,
0xf7);
write_regs (udev, 4, 0x83, 0x22, 0x87, 0x01, 0x83, 0x02, 0x87, 0x16);
write_regs (udev, 11, 0xa0, 0x00, 0x9c, 0x00, 0x9f, 0x00, 0x9d, 0x00, 0x9e,
0x00, 0xa0, 0x00, 0xce, 0x0c, 0x83, 0x20, 0xa5, 0x00, 0xa6,
0x00, 0xa7, 0x00);
set_gain_black (udev, rgreg, ggreg, bgreg, redreg, greenreg, bluereg);
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x02, 0x98,
0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x03, 0x98, 0x00, 0x99,
0x00, 0x9a, 0x00);
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x98, 0x83, 0x82, 0x85, 0x3a);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (dpi == 1200)
write_regs (udev, 1, 0x94, 0x71);
else
write_regs (udev, 1, 0x94, 0x61);
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x01, 0x83, 0x82, 0x85, 0x00);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (dpi == 1200)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8, 0xbf,
0xb9, 0x17);
else
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8, 0xdf,
0xb9, 0x1b);
write_regs (udev, 6, 0xc0, 0x00, 0x84, 0x00, 0x84, 0xb4, 0x80, 0xe1, 0xcf,
0x04, 0x82, 0x00);
if (dpi == 1200)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x02, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x08, 0x88, 0xa4, 0xc1, 0x02, 0xc2, 0x00,
0xc3, 0x02, 0xc4, 0x20, 0xc5, 0x08, 0xc6, 0x96, 0xc7, 0xa4,
0xc8, 0x06, 0xc0, 0xd2, 0x89, 0x24, 0x86, 0x01);
else
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x10, 0x88, 0xd0, 0xc1, 0x01, 0xc2, 0x00,
0xc3, 0x04, 0xc4, 0x20, 0xc5, 0x10, 0xc6, 0xc3, 0xc7, 0xd0,
0xc8, 0x1c, 0xc0, 0xd1, 0x89, 0x24, 0x86, 0x01);
write_regs (udev, 8, 0xbb, 0x05, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80, 0xbf,
0x00, 0x90, 0x40, 0x91, 0x00, 0x83, 0x82);
write_regs (udev, 1, 0xbe, 0x1d);
write_vctl (udev, 0x0c, 0x0003, 0x0001, 0x00);
len = usb_bulk_read (udev, 1, &rd_byte, 1, rd_timeout);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
record_mem (udev, (unsigned char **) (void *)&whitescan,
(5632 * 2 * 3 * (dpi == 1200 ? 2 : 1)) * 4);
write_regs (udev, 5, 0x83, 0x00, 0xa3, 0xff, 0xa4, 0xff, 0xa1, 0xff, 0xa2,
0xff);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
write_regs (udev, 2, 0xbe, 0x00, 0x84, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 4, 0x83, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0x97, 0x0a);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0b);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x0f);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x05);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xff, 0x83, 0x00, 0x8d, 0xff);
write_regs (udev, 1, 0x97, 0x00);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 1, 0x97, 0x00);
write_vctl (udev, 0x0c, 0x0004, 0x008b, 0x00);
read_vctl (udev, 0x0c, 0x0007, 0x0000, &rd_byte);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
write_regs (udev, 16, 0x84, 0x94, 0x80, 0xd1, 0x80, 0xc1, 0x82, 0x7f, 0xcf,
0x04, 0xc1, 0x02, 0xc2, 0x00, 0xc3, 0x06, 0xc4, 0xff, 0xc5,
0x40, 0xc6, 0x8c, 0xc7, 0xdc, 0xc8, 0x20, 0xc0, 0x72, 0x89,
0xff, 0x86, 0xff);
poll1 (udev);
/* ready scan position */
/* 1/3" of unscannable area at top... */
if (dpi == 300)
topreg = 120 * 4;
else if (dpi == 600)
topreg = 139 * 4;
else if (dpi == 1200)
topreg = 152 * 4;
else /*if (dpi == 150) */
topreg = 120 * 4;
topreg += topline * (1200 / dpi);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
write_regs (udev, 14, 0x84, 0xb4, 0x80, 0xe1, 0xcf, 0x04, 0xc1, 0x02, 0xc2,
0x00, 0xc3, 0x07, 0xc4, 0xff, 0xc5, 0x40, 0xc6, 0x8c, 0xc7,
0xdc, 0xc8, 0x20, 0xc0, 0x72, 0x89, topreg & 255, 0x86,
255 & (topreg >> 8));
write_regs (udev, 1, 0x97, 0x00);
poll2 (udev);
write_regs (udev, 8, 0x80, 0x00, 0x84, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0x86,
0x00, 0x89, 0x00, 0x94, 0x00, 0x01, 0x02);
write_vctl (udev, 0x0c, 0x00c0, 0x8406, 0x00);
write_vctl (udev, 0x0c, 0x00c0, 0x0406, 0x00);
write_regs (udev, 16, 0xbe, 0x18, 0x80, 0x00, 0x84, 0x00, 0x89, 0x00, 0x88,
0x00, 0x86, 0x00, 0x90, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xc8,
0x00, 0xc0, 0x00);
if (dpi == 1200)
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0x24, 0x83, 0x00, 0x8d, 0xff);
else
write_regs (udev, 4, 0x83, 0x20, 0x8d, 0xff, 0x83, 0x00, 0x8d, 0xff);
if (dpi != 1200)
write_regs (udev, 5, 0x83, 0x00, 0xa3, 0xff, 0xa4, 0xff, 0xa1, 0xff, 0xa2,
0xf7);
if (dpi == 1200)
write_regs (udev, 4, 0x83, 0x22, 0x87, 0x01, 0x83, 0x02, 0x87, 0x2c);
else
write_regs (udev, 4, 0x83, 0x22, 0x87, 0x01, 0x83, 0x02, 0x87, 0x16);
if (dpi == 1200)
write_regs (udev, 11, 0xa0, 0x00, 0x9c, 0x00, 0x9f, 0x40, 0x9d, 0x00,
0x9e, 0x00, 0xa0, 0x00, 0xce, 0x0c, 0x83, 0x20, 0xa5, 0x00,
0xa6, 0x00, 0xa7, 0x00);
else
write_regs (udev, 11, 0xa0, 0x00, 0x9c, 0x00, 0x9f, 0x00, 0x9d, 0x00,
0x9e, 0x00, 0xa0, 0x00, 0xce, 0x0c, 0x83, 0x20, 0xa5, 0x00,
0xa6, 0x00, 0xa7, 0x00);
set_gain_black (udev, rgreg, ggreg, bgreg, redreg, greenreg, bluereg);
if (!bpp16)
{
if (dpi == 1200)
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0xc7, 0x99, 0x99, 0x9a, 0xd5,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0xc8, 0x99, 0x99, 0x9a, 0xd3, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
else if (dpi == 150)
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0x94, 0x99, 0x67, 0x9a, 0x83,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0x7e, 0x99, 0x5d, 0x9a, 0x7d, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
else
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0xb3, 0x99, 0x72, 0x9a, 0x9d,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0xa3, 0x99, 0x6f, 0x9a, 0x94, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
}
else
{
if (dpi == 1200)
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0xb9, 0x99, 0x7a, 0x9a, 0xd6,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0xbc, 0x99, 0x7c, 0x9a, 0xd3, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
else if (dpi == 150)
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0x9c, 0x99, 0x5f, 0x9a, 0x87,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0x97, 0x99, 0x58, 0x9a, 0x81, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
else
write_regs (udev, 16, 0x9b, 0x00, 0x98, 0x9d, 0x99, 0x79, 0x9a, 0x8e,
0x9b, 0x01, 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b,
0x02, 0x98, 0x89, 0x99, 0x71, 0x9a, 0x80, 0x9b, 0x03,
0x98, 0x00, 0x99, 0x00, 0x9a, 0x00);
}
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x98, 0x83, 0x82, 0x85, 0x3a);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (!bpp16)
{
if (dpi == 1200)
write_regs (udev, 1, 0x94, 0x51);
else
write_regs (udev, 1, 0x94, 0x41);
}
else
{
if (dpi == 1200)
write_regs (udev, 1, 0x94, 0x71);
else
write_regs (udev, 1, 0x94, 0x61);
}
lightmap = (unsigned short *) malloc (whitemapsize);
calc_lightmap (whitescan, lightmap, 0, dpi, gain, offset);
select_pixels (lightmap, dpi, leftpix, scanpix);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x06, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x06);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x40, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0x7f, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
len =
usb_bulk_write (udev, 2, (unsigned char *) lightmap, whitemapsize,
wr_timeout);
calc_lightmap (whitescan, lightmap, 1, dpi, gain, offset);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0x7f, 0xb5, 0x07);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xbf, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
if (gray)
for (i = 0; i < whitemapsize / 2; i++)
lightmap[i] |= 0xc000;
len =
usb_bulk_write (udev, 2, (unsigned char *) lightmap, whitemapsize,
wr_timeout);
calc_lightmap (whitescan, lightmap, 2, dpi, gain, offset);
if (dpi == 1200)
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0x80, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x07);
else
write_regs (udev, 6, 0xb0, 0x00, 0xb1, 0xc0, 0xb2, 0x07, 0xb3, 0xff, 0xb4,
0xff, 0xb5, 0x07);
write_vctl (udev, 0x0c, 0x0002, whitemapsize, 0x00);
len =
usb_bulk_write (udev, 2, (unsigned char *) lightmap, whitemapsize,
wr_timeout);
free (whitescan);
free (lightmap);
if (!bpp16)
download_lut8 (udev, dpi, gray ? 0 : 1);
write_regs (udev, 4, 0x83, 0xa2, 0x85, 0x01, 0x83, 0x82, 0x85, 0x00);
write_regs (udev, 1, 0x9d, 0x80);
write_regs (udev, 1, 0x9d, 0x00);
if (!bpp16)
{
if (dpi == 1200)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0x1f, 0xb5, 0x06, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x43, 0xb9, 0x2d);
else if (dpi == 150)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0x0f, 0xb5, 0x07, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0xe0, 0xb9, 0x37);
else
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0x0f, 0xb5, 0x07, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x90, 0xb9, 0x37);
}
else
{
if (dpi == 1200)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x87, 0xb9, 0x18);
else if (dpi == 150)
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0xc1, 0xb9, 0x1e);
else
write_regs (udev, 10, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0xff,
0xb4, 0xff, 0xb5, 0x03, 0xb6, 0x01, 0xb7, 0x00, 0xb8,
0x21, 0xb9, 0x1e);
}
/* [86,89] controls number of 300dpi steps to scan */
botreg = scanlines * (1200 / dpi) + 400;
write_regs (udev, 6, 0xc0, 0x00, 0x84, 0x00, 0x84, 0xb4, 0x80, 0xe1, 0xcf,
0x04, 0x82, 0x00);
if (!bpp16)
{
if (dpi == 300)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x10, 0x88, 0xd0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x04, 0xc4, 0x20, 0xc5, 0x10, 0xc6, 0xc3,
0xc7, 0xd0, 0xc8, 0x12, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 600)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x10, 0x88, 0xd0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x04, 0xc4, 0x20, 0xc5, 0x10, 0xc6, 0xc3,
0xc7, 0xd0, 0xc8, 0x16, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 1200)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x02, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x08, 0x88, 0xa4, 0xc1, 0x02, 0xc2,
0x00, 0xc3, 0x02, 0xc4, 0x20, 0xc5, 0x08, 0xc6, 0x96,
0xc7, 0xa4, 0xc8, 0x06, 0xc0, 0xd2, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 150)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x06, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x1c, 0xbd, 0x08, 0x88, 0xe0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x03, 0xc4, 0x1c, 0xc5, 0x08, 0xc6, 0xd7,
0xc7, 0xe0, 0xc8, 0x11, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
if (dpi == 300)
write_regs (udev, 8, 0xbb, 0x01, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x20, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 600)
write_regs (udev, 8, 0xbb, 0x02, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x20, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 1200)
write_regs (udev, 8, 0xbb, 0x02, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x20, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 150)
write_regs (udev, 8, 0xbb, 0x00, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x20, 0x91, 0x00, 0x83, 0x82);
}
else
{
if (dpi == 300)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x10, 0x88, 0xd0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x04, 0xc4, 0x20, 0xc5, 0x10, 0xc6, 0xc3,
0xc7, 0xd0, 0xc8, 0x13, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 150)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x06, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x1c, 0xbd, 0x08, 0x88, 0xe0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x03, 0xc4, 0x1c, 0xc5, 0x08, 0xc6, 0xd7,
0xc7, 0xe0, 0xc8, 0x12, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 1200)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x02, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x08, 0x88, 0xa4, 0xc1, 0x02, 0xc2,
0x00, 0xc3, 0x02, 0xc4, 0x20, 0xc5, 0x08, 0xc6, 0x96,
0xc7, 0xa4, 0xc8, 0x0c, 0xc0, 0xd2, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
else if (dpi == 600)
write_regs (udev, 18, 0x83, 0xa2, 0x85, 0x04, 0x83, 0x82, 0x85, 0x00,
0xbc, 0x20, 0xbd, 0x10, 0x88, 0xd0, 0xc1, 0x01, 0xc2,
0x00, 0xc3, 0x04, 0xc4, 0x20, 0xc5, 0x10, 0xc6, 0xc3,
0xc7, 0xd0, 0xc8, 0x1a, 0xc0, 0xd1, 0x89, botreg & 255,
0x86, 255 & (botreg >> 8));
if (dpi == 300)
write_regs (udev, 8, 0xbb, 0x02, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x70, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 150)
write_regs (udev, 8, 0xbb, 0x01, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x70, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 1200)
write_regs (udev, 8, 0xbb, 0x05, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x70, 0x91, 0x00, 0x83, 0x82);
else if (dpi == 600)
write_regs (udev, 8, 0xbb, 0x04, 0x9b, 0x24, 0x8b, 0x00, 0x8e, 0x80,
0xbf, 0x00, 0x90, 0x70, 0x91, 0x00, 0x83, 0x82);
}
if (gray)
write_regs (udev, 1, 0xbe, 0x05);
else
write_regs (udev, 1, 0xbe, 0x0d);
write_vctl (udev, 0x0c, 0x0003, 0x0001, 0x00);
len = usb_bulk_read (udev, 1, &rd_byte, 1, rd_timeout);
write_vctl (udev, 0x0c, 0x0001, 0x0000, 0x00);
#ifndef BACKENDNAME
sprintf (fname, "%d.%s", dpi, gray ? "pgm" : "ppm");
if (stname)
strcpy (fname, stname);
sprintf (head, "P%d\n%d %d\n%d\n", gray ? 5 : 6, scanpix, scanlines,
bpp16 ? 65535 : 255);
if (nohead)
head[0] = 0;
if (!raw)
record_image (udev, fname, dpi, scanpix, scanlines, gray, head, bpp16);
else
record_head (udev, fname,
scanpix * (gray ? 1 : 3) * (bpp16 ? 2 : 1) * scanlines, "");
reset_scanner (udev);
idle_ab (udev);
set_lamp_timer (udev, 5);
#endif
}

24
configure vendored
Wyświetl plik

@ -9639,9 +9639,9 @@ fi;
if test "${ac_cv_header_usb_h}" = "yes" && test "$USE_LIBUSB" = "yes" ; then
echo "$as_me:$LINENO: checking for usb_get_busses in -lusb" >&5
echo $ECHO_N "checking for usb_get_busses in -lusb... $ECHO_C" >&6
if test "${ac_cv_lib_usb_usb_get_busses+set}" = set; then
echo "$as_me:$LINENO: checking for usb_interrupt_read in -lusb" >&5
echo $ECHO_N "checking for usb_interrupt_read in -lusb... $ECHO_C" >&6
if test "${ac_cv_lib_usb_usb_interrupt_read+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
@ -9659,11 +9659,11 @@ extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char usb_get_busses ();
char usb_interrupt_read ();
int
main ()
{
usb_get_busses ();
usb_interrupt_read ();
;
return 0;
}
@ -9689,20 +9689,20 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_usb_usb_get_busses=yes
ac_cv_lib_usb_usb_interrupt_read=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_usb_usb_get_busses=no
ac_cv_lib_usb_usb_interrupt_read=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_get_busses" >&5
echo "${ECHO_T}$ac_cv_lib_usb_usb_get_busses" >&6
if test $ac_cv_lib_usb_usb_get_busses = yes; then
echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_interrupt_read" >&5
echo "${ECHO_T}$ac_cv_lib_usb_usb_interrupt_read" >&6
if test $ac_cv_lib_usb_usb_interrupt_read = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBUSB 1
_ACEOF
@ -9711,7 +9711,7 @@ _ACEOF
fi
if test "${ac_cv_lib_usb_usb_get_busses}" = "yes" ; then
if test "${ac_cv_lib_usb_usb_interrupt_read}" = "yes" ; then
HAVE_LIBUSB="yes"
fi
fi
@ -25618,7 +25618,7 @@ echo "$as_me: Manually selected backends: ${BACKENDS}" >&6;}
microtek2 mustek mustek_usb nec pie plustek \
plustek_pp ricoh s9036 sceptre sharp \
sp15c st400 tamarack test teco1 teco2 teco3 umax umax_pp umax1220u \
artec_eplus48u ma1509 ibm hp5400 u12 snapscan niash"
artec_eplus48u ma1509 ibm hp5400 u12 snapscan niash sm3840"
if test "${sane_cv_use_libjpeg}" != "yes"; then
echo "*** disabling DC210 backend (failed to find JPEG library)"

Wyświetl plik

@ -299,7 +299,7 @@ else
microtek2 mustek mustek_usb nec pie plustek \
plustek_pp ricoh s9036 sceptre sharp \
sp15c st400 tamarack test teco1 teco2 teco3 umax umax_pp umax1220u \
artec_eplus48u ma1509 ibm hp5400 u12 snapscan niash"
artec_eplus48u ma1509 ibm hp5400 u12 snapscan niash sm3840"
if test "${sane_cv_use_libjpeg}" != "yes"; then
echo "*** disabling DC210 backend (failed to find JPEG library)"

Wyświetl plik

@ -52,7 +52,7 @@ SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
sane-teco1.5 sane-teco2.5 sane-teco3.5 sane-test.5 sane-sp15c.5 \
sane-coolscan2.5 sane-hpsj5s.5 sane-gt68xx.5 sane-artec_eplus48u.5 \
sane-ma1509.5 sane-ibm.5 sane-hp5400.5 sane-plustek_pp.5 sane-u12.5 \
sane-niash.5
sane-niash.5 sane-sm3840.5
SECT7 = sane.7
SECT8 = saned.8
MANPAGES = $(SECT1) $(SECT5) $(SECT7) $(SECT8)
@ -103,7 +103,7 @@ DISTFILES = Makefile.in backend-writing.txt descriptions.txt \
sane-teco1.man sane-teco2.man sane-teco3.man sane-test.man sane-sp15c.man \
sane-hpsj5s.man gamma4scanimage.man sane-gt68xx.man sane-artec_eplus48u.man \
sane-ma1509.man sane-ibm.man sane-hp5400.man sane-plustek_pp.man \
sane-u12.man sane-niash.man
sane-u12.man sane-niash.man sane-sm3840.man
.PHONY: all clean depend dist distclean html html-man install \
sane-html uninstall

Wyświetl plik

@ -0,0 +1,46 @@
;
; SANE Backend specification file
;
; It's basically emacs-lisp --- so ";" indicates comment to end of line.
; All syntactic elements are keyword tokens, followed by a string or
; keyword argument, as specified.
;
; ":backend" *must* be specified.
; All other information is optional (but what good is the file without it?).
;
; See doc/descriptions.txt for details.
:backend "sm3840" ; name of backend
:version "1.0" ; version of backend (or "unmaintained")
:new :yes ; Is the backend new to this SANE release?
; :yes or :no
:manpage "sane-sm3840" ; name of manpage (if it exists)
:url "http://www.ziplabel.com/sm3840/" ; backend's web page
:comment "This reverse-engineered backend supports the USB ScanMaker 3840 model"
; comment about the backend
:devicetype :scanner ; start of a list of devices....
; other types: :stillcam, :vidcam,
; :meta, :api
:mfg "Microtek" ; name a manufacturer
:url "http://www.microtek.com/" ; manufacturer's URL
:comment "Microtek makes a wide variety of devices."
; comment about the manufacturer
:model "ScanMaker 3840" ; name models for above-specified mfg.
:status :good ; :minimal, :basic, :good, :complete
; :untested, or :unsupported
:interface "USB" ; interface type of the device:
; "SCSI", "USB", "Parport (EPP)",
; "Parport (SPP)", "Parport (ECP)",
; "Serial port", "IEEE-1394", "JetDirect",
; or "Proprietary".
:comment "8 and 16 bit, color and grayscale" ; comment about the model
; :comment and :url specifiers are optional after :mfg, :model, :desc,
; and at the top-level.
; :status specifier is optional after :model and at the top-level

Wyświetl plik

@ -0,0 +1,89 @@
.TH sane-sm3840 5 "Feb 6, 2005" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-sm3840
.SH NAME
sane-sm3840 \- SANE backend for Microtek scanners with SCAN08 USB chip
.SH DESCRIPTION
The
.B sane-sm3840
library implements a SANE (Scanner Access Now Easy) backend that
provides access to some Microtek scanners with the SCAN08
USB chip.
.PP
There exist backends for Microtek scanners with SCSI command set.
Refer to sane-microtek(5) and sane-microtek2(5) for details.
.PP
At present, the following
scanners are known positively to work with this backend:
.PP
.RS
Vendor Product id: Remark:
.br
-------- -------------- -----------
.br
Microtek ScanMaker 3840 all modes ok
.RE
.PP
If you own a Microtek scanner with the SCAN08 chip other than the ones
listed above, it may or may not work with SANE. Feel free to contact the
backend author (earle@ziplabel.com) to report results with scanners not
on the list.
.SH "FRONTEND OPTIONS"
.PP
The following options are supported by the sm3840-driver:
.PP
.B --mode color|gray
.br
Color or grayscale mode.
.B --resolution 150|300|600|1200
.br
Pixels per inch for scans.
.B --depth 8|16
.br
Note that the least significant bits of 16bpp mode may be noise.
.B --brightness 1..4096
.br
Higher numbers increase brightness of returned image.
.B --contrast 0.1..9.9
.br
Larger numbers decrease contrast of returned image.
.B --lamp-timeout 1..15
.br
Time in minutes until the lamp is turned off after a scan.
.SH CONFIGURATION
This backend does not support a configuration file right now.
.SH FILES
.TP
.I @LIBDIR@/libsane-sm3840.a
The static library implementing this backend.
.TP
.I @LIBDIR@/libsane-sm3840.so
The shared library implementing this backend (present on systems that
support dynamic loading).
.SH ENVIRONMENT
.TP
.B SANE_DEBUG_SM3840
If the library was compiled with debug support enabled, this
environment variable controls the debug level for this backend. E.g.,
a value of 128 requests all debug output to be printed. Smaller
levels reduce verbosity. To see error messages on stderr set
SANE_DEBUG_SM3840 to 1.
.SH "SEE ALSO"
sane-microtek2(5), sane-sm3600(5), http://www.ziplabel.com/sm3840
.SH AUTHOR
.br
Earle F. Philhower III (earle@ziplabel.com)
.br

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane 7 "03 Aug 2004" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane 7 "20 Feb 2005" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane
.SH NAME
@ -376,6 +376,11 @@ The SANE sm3600 backend supports the Microtek ScanMaker 3600 USB scanner. See
.BR sane\-sm3600 (5)
for details.
.TP
.B sm3840
The SANE sm3840 backend suppoert the Microtek ScanMaker 3840 USB scanner. See
.BR sane\-sm3840 (5)
for details.
.TP
.B snapscan
The snapscan backend supports AGFA SnapScan flatbed scanners. See
.BR sane\-snapscan (5)
@ -804,4 +809,4 @@ David Mosberger-Tang and many many more (see
for details). This man page was written by Henning Meier-Geinitz. Quite a lot
of text was taken from the
.B SANE
standard, several man pages, and README files.
standard, several man pages, and README files.