hp5400: synching SANE CVS with hp5400backend sourceforge project CVS : added and modified hp5400 files (see Changelog)

merge-requests/1/head
Thomas Soumarmon 2003-06-05 07:05:59 +00:00
rodzic 64ea3dfc5f
commit c84bdda420
11 zmienionych plików z 1696 dodań i 1203 usunięć

Wyświetl plik

@ -113,7 +113,9 @@ DISTFILES = abaton.c abaton.conf abaton.h agfafocus.c agfafocus.conf \
hp-device.c hp-device.h hp.h hp-handle.c hp-handle.h hp-hpmem.c hp-option.c \
hp-option.h hp.README hp-scl.c hp-scl.h hp-scsi.h hp.TODO \
hpsj5s.c hpsj5s.conf hpsj5s.h \
hp5400.c hp5400.h hp5400.conf hp5400_internal.c hp5400_sanei.c hp5400_xfer.h \
hp5400.c hp5400.h hp5400.conf hp5400_debug.c hp5400_debug.h \
hp5400_internal.c hp5400_internal.h hp5400_xfer.h \
hp5400_sane.c hp5400_sanei.c hp5400_sanei.h \
ibm.c ibm.conf ibm.h ibm-scsi.c \
jinclude.h \
leo.c leo.h leo.conf \

Wyświetl plik

