From c84bdda420ca319211dde130c652d3c1d1db6876 Mon Sep 17 00:00:00 2001 From: Thomas Soumarmon Date: Thu, 5 Jun 2003 07:05:59 +0000 Subject: [PATCH] hp5400: synching SANE CVS with hp5400backend sourceforge project CVS : added and modified hp5400 files (see Changelog) --- backend/Makefile.in | 4 +- backend/hp5400.c | 941 +--------------------------------- backend/hp5400.h | 13 +- backend/hp5400_debug.c | 72 +++ backend/hp5400_debug.h | 76 +++ backend/hp5400_internal.c | 299 ++++------- backend/hp5400_internal.h | 235 +++++++++ backend/hp5400_sane.c | 1005 +++++++++++++++++++++++++++++++++++++ backend/hp5400_sanei.c | 94 ++-- backend/hp5400_sanei.h | 106 ++++ backend/hp5400_xfer.h | 54 +- 11 files changed, 1696 insertions(+), 1203 deletions(-) create mode 100644 backend/hp5400_debug.c create mode 100644 backend/hp5400_debug.h create mode 100644 backend/hp5400_internal.h create mode 100644 backend/hp5400_sane.c create mode 100644 backend/hp5400_sanei.h diff --git a/backend/Makefile.in b/backend/Makefile.in index ef2066edc..54958fc34 100644 --- a/backend/Makefile.in +++ b/backend/Makefile.in @@ -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 \ diff --git a/backend/hp5400.c b/backend/hp5400.c index 87004552f..c8b03312b 100644 --- a/backend/hp5400.c +++ b/backend/hp5400.c @@ -1,6 +1,7 @@ /* sane - Scanner Access Now Easy. Copyright (C) 2003 Martijn van Oosterhout - + Copyright (C) 2003 Thomas Soumarmon + 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 /* malloc, free */ #include /* memcpy */ #include -#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; -} diff --git a/backend/hp5400.h b/backend/hp5400.h index 4848aa27a..b0efb4f5e 100644 --- a/backend/hp5400.h +++ b/backend/hp5400.h @@ -1,17 +1,18 @@ /* sane - Scanner Access Now Easy. Copyright (C) 2003 Martijn van Oosterhout - + Copyright (C) 2003 Thomas Soumarmon + 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_ */ diff --git a/backend/hp5400_debug.c b/backend/hp5400_debug.c new file mode 100644 index 000000000..dcdd651b8 --- /dev/null +++ b/backend/hp5400_debug.c @@ -0,0 +1,72 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 2003 Martijn van Oosterhout + Copyright (C) 2003 Thomas Soumarmon + + 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 + +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 + +#endif + + diff --git a/backend/hp5400_debug.h b/backend/hp5400_debug.h new file mode 100644 index 000000000..5d4b151a1 --- /dev/null +++ b/backend/hp5400_debug.h @@ -0,0 +1,76 @@ +#ifndef __HP5400_DEBUG_H_ +#define __HP5400_DEBUG_H_ + +/* sane - Scanner Access Now Easy. + Copyright (C) 2003 Martijn van Oosterhout + Copyright (C) 2003 Thomas Soumarmon + + 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 + +#define DBG_ASSERT 1 +#define DBG_ERR 16 +#define DBG_MSG 32 +#define HP5400_DBG DBG + +#else + +#include +#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 diff --git a/backend/hp5400_internal.c b/backend/hp5400_internal.c index b01808cdd..2d7247830 100644 --- a/backend/hp5400_internal.c +++ b/backend/hp5400_internal.c @@ -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 + Copyright (C) 2003 Thomas Soumarmon + Copyright (c) 2003 Henning Meier-Geinitz, + + 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 /* for printf */ #include /* for exit */ #include -/*#include */ #include #include #include @@ -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 \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"))) diff --git a/backend/hp5400_internal.h b/backend/hp5400_internal.h new file mode 100644 index 000000000..1b2c66f20 --- /dev/null +++ b/backend/hp5400_internal.h @@ -0,0 +1,235 @@ +#ifndef _HP5400_INTERNAL_H_ +#define _HP5400_INTERNAL_H_ + +/* sane - Scanner Access Now Easy. + (C) 2003 Thomas Soumarmon + (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 diff --git a/backend/hp5400_sane.c b/backend/hp5400_sane.c new file mode 100644 index 000000000..79c85d73e --- /dev/null +++ b/backend/hp5400_sane.c @@ -0,0 +1,1005 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 2003 Martijn van Oosterhout + Copyright (C) 2003 Thomas Soumarmon + + 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. +*/ + + +/* + SANE interface for hp54xx scanners. Prototype. + Parts of this source were inspired by other backends. +*/ + + +/* definitions for debug */ +#include "hp5400_debug.h" + +#include "sane/sane.h" +#include "sane/sanei.h" +#include "sane/sanei_backend.h" +#include "sane/sanei_config.h" +#include "sane/saneopts.h" +#include "sane/config.h" + +#include /* malloc, free */ +#include /* memcpy */ +#include +#include + +#define HP5400_CONFIG_FILE "hp5400.conf" + +#include "hp5400.h" + +/* includes for data transfer methods */ +#include "hp5400.h" + +#ifdef STANDALONE +#include "hp5400_scanner.h" +#endif + +#if defined(LINUX_USB_SUPPORT) + #include "hp5400_linux.c" +#endif +#if defined(USCANNER_SUPPORT) + #include "hp5400_uscanner.c" +#endif +#if defined(LIBUSB_SUPPORT) + #include "hp5400_libusb.c" +#endif +#if defined(LIBIEEE1284_SUPPORT) + #include "hp5400_ieee1284.c" +#endif + + + +/* other definitions */ +#ifndef min +#define min(A,B) (((A)<(B)) ? (A) : (B)) +#endif +#ifndef max +#define max(A,B) (((A)>(B)) ? (A) : (B)) +#endif + +#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 + + +/* 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; + + + +/* Device filename for USB access */ +char * usb_devfile = "/dev/usb/scanner0"; + +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: + HP5400_DBG(DBG_ERR, "Uninitialised option %d\n", i); + break; + } + } +} + + +static int _ReportDevice(TScannerModel *pModel, char *pszDeviceName) +{ + TDevListEntry *pNew, *pDev; + + HP5400_DBG(DBG_MSG, "hp5400: _ReportDevice '%s'\n", pszDeviceName); + + pNew = malloc(sizeof(TDevListEntry)); + if (!pNew) { + HP5400_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 = (char*)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) +{ + char * filename = (char*) devname; + if (HP5400Detect (filename, _ReportDevice) < 0) + { + HP5400_DBG (DBG_MSG, "attach_one_device: couldn't attach %s\n", devname); + return SANE_STATUS_INVAL; + } + HP5400_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 (); + + HP5400_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) + { + HP5400_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] == '#') + { + HP5400_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. */ + HP5400_DBG (DBG_MSG, "Trying to attach %s\n", line); + sanei_usb_attach_matching_devices (line, attach_one_device); + } + } /* while */ + fclose (conf_fp); + } + else + { + HP5400_DBG (DBG_ERR, "Unable to read config file \"%s\": %s\n", + HP5400_CONFIG_FILE, strerror (errno)); + HP5400_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; + + HP5400_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; + + HP5400_DBG (DBG_MSG, "sane_get_devices\n"); + + local_only = local_only; + + if (_pSaneDevList) + { + free (_pSaneDevList); + } + + _pSaneDevList = malloc (sizeof (*_pSaneDevList) * (iNumSaneDev + 1)); + if (!_pSaneDevList) + { + HP5400_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; + + HP5400_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) + { + HP5400_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 ? */ + HP5400_DBG (DBG_ERR, "HP5400Open failed\n"); + free ((void *) s); + return SANE_STATUS_INVAL; /* is this OK? */ + } + HP5400_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; + + HP5400_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; + + HP5400_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; + + HP5400_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; */ + HP5400_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; */ + HP5400_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: + HP5400_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: + HP5400_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: + HP5400_DBG (DBG_MSG, "SANE_ACTION_GET_VALUE: Invalid option (%d)\n", n); + } + break; + + + case SANE_ACTION_SET_VALUE: + if (s->fScanning) + { + HP5400_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: + HP5400_DBG (DBG_MSG, "Writing gamma table\n"); + memcpy (s->aValues[n].wa, pVal, s->aOptions[n].size); + break; +/* + case optLamp: + fVal = *(SANE_Bool *)pVal; + HP5400_DBG(DBG_MSG, "lamp %s\n", fVal ? "on" : "off"); + SetLamp(&s->HWParams, fVal); + break; +*/ +#if 0 + case optCalibrate: +/* SimpleCalib(&s->HWParams); */ + break; +#endif + default: + HP5400_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: + HP5400_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; + HP5400_DBG (DBG_MSG, "sane_get_parameters\n"); + + s = (TScanner *) h; + + /* first do some checks */ + if (s->aValues[optTLX].w >= s->aValues[optBRX].w) + { + HP5400_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) + { + HP5400_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; + + HP5400_DBG (DBG_MSG, "sane_start\n"); + + s = (TScanner *) h; + + if (sane_get_parameters (h, &par) != SANE_STATUS_GOOD) + { + HP5400_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) + { + HP5400_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; + + HP5400_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 */ + HP5400_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++; + } + + HP5400_DBG (DBG_MSG, "sane_read: %d bytes read\n", *len); + + return SANE_STATUS_GOOD; +} + + +void +sane_cancel (SANE_Handle h) +{ + TScanner *s; + + HP5400_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) +{ + HP5400_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) +{ + HP5400_DBG (DBG_MSG, "sane_select_fd\n"); + + /* prevent compiler from complaining about unused parameters */ + h = h; + fd = fd; + + return SANE_STATUS_UNSUPPORTED; +} diff --git a/backend/hp5400_sanei.c b/backend/hp5400_sanei.c index 5def65673..550122968 100644 --- a/backend/hp5400_sanei.c +++ b/backend/hp5400_sanei.c @@ -1,24 +1,27 @@ /* sane - Scanner Access Now Easy. - (c) 2003 Henning Meier-Geinitz, - (c) 2003 Martijn van Oosterhout, kleptog@svana.org - (c) 2002 Bertrik Sikken, bertrik@zonnet.nl + Copyright (C) 2003 Martijn van Oosterhout + Copyright (C) 2003 Thomas Soumarmon + Copyright (c) 2003 Henning Meier-Geinitz, + + 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 -#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; } diff --git a/backend/hp5400_sanei.h b/backend/hp5400_sanei.h new file mode 100644 index 000000000..2197e06b6 --- /dev/null +++ b/backend/hp5400_sanei.h @@ -0,0 +1,106 @@ +#ifndef _HP5400_SANEI_H_ +#define _HP5400_SANEI_H_ + +/* sane - Scanner Access Now Easy. + Copyright (C) 2003 Martijn van Oosterhout + Copyright (C) 2003 Thomas Soumarmon + Copyright (c) 2003 Henning Meier-Geinitz, + + 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 diff --git a/backend/hp5400_xfer.h b/backend/hp5400_xfer.h index 146d17a07..d9fe12a3e 100644 --- a/backend/hp5400_xfer.h +++ b/backend/hp5400_xfer.h @@ -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 + Copyright (C) 2003 Thomas Soumarmon + + 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 -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