@ -1,6 +1,7 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
This file was initially copied from the hp3300 testools and adjusted to
suit. Original copyright notice follows:
@ -50,944 +51,30 @@
Parts of this source were inspired by other backends.
*/
/* definitions for debug */
#define BACKEND_NAME hp5400
#define BUILD 2
#include "hp5400.h"
#include "hp5400_debug.h"
#include "sane/config.h"
#include "sane/sane.h"
#include "sane/sanei.h"
#include "sane/sanei_backend.h"
#include "sane/sanei_config.h"
#include "sane/saneopts.h"
#include "../include/sane/config.h"
#include "../include/sane/sane.h"
#include "../include/sane/sanei.h"
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_config.h"
#include "../include/sane/saneopts.h"
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memcpy */
#include <stdio.h>
#define DBG_ASSERT 1
#define DBG_ERR 16
#define DBG_MSG 32
#define HP5400_CONFIG_FILE "hp5400.conf"
#include "hp5400.h"
#define BUILD 2
/* (source) includes for data transfer methods */
#include "hp5400_debug.c"
#include "hp5400_internal.c"
#include "hp5400_sane.c"
#include "hp5400_sanei.c"
/* other definitions */
#define TRUE 1
#define FALSE 0
#define MM_TO_PIXEL(_mm_, _dpi_) ((_mm_) * (_dpi_) / 25.4)
#define PIXEL_TO_MM(_pixel_, _dpi_) ((_pixel_) * 25.4 / (_dpi_))
#define NUM_GAMMA_ENTRIES 65536
/* Device filename for USB access */
static char *usb_devfile = "/dev/usb/scanner0";
/* options enumerator */
typedef enum
{
optCount = 0,
optGroupGeometry,
optTLX, optTLY, optBRX, optBRY,
optDPI,
optGroupImage,
optGammaTableRed, /* Gamma Tables */
optGammaTableGreen,
optGammaTableBlue,
optLast, /* Disable the offset code */
optGroupMisc,
optOffsetX, optOffsetY
/* put temporarily disabled options here after optLast */
/*
optLamp,
*/
}
EOptionIndex;
typedef union
{
SANE_Word w;
SANE_Word *wa; /* word array */
SANE_String s;
}
TOptionValue;
typedef struct
{
SANE_Option_Descriptor aOptions[optLast];
TOptionValue aValues[optLast];
TScanParams ScanParams;
THWParams HWParams;
TDataPipe DataPipe;
int iLinesLeft;
SANE_Int *aGammaTableR; /* a 16-to-16 bit color lookup table */
SANE_Int *aGammaTableG; /* a 16-to-16 bit color lookup table */
SANE_Int *aGammaTableB; /* a 16-to-16 bit color lookup table */
int fScanning; /* TRUE if actively scanning */
int fCanceled;
}
TScanner;
/* linked list of SANE_Device structures */
typedef struct TDevListEntry
{
struct TDevListEntry *pNext;
SANE_Device dev;
}
TDevListEntry;
static TDevListEntry *_pFirstSaneDev = 0;
static int iNumSaneDev = 0;
static const SANE_Device **_pSaneDevList = 0;
/* option constraints */
static const SANE_Range rangeGammaTable = { 0, 65535, 1 };
#ifdef SUPPORT_2400_DPI
static const SANE_Int setResolutions[] = { 6, 75, 150, 300, 600, 1200, 2400 };
#else
static const SANE_Int setResolutions[] = { 5, 75, 150, 300, 600, 1200 };
#endif
static const SANE_Range rangeXmm = { 0, 220, 1 };
static const SANE_Range rangeYmm = { 0, 300, 1 };
static const SANE_Range rangeXoffset = { 0, 20, 1 };
static const SANE_Range rangeYoffset = { 0, 70, 1 };
static const SANE_Int offsetX = 5;
static const SANE_Int offsetY = 52;
static void
_InitOptions (TScanner * s)
{
int i, j;
SANE_Option_Descriptor *pDesc;
TOptionValue *pVal;
/* set a neutral gamma */
if (s->aGammaTableR == NULL) /* Not yet allocated */
{
s->aGammaTableR = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
s->aGammaTableG = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
s->aGammaTableB = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
for (j = 0; j < NUM_GAMMA_ENTRIES; j++)
{
s->aGammaTableR[j] = j;
s->aGammaTableG[j] = j;
s->aGammaTableB[j] = j;
}
}
for (i = optCount; i < optLast; i++)
{
pDesc = &s->aOptions[i];
pVal = &s->aValues[i];
/* defaults */
pDesc->name = "";
pDesc->title = "";
pDesc->desc = "";
pDesc->type = SANE_TYPE_INT;
pDesc->unit = SANE_UNIT_NONE;
pDesc->size = sizeof (SANE_Word);
pDesc->constraint_type = SANE_CONSTRAINT_NONE;
pDesc->cap = 0;
switch (i)
{
case optCount:
pDesc->title = SANE_TITLE_NUM_OPTIONS;
pDesc->desc = SANE_DESC_NUM_OPTIONS;
pDesc->cap = SANE_CAP_SOFT_DETECT;
pVal->w = (SANE_Word) optLast;
break;
case optGroupGeometry:
pDesc->title = "Geometry";
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optTLX:
pDesc->name = SANE_NAME_SCAN_TL_X;
pDesc->title = SANE_TITLE_SCAN_TL_X;
pDesc->desc = SANE_DESC_SCAN_TL_X;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeXmm.min + offsetX;
break;
case optTLY:
pDesc->name = SANE_NAME_SCAN_TL_Y;
pDesc->title = SANE_TITLE_SCAN_TL_Y;
pDesc->desc = SANE_DESC_SCAN_TL_Y;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeYmm.min + offsetY;
break;
case optBRX:
pDesc->name = SANE_NAME_SCAN_BR_X;
pDesc->title = SANE_TITLE_SCAN_BR_X;
pDesc->desc = SANE_DESC_SCAN_BR_X;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeXmm.max + offsetX;
break;
case optBRY:
pDesc->name = SANE_NAME_SCAN_BR_Y;
pDesc->title = SANE_TITLE_SCAN_BR_Y;
pDesc->desc = SANE_DESC_SCAN_BR_Y;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeYmm.max + offsetY;
break;
case optDPI:
pDesc->name = SANE_NAME_SCAN_RESOLUTION;
pDesc->title = SANE_TITLE_SCAN_RESOLUTION;
pDesc->desc = SANE_DESC_SCAN_RESOLUTION;
pDesc->unit = SANE_UNIT_DPI;
pDesc->constraint_type = SANE_CONSTRAINT_WORD_LIST;
pDesc->constraint.word_list = setResolutions;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = setResolutions[1];
break;
case optGroupImage:
pDesc->title = SANE_I18N ("Image");
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optGammaTableRed:
pDesc->name = SANE_NAME_GAMMA_VECTOR_R;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_R;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_R;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableR;
break;
case optGammaTableGreen:
pDesc->name = SANE_NAME_GAMMA_VECTOR_G;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_G;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_G;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableG;
break;
case optGammaTableBlue:
pDesc->name = SANE_NAME_GAMMA_VECTOR_B;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_B;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_B;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableB;
break;
case optGroupMisc:
pDesc->title = SANE_I18N ("Miscellaneous");
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optOffsetX:
pDesc->title = SANE_I18N ("offset X");
pDesc->desc =
SANE_I18N ("Hardware internal X position of the scanning area.");
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXoffset;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pVal->w = offsetX;
break;
case optOffsetY:
pDesc->title = SANE_I18N ("offset Y");
pDesc->desc =
SANE_I18N ("Hardware internal Y position of the scanning area.");
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYoffset;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pVal->w = offsetY;
break;
#if 0
case optLamp:
pDesc->name = "lamp";
pDesc->title = SANE_I18N ("Lamp status");
pDesc->desc = SANE_I18N ("Switches the lamp on or off.");
pDesc->type = SANE_TYPE_BOOL;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
/* switch the lamp on when starting for first the time */
pVal->w = SANE_TRUE;
break;
#endif
#if 0
case optCalibrate:
pDesc->name = "calibrate";
pDesc->title = SANE_I18N ("Calibrate");
pDesc->desc = SANE_I18N ("Calibrates for black and white level.");
pDesc->type = SANE_TYPE_BUTTON;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pDesc->size = 0;
break;
#endif
default:
DBG (DBG_ERR, "Uninitialised option %d\n", i);
break;
}
}
}
static int
_ReportDevice (TScannerModel * pModel, char *pszDeviceName)
{
TDevListEntry *pNew, *pDev;
DBG (DBG_MSG, "hp5400: _ReportDevice '%s'\n", pszDeviceName);
pNew = malloc (sizeof (TDevListEntry));
if (!pNew)
{
DBG (DBG_ERR, "no mem\n");
return -1;
}
/* add new element to the end of the list */
if (_pFirstSaneDev == NULL)
{
_pFirstSaneDev = pNew;
}
else
{
for (pDev = _pFirstSaneDev; pDev->pNext; pDev = pDev->pNext)
{
;
}
pDev->pNext = pNew;
}
/* fill in new element */
pNew->pNext = 0;
pNew->dev.name = strdup (pszDeviceName);
pNew->dev.vendor = pModel->pszVendor;
pNew->dev.model = pModel->pszName;
pNew->dev.type = "flatbed scanner";
iNumSaneDev++;
return 0;
}
static SANE_Status
attach_one_device (SANE_String_Const devname)
{
if (HP5400Detect (devname, _ReportDevice) < 0)
{
DBG (DBG_MSG, "attach_one_device: couldn't attach %s\n", devname);
return SANE_STATUS_INVAL;
}
DBG (DBG_MSG, "attach_one_device: attached %s successfully\n", devname);
return SANE_STATUS_GOOD;
}
/*****************************************************************************/
SANE_Status
sane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth)
{
FILE *conf_fp; /* Config file stream */
SANE_Char line[PATH_MAX];
SANE_Char *str = NULL;
SANE_String_Const proper_str;
int nline = 0;
/* prevent compiler from complaing about unused parameters */
pfnAuth = pfnAuth;
DBG_INIT ();
DBG (DBG_MSG, "sane_init: SANE hp5400 backend version %d.%d-%d (from %s)\n",
V_MAJOR, V_MINOR, BUILD, PACKAGE_STRING);
sanei_usb_init ();
conf_fp = sanei_config_open (HP5400_CONFIG_FILE);
iNumSaneDev = 0;
if (conf_fp)
{
DBG (DBG_MSG, "Reading config file\n");
while (sanei_config_read (line, sizeof (line), conf_fp))
{
++nline;
if (str)
{
free (str);
}
proper_str = sanei_config_get_string (line, &str);
/* Discards white lines and comments */
if (!str || proper_str == line || str[0] == '#')
{
DBG (DBG_MSG, "Discarding line %d\n", nline);
}
else
{
/* If line's not blank or a comment, then it's the device
* filename or a usb directive. */
DBG (DBG_MSG, "Trying to attach %s\n", line);
sanei_usb_attach_matching_devices (line, attach_one_device);
}
} /* while */
fclose (conf_fp);
}
else
{
DBG (DBG_ERR, "Unable to read config file \"%s\": %s\n",
HP5400_CONFIG_FILE, strerror (errno));
DBG (DBG_MSG, "Using default built-in values\n");
attach_one_device (usb_devfile);
}
if (piVersion != NULL)
{
*piVersion = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BUILD);
}
return SANE_STATUS_GOOD;
}
void
sane_exit (void)
{
TDevListEntry *pDev, *pNext;
DBG (DBG_MSG, "sane_exit\n");
/* free device list memory */
if (_pSaneDevList)
{
for (pDev = _pFirstSaneDev; pDev; pDev = pNext)
{
pNext = pDev->pNext;
free ((void *) pDev->dev.name);
free (pDev);
}
_pFirstSaneDev = 0;
free (_pSaneDevList);
_pSaneDevList = 0;
}
}
SANE_Status
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
TDevListEntry *pDev;
int i;
DBG (DBG_MSG, "sane_get_devices\n");
local_only = local_only;
if (_pSaneDevList)
{
free (_pSaneDevList);
}
_pSaneDevList = malloc (sizeof (*_pSaneDevList) * (iNumSaneDev + 1));
if (!_pSaneDevList)
{
DBG (DBG_MSG, "no mem\n");
return SANE_STATUS_NO_MEM;
}
i = 0;
for (pDev = _pFirstSaneDev; pDev; pDev = pDev->pNext)
{
_pSaneDevList[i++] = &pDev->dev;
}
_pSaneDevList[i++] = 0; /* last entry is 0 */
*device_list = _pSaneDevList;
return SANE_STATUS_GOOD;
}
SANE_Status
sane_open (SANE_String_Const name, SANE_Handle * h)
{
TScanner *s;
DBG (DBG_MSG, "sane_open: %s\n", name);
/* check the name */
if (strlen (name) == 0)
{
/* default to first available device */
name = _pFirstSaneDev->dev.name;
}
s = malloc (sizeof (TScanner));
if (!s)
{
DBG (DBG_MSG, "malloc failed\n");
return SANE_STATUS_NO_MEM;
}
memset (s, 0, sizeof (TScanner)); /* Clear everything to zero */
if (HP5400Open (&s->HWParams, (char *) name) < 0)
{
/* is this OK ? */
DBG (DBG_ERR, "HP5400Open failed\n");
free ((void *) s);
return SANE_STATUS_INVAL; /* is this OK? */
}
DBG (DBG_MSG, "Handle=%d\n", s->HWParams.iXferHandle);
_InitOptions (s);
*h = s;
/* Turn on lamp by default at startup */
/* SetLamp(&s->HWParams, TRUE); */
return SANE_STATUS_GOOD;
}
void
sane_close (SANE_Handle h)
{
TScanner *s;
DBG (DBG_MSG, "sane_close\n");
s = (TScanner *) h;
/* turn of scanner lamp */
SetLamp (&s->HWParams, FALSE);
/* close scanner */
HP5400Close (&s->HWParams);
/* free scanner object memory */
free ((void *) s);
}
const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle h, SANE_Int n)
{
TScanner *s;
DBG (DBG_MSG, "sane_get_option_descriptor %d\n", n);
if ((n < optCount) || (n >= optLast))
{
return NULL;
}
s = (TScanner *) h;
return &s->aOptions[n];
}
SANE_Status
sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action,
void *pVal, SANE_Int * pInfo)
{
TScanner *s;
SANE_Int info;
DBG (DBG_MSG, "sane_control_option: option %d, action %d\n", n, Action);
s = (TScanner *) h;
info = 0;
switch (Action)
{
case SANE_ACTION_GET_VALUE:
switch (n)
{
/* Get options of type SANE_Word */
case optBRX:
case optTLX:
*(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - s->aValues[optOffsetX].w; */
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
*(SANE_Word *) pVal);
break;
case optBRY:
case optTLY:
*(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - - s->aValues[optOffsetY].w; */
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
*(SANE_Word *) pVal);
break;
case optOffsetX:
case optOffsetY:
case optCount:
case optDPI:
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
(int) s->aValues[n].w);
*(SANE_Word *) pVal = s->aValues[n].w;
break;
/* Get options of type SANE_Word array */
case optGammaTableRed:
case optGammaTableGreen:
case optGammaTableBlue:
DBG (DBG_MSG, "Reading gamma table\n");
memcpy (pVal, s->aValues[n].wa, s->aOptions[n].size);
break;
#if 0
/* Get options of type SANE_Bool */
case optLamp:
GetLamp (&s->HWParams, &fLampIsOn);
*(SANE_Bool *) pVal = fLampIsOn;
break;
#endif
#if 0
case optCalibrate:
/* although this option has nothing to read,
it's added here to avoid a warning when running scanimage --help */
break;
#endif
default:
DBG (DBG_MSG, "SANE_ACTION_GET_VALUE: Invalid option (%d)\n", n);
}
break;
case SANE_ACTION_SET_VALUE:
if (s->fScanning)
{
DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE not allowed during scan\n");
return SANE_STATUS_INVAL;
}
switch (n)
{
case optCount:
return SANE_STATUS_INVAL;
break;
case optBRX:
case optTLX:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetX].w; */
break;
case optBRY:
case optTLY:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetY].w; */
break;
case optDPI:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
#ifdef SUPPORT_2400_DPI
(s->aValues[n].w) = *(SANE_Word *) pVal;
#else
(s->aValues[n].w) = min (1200, *(SANE_Word *) pVal);
#endif
break;
case optGammaTableRed:
case optGammaTableGreen:
case optGammaTableBlue:
DBG (DBG_MSG, "Writing gamma table\n");
memcpy (s->aValues[n].wa, pVal, s->aOptions[n].size);
break;
/*
case optLamp:
fVal = *(SANE_Bool *)pVal;
DBG(DBG_MSG, "lamp %s\n", fVal ? "on" : "off");
SetLamp(&s->HWParams, fVal);
break;
*/
#if 0
case optCalibrate:
/* SimpleCalib(&s->HWParams); */
break;
#endif
default:
DBG (DBG_ERR, "SANE_ACTION_SET_VALUE: Invalid option (%d)\n", n);
}
if (pInfo != NULL)
{
*pInfo = info;
}
break;
case SANE_ACTION_SET_AUTO:
return SANE_STATUS_UNSUPPORTED;
default:
DBG (DBG_ERR, "Invalid action (%d)\n", Action);
return SANE_STATUS_INVAL;
}
return SANE_STATUS_GOOD;
}
SANE_Status
sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
{
TScanner *s;
DBG (DBG_MSG, "sane_get_parameters\n");
s = (TScanner *) h;
/* first do some checks */
if (s->aValues[optTLX].w >= s->aValues[optBRX].w)
{
DBG (DBG_ERR, "TLX should be smaller than BRX\n");
return SANE_STATUS_INVAL; /* proper error code? */
}
if (s->aValues[optTLY].w >= s->aValues[optBRY].w)
{
DBG (DBG_ERR, "TLY should be smaller than BRY\n");
return SANE_STATUS_INVAL; /* proper error code? */
}
/* return the data */
p->format = SANE_FRAME_RGB;
p->last_frame = SANE_TRUE;
p->depth = 8;
if (s->ScanParams.iLines) /* Initialised by doing a scan */
{
p->pixels_per_line = s->ScanParams.iBytesPerLine / 3;
p->lines = s->ScanParams.iLines;
p->bytes_per_line = s->ScanParams.iBytesPerLine;
}
else
{
p->lines = MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w,
s->aValues[optDPI].w);
p->pixels_per_line =
MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w,
s->aValues[optDPI].w);
p->bytes_per_line = p->pixels_per_line * 3;
}
return SANE_STATUS_GOOD;
}
#define BUFFER_READ_HEADER_SIZE 32
SANE_Status
sane_start (SANE_Handle h)
{
TScanner *s;
SANE_Parameters par;
DBG (DBG_MSG, "sane_start\n");
s = (TScanner *) h;
if (sane_get_parameters (h, &par) != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "Invalid scan parameters (sane_get_parameters)\n");
return SANE_STATUS_INVAL;
}
s->iLinesLeft = par.lines;
/* fill in the scanparams using the option values */
s->ScanParams.iDpi = s->aValues[optDPI].w;
s->ScanParams.iLpi = s->aValues[optDPI].w;
/* Guessing here. 75dpi => 1, 2400dpi => 32 */
/* s->ScanParams.iColourOffset = s->aValues[optDPI].w / 75; */
/* now we don't need correction => corrected by scan request type ? */
s->ScanParams.iColourOffset = 0;
s->ScanParams.iTop =
MM_TO_PIXEL (s->aValues[optTLY].w + s->HWParams.iTopLeftY, HW_LPI);
s->ScanParams.iLeft =
MM_TO_PIXEL (s->aValues[optTLX].w + s->HWParams.iTopLeftX, HW_DPI);
/* Note: All measurements passed to the scanning routines must be in HW_LPI */
s->ScanParams.iWidth =
MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w, HW_LPI);
s->ScanParams.iHeight =
MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w, HW_LPI);
/* After the scanning, the iLines and iBytesPerLine will be filled in */
/* copy gamma table */
WriteGammaCalibTable (s->HWParams.iXferHandle, s->aGammaTableR,
s->aGammaTableG, s->aGammaTableB);
/* prepare the actual scan */
/* We say normal here. In future we should have a preview flag to set preview mode */
if (InitScan (SCAN_TYPE_NORMAL, &s->ScanParams, &s->HWParams) != 0)
{
DBG (DBG_MSG, "Invalid scan parameters (InitScan)\n");
return SANE_STATUS_INVAL;
}
/* for the moment no lines has been read */
s->ScanParams.iLinesRead = 0;
s->fScanning = TRUE;
return SANE_STATUS_GOOD;
}
SANE_Status
sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
{
/* Read actual scan from the circular buffer */
/* Note: this is already color corrected, though some work still needs to be done
to deal with the colour offsetting */
TScanner *s;
char *buffer = buf;
DBG (DBG_MSG, "sane_read: request %d bytes \n", maxlen);
s = (TScanner *) h;
/* nothing has been read for the moment */
*len = 0;
/* if we read all the lines return EOF */
if (s->ScanParams.iLinesRead == s->ScanParams.iLines)
{
/* FinishScan( &s->HWParams ); *** FinishScan called in sane_cancel */
DBG (DBG_MSG, "sane_read: EOF\n");
return SANE_STATUS_EOF;
}
/* read as many lines the buffer may contain and while there are lines to be read */
while ((*len + s->ScanParams.iBytesPerLine <= maxlen)
&& (s->ScanParams.iLinesRead < s->ScanParams.iLines))
{
/* get one more line from the circular buffer */
CircBufferGetLine (s->HWParams.iXferHandle, &s->HWParams.pipe, buffer);
/* increment pointer, size and line number */
buffer += s->ScanParams.iBytesPerLine;
*len += s->ScanParams.iBytesPerLine;
s->ScanParams.iLinesRead++;
}
DBG (DBG_MSG, "sane_read: %d bytes read\n", *len);
return SANE_STATUS_GOOD;
}
void
sane_cancel (SANE_Handle h)
{
TScanner *s;
DBG (DBG_MSG, "sane_cancel\n");
s = (TScanner *) h;
/* to be implemented more thoroughly */
/* Make sure the scanner head returns home */
FinishScan (&s->HWParams);
s->fCanceled = TRUE;
s->fScanning = FALSE;
}
SANE_Status
sane_set_io_mode (SANE_Handle h, SANE_Bool m)
{
DBG (DBG_MSG, "sane_set_io_mode %s\n", m ? "non-blocking" : "blocking");
/* prevent compiler from complaining about unused parameters */
h = h;
if (m)
{
return SANE_STATUS_UNSUPPORTED;
}
return SANE_STATUS_GOOD;
}
SANE_Status
sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
{
DBG (DBG_MSG, "sane_select_fd\n");
/* prevent compiler from complaining about unused parameters */
h = h;
fd = fd;
return SANE_STATUS_UNSUPPORTED;
}

Wyświetl plik

@ -1,17 +1,18 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -41,10 +42,11 @@
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.
$Id$
*/
/*
Core HP5400 functions.
*/
@ -137,4 +139,5 @@ typedef struct
TScanParams;
#endif /* NO _HP5400_H_ */

Wyświetl plik

@ -0,0 +1,72 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
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 "hp5400_debug.h"
#ifdef STANDALONE
#include <stdio.h>
FILE *DBG_ASSERT = NULL;
FILE *DBG_ERR = NULL;
FILE *DBG_MSG = NULL;
void hp5400_dbg_start() {
DBG_MSG = stdout;
DBG_ERR = stderr;
DBG_ASSERT = stderr;
}
#else
#undef DEBUG_DECLARE_ONLY
#undef _SANEI_DEBUG_H
#include <sane/sanei_debug.h>
#endif

Wyświetl plik

@ -0,0 +1,76 @@
#ifndef __HP5400_DEBUG_H_
#define __HP5400_DEBUG_H_
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
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 STANDALONE
#define DEBUG_DECLARE_ONLY
#include <sane/sanei_debug.h>
#define DBG_ASSERT 1
#define DBG_ERR 16
#define DBG_MSG 32
#define HP5400_DBG DBG
#else
#include <stdio.h>
#define LOCAL_DBG
#define HP5400_DBG fprintf
extern FILE *DBG_ASSERT;
extern FILE *DBG_ERR;
extern FILE *DBG_MSG;
void hp5400_dbg_start();
#endif
#endif

Wyświetl plik

@ -1,23 +1,27 @@
/* sane - Scanner Access Now Easy.
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Copyright (c) 2003 Henning Meier-Geinitz, <henning@meier-geinitz.de>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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.
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.
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.
@ -43,7 +47,7 @@
HP5400/5470 Test util.
Currently is only able to read back the scanner version string,
but this basically demonstrates ability to communicate with the scanner.
Massively expanded. Can do calibration scan, upload gamma and calibration
tables and stores the results of a scan. - 19/02/2003 Martijn
*/
@ -51,7 +55,6 @@
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <assert.h>
/*#include <stdint.h>*/
#include <errno.h>
#include <string.h>
#include <unistd.h>
@ -60,6 +63,8 @@
#include "hp5400.h"
#include "hp5400_xfer.h"
#include "hp5400_internal.h"
#include "hp5400_debug.h" /* debug functions */
#ifndef min
@ -75,149 +80,27 @@
#define PACKED
#endif
/* If this is enabled, a copy of the raw data from the scanner will be saved to
/* If this is enabled, a copy of the raw data from the scanner will be saved to
imagedebug.dat and the attempted conversion to imagedebug.ppm */
/* #define IMAGE_DEBUG */
/* If this is defined you get extra info on the calibration */
/* #define CALIB_DEBUG */
#define CMD_GETVERSION 0x1200
#define CMD_GETUITEXT 0xf00b
#define CMD_GETCMDID 0xc500
#define CMD_SCANREQUEST 0x2505 /* This is for previews */
#define CMD_SCANREQUEST2 0x2500 /* This is for real scans */
#define CMD_SCANRESPONSE 0x3400
/* Testing stuff to make it work */
#define CMD_SETDPI 0x1500 /* ??? */
#define CMD_STOPSCAN 0x1B01 /* 0x40 = lamp in on, 0x00 = lamp is off */
#define CMD_STARTSCAN 0x1B05 /* 0x40 = lamp in on, 0x00 = lamp is off */
#define CMD_UNKNOWN 0x2300 /* Send fixed string */
#define CMD_UNKNOWN2 0xD600 /* ??? Set to 0x04 */
#define CMD_UNKNOWN3 0xC000 /* ??? Set to 02 03 03 3C */
#define CMD_SETOFFSET 0xE700 /* two ints in network order. X-offset, Y-offset of full scan */
/* Given values seem to be 0x0054 (=4.57mm) and 0x0282 (=54.36mm) */
#define CMD_INITBULK1 0x0087 /* send 0x14 */
#define CMD_INITBULK2 0x0083 /* send 0x24 */
#define CMD_INITBULK3 0x0082 /* transfer length 0xf000 */
const char MatchVersion[] = "SilitekIBlizd C3 ScannerV0.84";
const char MatchVersion2[] = "SilitekIBlizd C3 ScannerV0.86";
/*extern char *usb_devfile;*/ /* Is name of device to link to */
static TScannerModel Model_HP54xx =
{ "Hewlett-Packard", "HP54xx Flatbed Scanner" };
#ifdef STANDALONE
/* Debug messages levels */
#define DBG fprintf
FILE *DBG_ASSERT = NULL;
FILE *DBG_ERR = NULL;
FILE *DBG_MSG = NULL;
#endif
struct ScanRequest
{
u_int8_t x1; /* Set to 0x08 */
u_int16_t dpix, dpiy; /* Set to 75, 150 or 300 in network order */
u_int16_t offx, offy; /* Offset to scan, in 1/300th of dpi, in network order */
u_int16_t lenx, leny; /* Size of scan, in 1/300th of dpi, in network order */
u_int16_t flags1, flags2, flags3; /* Undetermined flag info */
/* Known combinations are:
1st calibration scan: 0x0000, 0x0010, 0x1820 = 24bpp
2nd calibration scan: 0x0000, 0x0010, 0x3020 = 48bpp ???
3rd calibration scan: 0x0000, 0x0010, 0x3024 = 48bpp ???
Preview scan: 0x0080, 0x0000, 0x18E8 = 8bpp
4th & 5th like 2nd and 3rd
B&W scan: 0x0080, 0x0040, 0x08E8 = 8bpp
6th & 7th like 2nd and 3rd
True colour scan 0x0080, 0x0040, 0x18E8 = 24bpp
*/
u_int8_t zero; /* Seems to always be zero */
u_int16_t gamma[3]; /* Set to 100 in network order. Gamma? */
u_int16_t pad[3]; /* Zero padding ot 32 bytes??? */
}
PACKED;
/* More known combos (All 24-bit):
300 x 300 light calibration: 0x0000, 0x0010, 0x1820
300 x 300 dark calibration: 0x0000, 0x0010, 0x3024
75 x 75 preview scan: 0x0080, 0x0000, 0x18E8
300 x 300 full scan: 0x0080, 0x0000, 0x18E8
600 x 300 light calibration: 0x0000, 0x0010, 0x3000
600 x 300 dark calibration: 0x0000, 0x0010, 0x3004
600 x 600 full scan: 0x0080, 0x0000, 0x18C8
1200 x 300 light calibration: 0x0000, 0x0010, 0x3000
1200 x 300 dark calibration: 0x0000, 0x0010, 0x3004
1200 x 1200 full scan: 0x0080, 0x0000, 0x18C8
2400 x 300 light calibration: 0x0000, 0x0010, 0x3000
2400 x 300 dark calibration: 0x0000, 0x0010, 0x3004
2400 x 2400 full scan: 0x0080, 0x0000, 0x18C0
*/
struct ScanResponse
{
u_int16_t x1; /* Usually 0x0000 or 0x4000 */
u_int32_t transfersize; /* Number of bytes to be transferred */
u_int32_t xsize; /* Shape of returned bitmap */
u_int16_t ysize; /* Why does the X get more bytes? */
u_int16_t pad[2]; /* Zero padding to 16 bytes??? */
}
PACKED;
static int InitScan2 (enum ScanType type, struct ScanRequest *req,
THWParams * pHWParams, struct ScanResponse *res,
int iColourOffset, int code);
static void FinishScan (THWParams * pHWParams);
static int WriteByte (int iHandle, int cmd, char data);
static int SetLamp (THWParams * pHWParams, int fLampOn);
static int WarmupLamp (int iHandle);
static int SetCalibration (int iHandle, int numPixels,
unsigned int *low_vals[3],
unsigned int *high_vals[3], int dpi);
static void WriteGammaCalibTable (int iHandle, const int *pabGammaR,
const int *pabGammaG,
const int *pabGammaB);
static void SetDefaultGamma (int iHandle);
static void CircBufferInit (int iHandle, TDataPipe * p, int iBytesPerLine,
int bpp, int iMisAlignment, int blksize,
int iTransferSize);
static int CircBufferGetLine (int iHandle, TDataPipe * p, void *pabLine);
static void CircBufferExit (TDataPipe * p);
static void DecodeImage (FILE * file, int planes, int bpp, int xsize, int ysize,
const char *filename);
static int hp5400_test_scan_response (struct ScanResponse *resp,
struct ScanRequest *req);
static int DoAverageScan (int iHandle, struct ScanRequest *req, int code,
unsigned int **array);
static int DoScan (int iHandle, struct ScanRequest *req, const char *filename, int code,
struct ScanResponse *res);
static int Calibrate (int iHandle, int dpi);
static int hp5400_scan (int iHandle, TScanParams * params, THWParams * pHWParams,
const char *filename);
static int PreviewScan (int iHandle);
static int InitScanner (int iHandle);
static int InitScan (enum ScanType scantype, TScanParams * pParams,
THWParams * pHWParams);
static void FinishScan (THWParams * pHWParams);
static int HP5400Open (THWParams * params, char *filename);
static void HP5400Close (THWParams * params);
static int HP5400Detect (char *filename,
int (*_ReportDevice) (TScannerModel * pModel,
char *pszDeviceName));
int
WriteByte (int iHandle, int cmd, char data)
{
if (hp5400_command_write (iHandle, cmd, 1, &data) < 0)
{
DBG (DBG_MSG, "failed to send byte (cmd=%04X)\n", cmd);
HP5400_DBG (DBG_MSG, "failed to send byte (cmd=%04X)\n", cmd);
return -1;
}
return 0;
@ -278,7 +161,7 @@ WarmupLamp (int iHandle)
}
*/
DBG (DBG_MSG, "***WARNING*** Warmup lamp failed...\n");
HP5400_DBG (DBG_MSG, "***WARNING*** Warmup lamp failed...\n");
return -1;
}
@ -411,6 +294,7 @@ void
CircBufferInit (int iHandle, TDataPipe * p, int iBytesPerLine,
int bpp, int iMisAlignment, int blksize, int iTransferSize)
{
iHandle = iHandle; /* to avoid compilation warning */
p->buffersize = max (BUFFER_SIZE, 3 * blksize);
if (p->buffer)
@ -453,7 +337,7 @@ CircBufferInit (int iHandle, TDataPipe * p, int iBytesPerLine,
temp = fopen ("imagedebug.dat", "w+b");
#endif
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"Begin: line=%d (%X), pixels=%d (%X), r=%d (%X), g=%d (%X), b=%d (%X), bpp=%d, step=%d\n",
p->linelength, p->linelength, p->pixels, p->pixels, p->roff, p->roff,
p->goff, p->goff, p->boff, p->boff, bpp, iMisAlignment);
@ -467,7 +351,7 @@ CircBufferGetLine (int iHandle, TDataPipe * p, void *pabLine)
int maxoff = 0;
/* DBG(DBG_MSG, "CircBufferGetLine:\n"); */
/* HP5400_DBG(DBG_MSG, "CircBufferGetLine:\n"); */
if (p->roff > maxoff)
maxoff = p->roff;
@ -507,15 +391,15 @@ CircBufferGetLine (int iHandle, TDataPipe * p, void *pabLine)
assert ((p->bufend + p->blksize) <= p->buffersize);
DBG (DBG_MSG, "Reading block, %d bytes remain\n", p->transfersize);
HP5400_DBG (DBG_MSG, "Reading block, %d bytes remain\n", p->transfersize);
p->transfersize -= p->blksize;
res =
hp5400_bulk_read_block (iHandle, CMD_INITBULK3, cmd, sizeof (cmd),
p->buffer + p->bufend, p->blksize);
p->buffer + p->bufend, p->blksize);
if (res != p->blksize)
{
DBG (DBG_ERR, "*** ERROR: Read returned %d. FATAL.", res);
HP5400_DBG (DBG_ERR, "*** ERROR: Read returned %d. FATAL.", res);
return -1;
}
#ifdef IMAGE_DEBUG
@ -611,7 +495,7 @@ DecodeImage (FILE * file, int planes, int bpp, int xsize, int ysize,
/* xsize is byte width, not pixel width */
xsize /= planes * bpp;
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"DecodeImage(planes=%d,bpp=%d,xsize=%d,ysize=%d) => %d (file=%s)\n",
planes, bpp, xsize, ysize, planes * bpp * xsize * ysize, filename);
@ -659,12 +543,13 @@ DecodeImage (FILE * file, int planes, int bpp, int xsize, int ysize,
int
hp5400_test_scan_response (struct ScanResponse *resp, struct ScanRequest *req)
{
DBG (DBG_MSG, "Scan response:\n");
DBG (DBG_MSG, " transfersize=%d htonl-> %d\n", resp->transfersize,
req = req; /* to avoid compilation warning */
HP5400_DBG (DBG_MSG, "Scan response:\n");
HP5400_DBG (DBG_MSG, " transfersize=%d htonl-> %d\n", resp->transfersize,
htonl (resp->transfersize));
DBG (DBG_MSG, " xsize=%d htonl-> %d\n", resp->xsize,
HP5400_DBG (DBG_MSG, " xsize=%d htonl-> %d\n", resp->xsize,
htonl (resp->xsize));
DBG (DBG_MSG, " ysize=%d htons-> %d\n", resp->ysize,
HP5400_DBG (DBG_MSG, " ysize=%d htons-> %d\n", resp->ysize,
htons (resp->ysize));
return 1;
}
@ -694,7 +579,7 @@ DoAverageScan (int iHandle, struct ScanRequest *req, int code,
length = htonl (res.xsize) / 6;
DBG (DBG_MSG, "Calibration scan: %d pixels wide\n", length);
HP5400_DBG (DBG_MSG, "Calibration scan: %d pixels wide\n", length);
for (j = 0; j < 3; j++)
{
@ -736,6 +621,8 @@ DoScan (int iHandle, struct ScanRequest *req, const char *filename, int code,
/* int bpp, planes; */
int i;
code = code; /*to avoid compilation warning*/
if (res == NULL)
res = &res_temp;
@ -744,7 +631,7 @@ DoScan (int iHandle, struct ScanRequest *req, const char *filename, int code,
file = fopen (filename, "w+b");
if (!file)
{
DBG (DBG_MSG, "Couldn't open outputfile (%s)\n", strerror (errno));
HP5400_DBG (DBG_MSG, "Couldn't open outputfile (%s)\n", strerror (errno));
return -1;
}
@ -838,7 +725,7 @@ Calibrate (int iHandle, int dpi)
strcat (buffer, " ... \n");
len += 6;
DBG (DBG_MSG, buffer);
HP5400_DBG (DBG_MSG, buffer);
}
#endif
@ -896,7 +783,7 @@ Calibrate (int iHandle, int dpi)
strcat (buffer, " ... \n");
len += 6;
DBG (DBG_MSG, buffer);
HP5400_DBG (DBG_MSG, buffer);
}
#endif
@ -913,15 +800,17 @@ hp5400_scan (int iHandle, TScanParams * params, THWParams * pHWParams,
struct ScanResponse res;
int result;
DBG (DBG_MSG, "\n");
DBG (DBG_MSG, "Scanning :\n");
DBG (DBG_MSG, " dpi(x) : %d\n", params->iDpi);
DBG (DBG_MSG, " dpi(y) : %d\n", params->iLpi);
DBG (DBG_MSG, " x0 : %d\n", params->iLeft);
DBG (DBG_MSG, " y0 : %d\n", params->iTop);
DBG (DBG_MSG, " width : %d\n", params->iWidth);
DBG (DBG_MSG, " height : %d\n", params->iHeight);
DBG (DBG_MSG, "\n");
pHWParams = pHWParams; /*to avoid compilation warning*/
HP5400_DBG (DBG_MSG, "\n");
HP5400_DBG (DBG_MSG, "Scanning :\n");
HP5400_DBG (DBG_MSG, " dpi(x) : %d\n", params->iDpi);
HP5400_DBG (DBG_MSG, " dpi(y) : %d\n", params->iLpi);
HP5400_DBG (DBG_MSG, " x0 : %d\n", params->iLeft);
HP5400_DBG (DBG_MSG, " y0 : %d\n", params->iTop);
HP5400_DBG (DBG_MSG, " width : %d\n", params->iWidth);
HP5400_DBG (DBG_MSG, " height : %d\n", params->iHeight);
HP5400_DBG (DBG_MSG, "\n");
bzero (&req, sizeof (req));
@ -1018,7 +907,7 @@ InitScanner (int iHandle)
if (hp5400_command_write (iHandle, 0xF10B, sizeof (UISetup1), UISetup1) < 0)
{
DBG (DBG_MSG, "failed to send UISetup1 (%d)\n", sizeof (UISetup1));
HP5400_DBG (DBG_MSG, "failed to send UISetup1 (%d)\n", sizeof (UISetup1));
return -1;
}
@ -1027,7 +916,7 @@ InitScanner (int iHandle)
if (hp5400_command_write (iHandle, 0xF10C, sizeof (UISetup2), UISetup2) < 0)
{
DBG (DBG_MSG, "failed to send UISetup2\n");
HP5400_DBG (DBG_MSG, "failed to send UISetup2\n");
return -1;
}
return 0;
@ -1070,11 +959,11 @@ InitScan (enum ScanType scantype, TScanParams * pParams,
return -1;
/* SetDefaultGamma( pHWParams->iXferHandle ); ** Must be done by caller */
DBG (DBG_MSG, "Calibration complete\n");
HP5400_DBG (DBG_MSG, "Calibration complete\n");
ret =
InitScan2 (scantype, &req, pHWParams, &res, pParams->iColourOffset, 0x40);
DBG (DBG_MSG, "InitScan2 returned %d\n", ret);
HP5400_DBG (DBG_MSG, "InitScan2 returned %d\n", ret);
/* Pass the results back to the parent */
pParams->iBytesPerLine = htonl (res.xsize);
@ -1104,7 +993,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
if (scantype != SCAN_TYPE_CALIBRATION)
{
DBG (DBG_MSG, "Off(%d,%d) : Len(%d,%d)\n", htons (req->offx),
HP5400_DBG (DBG_MSG, "Off(%d,%d) : Len(%d,%d)\n", htons (req->offx),
htons (req->offy), htons (req->lenx), htons (req->leny));
/* Yes, all the htons() is silly but we want this check as late as possible */
if (htons (req->offx) > 0x09F8)
@ -1133,7 +1022,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
if (hp5400_command_write (iHandle, CMD_STOPSCAN, sizeof (flag), &flag) <
0)
{
DBG (DBG_MSG, "failed to cancel scan flag\n");
HP5400_DBG (DBG_MSG, "failed to cancel scan flag\n");
return -1;
}
}
@ -1142,7 +1031,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
char data[4] = { 0x02, 0x03, 0x03, 0x3C };
if (hp5400_command_write (iHandle, CMD_UNKNOWN3, sizeof (data), data) < 0)
{
DBG (DBG_MSG, "failed to set unknown1\n");
HP5400_DBG (DBG_MSG, "failed to set unknown1\n");
return -1;
}
}
@ -1152,7 +1041,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
if (hp5400_command_write (iHandle, CMD_UNKNOWN2, sizeof (flag), &flag) <
0)
{
DBG (DBG_MSG, "failed to set unknown2\n");
HP5400_DBG (DBG_MSG, "failed to set unknown2\n");
return -1;
}
}
@ -1161,7 +1050,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
short dpi = htons (HW_LPI);
if (hp5400_command_write (iHandle, CMD_SETDPI, sizeof (dpi), &dpi) < 0)
{
DBG (DBG_MSG, "failed to set dpi\n");
HP5400_DBG (DBG_MSG, "failed to set dpi\n");
return -1;
}
}
@ -1176,19 +1065,19 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
if (hp5400_command_write
(iHandle, CMD_SETOFFSET, sizeof (offsets), offsets) < 0)
{
DBG (DBG_MSG, "failed to set offsets\n");
HP5400_DBG (DBG_MSG, "failed to set offsets\n");
return -1;
}
}
DBG (DBG_MSG, "Scan request: \n ");
HP5400_DBG (DBG_MSG, "Scan request: \n ");
{
int i;
size_t i;
for (i = 0; i < sizeof (*req); i++)
{
DBG (DBG_MSG, "%02X ", ((unsigned char *) req)[i]);
HP5400_DBG (DBG_MSG, "%02X ", ((unsigned char *) req)[i]);
}
DBG (DBG_MSG, "\n");
HP5400_DBG (DBG_MSG, "\n");
}
if (hp5400_command_write
@ -1197,7 +1086,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
SCAN_TYPE_CALIBRATION) ? CMD_SCANREQUEST2 : CMD_SCANREQUEST,
sizeof (*req), req) < 0)
{
DBG (DBG_MSG, "failed to send scan request\n");
HP5400_DBG (DBG_MSG, "failed to send scan request\n");
return -1;
}
@ -1206,35 +1095,35 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
if (hp5400_command_write (iHandle, CMD_STARTSCAN, sizeof (flag), &flag) <
0)
{
DBG (DBG_MSG, "failed to set gamma flag\n");
HP5400_DBG (DBG_MSG, "failed to set gamma flag\n");
return -1;
}
}
if (hp5400_command_read (iHandle, CMD_SCANRESPONSE, sizeof (res), &res) < 0)
{
DBG (DBG_MSG, "failed to read scan response\n");
HP5400_DBG (DBG_MSG, "failed to read scan response\n");
return -1;
}
DBG (DBG_MSG, "Scan response: \n ");
HP5400_DBG (DBG_MSG, "Scan response: \n ");
{
int i;
size_t i;
for (i = 0; i < sizeof (res); i++)
{
DBG (DBG_MSG, "%02X ", ((unsigned char *) &res)[i]);
HP5400_DBG (DBG_MSG, "%02X ", ((unsigned char *) &res)[i]);
}
DBG (DBG_MSG, "\n");
HP5400_DBG (DBG_MSG, "\n");
}
DBG (DBG_MSG, "Bytes to transfer: %d\nBitmap resolution: %d x %d\n",
HP5400_DBG (DBG_MSG, "Bytes to transfer: %d\nBitmap resolution: %d x %d\n",
htonl (res.transfersize), htonl (res.xsize), htons (res.ysize));
DBG (DBG_MSG, "Proceeding to scan\n");
HP5400_DBG (DBG_MSG, "Proceeding to scan\n");
if (htonl (res.transfersize) == 0)
{
DBG (DBG_MSG, "Hmm, size is zero. Obviously a problem. Aborting...\n");
HP5400_DBG (DBG_MSG, "Hmm, size is zero. Obviously a problem. Aborting...\n");
return -1;
}
@ -1248,7 +1137,7 @@ InitScan2 (enum ScanType scantype, struct ScanRequest *req,
int planes = (bpp == 1) ? 1 : 3;
bpp /= planes;
DBG (DBG_MSG, "bpp = %d / ( (%d * %d) * (%d * %d) / (%d * %d) ) = %d\n",
HP5400_DBG (DBG_MSG, "bpp = %d / ( (%d * %d) * (%d * %d) / (%d * %d) ) = %d\n",
htonl (res.transfersize),
htons (req->lenx), htons (req->leny),
htons (req->dpix), htons (req->dpiy), HW_LPI, HW_LPI, bpp);
@ -1282,7 +1171,7 @@ FinishScan (THWParams * pHWParams)
if (hp5400_command_write (iHandle, CMD_STOPSCAN, sizeof (flag), &flag) <
0)
{
DBG (DBG_MSG, "failed to set gamma flag\n");
HP5400_DBG (DBG_MSG, "failed to set gamma flag\n");
return;
}
}
@ -1293,10 +1182,11 @@ HP5400Open (THWParams * params, char *filename)
{
int iHandle = hp5400_open (filename);
char szVersion[32];
int i;
if (iHandle < 0)
{
DBG (DBG_MSG, "hp5400_open failed\n");
HP5400_DBG (DBG_MSG, "hp5400_open failed\n");
return -1;
}
@ -1306,10 +1196,15 @@ HP5400Open (THWParams * params, char *filename)
if (hp5400_command_read
(iHandle, CMD_GETVERSION, sizeof (szVersion), szVersion) < 0)
{
DBG (DBG_MSG, "failed to read version string\n");
HP5400_DBG (DBG_MSG, "failed to read version string\n");
goto hp5400_close_exit;
}
HP5400_DBG (DBG_MSG, "version String :\n");
for (i=0; i < 32; i++) {
HP5400_DBG (DBG_MSG, "%c", szVersion[i]);
}
HP5400_DBG (DBG_MSG, "\n");
#ifndef NO_STRING_VERSION_MATCH
/* Match on everything except the version number */
@ -1317,15 +1212,15 @@ HP5400Open (THWParams * params, char *filename)
{
if (memcmp (szVersion + 1, MatchVersion2, sizeof (MatchVersion2) - 4))
{
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"Sorry, unknown scanner version. Attempted match on '%s' and '%s'\n",
MatchVersion, MatchVersion2);
DBG (DBG_MSG, "Vesion is '%s'\n", szVersion);
HP5400_DBG (DBG_MSG, "Vesion is '%s'\n", szVersion);
goto hp5400_close_exit;
}
}
#else
DBG (DBG_MSG, "Warning, Version match is disabled. Version is '%s'\n",
HP5400_DBG (DBG_MSG, "Warning, Version match is disabled. Version is '%s'\n",
szVersion);
#endif /* NO_STRING_VERSION_MATCH */
@ -1361,7 +1256,7 @@ HP5400Detect (char *filename,
if (iHandle < 0)
{
DBG (DBG_MSG, "hp5400_open failed\n");
HP5400_DBG (DBG_MSG, "hp5400_open failed\n");
return -1;
}
@ -1369,7 +1264,7 @@ HP5400Detect (char *filename,
if (hp5400_command_read
(iHandle, CMD_GETVERSION, sizeof (szVersion), szVersion) < 0)
{
DBG (DBG_MSG, "failed to read version string\n");
HP5400_DBG (DBG_MSG, "failed to read version string\n");
ret = -1;
goto hp5400_close_exit;
}
@ -1379,16 +1274,16 @@ HP5400Detect (char *filename,
{
if (memcmp (szVersion + 1, MatchVersion2, sizeof (MatchVersion2) - 1))
{
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"Sorry, unknown scanner version. Attempted match on '%s' and '%s'\n",
MatchVersion, MatchVersion2);
DBG (DBG_MSG, "Vesion is '%s'\n", szVersion);
HP5400_DBG (DBG_MSG, "Vesion is '%s'\n", szVersion);
ret = -1;
goto hp5400_close_exit;
}
}
#else
DBG (DBG_MSG, "Warning, Version match is disabled. Version is '%s'\n",
HP5400_DBG (DBG_MSG, "Warning, Version match is disabled. Version is '%s'\n",
szVersion);
#endif /* NO_STRING_VERSION_MATCH */
@ -1409,13 +1304,11 @@ main (int argc, char *argv[])
assert (sizeof (struct ScanRequest) == 32);
assert (sizeof (struct ScanResponse) == 16);
DBG_MSG = stdout;
DBG_ERR = stderr;
DBG_ASSERT = stderr;
hp5400_dbg_start();
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"HP5400/5470C sample scan utility, by Martijn van Oosterhout <kleptog@svana.org>\n");
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"Based on the testutils by Bertrik Sikken (bertrik@zonnet.nl)\n");
if ((argc == 6) && (!strcmp (argv[1], "-decode")))

Wyświetl plik

@ -0,0 +1,235 @@
#ifndef _HP5400_INTERNAL_H_
#define _HP5400_INTERNAL_H_
/* sane - Scanner Access Now Easy.
(C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
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.
HP5400/5470 Test util.
Currently is only able to read back the scanner version string,
but this basically demonstrates ability to communicate with the scanner.
Massively expanded. Can do calibration scan, upload gamma and calibration
tables and stores the results of a scan. - 19/02/2003 Martijn
*/
#ifdef __GNUC__
#define PACKED __attribute__ ((packed))
#else
#define PACKED
#endif
/* If this is enabled, a copy of the raw data from the scanner will be saved to
imagedebug.dat and the attempted conversion to imagedebug.ppm */
/* #define IMAGE_DEBUG */
/* If this is defined you get extra info on the calibration */
/* #define CALIB_DEBUG */
#define CMD_GETVERSION 0x1200
#define CMD_GETUITEXT 0xf00b
#define CMD_GETCMDID 0xc500
#define CMD_SCANREQUEST 0x2505 /* This is for previews */
#define CMD_SCANREQUEST2 0x2500 /* This is for real scans */
#define CMD_SCANRESPONSE 0x3400
/* Testing stuff to make it work */
#define CMD_SETDPI 0x1500 /* ??? */
#define CMD_STOPSCAN 0x1B01 /* 0x40 = lamp in on, 0x00 = lamp is off */
#define CMD_STARTSCAN 0x1B05 /* 0x40 = lamp in on, 0x00 = lamp is off */
#define CMD_UNKNOWN 0x2300 /* Send fixed string */
#define CMD_UNKNOWN2 0xD600 /* ??? Set to 0x04 */
#define CMD_UNKNOWN3 0xC000 /* ??? Set to 02 03 03 3C */
#define CMD_SETOFFSET 0xE700 /* two ints in network order. X-offset, Y-offset of full scan */
/* Given values seem to be 0x0054 (=4.57mm) and 0x0282 (=54.36mm) */
#define CMD_INITBULK1 0x0087 /* send 0x14 */
#define CMD_INITBULK2 0x0083 /* send 0x24 */
#define CMD_INITBULK3 0x0082 /* transfer length 0xf000 */
struct ScanRequest
{
u_int8_t x1; /* Set to 0x08 */
u_int16_t dpix, dpiy; /* Set to 75, 150 or 300 in network order */
u_int16_t offx, offy; /* Offset to scan, in 1/300th of dpi, in network order */
u_int16_t lenx, leny; /* Size of scan, in 1/300th of dpi, in network order */
u_int16_t flags1, flags2, flags3; /* Undetermined flag info */
/* Known combinations are:
1st calibration scan: 0x0000, 0x0010, 0x1820 = 24bpp
2nd calibration scan: 0x0000, 0x0010, 0x3020 = 48bpp ???
3rd calibration scan: 0x0000, 0x0010, 0x3024 = 48bpp ???
Preview scan: 0x0080, 0x0000, 0x18E8 = 8bpp
4th & 5th like 2nd and 3rd
B&W scan: 0x0080, 0x0040, 0x08E8 = 8bpp
6th & 7th like 2nd and 3rd
True colour scan 0x0080, 0x0040, 0x18E8 = 24bpp
*/
u_int8_t zero; /* Seems to always be zero */
u_int16_t gamma[3]; /* Set to 100 in network order. Gamma? */
u_int16_t pad[3]; /* Zero padding ot 32 bytes??? */
}
PACKED;
/* More known combos (All 24-bit):
300 x 300 light calibration: 0x0000, 0x0010, 0x1820
300 x 300 dark calibration: 0x0000, 0x0010, 0x3024
75 x 75 preview scan: 0x0080, 0x0000, 0x18E8
300 x 300 full scan: 0x0080, 0x0000, 0x18E8
600 x 300 light calibration: 0x0000, 0x0010, 0x3000
600 x 300 dark calibration: 0x0000, 0x0010, 0x3004
600 x 600 full scan: 0x0080, 0x0000, 0x18C8
1200 x 300 light calibration: 0x0000, 0x0010, 0x3000
1200 x 300 dark calibration: 0x0000, 0x0010, 0x3004
1200 x 1200 full scan: 0x0080, 0x0000, 0x18C8
2400 x 300 light calibration: 0x0000, 0x0010, 0x3000
2400 x 300 dark calibration: 0x0000, 0x0010, 0x3004
2400 x 2400 full scan: 0x0080, 0x0000, 0x18C0
*/
struct ScanResponse
{
u_int16_t x1; /* Usually 0x0000 or 0x4000 */
u_int32_t transfersize; /* Number of bytes to be transferred */
u_int32_t xsize; /* Shape of returned bitmap */
u_int16_t ysize; /* Why does the X get more bytes? */
u_int16_t pad[2]; /* Zero padding to 16 bytes??? */
}
PACKED;
int
InitScan2 (enum ScanType type, struct ScanRequest *req,
THWParams * pHWParams, struct ScanResponse *res,
int iColourOffset, int code);
void
FinishScan (THWParams * pHWParams);
int
WriteByte (int iHandle, int cmd, char data);
int
SetLamp (THWParams * pHWParams, int fLampOn);
int
WarmupLamp (int iHandle);
int
SetCalibration (int iHandle, int numPixels,
unsigned int *low_vals[3],
unsigned int *high_vals[3], int dpi);
void
WriteGammaCalibTable (int iHandle, const int *pabGammaR,
const int *pabGammaG,
const int *pabGammaB);
void
SetDefaultGamma (int iHandle);
void
CircBufferInit (int iHandle, TDataPipe * p, int iBytesPerLine,
int bpp, int iMisAlignment, int blksize,
int iTransferSize);
int
CircBufferGetLine (int iHandle, TDataPipe * p, void *pabLine);
void
CircBufferExit (TDataPipe * p);
void
DecodeImage (FILE * file, int planes, int bpp, int xsize, int ysize,
const char *filename);
int
hp5400_test_scan_response (struct ScanResponse *resp,
struct ScanRequest *req);
int
DoAverageScan (int iHandle, struct ScanRequest *req, int code,
unsigned int **array);
int
DoScan (int iHandle, struct ScanRequest *req, const char *filename, int code,
struct ScanResponse *res);
int
Calibrate (int iHandle, int dpi);
int
hp5400_scan (int iHandle, TScanParams * params, THWParams * pHWParams,
const char *filename);
int
PreviewScan (int iHandle);
int
InitScanner (int iHandle);
int
InitScan (enum ScanType scantype, TScanParams * pParams,
THWParams * pHWParams);
void
FinishScan (THWParams * pHWParams);
int
HP5400Open (THWParams * params, char *filename);
void
HP5400Close (THWParams * params);
int
HP5400Detect (char *filename,
int (*_ReportDevice) (TScannerModel * pModel,
char *pszDeviceName));
#ifdef STANDALONE
int
main (int argc, char *argv[]);
#endif
#endif

1005
backend/hp5400_sane.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,24 +1,27 @@
/* sane - Scanner Access Now Easy.
(c) 2003 Henning Meier-Geinitz, <henning@meier-geinitz.de>
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Copyright (c) 2003 Henning Meier-Geinitz, <henning@meier-geinitz.de>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
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.
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.
@ -44,15 +47,16 @@
Transport layer for communication with HP5400/5470 scanner.
Implementation using sanei_usb
Additions to support bulk data transport. Added debugging info - 19/02/2003 Martijn
Changed to use sanei_usb instead of direct /dev/usb/scanner access - 15/04/2003 Henning
*/
#include "hp5400_xfer.h"
#include "hp5400_debug.h"
#include <stdio.h>
#include "../include/sane/sanei_usb.h"
#include "sane/sanei_usb.h"
#define CMD_INITBULK1 0x0087 /* send 0x14 */
#define CMD_INITBULK2 0x0083 /* send 0x24 */
@ -66,19 +70,19 @@ _UsbWriteControl (int fd, int iValue, int iIndex, void *pabData, int iSize)
int requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT;
int request = (iSize > 1) ? 0x04 : 0x0C;
DBG (DBG_MSG,
HP5400_DBG (DBG_MSG,
"Write: reqtype = 0x%02X, req = 0x%02X, value = %04X, len = %d\n",
requesttype, request, iValue, iSize);
if (iSize > 0)
{
int i;
DBG (DBG_MSG, " Data: ");
HP5400_DBG (DBG_MSG, " Data: ");
for (i = 0; i < iSize && i < 8; i++)
DBG (DBG_MSG, "%02X ", ((unsigned char *) pabData)[i]);
HP5400_DBG (DBG_MSG, "%02X ", ((unsigned char *) pabData)[i]);
if (iSize > 8)
DBG (DBG_MSG, "...");
DBG (DBG_MSG, "\n");
HP5400_DBG (DBG_MSG, "...");
HP5400_DBG (DBG_MSG, "\n");
}
if (fd != -1)
@ -102,7 +106,7 @@ _UsbReadControl (int fd, int iValue, int iIndex, void *pabData, int iSize)
int requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN;
int request = (iSize > 1) ? 0x04 : 0x0C;
DBG (DBG_MSG, "Read: reqtype = 0x%02X, req = 0x%02X, value = %04X\n",
HP5400_DBG (DBG_MSG, "Read: reqtype = 0x%02X, req = 0x%02X, value = %04X\n",
requesttype, request, iValue);
if (fd != -1)
@ -125,7 +129,7 @@ hp5400_open (const char *filename)
status = sanei_usb_open (filename, &fd);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "hp5400_open: open returned %s\n",
HP5400_DBG (DBG_MSG, "hp5400_open: open returned %s\n",
sane_strstatus (status));
return -1;
}
@ -133,7 +137,7 @@ hp5400_open (const char *filename)
status = sanei_usb_get_vendor_product (fd, &iVendor, &iProduct);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "hp5400_open: can't get vendor/product ids: %s\n",
HP5400_DBG (DBG_MSG, "hp5400_open: can't get vendor/product ids: %s\n",
sane_strstatus (status));
sanei_usb_close (fd);
return -1;
@ -141,13 +145,13 @@ hp5400_open (const char *filename)
if ((iVendor != 0x03F0) || ((iProduct != 0x1005) && (iProduct != 0x1105)))
{
DBG (DBG_MSG, "hp5400_open: vendor/product 0x%04X-0x%04X is not "
HP5400_DBG (DBG_MSG, "hp5400_open: vendor/product 0x%04X-0x%04X is not "
"supported\n", iVendor, iProduct);
sanei_usb_close (fd);
return -1;
}
DBG (DBG_MSG, "vendor/product 0x%04X-0x%04X opened\n", iVendor, iProduct);
HP5400_DBG (DBG_MSG, "vendor/product 0x%04X-0x%04X opened\n", iVendor, iProduct);
return fd;
}
@ -169,7 +173,7 @@ hp5400_command_verify (int iHandle, int iCmd)
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_verify: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_command_verify: invalid handle\n");
return -1;
}
fd = iHandle;
@ -179,7 +183,7 @@ hp5400_command_verify (int iHandle, int iCmd)
if (abData[0] != (iCmd >> 8))
{
DBG (DBG_ERR,
HP5400_DBG (DBG_ERR,
"hp5400_command_verify failed, expected 0x%02X%02X, got 0x%02X%02X\n",
(int) (iCmd >> 8), (int) (iCmd & 0xff), (int) abData[0],
(int) abData[1]);
@ -190,13 +194,13 @@ hp5400_command_verify (int iHandle, int iCmd)
if (abData[1] != 0) /* Error code non-zero */
{
_UsbReadControl (fd, 0x0300, 0, (char *) abData, 3);
DBG (DBG_ERR, " error response is: %02X %02X %02X\n", abData[0],
HP5400_DBG (DBG_ERR, " error response is: %02X %02X %02X\n", abData[0],
abData[1], abData[2]);
return -1;
}
DBG (DBG_MSG, "Command %02X verified\n", abData[0]);
HP5400_DBG (DBG_MSG, "Command %02X verified\n", abData[0]);
return 1;
}
@ -209,7 +213,7 @@ hp5400_command_read_noverify (int iHandle, int iCmd, int iLen, void *pbData)
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
return -1;
}
fd = iHandle;
@ -237,7 +241,7 @@ hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData)
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
return -1;
}
fd = iHandle;
@ -261,12 +265,12 @@ hp5400_bulk_read (int iHandle, int len, int block, FILE * file)
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
return -1;
}
fd = iHandle;
buffer = malloc (block);
buffer = (unsigned char*) malloc (block);
_UsbWriteControl (fd, CMD_INITBULK1, 0, &x1, 1);
_UsbWriteControl (fd, CMD_INITBULK2, 0, &x2, 1);
@ -277,7 +281,7 @@ hp5400_bulk_read (int iHandle, int len, int block, FILE * file)
sizeof (buf));
res = block;
sanei_usb_read_bulk (fd, buffer, &res);
DBG (DBG_MSG, "Read bulk returned %d, %d remain\n", res, len);
HP5400_DBG (DBG_MSG, "Read bulk returned %d, %d remain\n", res, len);
if (res > 0)
{
fwrite (buffer, (len < res) ? len : res, 1, file);
@ -298,7 +302,7 @@ hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_command_read_block: invalid handle\n");
return -1;
}
fd = iHandle;
@ -306,7 +310,7 @@ hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
_UsbWriteControl (fd, iCmd, 0, cmd, cmdlen);
res = len;
sanei_usb_read_bulk (fd, buffer, &res);
DBG (DBG_MSG, "Read block returned %d when reading %d\n", res, len);
HP5400_DBG (DBG_MSG, "Read block returned %d when reading %d\n", res, len);
return res;
}
@ -320,12 +324,12 @@ hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
HP5400_DBG (DBG_ERR, "hp5400_bulk_command_write: invalid handle\n");
return -1;
}
fd = iHandle;
DBG (DBG_MSG, "bulk_command_write(%04X,<%d bytes>,<%d bytes>)\n", iCmd,
HP5400_DBG (DBG_MSG, "bulk_command_write(%04X,<%d bytes>,<%d bytes>)\n", iCmd,
cmdlen, datalen);
_UsbWriteControl (fd, iCmd, 0, cmd, cmdlen);
@ -334,16 +338,16 @@ hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
{
{
int i;
DBG (DBG_MSG, " Data: ");
HP5400_DBG (DBG_MSG, " Data: ");
for (i = 0; i < datalen && i < block && i < 8; i++)
DBG (DBG_MSG, "%02X ", ((unsigned char *) data + offset)[i]);
HP5400_DBG (DBG_MSG, "%02X ", ((unsigned char *) data + offset)[i]);
if (i >= 8)
DBG (DBG_MSG, "...");
DBG (DBG_MSG, "\n");
HP5400_DBG (DBG_MSG, "...");
HP5400_DBG (DBG_MSG, "\n");
}
res = (datalen < block) ? datalen : block;
sanei_usb_write_bulk (fd, data + offset, &res);
DBG (DBG_MSG, "Write returned %d, %d remain\n", res, datalen);
HP5400_DBG (DBG_MSG, "Write returned %d, %d remain\n", res, datalen);
datalen -= block;
offset += block;
}

Wyświetl plik

@ -0,0 +1,106 @@
#ifndef _HP5400_SANEI_H_
#define _HP5400_SANEI_H_
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Copyright (c) 2003 Henning Meier-Geinitz, <henning@meier-geinitz.de>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
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.
Transport layer for communication with HP5400/5470 scanner.
Implementation using sanei_usb
Additions to support bulk data transport. Added debugging info - 19/02/2003 Martijn
Changed to use sanei_usb instead of direct /dev/usb/scanner access - 15/04/2003 Henning
*/
#define CMD_INITBULK1 0x0087 /* send 0x14 */
#define CMD_INITBULK2 0x0083 /* send 0x24 */
#define CMD_INITBULK3 0x0082 /* transfer length 0xf000 */
void _UsbWriteControl (int fd, int iValue, int iIndex, void *pabData, int iSize);
void hp5400_command_write_noverify (int fd, int iValue, void *pabData, int iSize);
void _UsbReadControl (int fd, int iValue, int iIndex, void *pabData, int iSize);
int hp5400_open (const char *filename);
void hp5400_close (int iHandle);
/* returns value > 0 if verify ok */
int hp5400_command_verify (int iHandle, int iCmd);
/* returns > 0 if command OK */
int hp5400_command_read_noverify (int iHandle, int iCmd, int iLen, void *pbData);
/* returns > 0 if command OK */
int hp5400_command_read (int iHandle, int iCmd, int iLen, void *pbData);
/* returns >0 if command OK */
int hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData);
/* returns >0 if command OK */
int hp5400_bulk_read (int iHandle, int len, int block, FILE * file);
/* returns >0 if command OK */
int hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
void *buffer, int len);
/* returns >0 if command OK */
int hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
int datalen, int block, char *data);
/**
ScannerIsOn
retrieve on/off status from scanner
@return 1 if is on 0 if is off -1 if is not reachable
*/
int hp5400_isOn (int iHandle);
#endif

Wyświetl plik

@ -1,23 +1,29 @@
#ifndef _HP5400_XFER_H_
#define _HP5400_XFER_H_
/* sane - Scanner Access Now Easy.
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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.
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.
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.
@ -45,19 +51,23 @@
Add support for bulk transport of data - 19/02/2003 Martijn
*/
static int hp5400_open (const char *filename);
static void hp5400_close (int iHandle);
#include <stdio.h>
static int hp5400_command_verify (int iHandle, int iCmd);
static int hp5400_command_read (int iHandle, int iCmd, int iLen, void *pbData);
static int hp5400_command_read_noverify (int iHandle, int iCmd, int iLen,
int hp5400_open (const char *filename);
void hp5400_close (int iHandle);
int hp5400_command_verify (int iHandle, int iCmd);
int hp5400_command_read (int iHandle, int iCmd, int iLen, void *pbData);
int hp5400_command_read_noverify (int iHandle, int iCmd, int iLen,
void *pbData);
static int hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData);
static void hp5400_command_write_noverify (int fd, int iValue, void *pabData,
int hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData);
void hp5400_command_write_noverify (int fd, int iValue, void *pabData,
int iSize);
static int hp5400_bulk_read (int iHandle, int size, int block, FILE * file);
static int hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
int hp5400_bulk_read (int iHandle, int size, int block, FILE * file);
int hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
void *buffer, int len);
static int hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
int hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
int len, int block, char *data);
static int hp5400_isOn (int iHandle);
int hp5400_isOn (int iHandle);
#endif