Update to version 0.45, added some new models and support for libusb.

RELEASE_1_0_11_BRANCH
Gerhard Jaeger 2003-01-10 13:32:11 +00:00
rodzic ee88748aa6
commit 8ba08fdfca
17 zmienionych plików z 3131 dodań i 1890 usunięć

Wyświetl plik

@ -1,3 +1,15 @@
2002-10-15 Gerhard Jaeger <gerhard@gjaeger.de>
* doc/sane-plustek.man: update to reflect version change
* doc/descriptions/plustek.desc: Added some Canon entries, status updates
* backend/plustek.conf updated options
* backend/plustek.c backend/plustek-devs.c backend/plustek-usb.c
backend/plustek-usbhw.c backend/plustek-pp.c
backend/plustek-usbmap.c backend/plustek-usbimg.c
backend/plustek-usbscan.c backend/plustek-usbshading.c
backend/plustek.h backend/plustek-share.h backend/plustek-usb.h
New version + support for libusb
2003-01-09 Peter Fales <peter@fales-lorenz.net>
* backend/dc210.c, backend/dc240.c: Fix compile failure
@ -510,7 +522,7 @@
* backend/umax_pp.c backend/umax_pp_mid.c : OS/2 compile fix, indent
correction
2002-11-03 Karl Heinz Kremer <khk@khk.net>
* sanei/sanei_usb.c: Use endpoint address with direction information
@ -553,7 +565,7 @@
* configure, acinclude.m4, aclocal.m4 - Remove checks for
specific version numbers of gphoto2 - that's not good for long
term maintenance, and the API has settled down enough that all
term maintenance, and the API has settled down enough that all
recent versions (both releases and CVS) are workable for SANE.
It is still necessary to specify --with-gphoto2 if you want to
use the gphoto2 backend.

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,26 +1,24 @@
/*.............................................................................
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
* File: plustek_pp.c - the interface to the parport driver...
*.............................................................................
*/
/** @file plustek-pp.c
* @brief The interface to the parport driver.
*
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*
* based on Kazuhiro Sasayama previous work on
* plustek.[ch] file from the SANE package.
* original code taken from sane-0.71
* Copyright (C) 1997 Hypercore Software Design, Ltd.
* also based on the work done by Rick Bronson
* Copyright (C) 2000-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
* History:
* 0.40 - initial version
* 0.41 - added _PTDRV_ADJUST call
* 0.42 - added setmap function
* fixed the stopscan problem, that causes a crash in the kernel module
* 0.43 - no changes
* 0.44 - added initialized setting
*
*.............................................................................
*
* - 0.40 - initial version
* - 0.41 - added _PTDRV_ADJUST call
* - 0.42 - added setmap function
* - fixed the stopscan problem, that causes a crash in the kernel module
* - 0.43 - no changes
* - 0.44 - added initialized setting
* - 0.45 - no changes
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -58,6 +56,7 @@
* 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.
* <hr>
*/
/******************* wrapper functions for parport device ********************/

Wyświetl plik

@ -1,32 +1,34 @@
/*.............................................................................
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
* File: plustek-share.h - definitions for the backend and the driver
*.............................................................................
*/
/** @file plustek-share.h
* @brief Common definitions for the backend and the kernel driver
*
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*
* Copyright (C) 2000-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
* History:
* 0.36 - initial version
* 0.37 - updated scanner info list
* removed override switches
* 0.38 - changed the dwFlag entry in ScannerCaps and its meaning
* changed _NO_BASE
* fixed model list
* removed gray-scale capabilities for TPA scans
* 0.39 - added user-space stuff
* added Genius Colorpage Vivid III V2 stuff
* 0.40 - added stuff to share with USB and Parport
* 0.41 - changed the IOCTL version number
* added adjustment stuff
* 0.42 - added FLAG_CUSTOM_GAMMA and _MAP_ definitions
* changed IOCTL interface to allow downloadable MAPS
* added error codes
* 0.43 - added tpa entry for AdjDef
* 0.44 - extended AdjDef
*
*.............................................................................
*
* - 0.36 - initial version
* - 0.37 - updated scanner info list
* - removed override switches
* - 0.38 - changed the dwFlag entry in ScannerCaps and its meaning
* - changed _NO_BASE
* - fixed model list
* - removed gray-scale capabilities for TPA scans
* - 0.39 - added user-space stuff
* - added Genius Colorpage Vivid III V2 stuff
* - 0.40 - added stuff to share with USB and Parport
* - 0.41 - changed the IOCTL version number
* - added adjustment stuff
* - 0.42 - added FLAG_CUSTOM_GAMMA and _MAP_ definitions
* - changed IOCTL interface to allow downloadable MAPS
* - added error codes
* - 0.43 - added tpa entry for AdjDef
* - 0.44 - extended AdjDef
* - 0.45 - added skipFine and skipFineWhite to AdjDef
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -64,6 +66,7 @@
* 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.
* <hr>
*/
#ifndef __PLUSTEK_SHARE_H__
#define __PLUSTEK_SHARE_H__
@ -260,6 +263,8 @@ typedef struct {
int warmup;
int enableTpa;
int skipCalibration;
int skipFine;
int skipFineWhite;
int invertNegatives;
int rgain;
@ -484,7 +489,7 @@ typedef struct {
#define COLOR_TRUE36 5
/* We don't support halftone mode now --> Plustek statement for USB */
#define COLOR_GRAY16 COLOR_HALFTONE
#define COLOR_GRAY16 6
/* IDs the ASIC returns */

Wyświetl plik

@ -1,25 +1,32 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usb.c - the interface functions to the USB driver stuff
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usb.c
* @brief The interface functions to the USB driver stuff.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - removed CHECK
* added Canon to the manufacturer list
* 0.42 - added warmup stuff
* added setmap function
* changed detection stuff, so we first check whether
* the vendor and product Ids match with the ones in our list
* 0.43 - cleanup
* 0.44 - changes to integration CIS based devices
*
*.............................................................................
*
* - 0.40 - starting version of the USB support
* - 0.41 - removed CHECK
* - added Canon to the manufacturer list
* - 0.42 - added warmup stuff
* - added setmap function
* - changed detection stuff, so we first check whether
* - the vendor and product Ids match with the ones in our list
* - 0.43 - cleanup
* - 0.44 - changes to integration CIS based devices
* - 0.45 - added skipFine assignment
* - added auto device name detection if only product and vendor id<br>
* has been specified
* - made 16-bit gray mode work
* - added special handling for Genius devices
* - added TPA autodetection for EPSON Photo
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -57,9 +64,10 @@
* 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.
* <hr>
*/
/*
/**
* to allow different vendors...
*/
static TabDef usbVendors[] = {
@ -71,12 +79,20 @@ static TabDef usbVendors[] = {
{ 0x03F0, "Hewlett-Packard" },
{ 0x04B8, "Epson" },
{ 0x04A9, "Canon" },
{ 0x1606, "UMAX" },
{ 0xFFFF, NULL }
};
/** for autodetection */
SANE_Char USB_devname[1024];
/** we use at least 8 megs for scanning... */
#define _SCANBUF_SIZE (8 * 1024 * 1024)
/********************** the USB scanner interface ****************************/
/*.............................................................................
/**
* assign the values to the structures used by the currently found scanner
*/
static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
@ -87,6 +103,7 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
DBG( _DBG_INFO, "usb_initDev(%d,0x%04x,%u)\n",
idx, vendor, dev->initialized );
/* copy the original values... */
memcpy( &dev->usbDev.Caps, Settings[idx].pDevCaps, sizeof(DCapsDef));
memcpy( &dev->usbDev.HwSetting, Settings[idx].pHwDef, sizeof(HWDef));
@ -102,9 +119,17 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
if( dev->adj.skipCalibration > 0 )
dev->usbDev.Caps.workaroundFlag |= _WAF_BYPASS_CALIBRATION;
if( dev->adj.skipFine > 0 )
dev->usbDev.Caps.workaroundFlag |= _WAF_SKIP_FINE;
if( dev->adj.skipFineWhite > 0 )
dev->usbDev.Caps.workaroundFlag |= _WAF_SKIP_WHITEFINE;
if( dev->adj.invertNegatives > 0 )
dev->usbDev.Caps.workaroundFlag |= _WAF_INV_NEGATIVE_MAP;
DBG( _DBG_INFO, "Device WAF: 0x%08lx\n", dev->usbDev.Caps.workaroundFlag );
/*
* adjust data origin
*/
@ -131,15 +156,40 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
/*
* the following you normally get from the registry...
* 30 and 8 are for a UT12
*/
bMaxITA = 0; /* Maximum integration time adjust */
dev->usbDev.dwBufferSize = 8 * 1024 * 1024; /*min val is 4MB!!!*/
bMaxITA = 0; /* Maximum integration time adjust */
dev->usbDev.ModelStr = Settings[idx].pModelString;
dev->fd = handle;
/* check for TPA on EPSON device
*/
if( !dev->initialized && vendor == 0x04B8 ) {
u_char t;
usb_switchLampX ( dev, SANE_FALSE, SANE_TRUE );
usbio_WriteReg ( handle, 0x58, 0x1d );
usbio_WriteReg ( handle, 0x59, 0x49 );
usbio_ReadReg ( handle, 0x02, &t );
usbio_WriteReg ( handle, 0x58, dev->usbDev.HwSetting.bReg_0x58 );
usbio_WriteReg ( handle, 0x59, dev->usbDev.HwSetting.bReg_0x59 );
DBG( _DBG_INFO, "REG[0x02] = 0x%02x\n", t );
if( t & 0x02 ) {
DBG( _DBG_INFO, "TPA detected\n" );
dev->usbDev.Caps.wFlags |= DEVCAPSFLAG_TPA;
} else
DBG( _DBG_INFO, "TPA NOT detected\n" );
if( dev->adj.enableTpa ) {
DBG( _DBG_INFO, "Enabled TPA for EPSON (override)\n" );
dev->usbDev.Caps.wFlags |= DEVCAPSFLAG_TPA;
}
}
/*
* well now we patch the vendor string...
* if not found, the default vendor will be Plustek
@ -153,13 +203,6 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
}
}
if( vendor == 0x04B8 ) {
if( dev->adj.enableTpa ) {
DBG( _DBG_INFO, "Enabled TPA for EPSON\n" );
dev->usbDev.Caps.wFlags |= DEVCAPSFLAG_TPA;
}
}
dev->usbDev.currentLamp = usb_GetLampStatus( dev );
usb_ResetRegisters( dev );
@ -189,7 +232,7 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
dev->initialized = SANE_TRUE;
}
/*.............................................................................
/**
* will be used for retrieving a Plustek device
*/
static int usb_CheckForPlustekDevice( int handle, pPlustek_Device dev )
@ -254,7 +297,7 @@ static int usb_CheckForPlustekDevice( int handle, pPlustek_Device dev )
if( 0 == strcmp( Settings[i].pIDString, tmp )) {
DBG(_DBG_INFO, "Device description for >%s< found.\n", tmp );
usb_initDev( dev, i, handle, 0x07B3 );
usb_initDev( dev, i, handle, dev->usbDev.vendor );
return handle;
}
}
@ -262,7 +305,7 @@ static int usb_CheckForPlustekDevice( int handle, pPlustek_Device dev )
return -1;
}
/*.............................................................................
/**
* will be called upon sane_exit
*/
static void usbDev_shutdown( Plustek_Device *dev )
@ -318,7 +361,57 @@ static SANE_Bool usb_IsDeviceInList( char *usbIdStr )
return SANE_FALSE;
}
/*.............................................................................
/**
*
*/
static SANE_Status usb_attach( SANE_String_Const dev_name )
{
if( USB_devname[0] == '\0' ) {
DBG( _DBG_INFO, "Found device at >%s<\n", dev_name );
strncpy( USB_devname, dev_name, 1023 );
USB_devname[1023] = '\0';
} else {
DBG( _DBG_INFO, "Device >%s< ignoring\n", dev_name );
}
return SANE_STATUS_GOOD;
}
/** here we roam through our list of supported devices and
* cross check with the ones the system reports...
* @param vendor - pointer to receive vendor ID
* @param product - pointer to receive product ID
* @return SANE_TRUE if a matching device has been found or
* SANE_FALSE if nothing supported found...
*/
static SANE_Bool usbDev_autodetect( SANE_Word *vendor, SANE_Word *product )
{
int i;
SANE_Word v, p;
DBG( _DBG_INFO, "Autodetection...\n" );
for( i = 0; NULL != Settings[i].pIDString; i++ ) {
v = strtol( &(Settings[i].pIDString)[0], 0, 0 );
p = strtol( &(Settings[i].pIDString)[7], 0, 0 );
DBG( _DBG_INFO2, "Checking for 0x%04x-0x%04x\n", v, p );
sanei_usb_find_devices( v, p, usb_attach );
if( USB_devname[0] != '\0' ) {
*vendor = v;
*product = p;
return SANE_TRUE;
}
}
return SANE_FALSE;
}
/**
*
*/
static int usbDev_open( const char *dev_name, void *misc )
@ -336,9 +429,44 @@ static int usbDev_open( const char *dev_name, void *misc )
/* preset our internal usb device structure */
memset( &dev->usbDev, 0, sizeof(DeviceDef));
USB_devname[0] = '\0';
if( SANE_STATUS_GOOD != sanei_usb_open( dev_name, &handle )) {
return -1;
if( !strcmp( dev_name, "auto" )) {
if( dev->usbId[0] == '\0' ) {
if( !usbDev_autodetect( &vendor, &product )) {
DBG( _DBG_ERROR, "No supported device found!\n" );
return -1;
}
} else {
vendor = strtol( &dev->usbId[0], 0, 0 );
product = strtol( &dev->usbId[7], 0, 0 );
sanei_usb_find_devices( vendor, product, usb_attach );
if( USB_devname[0] == '\0' ) {
DBG( _DBG_ERROR, "No matching device found!\n" );
return -1;
}
}
if( SANE_STATUS_GOOD != sanei_usb_open( USB_devname, &handle ))
return -1;
/* replace the old devname, so we are able to have multiple
* auto-detected devices
*/
free( dev->name );
dev->name = strdup( USB_devname );
dev->sane.name = dev->name;
} else {
if( SANE_STATUS_GOOD != sanei_usb_open( dev_name, &handle ))
return -1;
}
was_empty = SANE_FALSE;
@ -403,14 +531,10 @@ static int usbDev_open( const char *dev_name, void *misc )
return -1;
}
#if 1
dev->fd = handle;
usbio_ResetLM983x ( dev );
usb_IsScannerReady( dev );
dev->fd = -1;
#else
sanei_lm983x_reset( handle );
#endif
dev->usbDev.vendor = vendor;
dev->usbDev.product = product;
@ -420,7 +544,7 @@ static int usbDev_open( const char *dev_name, void *misc )
* (PCB = printed circuit board), so it's possible to have one
* product ID and up to 7 different devices...
*/
if( 0x07B3 == vendor ) {
if((0x07B3 == vendor) || (0x0458 == vendor)) {
handle = usb_CheckForPlustekDevice( handle, dev );
@ -457,7 +581,7 @@ static int usbDev_open( const char *dev_name, void *misc )
return -1;
}
/*.............................................................................
/**
*
*/
static int usbDev_close( Plustek_Device *dev )
@ -567,7 +691,7 @@ static int usbDev_getCropInfo( Plustek_Device *dev, pCropInfo ci )
return 0;
}
/*.............................................................................
/**
*
*/
static int usbDev_setMap( Plustek_Device *dev, SANE_Word *map,
@ -603,11 +727,13 @@ static int usbDev_setMap( Plustek_Device *dev, SANE_Word *map,
return 0;
}
/*.............................................................................
/**
*
*/
static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
{
pHWDef hw = &dev->usbDev.HwSetting;
DBG( _DBG_INFO, "usbDev_setScanEnv()\n" );
/* clear all the stuff */
@ -621,15 +747,12 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
if( si->ImgDef.wDataType == COLOR_256GRAY ) {
#if 0
if( dev->scanning.fGrayFromColor = Registry.GetGrayFromColor())
si->ImgDef.wDataType = COLOR_TRUE24;
else
#endif
if( !(si->ImgDef.dwFlag & SCANDEF_Adf ) &&
(dev->usbDev.Caps.OpticDpi.x == 1200 && si->ImgDef.xyDpi.x <= 300)) {
dev->scanning.fGrayFromColor = 2;
si->ImgDef.wDataType = COLOR_TRUE24;
DBG( _DBG_INFO, "Gray from color set!\n" );
}
}
@ -669,6 +792,27 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
dev->scanning.dwBytesLine = dev->scanning.sParam.Size.dwBytes;
}
/* on CIS based devices we have to reconfigure the illumination
* settings for the gray modes
*/
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
if((dev->scanning.sParam.bDataType == SCANDATATYPE_Gray) ||
(dev->scanning.sParam.bDataType == SCANDATATYPE_BW)) {
hw->bReg_0x29 = hw->illu_mono.mode;
memcpy( &hw->red_lamp_on,
&hw->illu_mono.red_lamp_on, sizeof(u_short) * 6 );
} else {
hw->bReg_0x29 = hw->illu_color.mode;
memcpy( &hw->red_lamp_on,
&hw->illu_color.red_lamp_on, sizeof(u_short) * 6 );
}
}
if( dev->scanning.dwFlag & SCANFLAG_BottomUp)
dev->scanning.lBufAdjust = -(long)dev->scanning.dwBytesLine;
else
@ -691,26 +835,34 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
if( dev->scanning.sParam.bSource == SOURCE_Reflection ) {
dev->usbDev.pSource = &dev->usbDev.Caps.Normal;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Normal.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Normal.lUp;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x +
(u_long)dev->usbDev.Normal.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y +
(u_long)dev->usbDev.Normal.lUp;
} else if( dev->scanning.sParam.bSource == SOURCE_Transparency ) {
dev->usbDev.pSource = &dev->usbDev.Caps.Positive;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Positive.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Positive.lUp;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x +
(u_long)dev->usbDev.Positive.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y +
(u_long)dev->usbDev.Positive.lUp;
} else if( dev->scanning.sParam.bSource == SOURCE_Negative ) {
dev->usbDev.pSource = &dev->usbDev.Caps.Negative;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Negative.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Negative.lUp;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x +
(u_long)dev->usbDev.Negative.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y +
(u_long)dev->usbDev.Negative.lUp;
} else {
dev->usbDev.pSource = &dev->usbDev.Caps.Adf;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Normal.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Normal.lUp;
dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x +
(u_long)dev->usbDev.Normal.lLeft;
dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y +
(u_long)dev->usbDev.Normal.lUp;
}
if( dev->scanning.sParam.bSource == SOURCE_ADF ) {
@ -724,7 +876,7 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
return 0;
}
/*.............................................................................
/**
*
*/
static int usbDev_stopScan( Plustek_Device *dev, int *mode )
@ -746,7 +898,7 @@ static int usbDev_stopScan( Plustek_Device *dev, int *mode )
return 0;
}
/*.............................................................................
/**
*
*/
static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
@ -756,7 +908,7 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
DBG( _DBG_INFO, "usbDev_startScan()\n" );
/* HEINER: PReview currently not working correctly */
/* HEINER: Preview currently not working correctly */
#if 0
if( scanning->dwFlag & SCANDEF_QualityScan )
a_bRegs[0x0a] = 0;
@ -765,7 +917,6 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
#endif
a_bRegs[0x0a] = 0;
/* Allocate shading buffer */
if((dev->scanning.dwFlag & SCANDEF_Adf) &&
(dev->scanning.dwFlag & SCANDEF_ContinuousScan)) {
@ -778,7 +929,7 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
scanning->sParam.PhyDpi.x = usb_SetAsicDpiX(dev,scanning->sParam.UserDpi.x);
scanning->sParam.PhyDpi.y = usb_SetAsicDpiY(dev,scanning->sParam.UserDpi.y);
scanning->pScanBuffer = (u_char*)malloc( dev->usbDev.dwBufferSize );
scanning->pScanBuffer = (u_char*)malloc( _SCANBUF_SIZE );
if( NULL != scanning->pScanBuffer ) {
@ -795,9 +946,9 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
return _E_ALLOC;
}
/*.............................................................................
/**
* do the reading stuff here...
* first we perform the calibration step, and the we read the image
* first we perform the calibration step, and then we read the image
* line for line
*/
static int usbDev_readImage( struct Plustek_Device *dev,
@ -825,152 +976,153 @@ static int usbDev_readImage( struct Plustek_Device *dev,
DBG( _DBG_INFO, "calibration done.\n" );
scaler = 1;
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
if( pParam->bDataType == SCANDATATYPE_Color ) {
scaler = 3;
}
if((hw->bReg_0x26 & _ONE_CH_COLOR) &&
(scanning->sParam.bDataType == SCANDATATYPE_Color)) {
scaler = 3;
}
if( !( scanning->dwFlag & SCANFLAG_Scanning )) {
usleep( 10 * 1000 );
if( usb_SetScanParameters( dev, &scanning->sParam )) {
/* what if error !!!*/
/*
* if we bypass the calibration step, we wait on lamp warmup here...
*/
if( scaps->workaroundFlag & _WAF_BYPASS_CALIBRATION ) {
if( !usb_Wait4Warmup( dev )) {
DBG( _DBG_INFO, "ReadImage() - Cancel detected...\n" );
return 0;
}
}
scanning->pbScanBufBegin = scanning->pScanBuffer;
if((dev->caps.dwFlag & SFLAG_ADF) && (scaps->OpticDpi.x == 600))
scanning->dwLinesScanBuf = 8;
else
scanning->dwLinesScanBuf = 32;
scanning->dwBytesScanBuf = scanning->dwLinesScanBuf *
scanning->sParam.Size.dwPhyBytes *
scaler;
scanning->dwNumberOfScanBufs = dev->usbDev.dwBufferSize /
scanning->dwBytesScanBuf;
scanning->dwLinesPerScanBufs = scanning->dwNumberOfScanBufs *
scanning->dwLinesScanBuf;
scanning->pbScanBufEnd = scanning->pbScanBufBegin +
scanning->dwLinesPerScanBufs *
scanning->sParam.Size.dwPhyBytes *
scaler;
if( scanning->sParam.bChannels == 3 ) {
scanning->dwLinesDiscard = (u_long)scaps->bSensorDistance *
scanning->sParam.PhyDpi.y / scaps->OpticDpi.y;
switch( scaps->bSensorOrder ) {
case SENSORORDER_rgb:
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_rbg:
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_gbr:
scanning->Green.pb = scanning->pbScanBufBegin;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_grb:
scanning->Green.pb = scanning->pbScanBufBegin;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_brg:
scanning->Blue.pb = scanning->pbScanBufBegin;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_bgr:
scanning->Blue.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
}
/* double it for last channel */
scanning->dwLinesDiscard <<= 1;
scanning->dwGreenShift = (7UL+scanning->sParam.bBitDepth) >> 3;
scanning->Green.pb += scanning->dwGreenShift;
scanning->Blue.pb += (scanning->dwGreenShift * 2);
if( scanning->dwFlag & SCANFLAG_bgr) {
u_char *pb = scanning->Blue.pb;
scanning->Blue.pb = scanning->Red.pb;
scanning->Red.pb = pb;
scanning->dwBlueShift = 0;
scanning->dwRedShift = scanning->dwGreenShift << 1;
} else {
scanning->dwRedShift = 0;
scanning->dwBlueShift = scanning->dwGreenShift << 1;
}
} else {
/* this might be simple gray operation or AFE 1 channel op */
scanning->dwLinesDiscard = 0;
scanning->Green.pb = scanning->pbScanBufBegin;
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes );
scanning->Blue.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes )* 2UL;
}
}
if( !usb_SetScanParameters( dev, &scanning->sParam )) {
DBG( _DBG_ERROR, "Setting Scan Parameters failed!\n" );
return 0;
}
/*
* if we bypass the calibration step, we wait on lamp warmup here...
*/
if( scaps->workaroundFlag & _WAF_BYPASS_CALIBRATION ) {
if( !usb_Wait4Warmup( dev )) {
DBG( _DBG_INFO, "ReadImage() - Cancel detected...\n" );
return 0;
}
}
scanning->pbScanBufBegin = scanning->pScanBuffer;
if((dev->caps.dwFlag & SFLAG_ADF) && (scaps->OpticDpi.x == 600))
scanning->dwLinesScanBuf = 8;
else
scanning->dwLinesScanBuf = 32;
scanning->dwBytesScanBuf = scanning->dwLinesScanBuf *
scanning->sParam.Size.dwPhyBytes *
scaler;
scanning->dwNumberOfScanBufs = _SCANBUF_SIZE /
scanning->dwBytesScanBuf;
scanning->dwLinesPerScanBufs = scanning->dwNumberOfScanBufs *
scanning->dwLinesScanBuf;
scanning->pbScanBufEnd = scanning->pbScanBufBegin +
scanning->dwLinesPerScanBufs *
scanning->sParam.Size.dwPhyBytes *
scaler;
if( scanning->sParam.bChannels == 3 ) {
scanning->dwLinesDiscard = (u_long)scaps->bSensorDistance *
scanning->sParam.PhyDpi.y / scaps->OpticDpi.y;
switch( scaps->bSensorOrder ) {
case SENSORORDER_rgb:
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_rbg:
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_gbr:
scanning->Green.pb = scanning->pbScanBufBegin;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_grb:
scanning->Green.pb = scanning->pbScanBufBegin;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_brg:
scanning->Blue.pb = scanning->pbScanBufBegin;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
break;
case SENSORORDER_bgr:
scanning->Blue.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes;
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwLinesDiscard *
scanning->sParam.Size.dwPhyBytes * 2UL;
}
/* double it for last channel */
scanning->dwLinesDiscard <<= 1;
scanning->dwGreenShift = (7UL+scanning->sParam.bBitDepth) >> 3;
scanning->Green.pb += scanning->dwGreenShift;
scanning->Blue.pb += (scanning->dwGreenShift * 2);
if( scanning->dwFlag & SCANFLAG_bgr) {
u_char *pb = scanning->Blue.pb;
scanning->Blue.pb = scanning->Red.pb;
scanning->Red.pb = pb;
scanning->dwBlueShift = 0;
scanning->dwRedShift = scanning->dwGreenShift << 1;
} else {
scanning->dwRedShift = 0;
scanning->dwBlueShift = scanning->dwGreenShift << 1;
}
} else {
/* this might be simple gray operation or AFE 1 channel op */
scanning->dwLinesDiscard = 0;
scanning->Green.pb = scanning->pbScanBufBegin;
if(( scanning->sParam.bDataType == SCANDATATYPE_Color ) &&
( hw->bReg_0x26 & _ONE_CH_COLOR )) {
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes );
scanning->Blue.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes )* 2UL;
}
}
/* set a funtion to process the RAW data... */
usb_GetImageProc( dev );
@ -1033,6 +1185,7 @@ static int usbDev_readImage( struct Plustek_Device *dev,
DBG(_DBG_INFO,"dwPhyPixels = %lu\n",scanning->sParam.Size.dwPhyPixels);
DBG(_DBG_INFO,"dwTotalBytes = %lu\n",scanning->sParam.Size.dwTotalBytes);
DBG(_DBG_INFO,"dwPixels = %lu\n",scanning->sParam.Size.dwPixels);
DBG(_DBG_INFO,"dwBytes = %lu\n",scanning->sParam.Size.dwBytes);
DBG(_DBG_INFO,"dwValidPixels = %lu\n",scanning->sParam.Size.dwValidPixels);
DBG(_DBG_INFO,"dwBytesScanBuf = %lu\n",scanning->dwBytesScanBuf );
DBG(_DBG_INFO,"dwLinesDiscard = %lu\n",scanning->dwLinesDiscard );
@ -1123,14 +1276,11 @@ static int usbDev_readImage( struct Plustek_Device *dev,
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
if( pParam->bDataType == SCANDATATYPE_Color ) {
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes );
scanning->Blue.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes )* 2UL;
}
scanning->Blue.pb = scanning->pbScanBufBegin +
(scanning->sParam.Size.dwPhyBytes )* 2UL;
}
}

Wyświetl plik

@ -1,50 +1,79 @@
/*.............................................................................
* Project : linux driver for Plustek USB scanners
*.............................................................................
* File: plustek-usb.h
* here are the definitions we need...
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usb.h
* @brief Main defines for the USB devices.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - added workaround flag to struct DevCaps
* 0.42 - added MODEL_NOPLUSTEK
* replaced fLM9831 by chip (valid entries: _LM9831, _LM9832, _LM9833)
* added _WAF_MISC_IO3_LAMP for UMAX 3400
* 0.43 - added _WAF_MISC_IOx_LAMP (x=1,2,4,5)
* added CLKDef
* 0.44 - added vendor and product ID to struct DeviceDef
* added _WAF_BYPASS_CALIBRATION
* added _WAF_INV_NEGATIVE_MAP
* - 0.40 - starting version of the USB support
* - 0.41 - added workaround flag to struct DevCaps
* - 0.42 - added MODEL_NOPLUSTEK
* - replaced fLM9831 by chip (valid entries: _LM9831, _LM9832, _LM9833)
* - added _WAF_MISC_IO3_LAMP for UMAX 3400
* - 0.43 - added _WAF_MISC_IOx_LAMP (x=1,2,4,5)
* - added CLKDef
* - 0.44 - added vendor and product ID to struct DeviceDef
* - added _WAF_BYPASS_CALIBRATION
* - added _WAF_INV_NEGATIVE_MAP
* - 0.45 - added _WAF_SKIP_FINE for skipping fine calibration
* added _WAF_SKIP_WHITEFINE for skipping fine white calibration
* added MCLK setting for 16 bit modes
* .
* <hr>
* 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 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.
* 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., 675 Mass Ave, Cambridge, MA 02139, 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.
*
* 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.
* <hr>
*/
#ifndef __PLUSTEK_USB_H__
#define __PLUSTEK_USB_H__
/* CCD ID (PCB ID): total 3 bits */
/** CCD ID (PCB ID): total 3 bits */
#define kNEC3799 0
#define kSONY518 1
#define kSONY548 2
#define kNEC8861 3
#define kNEC3778 4
#define kNECSLIM 5
/*********************************** plustek_types.h!!! ************************/
@ -123,7 +152,7 @@ typedef union {
#define DRAM_UsedByAsic8BitMode 216 /* in KB */
#define DRAM_UsedByAsic16BitMode 196 /*192*/ /* in KB */
/* Chip-types */
/** Chip-types */
typedef enum _CHIPSET
{
_LM9831,
@ -131,7 +160,7 @@ typedef enum _CHIPSET
_LM9833
} eChipDef;
/* ScanParam.bCalibration */
/** ScanParam.bCalibration */
enum _SHADINGID
{
PARAM_Scan,
@ -141,7 +170,7 @@ enum _SHADINGID
PARAM_Offset
};
/* ScanParam.bDataType */
/** ScanParam.bDataType */
enum _SCANDATATYPE
{
SCANDATATYPE_BW,
@ -149,7 +178,7 @@ enum _SCANDATATYPE
SCANDATATYPE_Color
};
/* DCapsDef.bSensorColor */
/** DCapsDef.bSensorColor */
enum _SENSORCOLOR
{
SENSORORDER_rgb,
@ -160,7 +189,7 @@ enum _SENSORCOLOR
SENSORORDER_bgr
};
/* DCapsDef.wFlags */
/** DCapsDef.wFlags */
enum _DEVCAPSFLAG
{
DEVCAPSFLAG_Normal = 0x0001,
@ -170,6 +199,7 @@ enum _DEVCAPSFLAG
DEVCAPSFLAG_Adf = 0x0008
};
/** to allow some workarounds */
enum _WORKAROUNDS
{
_WAF_NONE = 0x00000000, /* no fix anywhere needed */
@ -177,9 +207,12 @@ enum _WORKAROUNDS
_WAF_MISC_IO_LAMPS = 0x00000002, /* special lamp switching */
_WAF_BLACKFINE = 0x00000004, /* use black calibration strip */
_WAF_BYPASS_CALIBRATION = 0x00000008, /* no calibration,use linear gamma */
_WAF_INV_NEGATIVE_MAP = 0x00000010 /* the backend does the neg. stuff */
_WAF_INV_NEGATIVE_MAP = 0x00000010, /* the backend does the neg. stuff */
_WAF_SKIP_FINE = 0x00000020, /* skip the fine calbration */
_WAF_SKIP_WHITEFINE = 0x00000040 /* skip the fine white calbration */
};
/** for lamps connected to the misc I/O pins*/
enum _LAMPS
{
_NO_MIO = 0,
@ -191,28 +224,39 @@ enum _LAMPS
_MIO6 = 0x0020
};
#define _TPA(flag) ((u_long)(flag << 16))
/** for encoding a misc I/O register as TPA */
#define _TPA(register) ((u_long)(register << 16))
/** Mask to check for available TPA */
#define _HAS_TPA(flag) (flag & 0xFFFF0000)
/** Get the TPA misc I/O register */
#define _GET_TPALAMP(flag) (flag >> 16)
/* motor types */
/** motor types */
typedef enum
{
MODEL_KaoHsiung = 0,
MODEL_HuaLien,
MODEL_Tokyo600,
MODEL_NOPLUSTEK_600, /* for 600 dpi models */
MODEL_NOPLUSTEK_1200, /* for 1200 dpi models */
MODEL_MUSTEK600, /* for BearPaw 1200 */
MODEL_MUSTEK1200, /* for BearPaw 2400 */
MODEL_HP, /* for HP2x00 */
MODEL_CANON1200, /* for Canon N670U/676U */
MODEL_NOPLUSTEK_600, /**< for 600 dpi models */
MODEL_NOPLUSTEK_1200, /**< for 1200 dpi models */
MODEL_EPSON, /**< for EPSON1250/1260 */
MODEL_MUSTEK600, /**< for BearPaw 1200 */
MODEL_MUSTEK1200, /**< for BearPaw 2400 */
MODEL_HP, /**< for HP2x00 */
MODEL_CANON650 , /**< for Canon N650U/656U */
MODEL_CANON1220, /**< for Canon N1220U */
MODEL_CANON670 , /**< for Canon N670U/676U */
MODEL_CANON1240, /**< for Canon N1240U */
MODEL_UMAX, /**< for UMAX 3400/3450 */
MODEL_LAST
} eModelDef;
/** to distinguish between Plustek and other devices */
#define _IS_PLUSTEKMOTOR(x) (x<=MODEL_Tokyo600)
/* Generic usage */
/** Generic usage */
enum _CHANNEL
{
CHANNEL_red,
@ -221,7 +265,7 @@ enum _CHANNEL
CHANNEL_rgb
};
/* motor movement */
/** motor movement */
enum MODULEMOVE
{
MOVE_Forward,
@ -233,7 +277,7 @@ enum MODULEMOVE
MOVE_ToShading
};
/* SCANDEF.dwFlags */
/** SCANDEF.dwFlags */
enum SCANFLAG
{
SCANFLAG_bgr = SCANDEF_ColorBGROrder,
@ -258,39 +302,56 @@ typedef struct Origins
typedef struct SrcAttr
{
XY DataOrigin; /* The origin x is from visible pixel not CCD */
/* pixel 0, in 300 DPI base. */
/* The origin y is from visible top (glass area),*/
/* in 300 DPI */
short ShadingOriginY; /* The origin y is from top of scanner body */
XY Size; /* Scanning width/height, in 300 DPI base. */
XY MinDpi; /* Minimum dpi supported for scanning */
u_char bMinDataType; /* Minimum data type supports */
XY DataOrigin; /**< The origin x is from visible pixel not CCD */
/* pixel 0, in 300 DPI base. */
/* The origin y is from visible top */
/* (glass area), in 300 DPI */
short ShadingOriginY; /**< The origin y is from top of scanner body */
short DarkShadOrgY; /**< if the device has a dark calibration strip */
XY Size; /**< Scanning width/height, in 300 DPI base. */
XY MinDpi; /**< Minimum dpi supported for scanning */
u_char bMinDataType; /**< Minimum data type supports */
} SrcAttrDef, *pSrcAttrDef;
typedef struct DevCaps
{
SrcAttrDef Normal; /* Reflection */
SrcAttrDef Positive; /* Positive film */
SrcAttrDef Negative; /* Negative film */
SrcAttrDef Adf; /* Adf device */
XY OpticDpi; /* Maximum DPI */
u_short wFlags; /* Flag to indicate what kinds of elements */
/* are available */
u_char bSensorOrder; /* CCD color sequences, see _SENSORORDER */
u_char bSensorDistance;/* CCD Color distance */
u_char bButtons; /* Number of buttons */
u_char bCCD; /* CCD ID */
u_char bPCB; /* PCB ID */
u_long workaroundFlag; /* Flag to allow special work arounds, see */
/* _WORKAROUNDS */
u_long lamp; /* for lamp: loword: normal, hiword: tpa */
SrcAttrDef Normal; /**< Reflection */
SrcAttrDef Positive; /**< Positive film */
SrcAttrDef Negative; /**< Negative film */
SrcAttrDef Adf; /**< Adf device */
XY OpticDpi; /**< Maximum DPI */
u_short wFlags; /**< Flag to indicate what kinds of elements */
/* are available */
u_char bSensorOrder; /**< CCD color sequences, see _SENSORORDER */
u_char bSensorDistance;/**< CCD Color distance */
u_char bButtons; /**< Number of buttons */
u_char bCCD; /**< CCD ID */
u_char bPCB; /**< PCB ID */
u_long workaroundFlag; /**< Flag to allow special work arounds, see */
/* _WORKAROUNDS */
u_long lamp; /**< for lamp: loword: normal, hiword: tpa */
} DCapsDef, *pDCapsDef;
/*
* TODO: strip down non-used stuff
/**
* for keeping intial illumination settings
*/
typedef struct
{
u_char mode;
u_short red_lamp_on;
u_short red_lamp_off;
u_short green_lamp_on;
u_short green_lamp_off;
u_short blue_lamp_on;
u_short blue_lamp_off;
} IllumiDef, *pIllumiDef;
/** basic register settings
*/
typedef struct HWDefault
{
@ -319,8 +380,12 @@ typedef struct HWDefault
u_char bReg_0x26;
u_char bReg_0x27;
/* illumination mode reg 0x29 */
/* illumination mode reg 0x29 (runtime) */
u_char bReg_0x29;
/* initial illumination settings */
IllumiDef illu_mono;
IllumiDef illu_color;
/* 0x1a & 0x1b, remember the u_char order is not Intel
* format, you have to pay your attention when you
@ -338,7 +403,7 @@ typedef struct HWDefault
u_short wActivePixelsStart; /* 0x1e & 0x1f */
u_short wLineEnd; /* 0x20 & 0x21 */
/* illumination settings */
/* illumination settings (runtime) */
u_short red_lamp_on; /* 0x2c & 0x2d */
u_short red_lamp_off; /* 0x2e & 0x2f */
u_short green_lamp_on; /* 0x30 & 0x31 */
@ -368,28 +433,26 @@ typedef struct HWDefault
} HWDef, *pHWDef;
/*
*
/** device description during runtime
*/
typedef struct DeviceDef
{
char* ModelStr; /* pointer to our model string */
int vendor; /* vendor ID */
int product; /* product ID */
DCapsDef Caps; /* pointer to the attribute of current dev */
HWDef HwSetting; /* Pointer to the characteristics of device */
pSrcAttrDef pSource; /* Scanning src, it's equal to Caps.Normal */
/* on the source that the user specified. */
OrgDef Normal; /* Reflection - Pix to adjust scanning orgs */
OrgDef Positive; /* Pos film - Pix to adjust scanning orgs */
OrgDef Negative; /* Neg film - Pix to adjust scanning orgs */
OrgDef Adf; /* Adf - Pixels to adjust scanning origins */
u_long dwWarmup; /* Ticks to wait for lamp stable, in ms. */
u_long dwTicksLampOn; /* The ticks when lamp turns on */
u_long dwLampOnPeriod; /* How many seconds to keep lamp on */
SANE_Bool bLampOffOnEnd; /* switch lamp off on end or keep cur. state*/
int currentLamp; /* The lamp ID */
u_long dwBufferSize; /* */
char* ModelStr; /**< pointer to our model string */
int vendor; /**< vendor ID */
int product; /**< product ID */
DCapsDef Caps; /**< pointer to the attribute of current dev */
HWDef HwSetting; /**< Pointer to the characteristics of device */
pSrcAttrDef pSource; /**< Scanning src, it's equal to Caps.Normal */
/**< on the source that the user specified. */
OrgDef Normal; /**< Reflection - Pix to adjust scanning orgs */
OrgDef Positive; /**< Pos film - Pix to adjust scanning orgs */
OrgDef Negative; /**< Neg film - Pix to adjust scanning orgs */
OrgDef Adf; /**< Adf - Pixels to adjust scanning origins */
u_long dwWarmup; /**< Ticks to wait for lamp stable, in ms. */
u_long dwTicksLampOn; /**< The ticks when lamp turns on */
u_long dwLampOnPeriod;/**< How many seconds to keep lamp on */
SANE_Bool bLampOffOnEnd; /**< switch lamp off on end or keep cur. state*/
int currentLamp; /**< The lamp ID of the currently used lamp */
} DeviceDef, *pDeviceDef;
@ -403,24 +466,26 @@ typedef struct Settings
} SetDef, *pSetDef;
/**
*/
typedef struct
{
/* User Information */
u_long dwBytes;
u_long dwPixels;
u_long dwLines;
/** User Information */
u_long dwBytes; /**< bytes per line */
u_long dwPixels; /**< pixels per line */
u_long dwLines; /**< lines */
/** Driver Info */
u_long dwValidPixels; /**< only valid pixels, not incl. pad pix(B/W,Gray)*/
u_long dwPhyPixels; /**< inlcude pad pixels for ASIC (B/W, Gray) */
u_long dwPhyBytes; /**< bytes to read from ASIC */
u_long dwPhyLines; /**< should include the extra lines accord to the */
/* request dpi (CCD lines distance) */
u_long dwTotalBytes; /**< Total bytes per scan */
/* Driver Info */
u_long dwValidPixels; /* only valid pixels, not incl. pad pix (B/W, Gray)*/
u_long dwPhyPixels; /* inlcude pad pixels for ASIC (B/W, Gray) */
u_long dwPhyBytes;
u_long dwPhyLines; /* should include the extra lines accord to the */
/* request dpi (CCD lines distance) */
u_long dwTotalBytes; /* Total bytes per scan */
} WinInfo, *pWinInfo;
/*
*
/**
*/
typedef struct
{
@ -439,17 +504,17 @@ typedef struct
/* INPUT - User info. All sizes and coordinates are specified in the
* unit based on 300 DPI
*/
XY UserDpi; /* User specified DPI */
XY Origin; /* Scanning origin in optic dpi */
double dMCLK; /* for positive & negative & Adf */
XY UserDpi; /**< User specified DPI */
XY Origin; /**> Scanning origin in optic dpi */
double dMCLK; /**< for positive & negative & Adf */
short brightness;
short contrast;
short siThreshold; /* only for B/W output */
u_char bSource; /* Reflection/Positive/Negative/Adf (SOURCE_xxx) */
u_char bDataType; /* Bw, Gray or Color (see _SCANDATATYPE) */
u_char bBitDepth; /* 1/8/14 */
u_char bChannels; /* Color or Gray */
u_char bCalibration; /* 1 or 2: the origin.x is from CCD pixel 0 and the
short siThreshold; /**< only for B/W output */
u_char bSource; /**< Reflection/Positive/Negative/Adf(SOURCE_xxx)*/
u_char bDataType; /**< Bw, Gray or Color (see _SCANDATATYPE) */
u_char bBitDepth; /**< 1/8/14 */
u_char bChannels; /**< Color or Gray */
u_char bCalibration; /**< 1 or 2: the origin.x is from CCD pixel 0 and
* the origin.y is from Top of scanner.
* In this case, the WININFO.dwPhyLines
* will not included the extra lines for
@ -457,39 +522,31 @@ typedef struct
* 0: normal scan, the both directions have to
* add the distance
*/
int swOffset[3];
int swGain[3];
int swOffset[3]; /**< for calibration adjustment */
int swGain[3]; /**< for calibration adjustment */
} ScanParam, *pScanParam;
struct Plustek_Device;
/**
*
/** structure to hold all necessary buffer informations for current scan
*/
typedef struct ScanDef
{
/*
* from calibration...
*/
SANE_Bool fCalibrated;
SANE_Bool fCalibrated; /**< calibrated or not */
u_long dwFlag; /**< scan attributes */
/*
* the other stuff...
*/
u_long dwFlag;
ScanParam sParam; /**< all we need to scan */
ScanParam sParam;
AnyPtr UserBuf; /**< pointer to the user buffer */
u_long dwLinesUser; /**< Number of lines of user buffer */
u_long dwBytesLine; /**< Bytes per line of user buffer. */
/* User buffer */
AnyPtr UserBuf;
u_long dwLinesUser; /* Number of lines of user buffer */
u_long dwBytesLine; /* Bytes per line of user buffer. */
/** Image processing routine according to the scan mode */
void (*pfnProcess)(struct Plustek_Device*);
void (*pfnProcess)(struct Plustek_Device*);/* Image process routine */
u_char* pScanBuffer; /**< our scan buffer */
/* Scan buffer */
u_char* pScanBuffer;
u_long dwTotalBytes; /* Total bytes of image */
u_long dwLinesPerScanBufs;
u_long dwNumberOfScanBufs;
@ -508,22 +565,22 @@ typedef struct ScanDef
AnyPtr Red;
AnyPtr Blue;
long lBufAdjust; /* bytes to adjust buffer pointer */
/* after a image line processed */
u_short wSumY; /* for lines sampling */
long lBufAdjust; /**< bytes to adjust buffer pointer */
/* after a image line processed */
u_short wSumY; /**< for line sampling */
u_char bLineDistance; /* Color offset in specific dpi y */
int fGrayFromColor;
u_char bLineDistance; /**< Color offset in specific dpi y */
int fGrayFromColor; /**< channel to use for gray mode */
u_char bLinesToSkip;
u_char bLinesToSkip; /**< how many lines to skip at start */
} ScanDef, *pScanDef;
/** max number of different colck settings */
#define _MAX_CLK 10
/**
*
/** structure to hold PWN settings
*/
typedef struct
{
@ -532,36 +589,36 @@ typedef struct
} MDef, *pMDef;
/**
* array used to get motor-settings and mclk-settings
/** array used to get motor-settings and mclk-settings
*/
static int dpi_ranges[] = { 75,100,150,200,300,400,600,800,1200,2400 };
/**
*
/** according to the CCD and motor, we provide various settings
*/
typedef struct {
eModelDef motorModel;
eModelDef motorModel; /**< the motor ID */
u_char pwm_fast;
u_char pwm_duty_fast;
u_char mclk_fast;
u_char pwm_fast; /**< PWM during fast movement */
u_char pwm_duty_fast; /**< PWM duty during fast movement */
u_char mclk_fast; /**< MCLK during fast movement */
/*
/**
* here we define some ranges for better supporting
* non-Plustek devices with it's different hardware
* we can set the MCLK and the motor PWM stuff for color
* and gray modes
* and gray modes (8bit and 14/16bit modes)
* 0 1 2 3 4 5 6 7 8 9
* <= 75 <=100 <=150 <=200 <=300 <=400 <=600 <= 800 <=1200 <=2400DPI
*/
MDef motor_sets[_MAX_CLK];
double color_mclk[_MAX_CLK];
double gray_mclk[_MAX_CLK];
MDef motor_sets[_MAX_CLK]; /**< motor PWM settings during scan */
double color_mclk_8[_MAX_CLK]; /**< MCLK settings for color scan */
double color_mclk_16[_MAX_CLK]; /**< MCLK settings for color (16bit) scan*/
double gray_mclk_8[_MAX_CLK]; /**< MCLK settings for gray scan */
double gray_mclk_16[_MAX_CLK]; /**< MCLK settings for gray (16bit) scan */
} ClkMotorDef, *pClkMotorDef;
#endif /* guard __PLUSTEK_USB_H__ */
#endif /* guard __PLUSTEK_USB_H__ */
/* END PLUSTEK-USB.H ........................................................*/

Wyświetl plik

@ -1,30 +1,32 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usbhw.c
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usbhw.c
* @brief Functions to control the scanner hardware.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - added EPSON1250 specific stuff
* - added alternative usb_IsScannerReady function
* 0.42 - added warmup stuff
* added UMAX 3400 stuff
* fixed problem with minimum wait time...
* 0.43 - added usb_switchLamp for non-Plustek devices
* 0.44 - added bStepsToReverse and active Pixelstart values
* to resetRegister function
* modified getLampStatus function for CIS devices
* added usb_Wait4Warmup()
* moved usb_IsEscPressed to this file
* added usb_switchLampX
* do now not reinitialized MISC I/O pins upon reset registers
*
*.............................................................................
*
* - 0.40 - starting version of the USB support
* - 0.41 - added EPSON1250 specific stuff
* - added alternative usb_IsScannerReady function
* - 0.42 - added warmup stuff
* - added UMAX 3400 stuff
* - fixed problem with minimum wait time...
* - 0.43 - added usb_switchLamp for non-Plustek devices
* - 0.44 - added bStepsToReverse and active Pixelstart values
* - to resetRegister function
* - modified getLampStatus function for CIS devices
* - added usb_Wait4Warmup()
* - moved usb_IsEscPressed to this file
* - added usb_switchLampX
* - do now not reinitialized MISC I/O pins upon reset registers
* - 0.45 - added function usb_AdjustLamps() to tweak CIS lamp settings
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -62,7 +64,9 @@
* 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.
* <hr>
*/
#include <sys/time.h>
#define DEV_LampReflection 1
@ -77,7 +81,7 @@ static u_long dwCrystalFrequency = 48000000UL;
static SANE_Bool fModuleFirstHome; /* HEINER: this has to be initialized */
static SANE_Bool fLastScanIsAdf;
static u_char a_bRegs[0x80];
static u_char a_bRegs[0x80]; /**< our global register file */
/** usb_GetMotorSet
@ -162,7 +166,7 @@ static SANE_Bool usb_IsScannerReady( pPlustek_Device dev )
return SANE_FALSE;
}
/*.............................................................................
/**
*
*/
static SANE_Bool usb_SensorAdf( int handle )
@ -174,7 +178,7 @@ static SANE_Bool usb_SensorAdf( int handle )
return (value & 0x20);
}
/*.............................................................................
/**
*
*/
static SANE_Bool usb_SensorPaper( int handle )
@ -186,7 +190,7 @@ static SANE_Bool usb_SensorPaper( int handle )
return (value & 0x02);
}
/*.............................................................................
/**
* Home sensor always on when backward move.
* dwStep is steps to move and based on 300 dpi, but
* if the action is MOVE_Both, it becomes the times
@ -203,11 +207,10 @@ static SANE_Bool usb_ModuleMove( pPlustek_Device dev,
pClkMotorDef clk;
pHWDef hw = &dev->usbDev.HwSetting;
/* Check if LM9831 is ready for setting command */
if( bAction != MOVE_ToPaperSensor &&
bAction != MOVE_EjectAllPapers &&
bAction != MOVE_SkipPaperSensor &&
bAction != MOVE_ToShading && !dwStep) {
bAction != MOVE_ToShading && !dwStep ) {
return SANE_TRUE;
}
@ -257,8 +260,13 @@ static SANE_Bool usb_ModuleMove( pPlustek_Device dev,
if( dToShadingSpeed != 0.0 )
dMaxMoveSpeed = dToShadingSpeed;
else
dMaxMoveSpeed = hw->dMaxMoveSpeed - 0.5;
else {
if( hw->dMaxMoveSpeed > 0.5 )
dMaxMoveSpeed = hw->dMaxMoveSpeed - 0.5;
else
dMaxMoveSpeed = hw->dMaxMoveSpeed;
}
} else {
dMaxMoveSpeed = hw->dMaxMoveSpeed;
@ -497,6 +505,8 @@ static SANE_Bool usb_ModuleToHome( pPlustek_Device dev, SANE_Bool fWait )
a_bRegs[0x45] |= 0x10;
DBG( _DBG_INFO2,"MotorDPI=%u, MaxMotorSpeed=%.3f, FFStepSize=%u\n",
hw->wMotorDpi, hw->dMaxMotorSpeed, wFastFeedStepSize );
DBG( _DBG_INFO, "MOTOR: "
"PWM=0x%02x, PWM_DUTY=0x%02x 0x45=0x%02x "
"0x48=0x%02x, 0x49=0x%02x\n",
@ -591,7 +601,7 @@ static SANE_Bool usb_ModuleToHome( pPlustek_Device dev, SANE_Bool fWait )
return SANE_TRUE;
}
/*.............................................................................
/**
*
*/
static SANE_Bool usb_MotorSelect( pPlustek_Device dev, SANE_Bool fADF )
@ -825,6 +835,32 @@ static void usb_LedOn( pPlustek_Device dev, SANE_Bool fOn )
}
}
/** function to adjust the lamp settings of a device
*
*/
static SANE_Bool usb_AdjustLamps( pPlustek_Device dev )
{
pHWDef hw = &dev->usbDev.HwSetting;
a_bRegs[0x2c] = hw->red_lamp_on / 256;
a_bRegs[0x2d] = hw->red_lamp_on & 0xFF;
a_bRegs[0x2e] = hw->red_lamp_off / 256;
a_bRegs[0x2f] = hw->red_lamp_off & 0xFF;
a_bRegs[0x30] = hw->green_lamp_on / 256;
a_bRegs[0x31] = hw->green_lamp_on & 0xFF;
a_bRegs[0x32] = hw->green_lamp_off / 256;
a_bRegs[0x33] = hw->green_lamp_off & 0xFF;
a_bRegs[0x34] = hw->blue_lamp_on / 256;
a_bRegs[0x35] = hw->blue_lamp_on & 0xFF;
a_bRegs[0x36] = hw->blue_lamp_off / 256;
a_bRegs[0x37] = hw->blue_lamp_off & 0xFF;
return sanei_lm983x_write( dev->fd, 0x2c,
&a_bRegs[0x2c], 0x37-0x2c+1, SANE_TRUE );
}
/** usb_LampOn
*
*/

Wyświetl plik

@ -1,22 +1,24 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usbimg.c - image processing function for copying and
* scaling image lines
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usbimg.c
* @brief Image processing functions for copying and scaling image lines.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - fixed the 14bit problem for LM9831 devices
* 0.42 - no changes
* 0.43 - no changes
* 0.44 - added CIS parts and dumpPic function
*
*.............................................................................
*
* - 0.40 - starting version of the USB support
* - 0.41 - fixed the 14bit problem for LM9831 devices
* - 0.42 - no changes
* - 0.43 - no changes
* - 0.44 - added CIS parts and dumpPic function
* - 0.45 - added gray scaling functions for CIS devices
* - fixed usb_GrayScale16 function
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -54,15 +56,16 @@
* 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.
* <hr>
*/
#define _SCALER 1000
static u_char bShift;
static u_char bShift, Shift;
static u_char *pbSrce, *pbDest;
static int iNext;
static u_long dwPixels, dwBitsPut;
static u_short wSum;
static u_short wSum, Mask;
static u_short *pwDest;
static u_short wR, wG, wB;
static pHiLoDef pwm;
@ -261,7 +264,7 @@ static void usb_AverageColorWord( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_AverageGrayByte( struct Plustek_Device *dev )
@ -308,7 +311,7 @@ static void usb_AverageGrayWord( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
* returns the zoom value, used for our scaling algorithm (DDA algo
* digital differential analyzer).
*/
@ -322,7 +325,7 @@ static int usb_GetScaler( pScanDef scanning )
return (int)(1.0/ratio * _SCALER);
}
/*.............................................................................
/**
*
*/
static void usb_ColorScaleGray( struct Plustek_Device *dev )
@ -400,6 +403,83 @@ static void usb_ColorScaleGray( struct Plustek_Device *dev )
}
}
/**
*
*/
static void usb_ColorScaleGray_2( struct Plustek_Device *dev )
{
int izoom, ddax;
u_long dw;
pScanDef scanning = &dev->scanning;
usb_AverageColorByte( dev );
dw = scanning->sParam.Size.dwPixels;
if( scanning->sParam.bSource == SOURCE_ADF ) {
iNext = -1;
dwPixels = scanning->sParam.Size.dwPixels - 1;
} else {
iNext = 1;
dwPixels = 0;
}
izoom = usb_GetScaler( scanning );
switch( scanning->fGrayFromColor ) {
case 1:
for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) {
ddax -= _SCALER;
while((ddax < 0) && (dw > 0)) {
scanning->UserBuf.pb[dwPixels] =
scanning->Red.pb[dwBitsPut];
dwPixels = dwPixels + iNext;
ddax += izoom;
dw--;
}
}
break;
case 2:
for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) {
ddax -= _SCALER;
while((ddax < 0) && (dw > 0)) {
scanning->UserBuf.pb[dwPixels] =
scanning->Green.pb[dwBitsPut];
dwPixels = dwPixels + iNext;
ddax += izoom;
dw--;
}
}
break;
case 3:
for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) {
ddax -= _SCALER;
while((ddax < 0) && (dw > 0)) {
scanning->UserBuf.pb[dwPixels] = scanning->Blue.pb[dwBitsPut];
dwPixels = dwPixels + iNext;
ddax += izoom;
dw--;
}
}
break;
}
}
/*.............................................................................
* here we copy and scale from scanner world to user world...
*/
@ -517,13 +597,13 @@ static void usb_ColorScale16( struct Plustek_Device *dev )
while((ddax < 0) && (dw > 0)) {
scanning->UserBuf.pw_rgb[dwPixels].Red =
_HILO2WORD(scanning->Red.pcw[dwBitsPut].HiLo[0]) >> 2;
_HILO2WORD(scanning->Red.pcw[dwBitsPut].HiLo[0]) >> Shift;
scanning->UserBuf.pw_rgb[dwPixels].Green =
_HILO2WORD(scanning->Green.pcw[dwBitsPut].HiLo[0]) >>2;
_HILO2WORD(scanning->Green.pcw[dwBitsPut].HiLo[0]) >> Shift;
scanning->UserBuf.pw_rgb[dwPixels].Blue =
_HILO2WORD(scanning->Blue.pcw[dwBitsPut].HiLo[0]) >> 2;
_HILO2WORD(scanning->Blue.pcw[dwBitsPut].HiLo[0]) >> Shift;
dwPixels = dwPixels + iNext;
ddax += izoom;
@ -589,13 +669,13 @@ static void usb_ColorScale16_2( struct Plustek_Device *dev )
while((ddax < 0) && (dw > 0)) {
tmp = *((pHiLoDef)&scanning->Red.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> Shift;
tmp = *((pHiLoDef)&scanning->Green.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> Shift;
tmp = *((pHiLoDef)&scanning->Blue.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> Shift;
dwPixels = dwPixels + iNext;
ddax += izoom;
@ -758,19 +838,26 @@ static void usb_ColorDuplicate16( struct Plustek_Device *dev )
if( scanning->dwFlag & SCANFLAG_RightAlign ) {
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
{
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(scanning->Red.pcw[dw].HiLo[0]) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(scanning->Green.pcw[dw].HiLo[0]) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(scanning->Blue.pcw[dw].HiLo[0]) >> 2;
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++,
dwPixels = dwPixels + iNext) {
scanning->UserBuf.pw_rgb[dwPixels].Red =
_HILO2WORD(scanning->Red.pcw[dw].HiLo[0]) >> Shift;
scanning->UserBuf.pw_rgb[dwPixels].Green =
_HILO2WORD(scanning->Green.pcw[dw].HiLo[0]) >> Shift;
scanning->UserBuf.pw_rgb[dwPixels].Blue =
_HILO2WORD(scanning->Blue.pcw[dw].HiLo[0]) >> Shift;
}
} else {
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
{
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(scanning->Red.pcw[dw].HiLo[0]);
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(scanning->Green.pcw[dw].HiLo[0]);
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(scanning->Blue.pcw[dw].HiLo[0]);
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++,
dwPixels = dwPixels + iNext) {
scanning->UserBuf.pw_rgb[dwPixels].Red =
_HILO2WORD(scanning->Red.pcw[dw].HiLo[0]);
scanning->UserBuf.pw_rgb[dwPixels].Green =
_HILO2WORD(scanning->Green.pcw[dw].HiLo[0]);
scanning->UserBuf.pw_rgb[dwPixels].Blue =
_HILO2WORD(scanning->Blue.pcw[dw].HiLo[0]);
}
}
}
@ -799,13 +886,13 @@ static void usb_ColorDuplicate16_2( struct Plustek_Device *dev )
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
{
tmp = *((pHiLoDef)&scanning->Red.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> Shift;
tmp = *((pHiLoDef)&scanning->Green.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> Shift;
tmp = *((pHiLoDef)&scanning->Blue.pw[dw]);
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> 2;
scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> Shift;
}
} else {
@ -859,7 +946,7 @@ static void usb_ColorDuplicatePseudo16( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_ColorDuplicateGray( struct Plustek_Device *dev )
@ -897,7 +984,45 @@ static void usb_ColorDuplicateGray( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_ColorDuplicateGray_2( struct Plustek_Device *dev )
{
u_long dw;
pScanDef scanning = &dev->scanning;
usb_AverageColorByte( dev );
if (scanning->sParam.bSource == SOURCE_ADF)
{
iNext = -1;
dwPixels = scanning->sParam.Size.dwPixels - 1;
}
else
{
iNext = 1;
dwPixels = 0;
}
switch(scanning->fGrayFromColor)
{
case 1:
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
scanning->UserBuf.pb[dwPixels] = scanning->Red.pb[dw];
break;
case 2:
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
scanning->UserBuf.pb[dwPixels] = scanning->Green.pb[dw];
break;
case 3:
for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext)
scanning->UserBuf.pb[dwPixels] = scanning->Blue.pb[dw];
break;
}
}
/**
*
*/
static void usb_BWScale( struct Plustek_Device *dev )
@ -928,8 +1053,8 @@ static void usb_BWScale( struct Plustek_Device *dev )
memset( pbDest, 0, scanning->dwBytesLine );
ddax = 0;
dw = 0;
for( i = 0; i < scanning->sParam.Size.dwPixels; i++ ) {
for( i = 0; i < scanning->sParam.Size.dwValidPixels; i++ ) {
ddax -= _SCALER;
@ -937,7 +1062,7 @@ static void usb_BWScale( struct Plustek_Device *dev )
tmp = pbSrce[(i>>3)];
if((dw>>3) < scanning->sParam.Size.dwPixels ) {
if((dw>>3) < scanning->sParam.Size.dwValidPixels ) {
if( 0 != (tmp &= (1 << ((~(i & 0x7))&0x7))))
pbDest[dw>>3] |= (1 << ((~(dw & 0x7))&0x7));
@ -948,7 +1073,7 @@ static void usb_BWScale( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_BWDuplicate( struct Plustek_Device *dev )
@ -966,7 +1091,7 @@ static void usb_BWDuplicate( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_GrayScale8( struct Plustek_Device *dev )
@ -1001,7 +1126,7 @@ static void usb_GrayScale8( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_GrayScale16( struct Plustek_Device *dev )
@ -1027,15 +1152,14 @@ static void usb_GrayScale16( struct Plustek_Device *dev )
if( scanning->dwFlag & SCANFLAG_RightAlign ) {
for( dwPixels = scanning->sParam.Size.dwPixels -
scanning->sParam.UserDpi.x; dwPixels; pwm++ ) {
for( dwPixels = scanning->sParam.Size.dwPixels; dwPixels; pwm++ ) {
ddax -= _SCALER;
while((ddax < 0) && (dwPixels > 0)) {
*pwDest = _PHILO2WORD( pwm ) >> 2;
pbDest = pbDest + iNext;
*pwDest = _PHILO2WORD( pwm ) >> Shift;
pwDest = pwDest + iNext;
ddax += izoom;
dwPixels--;
}
@ -1043,15 +1167,14 @@ static void usb_GrayScale16( struct Plustek_Device *dev )
} else {
for( dwPixels = scanning->sParam.Size.dwPixels -
scanning->sParam.UserDpi.x; dwPixels; pwm++ ) {
for( dwPixels = scanning->sParam.Size.dwPixels; dwPixels; pwm++ ) {
ddax -= _SCALER;
while((ddax < 0) && (dwPixels > 0)) {
*pwDest = _PHILO2WORD( pwm );
pbDest = pbDest + iNext;
pwDest = pwDest + iNext;
ddax += izoom;
dwPixels--;
}
@ -1059,7 +1182,7 @@ static void usb_GrayScale16( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_GrayScalePseudo16( struct Plustek_Device *dev )
@ -1098,7 +1221,7 @@ static void usb_GrayScalePseudo16( struct Plustek_Device *dev )
}
}
/*.............................................................................
/**
*
*/
static void usb_GrayDuplicate8( struct Plustek_Device *dev )
@ -1121,7 +1244,7 @@ static void usb_GrayDuplicate8( struct Plustek_Device *dev )
scanning->Green.pb, scanning->sParam.Size.dwBytes );
}
/*.............................................................................
/**
*
*/
static void usb_GrayDuplicate16( struct Plustek_Device *dev )
@ -1143,13 +1266,13 @@ static void usb_GrayDuplicate16( struct Plustek_Device *dev )
pwm = scanning->Green.philo;
if (scanning->dwFlag & SCANFLAG_RightAlign)
for (dwPixels = scanning->sParam.Size.dwPixels; dwPixels--; pwm++, pwDest = pwDest + iNext)
*pwDest = ~(_PHILO2WORD(pwm)) >> 2;
*pwDest = (_PHILO2WORD(pwm)) >> Shift;
else
for (dwPixels = scanning->sParam.Size.dwPixels; dwPixels--; pwm++, pwDest = pwDest + iNext)
*pwDest = ~(_PHILO2WORD(pwm)) & 0xfffc;
*pwDest = (_PHILO2WORD(pwm)) & Mask;
}
/*.............................................................................
/**
*
*/
static void usb_GrayDuplicatePseudo16( struct Plustek_Device *dev )
@ -1210,8 +1333,14 @@ static void usb_GetImageProc( struct Plustek_Device *dev )
DBG( _DBG_INFO, "ImageProc is: ColorScalePseudo16\n" );
} else if (scanning->fGrayFromColor) {
scanning->pfnProcess = usb_ColorScaleGray;
DBG( _DBG_INFO, "ImageProc is: ColorScaleGray\n" );
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
scanning->pfnProcess = usb_ColorScaleGray_2;
DBG( _DBG_INFO, "ImageProc is: ColorScaleGray_2\n" );
} else {
scanning->pfnProcess = usb_ColorScaleGray;
DBG( _DBG_INFO, "ImageProc is: ColorScaleGray\n" );
}
} else {
@ -1265,8 +1394,13 @@ static void usb_GetImageProc( struct Plustek_Device *dev )
scanning->pfnProcess = usb_ColorDuplicatePseudo16;
DBG( _DBG_INFO, "ImageProc is: ColorDuplicatePseudo16\n" );
} else if (scanning->fGrayFromColor) {
scanning->pfnProcess = usb_ColorDuplicateGray;
DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray\n" );
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
scanning->pfnProcess = usb_ColorDuplicateGray_2;
DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray_2\n" );
} else {
scanning->pfnProcess = usb_ColorDuplicateGray;
DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray\n" );
}
} else {
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
scanning->pfnProcess = usb_ColorDuplicate8_2;
@ -1320,9 +1454,17 @@ static void usb_GetImageProc( struct Plustek_Device *dev )
DBG( _DBG_INFO, "bShift adjusted: %u\n", bShift );
}
}
if( _LM9833 == hw->chip ) {
Shift = 0;
Mask = 0xFFFF;
} else {
Shift = 2;
Mask = 0xFFFC;
}
}
/*.............................................................................
/**
* here we read the image data into our intermediate buffer (in the NT version
* the function was implemented as thread)
*/
@ -1332,7 +1474,6 @@ static SANE_Int usb_ReadData( struct Plustek_Device *dev )
pScanDef scanning = &dev->scanning;
pHWDef hw = &dev->usbDev.HwSetting;
DBG( _DBG_READ, "usb_ReadData()\n" );
dwAdjust = 1;
@ -1360,8 +1501,10 @@ static SANE_Int usb_ReadData( struct Plustek_Device *dev )
if(!scanning->sParam.Size.dwTotalBytes && dw < (m_dwPauseLimit * 1024))
{
if(!(a_bRegs[0x4e] = (u_char)ceil(dw / (4 * hw->wDRAMSize))))
if(!(a_bRegs[0x4e] = (u_char)ceil((double)dw /
(4.0 * hw->wDRAMSize)))) {
a_bRegs[0x4e] = 1;
}
a_bRegs[0x4f] = 0;

Wyświetl plik

@ -1,22 +1,25 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usbio.c - some I/O stuff
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usbio.c
* @brief Some I/O stuff.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - moved some functions to a sane library (sanei_lm983x.c)
* 0.42 - no changes
* 0.43 - no changes
* 0.44 - added dump registers and dumpPic functions
* beautyfied output of ASIC detection
*
*.............................................................................
*
* History:
* - 0.40 - starting version of the USB support
* - 0.41 - moved some functions to a sane library (sanei_lm983x.c)
* - 0.42 - no changes
* - 0.43 - no changes
* - 0.44 - added dump registers and dumpPic functions
* - beautyfied output of ASIC detection
* - 0.45 - fixed dumpRegs
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -54,8 +57,9 @@
* 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.
* <hr>
*/
#include "sane/sanei_usb.h"
#include "sane/sanei_lm983x.h"
@ -144,6 +148,8 @@ static void dumpregs( int fd, SANE_Byte *cmp )
if( cmp ) {
buf[0] = '\0';
DBG( _DBG_INFO2, "Internal setting:\n" );
for( i = 0x0; i < 0x80; i++ ) {

Wyświetl plik

@ -1,21 +1,23 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usbmap.c - creating and manipulating lookup tables
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usbmap.c
* @brief Creating and manipulating lookup tables.
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - fixed brightness problem for lineart mode
* 0.42 - removed preset of linear gamma tables
* 0.43 - no changes
* 0.44 - map inversion for negatatives now only upon user request
*
*.............................................................................
*
* - 0.40 - starting version of the USB support
* - 0.41 - fixed brightness problem for lineart mode
* - 0.42 - removed preset of linear gamma tables
* - 0.43 - no changes
* - 0.44 - map inversion for negatatives now only upon user request
* - 0.45 - no changes
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -53,6 +55,7 @@
* 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.
* <hr>
*/
#define _MAP_SIZE 4096U
@ -72,7 +75,7 @@ static void usb_MapAdjust( pPlustek_Device dev )
/*
* adjust brightness (b) and contrast (c) using the function:
*
* s´(x,y) = (s(x,y) + b) * c
* s(x,y) = (s(x,y) + b) * c
* b = [-127, 127]
* c = [0,2]
*/
@ -93,7 +96,7 @@ static void usb_MapAdjust( pPlustek_Device dev )
tmp = ((double)(a_bMap[i] + b)) * c;
if( tmp < 0 ) tmp = 0;
if( tmp > 255 ) tmp = 255;
a_bMap[i] = (u_char)tmp;
a_bMap[i] = (u_char)tmp;
tmp = ((double)(a_bMap[tabLen+i] + b)) * c;
if( tmp < 0 ) tmp = 0;
@ -103,7 +106,7 @@ static void usb_MapAdjust( pPlustek_Device dev )
tmp = ((double)(a_bMap[tabLen*2+i] + b)) * c;
if( tmp < 0 ) tmp = 0;
if( tmp > 255 ) tmp = 255;
a_bMap[tabLen*2+i] = (u_char)tmp;
a_bMap[tabLen*2+i] = (u_char)tmp;
}
}
@ -131,6 +134,10 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
if( !usbio_WriteReg( dev->fd, 7, 0))
return SANE_FALSE;
/* we download all the time all three color maps, as we run
* into trouble elsewhere on CanoScan models using gray mode
*/
#if 0
if( bDataType == SCANDATATYPE_Color ) {
color = 0;
maxColor = 3;
@ -138,6 +145,12 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
color = 1;
maxColor = 2;
}
#else
_VAR_NOT_USED( bDataType );
color = 0;
maxColor = 3;
#endif
for( ; color < maxColor; color++) {

Wyświetl plik

@ -1,22 +1,25 @@
/*.............................................................................
* Project : SANE library for Plustek USB flatbed scanners.
*.............................................................................
* File: plustek-usbscan.c
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
*/
/** @file plustek-usbscan.c
* @brief Scanning...
*
* based on sources acquired from Plustek Inc.
* Based on sources acquired from Plustek Inc.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
*
* History:
* 0.40 - starting version of the USB support
* 0.41 - minor fixes
* 0.42 - added some stuff for CIS devices
* 0.43 - no changes
* 0.44 - added CIS specific settings and calculations
* removed usb_IsEscPressed
*
*.............................................................................
*
* - 0.40 - starting version of the USB support
* - 0.41 - minor fixes
* - 0.42 - added some stuff for CIS devices
* - 0.43 - no changes
* - 0.44 - added CIS specific settings and calculations
* - removed usb_IsEscPressed
* - 0.45 - fixed the special setting stuff for CanoScan
* - fixed pixel calculation for binary modes
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -54,10 +57,9 @@
* 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.
* <hr>
*/
/** @file plustek-usbscan.c
*/
static u_char bMaxITA;
static SANE_Bool m_fAutoPark;
@ -116,6 +118,7 @@ static u_long usb_max( u_long val1, u_long val2 )
*/
static u_short usb_SetAsicDpiX( pPlustek_Device dev, u_short xdpi )
{
u_short res;
pScanDef scanning = &dev->scanning;
pDCapsDef scaps = &dev->usbDev.Caps;
@ -127,7 +130,7 @@ static u_short usb_SetAsicDpiX( pPlustek_Device dev, u_short xdpi )
xdpi < 150 &&
scanning->sParam.bDataType == SCANDATATYPE_BW ) {
xdpi = 150;
DBG( _DBG_INFO, "LIMIT XDPI to %udpi\n", xdpi );
DBG( _DBG_INFO, "* LIMIT XDPI to %udpi\n", xdpi );
}
m_dHDPIDivider = (double)scaps->OpticDpi.x / xdpi;
@ -177,8 +180,12 @@ static u_short usb_SetAsicDpiX( pPlustek_Device dev, u_short xdpi )
if( a_bRegs[0x0a] )
a_bRegs[0x09] -= ((a_bRegs[0x0a] >> 2) + 2);
DBG( _DBG_INFO, "HDPI: %.3f\n", m_dHDPIDivider );
return (u_short)((double)scaps->OpticDpi.x / m_dHDPIDivider);
DBG( _DBG_INFO, "* HDPI: %.3f\n", m_dHDPIDivider );
res = (u_short)((double)scaps->OpticDpi.x / m_dHDPIDivider);
DBG( _DBG_INFO, "* XDPI=%u, HDPI=%.3f\n", res, m_dHDPIDivider );
return res;
}
/**
@ -221,12 +228,11 @@ static u_short usb_SetAsicDpiY( pPlustek_Device dev, u_short ydpi )
}
}
DBG( _DBG_INFO2, "YDPI=%u, MinDPIY=%u\n", wDpi, wMinDpi );
DBG( _DBG_INFO2, "* YDPI=%u, MinDPIY=%u\n", wDpi, wMinDpi );
return wDpi;
}
/**
*
/** set color mode and sensor configuration stuff, according to the data mode
* Affected registers:<br>
* 0x26 - 0x27 - Color Mode settings<br>
* 0x0f - 0x18 - Sensor Configuration - directly from the HwDefs<br>
@ -268,7 +274,7 @@ static void usb_SetColorAndBits( pPlustek_Device dev, pScanParam pParam )
case SCANDATATYPE_BW:
m_bCM = 1;
a_bRegs[0x26] = (hw->bReg_0x26 & 0x18) | 0x04;
memcpy( &a_bRegs [0x0f], hw->bReg_0x0f_Mono, 10 );
memcpy( &a_bRegs[0x0f], hw->bReg_0x0f_Mono, 10 );
break;
}
@ -303,7 +309,8 @@ static void usb_GetScanRect( pPlustek_Device dev, pScanParam pParam )
pHWDef hw = &dev->usbDev.HwSetting;
/* Convert pixels to physical dpi based */
pParam->Size.dwValidPixels = pParam->Size.dwPixels * pParam->PhyDpi.x / pParam->UserDpi.x;
pParam->Size.dwValidPixels = pParam->Size.dwPixels *
pParam->PhyDpi.x / pParam->UserDpi.x;
/* HEINER: check ADF stuff... */
#if 0
@ -336,17 +343,25 @@ static void usb_GetScanRect( pPlustek_Device dev, pScanParam pParam )
/* Compute data start pixel */
wDataPixelStart = (u_short)((u_long) pParam->Origin.x * sCaps->OpticDpi.x / 300UL);
/*
* during the calibration steps, we read the entire CCD data
*/
if (pParam->bCalibration != PARAM_Gain && pParam->bCalibration != PARAM_Offset)
{
/* HEINER: check ADF stuff... */
#if 0
if(ScanInf.m_fADF)
wDataPixelStart = 2550 * sCaps->OpticDpi.x / 300UL - (u_short)(m_dHDPIDivider * pParam->Size.dwValidPixels + 0.5);
wDataPixelStart = 2550 * sCaps->OpticDpi.x / 300UL -
(u_short)(m_dHDPIDivider * pParam->Size.dwValidPixels + 0.5);
#endif
wDataPixelStart += hw->wActivePixelsStart;
}
wLineEnd = wDataPixelStart + (u_short)(m_dHDPIDivider * pParam->Size.dwPhyPixels + 0.5);
DBG( _DBG_INFO, "DataPixelStart=%u, LineEnd=%u\n",
wLineEnd = wDataPixelStart + (u_short)(m_dHDPIDivider *
pParam->Size.dwPhyPixels + 0.5);
DBG( _DBG_INFO, "* DataPixelStart=%u, LineEnd=%u\n",
wDataPixelStart, wLineEnd );
a_bRegs[0x22] = _HIBYTE( wDataPixelStart );
@ -405,16 +420,17 @@ static void usb_GetScanRect( pPlustek_Device dev, pScanParam pParam )
* always be RGB or BGR order).
*/
if (pParam->bDataType != SCANDATATYPE_Color)
pParam->Origin.y += (u_long)(300UL * sCaps->bSensorDistance / sCaps->OpticDpi.y );
pParam->Origin.y += (u_long)(300UL *
sCaps->bSensorDistance / sCaps->OpticDpi.y);
}
pParam->Origin.y = (u_short)((u_long)pParam->Origin.y * hw->wMotorDpi / 300UL);
pParam->Origin.y=(u_short)((u_long)pParam->Origin.y * hw->wMotorDpi/300UL);
/* Something wrong, but I can not find it. */
if( hw->motorModel == MODEL_HuaLien && sCaps->OpticDpi.x == 600)
pParam->Origin.y = pParam->Origin.y * 297 / 298;
DBG( _DBG_INFO, "Full Steps to Skip at Start = 0x%04x\n", pParam->Origin.y );
DBG( _DBG_INFO, "* Full Steps to Skip at Start = 0x%04x\n", pParam->Origin.y );
a_bRegs[0x4a] = _HIBYTE( pParam->Origin.y );
a_bRegs[0x4b] = _LOBYTE( pParam->Origin.y );
@ -455,12 +471,14 @@ static void usb_GetDPD( pPlustek_Device dev )
{
dpd = (((qtcnt * 4) + (hfcnt * 2) + strev) * 4 * st) %
(m_wLineLength * m_bLineRateColor);
DBG( _DBG_INFO2, "* DPD =%u (0x%04x)\n", dpd, dpd );
dpd = m_wLineLength * m_bLineRateColor - dpd;
}
DBG( _DBG_INFO2, "DPD =%u, step size=%u, steps2rev=%u\n", dpd, st, strev );
DBG( _DBG_INFO2, "llen=%u, lineRateColor=%u, qtcnt=%u, hfcnt=%u\n",
m_wLineLength, m_bLineRateColor, qtcnt, hfcnt );
DBG( _DBG_INFO2, "* DPD =%u (0x%04x), step size=%u, steps2rev=%u\n",
dpd, dpd, st, strev);
DBG( _DBG_INFO2, "* llen=%u, lineRateColor=%u, qtcnt=%u, hfcnt=%u\n",
m_wLineLength, m_bLineRateColor, qtcnt, hfcnt );
a_bRegs[0x51] |= (u_char)((dpd >> 16) & 0x03);
a_bRegs[0x52] = (u_char)(dpd >> 8);
@ -469,7 +487,8 @@ static void usb_GetDPD( pPlustek_Device dev )
/**
* Plusteks' poor-man MCLK calculation...
*
* at least we give the master clock divider and adjust the step size
* and integration time (for 14/16 bit modes)
*/
static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam )
{
@ -488,11 +507,8 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam )
else
m_bIntTimeAdjust = ceil( 5.3/*6.0*/ / (m_dHDPIDivider*m_dMCLKDivider));
DBG( _DBG_INFO, "Integration Time Adjust = %u (HDPI=%.3f,MCLKD=%.3f)\n",
m_bIntTimeAdjust, m_dHDPIDivider, m_dMCLKDivider );
if( pParam->bCalibration == PARAM_Scan ) {
/* Compare Integration with USB speed to find the best ITA value */
if( pParam->bBitDepth > 8 ) {
@ -506,8 +522,21 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam )
sCaps->bCCD == kNEC3799 && m_bIntTimeAdjust > bMaxITA) {
m_bIntTimeAdjust = bMaxITA;
}
if((hw->motorModel == MODEL_HP) && (sCaps->bCCD == kNECSLIM)) {
bMaxITA = (u_char)floor((m_dMCLKDivider + 1) / 2.0);
DBG( _DBG_INFO, "* MaxITA (HP) = %u\n", bMaxITA );
if( m_bIntTimeAdjust > bMaxITA ) {
DBG( _DBG_INFO, "* ITA (%u) limited\n", m_bIntTimeAdjust );
m_bIntTimeAdjust = bMaxITA;
}
}
}
}
DBG( _DBG_INFO, "* Integration Time Adjust = %u (HDPI=%.3f,MCLKD=%.3f)\n",
m_bIntTimeAdjust, m_dHDPIDivider, m_dMCLKDivider );
a_bRegs[0x08] = (u_char)((m_dMCLKDivider - 1) * 2);
a_bRegs[0x19] = m_bIntTimeAdjust;
@ -522,7 +551,7 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam )
a_bRegs[0x46] = _HIBYTE(m_wStepSize);
a_bRegs[0x47] = _LOBYTE(m_wStepSize);
DBG( _DBG_INFO2, "Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
DBG( _DBG_INFO2, "* Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
m_wStepSize, a_bRegs[0x46], a_bRegs[0x47] );
usb_GetDPD( dev );
}
@ -534,291 +563,42 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam )
dMaxMCLKDivider = (double)dwCrystalFrequency * dMaxIntegrationTime /
(1000 * 8 * m_bCM * m_wLineLength);
/* Determine PWM setting */
/* Determine lamp PWM setting */
if( m_dMCLKDivider > dMaxMCLKDivider ) {
a_bRegs[0x2A] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
a_bRegs[0x2B] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
DBG( _DBG_INFO2, "* Setting GreenPWMDutyCycleLow\n" );
a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
} else {
a_bRegs[0x2A] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
a_bRegs[0x2B] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
DBG( _DBG_INFO2, "* Setting GreenPWMDutyCycleHigh\n" );
a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
}
DBG( _DBG_INFO, "Current MCLK Divider = %f\n", m_dMCLKDivider );
DBG( _DBG_INFO, "* Current MCLK Divider = %f\n", m_dMCLKDivider );
/* return m_dMCLKDivider; */
/*
* this is the original NS code adapted to the backends' needs
*/
/*-------------------------------------------------------
* FUNCTION : ComputeCalibrationMClk(int *regs)
*
* DESCRIPTION : calculate the mclk for calibration and scanning
*
* if the pctransfer rate has not been computed, compute it
*compute ideal_step_size
*calculate ideal mclk divider from average pc transfer rate
*calculate mclk divider for max integration time
*calculate mclk divider for max motor speed
*check if stepsize must be adjusted because max integration time
*gives too fast motor speed
* else limit mclk divider between max integration time and max motor speed
*
* scaninfo.yres is the vertical res that may be changed
*
* RETURNS : calculated mclk
* registers set: 19
* 46:47 step size
* 4e pause limit
* 52:53 dpd
*/
#if 1
{
/*#define PCTR 2000000*/
#define PCTR 1000000 /* --> typical transfer rate... */
#define MCLKDIV_SCALING 2
int minmclk, maxmclk, mclkdiv, max_mclkdiv, min_mclkdiv;
int stepsize;
int j;
int pixelbits, pixelsperline;
unsigned long PCTransferRate = PCTR;
double dpi;
double min_integration_time;
/* Hardware.merlininfo.timeadj = regs[0x19] = 0; already set !*/
/* the first calibration needs to have the pc transfer rate
* 0. if the pctransfer rate has not been computed
* 1. compute ideal_step_size
* step size = tr*vres/(4*motor steps/in)
* tr is from the dpd calculation but does include the cm component
* vres is the vertical resolution and is stored in scaninfo.yres
* motor steps/in is from ini file
*/
stepsize = 256 * a_bRegs[0x46] + a_bRegs[0x47];
/* 1.5, calculate the min mclk divider based on min integration time
* save mclk divider as int*2 value
* calculate the max mclk divider and save as *2
* r=24 for pixel rate, 8 for line rate
*/
/* use high or low res min integration time */
min_integration_time = ((a_bRegs[0x9]&7) > 2 ?
hw->dMinIntegrationTimeLowres:
hw->dMinIntegrationTimeHighres);
minmclk = (int) ceil((double)MCLKDIV_SCALING *
dwCrystalFrequency *
min_integration_time
/((double) 1000. * 8 * m_bCM * m_wLineLength));
minmclk = usb_max(minmclk, MCLKDIV_SCALING);
maxmclk = (int) (32.5*MCLKDIV_SCALING + .5); /*round to be sure proper int*/
DBG( _DBG_INFO2, "lower mclkdiv limit=%f\n",(double)minmclk/MCLKDIV_SCALING );
DBG( _DBG_INFO2, "upper mclkdiv limit=%f\n",(double)maxmclk/MCLKDIV_SCALING );
/*
* 2. calculate ideal mclk divider from average pc transfer rate
* ideal mclkdiv = pixelsinline*clock in/(8*line width*data rate)
* *2 and round up
* byte in line from calculation
* line width = tr from dpd calculation
*/
/* get the bits per pixel */
switch( a_bRegs[0x9] & 0x38 ) {
case 0: pixelbits=1; break;
case 0x8: pixelbits=2; break;
case 0x10: pixelbits=4; break;
case 0x18: pixelbits=8; break;
default: pixelbits=16;break;
}
/* compute the horizontal dpi (pixels per inch) */
j = a_bRegs[0x9] & 0x7;
dpi = ((j&1)*.5+1)*(j&2?2:1)*(j&4?4:1);
pixelsperline = (int)((256 * a_bRegs[0x24] + a_bRegs[0x25] -
256 * a_bRegs[0x22] - a_bRegs[0x23])
*pixelbits/(dpi * 8));
mclkdiv = (int) ceil ((double) MCLKDIV_SCALING * pixelsperline *
dwCrystalFrequency
/((double) 8. * m_wLineLength * PCTransferRate));
DBG( _DBG_INFO2, "mclkdiv before limit=%f\n", (double)mclkdiv/MCLKDIV_SCALING);
mclkdiv = usb_max( mclkdiv,minmclk );
mclkdiv = usb_min( mclkdiv,maxmclk );
DBG( _DBG_INFO2, "mclkdiv after limit=%f\n", (double)mclkdiv/MCLKDIV_SCALING);
#if 1
/* limited by the transfer speed... */
if (PCTransferRate == PCTR)
{
{
int mult,timeadj;
mult = timeadj = m_bIntTimeAdjust;
if (!mult) mult++;
while (mclkdiv*dpi*mult < 6.*MCLKDIV_SCALING)
{
mclkdiv++; /* for now */
}
/* Hardware.merlininfo.timeadj = regs[0x19] = timeadj; */
}
DBG( _DBG_INFO, "PC-Rate mclkdiv=%f\n", (double)mclkdiv/MCLKDIV_SCALING );
/* return mclkdiv; */
return m_dMCLKDivider; /* = ((double)mclkdiv/MCLKDIV_SCALING); */
}
#endif
DBG( _DBG_INFO2, "mclkdiv=%f\n",(double)mclkdiv/MCLKDIV_SCALING );
DBG( _DBG_INFO2, "pixel bytes per line=%d\n",pixelsperline*m_bCM);
DBG( _DBG_INFO2, "linewidth=%d\n", m_wLineLength);
/*
* 3. calculate max mclk divider based on max integration time
* max mclkdiv = (clock in * max integration time)/(r * line width)
* *2 and round down
* limit to min,max
*/
max_mclkdiv = (int) floor((double) MCLKDIV_SCALING *
dwCrystalFrequency * hw->dIntegrationTimeLowLamp
/((double) 1000. * 8 * m_bCM * m_wLineLength));
DBG( _DBG_INFO2, "max mclkdiv before limit=%f\n", (double)max_mclkdiv/MCLKDIV_SCALING);
max_mclkdiv = usb_max( max_mclkdiv,minmclk );
max_mclkdiv = usb_min( max_mclkdiv,maxmclk );
DBG( _DBG_INFO2, "max mclkdiv after limit=%f\n", (double)max_mclkdiv/MCLKDIV_SCALING);
/*
* 4. calculate min mclk divider based on max motor speed
* min mclkdiv = clock in/(stepsize*max motor speed*r*step_per_inch*4)
* *2 and round up
* limit to min,max
*/
min_mclkdiv = (int) ceil((double) MCLKDIV_SCALING * dwCrystalFrequency /
((double) stepsize * hw->dMaxMotorSpeed *8 * m_bCM *
hw->wMotorDpi * 4.));
DBG( _DBG_INFO2, "min mclkdiv before limit=%f\n", (double)min_mclkdiv/MCLKDIV_SCALING);
min_mclkdiv = usb_max( min_mclkdiv,minmclk );
min_mclkdiv = usb_min( min_mclkdiv,maxmclk );
DBG( _DBG_INFO2, "min mclkdiv after limit=%f\n", (double)min_mclkdiv/MCLKDIV_SCALING);
/* 5.Check if stepsize must be adjusted because max integration
* time gives too fast motor speed
*/
if( min_mclkdiv > max_mclkdiv ) {
double x;
mclkdiv = max_mclkdiv;
min_mclkdiv = mclkdiv;
x = ((double)dwCrystalFrequency /
((double)hw->wMotorDpi * 4. * hw->dMaxMotorSpeed *
8 * m_bCM * mclkdiv/MCLKDIV_SCALING));
stepsize = (int)ceil(x);
DBG( _DBG_INFO2, "step size for mclk calc=%d\n", stepsize );
#if 0
Hardware.LimitStepSize(stepsize,regs);
Hardware.NSCStatusOut("5. step size for mclk calc=%d\n",stepsize);
int tr = Hardware.ComputeTR(regs); // recompute for this step size
pParam->PhyDpi.y = stepsize * 4 * Hardware.merlininfo.Motor_Steps_Per_Inch/tr;
ScanParms.yres = pParam->PhyDpi.y;
Hardware.NSCStatusOut("5. vres=%d\n",pParam->PhyDpi.y);
#endif
}
/* else limited by motor speed and integration time */
{
int org_mclkdiv = mclkdiv;
int timeadj = 0;
int org_timeadj = timeadj;
int mult = timeadj;
double x;
if( !mult )
mult++;
while ((mclkdiv*dpi*mult < 6.*MCLKDIV_SCALING) ||
(mclkdiv > max_mclkdiv) ||
(mclkdiv*(timeadj+1) < org_mclkdiv*(org_timeadj+1)))
{
if (!timeadj && (mclkdiv < max_mclkdiv))
mclkdiv++;
else
{
mclkdiv = min_mclkdiv;
timeadj = ++mult;
}
}
/*Hardware.merlininfo.timeadj = a_bRegs[0x19] = timeadj; */
DBG( _DBG_INFO2, "time adj=%d\n", timeadj);
x = stepsize;
if( timeadj )
x = x * (timeadj+1)/(double)timeadj;
stepsize = (int) ceil(x);
}
mclkdiv = usb_max( mclkdiv,min_mclkdiv );
DBG( _DBG_INFO, "final mclkdiv=%f\n", (double)mclkdiv/MCLKDIV_SCALING);
#if 0
Hardware.LimitStepSize(stepsize,regs);
Hardware.NSCStatusOut("5. step size for mclk calc=%d",stepsize);
if( Hardware.merlininfo.timeadj > bMaxITA ) {
if (Hardware.merlininfo.Color_Mode == 0) {
Hardware.merlininfo.Color_Mode = 1;
ScanParms.linerate = 1;
regs[0x26] |= 1;
Hardware.merlininfo.timeadj = regs[0x19] = 0;
return -1; //force calculation
}
}
m_dMCLKDivider = mclkdiv/MCLKDIV_SCALING;
/* set the registers !!!! */
#endif
}
#endif
return m_dMCLKDivider;
}
/*.............................................................................
*
/**
* calculate the step size of each scan step
*/
static void usb_GetStepSize( pPlustek_Device dev, pScanParam pParam )
{
pHWDef hw = &dev->usbDev.HwSetting;
/* Compute step size using equation 1 */
if (m_bIntTimeAdjust != 0)
m_wStepSize = (u_short)(((u_long) pParam->PhyDpi.y * m_wLineLength * m_bLineRateColor *
(m_bIntTimeAdjust + 1)) /
if (m_bIntTimeAdjust != 0) {
m_wStepSize = (u_short)(((u_long) pParam->PhyDpi.y * m_wLineLength *
m_bLineRateColor * (m_bIntTimeAdjust + 1)) /
(4 * hw->wMotorDpi * m_bIntTimeAdjust));
else
m_wStepSize = (u_short)(((u_long) pParam->PhyDpi.y * m_wLineLength * m_bLineRateColor) /
(4 * hw->wMotorDpi));
} else {
m_wStepSize = (u_short)(((u_long) pParam->PhyDpi.y * m_wLineLength *
m_bLineRateColor) / (4 * hw->wMotorDpi));
}
if (m_wStepSize < 2)
m_wStepSize = 2;
@ -827,11 +607,11 @@ static void usb_GetStepSize( pPlustek_Device dev, pScanParam pParam )
a_bRegs[0x46] = _HIBYTE( m_wStepSize );
a_bRegs[0x47] = _LOBYTE( m_wStepSize );
DBG( _DBG_INFO2, "Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
m_wStepSize, a_bRegs[0x46], a_bRegs[0x47] );
DBG( _DBG_INFO2, "* Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
m_wStepSize, a_bRegs[0x46], a_bRegs[0x47] );
}
/*.............................................................................
/**
*
*/
static void usb_GetLineLength( pPlustek_Device dev )
@ -931,8 +711,8 @@ static void usb_GetLineLength( pPlustek_Device dev )
}
m_wLineLength = tr / m_bLineRateColor;
DBG( _DBG_INFO2, "LineLength=%d, LineRateColor=%u\n",
m_wLineLength, m_bLineRateColor );
DBG( _DBG_INFO2, "* LineLength=%d, LineRateColor=%u\n",
m_wLineLength, m_bLineRateColor );
}
/** usb_GetMotorParam
@ -1066,11 +846,11 @@ static void usb_GetMotorParam( pPlustek_Device dev, pScanParam pParam )
}
}
DBG( _DBG_INFO, "MOTOR-Settings: PWM=0x%02x, PWM_DUTY=0x%02x\n",
DBG( _DBG_INFO, "* MOTOR-Settings: PWM=0x%02x, PWM_DUTY=0x%02x\n",
a_bRegs[0x56], a_bRegs[0x57] );
}
/*.............................................................................
/**
*
*/
static void usb_GetPauseLimit( pPlustek_Device dev, pScanParam pParam )
@ -1107,13 +887,13 @@ static void usb_GetPauseLimit( pPlustek_Device dev, pScanParam pParam )
m_dwPauseLimit -= ((a_bRegs[0x54] & 7) *
(pParam->Size.dwPhyBytes * scaler) + 1023) / 1024;
DBG( _DBG_INFO, "PL=%lu, coeffsize=%u, scaler=%u\n",
DBG( _DBG_INFO, "* PL=%lu, coeffsize=%u, scaler=%u\n",
m_dwPauseLimit, coeffsize, scaler );
m_dwPauseLimit = usb_max( usb_min(m_dwPauseLimit,
(u_long)ceil(pParam->Size.dwTotalBytes / 1024.0)), 2);
a_bRegs[0x4e] = (u_char)floor((m_dwPauseLimit*512.0) / (2*hw->wDRAMSize));
a_bRegs[0x4e] = (u_char)floor((m_dwPauseLimit*512.0)/(2.0*hw->wDRAMSize));
if( a_bRegs[0x4e] > 1 ) {
a_bRegs[0x4e]--;
@ -1127,7 +907,7 @@ static void usb_GetPauseLimit( pPlustek_Device dev, pScanParam pParam )
*/
a_bRegs[0x4f] = 1;
DBG( _DBG_INFO, "PauseLimit = %lu, [0x4e] = 0x%02x, [0x4f] = 0x%02x\n",
DBG( _DBG_INFO, "* PauseLimit = %lu, [0x4e] = 0x%02x, [0x4f] = 0x%02x\n",
m_dwPauseLimit, a_bRegs[0x4e], a_bRegs[0x4f] );
}
@ -1157,10 +937,13 @@ static void usb_GetScanLinesAndSize( pPlustek_Device dev, pScanParam pParam )
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
if( pParam->bDataType == SCANDATATYPE_Color ) {
pParam->Size.dwTotalBytes *= 3;
}
}
DBG( _DBG_INFO, "* PhyBytes = %lu\n", pParam->Size.dwPhyBytes );
DBG( _DBG_INFO, "* PhyLines = %lu\n", pParam->Size.dwPhyLines );
DBG( _DBG_INFO, "* TotalBytes = %lu\n", pParam->Size.dwTotalBytes );
}
/** function to preset/reset the merlin registers
@ -1231,7 +1014,7 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam )
if(!(pParam->bCalibration == PARAM_Scan &&
pParam->bSource == SOURCE_ADF && fLastScanIsAdf )) {
DBG( _DBG_INFO2, "Scan calculations...\n" );
DBG( _DBG_INFO2, "* Scan calculations...\n" );
usb_GetLineLength ( dev );
usb_GetStepSize ( dev, pParam );
usb_GetDPD ( dev );
@ -1254,6 +1037,9 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam )
a_bRegs[0x48] = _HIBYTE( m_wFastFeedStepSize );
a_bRegs[0x49] = _LOBYTE( m_wFastFeedStepSize );
DBG( _DBG_INFO2, "* FFStepSize = %u, [0x48] = 0x%02x, [0x49] = 0x%02x\n",
m_wFastFeedStepSize, a_bRegs[0x48], a_bRegs[0x49] );
/* Compute the number of lines to scan using actual Y resolution */
usb_GetScanLinesAndSize( dev, pParam );
@ -1298,15 +1084,21 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam )
memset( &a_bRegs[0x03], 0, 3 );
memset( &a_bRegs[0x5C], 0, 0x7F-0x5C+1 );
/* 0x08 - 0x5a */
_UIO(sanei_lm983x_write( dev->fd, 0x08, &a_bRegs[0x08], 0x5a - 0x08+1, SANE_TRUE));
usbio_ReadReg( dev->fd, 0x69, &a_bRegs[0x69] );
/* 0x08 - 0x5a (not 0x28) */
_UIO(sanei_lm983x_write( dev->fd, 0x08, &a_bRegs[0x08], 0x27 - 0x08+1, SANE_TRUE));
_UIO(sanei_lm983x_write( dev->fd, 0x29, &a_bRegs[0x29], 0x5a - 0x29+1, SANE_TRUE));
/* 0x03 - 0x05 */
_UIO(sanei_lm983x_write( dev->fd, 0x03, &a_bRegs[0x03], 3, SANE_TRUE));
/* special setting for CANON... */
if( dev->usbDev.vendor == 0x4a9 )
/* special settings for CANON... */
if( dev->usbDev.vendor == 0x4a9 ) {
a_bRegs[0x5c] = 0x01;
a_bRegs[0x70] = 0x73;
}
/* 0x5C - 0x7F */
_UIO(sanei_lm983x_write( dev->fd, 0x5c, &a_bRegs[0x5c], 0x7f - 0x5c +1, SANE_TRUE));
@ -1314,7 +1106,7 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam )
usbio_WriteReg( dev->fd, 0x5a, a_bRegs[0x5a] );
usbio_WriteReg( dev->fd, 0x5b, a_bRegs[0x5b] );
if( !usbio_WriteReg( dev->fd, 0x07, 0 ))
if( !usbio_WriteReg( dev->fd, 0x07, 0 ))
return SANE_FALSE;
/* special procedure for CANON... */
@ -1322,13 +1114,32 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam )
SANE_Byte tmp;
usbio_WriteReg( dev->fd, 0x5b, 0x11 );
usbio_WriteReg( dev->fd, 0x5b, 0x91 );
usbio_ReadReg ( dev->fd, 0x5a, &tmp );
usbio_WriteReg( dev->fd, 0x5a, 0x14 );
if( dev->usbDev.product == 0x2206 ||
dev->usbDev.product == 0x2207) {
usbio_WriteReg( dev->fd, 0x59, a_bRegs[0x59] );
usbio_WriteReg( dev->fd, 0x5a, a_bRegs[0x5a] );
usbio_WriteReg( dev->fd, 0x5a, 0x92 );
usbio_WriteReg( dev->fd, 0x5b, 0x19 );
usbio_ReadReg ( dev->fd, 0x09, &tmp );
usbio_WriteReg( dev->fd, 0x09, tmp );
usbio_WriteReg( dev->fd, 0x5a, 0x12 );
usbio_WriteReg( dev->fd, 0x5b, 0x11 );
usbio_WriteReg( dev->fd, 0x59, 0x24 );
} else {
usbio_WriteReg( dev->fd, 0x5b, 0x11 );
usbio_WriteReg( dev->fd, 0x5b, 0x91 );
usbio_ReadReg ( dev->fd, 0x5a, &tmp );
usbio_WriteReg( dev->fd, 0x5a, 0x14 );
usbio_ReadReg ( dev->fd, 0x09, &tmp );
usbio_WriteReg( dev->fd, 0x09, tmp );
usbio_WriteReg( dev->fd, 0x5a, 0x16 );
usbio_WriteReg( dev->fd, 0x59, 0x66 );
}
}
DBG( _DBG_INFO, "usb_SetScanParameters() done.\n" );
@ -1441,7 +1252,7 @@ static SANE_Bool usb_ScanEnd( pPlustek_Device dev )
return SANE_TRUE;
}
/*.............................................................................
/**
*
*/
static SANE_Bool usb_IsDataAvailableInDRAM( pPlustek_Device dev )
@ -1576,7 +1387,7 @@ static SANE_Bool usb_ScanReadImage( pPlustek_Device dev,
return SANE_FALSE;
}
/*.............................................................................
/**
*
*/
static void usb_GetImageInfo( pImgDef pInfo, pWinInfo pSize )
@ -1605,12 +1416,13 @@ static void usb_GetImageInfo( pImgDef pInfo, pWinInfo pSize )
break;
default:
pSize->dwBytes = (pSize->dwPixels + 7UL) >> 3;
pSize->dwBytes = (pSize->dwPixels + 7UL) >> 3;
pSize->dwPixels = pSize->dwBytes * 8;
break;
}
}
/*.............................................................................
/**
*
*/
static void usb_SaveImageInfo( pPlustek_Device dev, pImgDef pInfo )

Wyświetl plik

@ -1,60 +1,63 @@
/*.............................................................................
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
* File: plustek.c - the SANE backend for the plustek driver
*.............................................................................
*/
/** @file plustek.c
* @brief SANE backend for Plustek scanner
*
* Based on Kazuhiro Sasayama previous work on
* plustek.[ch] file from the SANE package.<br>
* Original code taken from sane-0.71<br>
* Copyright (C) 1997 Hypercore Software Design, Ltd.<br>
* Also based on the work done by Rick Bronson<br>
* Copyright (C) 2000-2002 Gerhard Jaeger <gerhard@gjaeger.de><br>
*
* based on Kazuhiro Sasayama previous work on
* plustek.[ch] file from the SANE package.
* original code taken from sane-0.71
* Copyright (C) 1997 Hypercore Software Design, Ltd.
* also based on the work done by Rick Bronson
* Copyright (C) 2000-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
* History:
* 0.30 - initial version
* 0.31 - no changes
* 0.32 - no changes
* 0.33 - no changes
* 0.34 - moved some definitions and typedefs to plustek.h
* 0.35 - removed Y-correction for 12000P model
* getting Y-size of scan area from driver
* 0.36 - disabled Dropout, as this does currently not work
* enabled Halftone selection only for Halftone-mode
* made the cancel button work by using a child process during read
* added version code to driver interface
* cleaned up the code
* fixed sane compatibility problems
* added multiple device support
* 12bit color-depth are now available for scanimage
* 0.37 - removed X/Y autocorrection, now correcting the stuff
* before scanning
* applied Michaels' patch to solve the sane_get_parameter problem
* getting X-size of scan area from driver
* applied Michaels´ patch for OPT_RESOLUTION (SANE_INFO_INEXACT stuff)
* 0.38 - now using the information from the driver
* some minor fixes
* removed dropout stuff
* removed some warning conditions
* 0.39 - added stuff to use the backend completely in user mode
* fixed a potential buffer problem
* removed function attach_one()
* added USB interface stuff
* 0.40 - USB scanning works now
* 0.41 - added some configuration stuff and also changed .conf file
* added call to sanei_usb_init() and sanei_lm983x_init()
* 0.42 - added adjustment stuff
* added custom gamma tables
* fixed a problem with the "size-sliders"
* fixed a bug that causes segfault when using the autodetection for USB
* devices
* added OS/2 switch to disable the USB stuff for OS/2
* 0.43 - added support for PREVIEW flag
* 0.44 - added _DBG_DUMP debug level
* fixed a bug, that stops our lamp timer
*
*.............................................................................
*
* - 0.30 - initial version
* - 0.31 - no changes
* - 0.32 - no changes
* - 0.33 - no changes
* - 0.34 - moved some definitions and typedefs to plustek.h
* - 0.35 - removed Y-correction for 12000P model<br>
* - getting Y-size of scan area from driver
* - 0.36 - disabled Dropout, as this does currently not work<br>
* - enabled Halftone selection only for Halftone-mode<br>
* - made the cancel button work by using a child process during read<br>
* - added version code to driver interface<br>
* - cleaned up the code<br>
* - fixed sane compatibility problems<br>
* - added multiple device support<br>
* - 12bit color-depth are now available for scanimage
* - 0.37 - removed X/Y autocorrection, now correcting the stuff
* before scanning
* - applied Michaels' patch to solve the sane_get_parameter problem<br>
* - getting X-size of scan area from driver<br>
* - applied Michaels patch for OPT_RESOLUTION (SANE_INFO_INEXACT stuff)
* - 0.38 - now using the information from the driver
* - some minor fixes<br>
* - removed dropout stuff<br>
* - removed some warning conditions
* - 0.39 - added stuff to use the backend completely in user mode<br>
* - fixed a potential buffer problem<br>
* - removed function attach_one()<br>
* - added USB interface stuff
* - 0.40 - USB scanning works now
* - 0.41 - added some configuration stuff and also changed .conf file<br>
* - added call to sanei_usb_init() and sanei_lm983x_init()
* - 0.42 - added adjustment stuff<br>
* - added custom gamma tables<br>
* - fixed a problem with the "size-sliders"<br>
* - fixed a bug that causes segfault when using the autodetection for
* USB devices<br>
* - added OS/2 switch to disable the USB stuff for OS/2
* - 0.43 - added support for PREVIEW flag
* - 0.44 - added _DBG_DUMP debug level<br>
* - fixed a bug, that stops our lamp timer
* - 0.45 - added additional flags
* - added WIFSIGNALED to check result of child termination
*.
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -92,7 +95,13 @@
* 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.
* <hr>
*/
/** @mainpage
* @verbinclude Plustek-USB.txt
*/
#ifdef _AIX
# include <lalloca.h> /* MUST come first for AIX! */
#endif
@ -120,12 +129,12 @@
#include "sane/sanei.h"
#include "sane/saneopts.h"
#define BACKEND_VERSION "0.44-10"
#define BACKEND_VERSION "0.45-1"
#define BACKEND_NAME plustek
#include "sane/sanei_backend.h"
#include "sane/sanei_config.h"
/* might be used to disable all USB stuff - esp. for OS/2 */
/** might be used to disable all USB stuff - esp. for OS/2 */
#ifndef HAVE_OS2_H
# define _PLUSTEK_USB
#endif
@ -199,9 +208,10 @@ static ModeParam mode_9800x_params[] =
static ModeParam mode_usb_params[] =
{
{0, 1, COLOR_BW},
{0, 8, COLOR_256GRAY},
{1, 8, COLOR_TRUE24},
{0, 1, COLOR_BW},
{0, 8, COLOR_256GRAY},
{0, 16, COLOR_GRAY16},
{1, 8, COLOR_TRUE24},
{1, 16, COLOR_TRUE48}
};
@ -229,8 +239,9 @@ static const SANE_String_Const mode_usb_list[] =
{
SANE_I18N("Binary"),
SANE_I18N("Gray"),
SANE_I18N("Gray 14/16"),
SANE_I18N("Color"),
SANE_I18N("Color42"),
SANE_I18N("Color 42/48"),
NULL
};
@ -238,8 +249,7 @@ static const SANE_String_Const ext_mode_list[] =
{
SANE_I18N("Normal"),
SANE_I18N("Transparency"),
/* SANE_I18N("Negative"),TEMP. DISABLED ! */
"Negative",
SANE_I18N("Negative"),
NULL
};
@ -288,6 +298,8 @@ static void show_cnf( pCnfDef cnf )
DBG( _DBG_SANE_INIT, "lampOff : %d\n", cnf->adj.lampOff );
DBG( _DBG_SANE_INIT, "lampOffOnEnd : %d\n", cnf->adj.lampOffOnEnd );
DBG( _DBG_SANE_INIT, "skipCalibr. : %d\n", cnf->adj.skipCalibration );
DBG( _DBG_SANE_INIT, "skipFine : %d\n", cnf->adj.skipFine );
DBG( _DBG_SANE_INIT, "skipFineWhite: %d\n", cnf->adj.skipFineWhite );
DBG( _DBG_SANE_INIT, "invertNegs. : %d\n", cnf->adj.invertNegatives );
DBG( _DBG_SANE_INIT, "pos_x : %d\n", cnf->adj.pos.x );
DBG( _DBG_SANE_INIT, "pos_y : %d\n", cnf->adj.pos.y );
@ -308,8 +320,7 @@ static void show_cnf( pCnfDef cnf )
DBG( _DBG_SANE_INIT, "---------------------\n" );
}
/**
* open the device specific driver and reset the internal timing stuff
/** open the device specific driver and reset the internal timing stuff
* @param dev - pointer to the device specific structure
* @return the function returns the result of the open call, on success
* of course the handle
@ -327,8 +338,7 @@ static int drvopen( Plustek_Device *dev )
return handle;
}
/*
* Calls the devic specific stop and close functions.
/** Calls the device specific stop and close functions.
* @param dev - pointer to the device specific structure
* @return The function always returns SANE_STATUS_GOOD
*/
@ -356,8 +366,7 @@ static SANE_Status drvclose( Plustek_Device *dev )
return SANE_STATUS_GOOD;
}
/*.............................................................................
* according to the mode and source we return the corresponding mode list
/** according to the mode and source we return the corresponding mode list
*/
static pModeParam getModeList( Plustek_Scanner *scanner )
{
@ -381,7 +390,7 @@ static pModeParam getModeList( Plustek_Scanner *scanner )
if( 0 != scanner->val[OPT_EXT_MODE].w ) {
if( _ASIC_IS_USB == scanner->hw->caps.AsicID )
mp = &mp[_TPAModeSupportMin-1];
mp = &mp[_TPAModeSupportMin];
else
mp = &mp[_TPAModeSupportMin];
}
@ -408,11 +417,19 @@ static SANE_Bool getReaderProcessExitCode( Plustek_Scanner *scanner )
DBG( _DBG_INFO, "res=%i, status=%i\n",res,status );
if( WIFEXITED( status )) {
scanner->exit_code = WEXITSTATUS(status);
DBG( _DBG_INFO, "Child WEXITSTATUS = %d\n", scanner->exit_code );
DBG( _DBG_INFO, "Child WEXITSTATUS = %d\n",scanner->exit_code);
} else {
scanner->exit_code = SANE_STATUS_GOOD;
DBG( _DBG_INFO, "Child termination okay\n" );
if( !WIFSIGNALED( status )) {
scanner->exit_code = SANE_STATUS_GOOD;
DBG( _DBG_INFO, "Child termination okay\n" );
} else {
DBG( _DBG_ERROR, "Child terminated by signal %d\n",
WTERMSIG(status));
}
}
scanner->reader_pid = -1;
@ -423,7 +440,7 @@ static SANE_Bool getReaderProcessExitCode( Plustek_Scanner *scanner )
return SANE_FALSE;
}
/*.............................................................................
/**
*
*/
static SANE_Status close_pipe( Plustek_Scanner *scanner )
@ -439,7 +456,7 @@ static SANE_Status close_pipe( Plustek_Scanner *scanner )
return SANE_STATUS_EOF;
}
/*.............................................................................
/**
*
*/
static void sig_chldhandler( int signo )
@ -447,8 +464,7 @@ static void sig_chldhandler( int signo )
DBG( _DBG_PROC, "Child is down (signal=%d)\n", signo );
}
/*.............................................................................
* signal handler to kill the child process
/** signal handler to kill the child process
*/
static RETSIGTYPE reader_process_sigterm_handler( int signal )
{
@ -468,8 +484,7 @@ static RETSIGTYPE sigalarm_handler( int signal )
DBG( _DBG_PROC, "ALARM!!!\n" );
}
/*.............................................................................
* executed as a child process
/** executed as a child process
* read the data from the driver and send the to the parent process
*/
static int reader_process( Plustek_Scanner *scanner, int pipe_fd )
@ -533,8 +548,7 @@ static int reader_process( Plustek_Scanner *scanner, int pipe_fd )
return SANE_STATUS_GOOD;
}
/*.............................................................................
* stop the current scan process
/** stop the current scan process
*/
static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
{
@ -600,8 +614,7 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
return SANE_STATUS_CANCELLED;
}
/**
* because of some internal problems (inside the parport driver), we have to
/** because of some internal problems (inside the parport driver), we have to
* limit the max resolution to optical resolution. This is done by this
* function
* @param dev - pointer to the device specific structure
@ -636,8 +649,7 @@ static SANE_Status limitResolution( Plustek_Device *dev )
return SANE_STATUS_GOOD;
}
/**
* Currently we support only LM9831/2/3 chips and these use the same
/** Currently we support only LM9831/2/3 chips and these use the same
* sizes...
* @param s - pointer to the scanner specific structure
* @return The function always returns SANE_STATUS_GOOD
@ -664,6 +676,7 @@ static SANE_Status initGammaSettings( Plustek_Scanner *s )
}
DBG( _DBG_INFO, "Presetting Gamma tables (len=%u)\n", s->gamma_length );
DBG( _DBG_INFO, "----------------------------------\n" );
/*
* preset the gamma maps
@ -693,8 +706,7 @@ static SANE_Status initGammaSettings( Plustek_Scanner *s )
return SANE_STATUS_GOOD;
}
/**
* Check the gamma vectors we got back and limit if necessary
/** Check the gamma vectors we got back and limit if necessary
* @param s - pointer to the scanner specific structure
* @return nothing
*/
@ -711,8 +723,7 @@ static void checkGammaSettings( Plustek_Scanner *s )
}
}
/*.............................................................................
* initialize the options for the backend according to the device we have
/** initialize the options for the backend according to the device we have
*/
static SANE_Status init_options( Plustek_Scanner *s )
{
@ -751,7 +762,7 @@ static SANE_Status init_options( Plustek_Scanner *s )
if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
s->val[OPT_MODE].w = 2; /* Color */
s->val[OPT_MODE].w = 3; /* Color */
} else {
if((_ASIC_IS_98001 == s->hw->caps.AsicID) ||
@ -948,8 +959,7 @@ static SANE_Status init_options( Plustek_Scanner *s )
return SANE_STATUS_GOOD;
}
/**
* Function to retrieve the vendor and product id from a given string
/** Function to retrieve the vendor and product id from a given string
* @param src - string, that should be investigated
* @param dest - pointer to a string to receive the USB ID
*/
@ -1000,8 +1010,7 @@ static void decodeUsbIDs( char *src, char **dest )
#define _INT 0
#define _FLOAT 1
/**
* function to decode an value and give it back to the caller.
/** function to decode an value and give it back to the caller.
* @param src - pointer to the source string to check
* @param opt - string that keeps the option name to check src for
* @param what - _FLOAT or _INT
@ -1072,8 +1081,7 @@ static SANE_Bool decodeVal( char *src, char *opt,
return SANE_FALSE;
}
/**
* function to retrive the device name of a given string
/** function to retrive the device name of a given string
* @param src - string that keeps the option name to check src for
* @param dest - pointer to the string, that should receive the detected
* devicename
@ -1106,8 +1114,7 @@ static SANE_Bool decodeDevName( char *src, char *dest )
return SANE_FALSE;
}
/*.............................................................................
* attach a device to the backend
/** attach a device to the backend
*/
static SANE_Status attach( const char *dev_name, pCnfDef cnf,
Plustek_Device **devp )
@ -1297,14 +1304,16 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf,
return SANE_STATUS_GOOD;
}
/**
* function to preset a configuration structure
/** function to preset a configuration structure
* @param cnf - pointer to the structure that should be initialized
*/
static void init_config_struct( pCnfDef cnf )
static void init_config_struct( pCnfDef cnf, SANE_Bool is_usb )
{
memset( cnf, 0, sizeof(CnfDef));
if( is_usb )
strcpy( cnf->devName, "auto" );
cnf->adj.warmup = -1;
cnf->adj.lampOff = -1;
cnf->adj.lampOffOnEnd = -1;
@ -1322,8 +1331,7 @@ static void init_config_struct( pCnfDef cnf )
cnf->adj.bgamma = 1.0;
}
/*.............................................................................
* intialize the backend
/** intialize the backend
*/
SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
{
@ -1353,7 +1361,7 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
num_devices = 0;
/* initialize the configuration structure */
init_config_struct( &config );
init_config_struct( &config, SANE_FALSE );
if( version_code != NULL )
*version_code = SANE_VERSION_CODE(V_MAJOR, V_MINOR, 0);
@ -1396,6 +1404,10 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
decodeVal( str, "enableTPA", _INT, &config.adj.enableTpa, &ival);
decodeVal( str, "skipCalibration",
_INT, &config.adj.skipCalibration,&ival);
decodeVal( str, "skipFine",
_INT, &config.adj.skipFine,&ival);
decodeVal( str, "skipFineWhite",
_INT, &config.adj.skipFineWhite,&ival);
decodeVal( str, "invertNegatives",
_INT, &config.adj.invertNegatives,&ival);
@ -1425,7 +1437,7 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
attach( config.devName, &config, 0 );
/* re-initialize the configuration structure */
init_config_struct( &config );
init_config_struct( &config, SANE_TRUE );
tmp = config.usbId;
decodeUsbIDs( str, &tmp );
@ -1441,7 +1453,7 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
attach( config.devName, &config, 0 );
/* re-initialize the configuration structure */
init_config_struct( &config );
init_config_struct( &config, SANE_FALSE );
DBG( _DBG_SANE_INIT, "next device is a PARPORT device\n" );
continue;
@ -1461,8 +1473,7 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
return SANE_STATUS_GOOD;
}
/*.............................................................................
* cleanup the backend...
/** cleanup the backend...
*/
void sane_exit( void )
{
@ -1504,8 +1515,7 @@ void sane_exit( void )
first_handle = NULL;
}
/*.............................................................................
* return a list of all devices
/** return a list of all devices
*/
SANE_Status sane_get_devices(const SANE_Device ***device_list,
SANE_Bool local_only )
@ -1533,8 +1543,7 @@ SANE_Status sane_get_devices(const SANE_Device ***device_list,
return SANE_STATUS_GOOD;
}
/*.............................................................................
* open the sane device
/** open the sane device
*/
SANE_Status sane_open( SANE_String_Const devicename, SANE_Handle* handle )
{
@ -1594,8 +1603,7 @@ SANE_Status sane_open( SANE_String_Const devicename, SANE_Handle* handle )
return SANE_STATUS_GOOD;
}
/*.............................................................................
*
/**
*/
void sane_close (SANE_Handle handle)
{
@ -1632,8 +1640,7 @@ void sane_close (SANE_Handle handle)
free(s);
}
/*.............................................................................
* goes through a string list and returns the start-address of the string
/** goes through a string list and returns the start-address of the string
* that has been found, or NULL on error
*/
static const SANE_String_Const *search_string_list(
@ -1648,8 +1655,7 @@ static const SANE_String_Const *search_string_list(
return list;
}
/*.............................................................................
* return or set the parameter values, also do some checks
/** return or set the parameter values, also do some checks
*/
SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
SANE_Action action, void *value,
@ -1781,8 +1787,9 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
if( SANE_TRUE == s->val[option].w ) {
if( scanmode == COLOR_256GRAY ) {
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
if((scanmode == COLOR_256GRAY) ||
(scanmode == COLOR_GRAY16)) {
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
} else {
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
@ -1793,8 +1800,9 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
initGammaSettings( s );
if( scanmode == COLOR_256GRAY ) {
s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
if((scanmode == COLOR_256GRAY) ||
(scanmode == COLOR_GRAY16)) {
s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
} else {
s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
@ -1845,7 +1853,8 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
if( s->val[OPT_CUSTOM_GAMMA].w &&
!(s->opt[OPT_CUSTOM_GAMMA].cap & SANE_CAP_INACTIVE)) {
if( mp[idx].scanmode == COLOR_256GRAY ) {
if((mp[idx].scanmode == COLOR_256GRAY) ||
(mp[idx].scanmode == COLOR_GRAY16)) {
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
} else {
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
@ -1886,7 +1895,7 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
s->opt[OPT_MODE].constraint.string_list = mode_9800x_list;
} else if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
s->val[OPT_MODE].w = 2; /* COLOR_TRUE24 */
s->val[OPT_MODE].w = 3; /* COLOR_TRUE24 */
} else {
s->opt[OPT_MODE].constraint.string_list = mode_list;
}
@ -1916,7 +1925,7 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
if( _ASIC_IS_USB == s->hw->caps.AsicID )
s->opt[OPT_MODE].constraint.string_list =
&mode_usb_list[_TPAModeSupportMin-1];
&mode_usb_list[_TPAModeSupportMin];
else
s->opt[OPT_MODE].constraint.string_list =
&mode_9800x_list[_TPAModeSupportMin];
@ -1957,8 +1966,7 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
return SANE_STATUS_GOOD;
}
/*.............................................................................
* according to the option number, return a pointer to a descriptor
/** according to the option number, return a pointer to a descriptor
*/
const SANE_Option_Descriptor *
sane_get_option_descriptor( SANE_Handle handle, SANE_Int option )
@ -1971,8 +1979,7 @@ const SANE_Option_Descriptor *
return &(s->opt[option]);
}
/*.............................................................................
* return the current parameter settings
/** return the current parameter settings
*/
SANE_Status sane_get_parameters( SANE_Handle handle, SANE_Parameters *params )
{
@ -2026,8 +2033,7 @@ SANE_Status sane_get_parameters( SANE_Handle handle, SANE_Parameters *params )
return SANE_STATUS_GOOD;
}
/*.............................................................................
* initiate the scan process
/** initiate the scan process
*/
SANE_Status sane_start( SANE_Handle handle )
{
@ -2214,7 +2220,7 @@ SANE_Status sane_start( SANE_Handle handle )
}
/* download gamma correction tables... */
if( scanmode <= COLOR_256GRAY ) {
if( scanmode <= COLOR_256GRAY || scanmode == COLOR_GRAY16 ) {
s->hw->setMap( s->hw, s->gamma_table[0], s->gamma_length, _MAP_MASTER);
} else {
s->hw->setMap( s->hw, s->gamma_table[1], s->gamma_length, _MAP_RED );
@ -2306,8 +2312,7 @@ SANE_Status sane_start( SANE_Handle handle )
return SANE_STATUS_GOOD;
}
/*.............................................................................
* function to read the data from our child process
/** function to read the data from our child process
*/
SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data,
SANE_Int max_length, SANE_Int *length )
@ -2366,8 +2371,7 @@ SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data,
return SANE_STATUS_GOOD;
}
/*.............................................................................
* cancel the scanning process
/** cancel the scanning process
*/
void sane_cancel (SANE_Handle handle)
{
@ -2379,8 +2383,7 @@ void sane_cancel (SANE_Handle handle)
do_cancel( s, SANE_FALSE );
}
/*.............................................................................
* set the pipe to blocking/non blocking mode
/** set the pipe to blocking/non blocking mode
*/
SANE_Status sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
@ -2407,8 +2410,7 @@ SANE_Status sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
return SANE_STATUS_GOOD;
}
/*.............................................................................
* return the descriptor if available
/** return the descriptor if available
*/
SANE_Status sane_get_select_fd( SANE_Handle handle, SANE_Int * fd )
{

Wyświetl plik

@ -23,6 +23,10 @@ option lampOff -1
# i.e. for Plustek (0x07B3) UT12/16/24 (0x0017)
# [usb] 0x07B3 0x0017
# device /dev/usbscanner
# or
# device libusb:bbb:ddd
# where bbb is the busnumber and ddd the device number
# make sure that your user has access to /proc/bus/usb/bbb/ddd
#
# additionally you can specify some options
# warmup, lOffOnEnd, lampOff
@ -31,6 +35,14 @@ option lampOff -1
# [usb]
# device /dev/usbscanner
#
# or simply
# [usb]
#
# or if you want a specific device but you have no idea about
# the device node or you use libusb, simply set vendor- and product-ID
# [usb] 0x07B3 0x0017
# device auto
#
# NOTE: autodetection is safe, as it uses the info it got
# from the USB subsystem. If you're not using the
# autodetection, you MUST have attached that device
@ -43,14 +55,14 @@ option lampOff -1
# options for the previous USB entry
#
# switch lamp off after xxx secs, 0 disables the feature
option lampOff 0
option lampOff 300
# warmup period in seconds, 0 means no warmup
option warmup 30
option warmup 15
# 0 means leave lamp-status untouched, not 0 means switch off
# on sane_close
option lOffOnEnd 0
option lOffOnEnd 1
#
# options to tweak the image start-position
@ -83,9 +95,16 @@ option negShadingY -1
#
option invertNegatives 0
# for skipping calibration step
# for skipping whole calibration step
option skipCalibration 0
# for skipping entire fine calibration step
# coarse calibration is done
option skipFineCalibration 0
# discard the result of the fine white calibration
option skipFineWhite 0
# for replacing the gain values found during
# calibration
option red_gain -1
@ -94,7 +113,6 @@ option blue_gain -1
#
# for adjusting the default gamma values
# use values of 2.5 for CanoScan
#
option redGamma 1.0
option greenGamma 1.0
@ -111,7 +129,8 @@ option enableTPA 0
#
# and of course the device-name
#
device /dev/usbscanner
# device /dev/usbscanner
device auto
#
# to define a new device, start with a new section:

Wyświetl plik

@ -1,45 +1,47 @@
/*.............................................................................
* Project : SANE library for Plustek flatbed scanners.
*.............................................................................
* File: plustek.h - definitions for the backend
*.............................................................................
*/
/** @file plustek.h
* @brief Definitions for the backend.
*
* based on Kazuhiro Sasayama previous
* Work on plustek.[ch] file from the SANE package.
* Based on Kazuhiro Sasayama previous
* Work on plustek.[ch] file from the SANE package.<br>
*
* original code taken from sane-0.71<br>
* Copyright (C) 1997 Hypercore Software Design, Ltd.<br>
* Copyright (C) 2001-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*
* original code taken from sane-0.71
* Copyright (C) 1997 Hypercore Software Design, Ltd.
* Copyright (C) 2000-2002 Gerhard Jaeger <gerhard@gjaeger.de>
*.............................................................................
* History:
* 0.30 - initial version
* 0.31 - no changes
* 0.32 - no changes
* 0.33 - no changes
* 0.34 - moved some definitions and typedefs from plustek.c
* 0.35 - removed OPT_MODEL from options list
* added max_y to struct Plustek_Scan
* 0.36 - added reader_pid, pipe and bytes_read to struct Plustek_Scanner
* removed unused variables from struct Plustek_Scanner
* moved fd from struct Plustek_Scanner to Plustek_Device
* added next members to struct Plustek_Scanner and Plustek_Device
* 0.37 - added max_x to struct Plustek_Device
* 0.38 - added caps to struct Plustek_Device
* added exit code to struct Plustek_Scanner
* removed dropout stuff
* 0.39 - PORTTYPE enum
* added function pointers to control a scanner device
* - 0.30 - initial version
* - 0.31 - no changes
* - 0.32 - no changes
* - 0.33 - no changes
* - 0.34 - moved some definitions and typedefs from plustek.c
* - 0.35 - removed OPT_MODEL from options list
* - added max_y to struct Plustek_Scan
* - 0.36 - added reader_pid, pipe and bytes_read to struct Plustek_Scanner
* - removed unused variables from struct Plustek_Scanner
* - moved fd from struct Plustek_Scanner to Plustek_Device
* - added next members to struct Plustek_Scanner and Plustek_Device
* - 0.37 - added max_x to struct Plustek_Device
* - 0.38 - added caps to struct Plustek_Device
* - added exit code to struct Plustek_Scanner
* - removed dropout stuff
* - 0.39 - PORTTYPE enum
* - added function pointers to control a scanner device
* (Parport and USB)
* 0.40 - added USB stuff
* 0.41 - added configuration stuff
* 0.42 - added custom gamma tables
* changed usbId to static array
* added _MAX_ID_LEN
* 0.43 - no changes
* 0.44 - added flag initialized
*
*.............................................................................
*
* - 0.40 - added USB stuff
* - 0.41 - added configuration stuff
* - 0.42 - added custom gamma tables
* - changed usbId to static array
* - added _MAX_ID_LEN
* - 0.43 - no changes
* - 0.44 - added flag initialized
* - 0.45 - no changes
* .
* <hr>
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
@ -77,6 +79,7 @@
* 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.
* <hr>
*/
#ifndef __PLUSTEK_H__
#define __PLUSTEK_H__

Wyświetl plik

@ -10,7 +10,7 @@
;
:backend "plustek" ; name of backend
:version "0.44" ; version of backend
:version "0.45" ; version of backend
:status :stable ; :alpha, :beta, :stable, :new
:manpage "sane-plustek" ; name of manpage (if it exists)
@ -215,22 +215,18 @@
:model "Perfection 1250"
:interface "USB"
:status :stable
:comment "Mostly OK"
:model "Perfection 1250Photo"
:interface "USB"
:status :stable
:comment "Mostly OK - use option enableTPA"
:model "Perfection 1260"
:interface "USB"
:status :stable
:comment "Mostly OK"
:model "Perfection 1260Photo"
:interface "USB"
:status :stable
:comment "Mostly OK - use option enableTPA"
:mfg "Umax" ; name of manufacturer
:url "http://www.umax.com/"
@ -238,7 +234,10 @@
:model "UMAX 3400"
:interface "USB"
:status :stable
:comment "Mostly OK"
:model "UMAX 5400"
:interface "USB"
:status :untested
:mfg "Canon" ; name a manufacturer
:url "http://www.canon.com/"
@ -246,12 +245,32 @@
:model "CanoScan N650U/N656U"
:interface "USB"
:status :stable
:comment "8-bit Color mode only"
:comment "Poor color picture quality"
:model "CanoScan N1220U"
:interface "USB"
:status :stable
:comment "Poor color picture quality"
:model "CanoScan N670U/N676U"
:interface "USB"
:status :stable
:comment "8-bit Color mode only"
:comment "Poor color picture quality"
:model "CanoScan N1240U"
:interface "USB"
:status :stable
:comment "Poor color picture quality"
:model "CanoScan LIDE20"
:interface "USB"
:status :stable
:comment "Poor color picture quality"
:model "CanoScan LIDE30"
:interface "USB"
:status :stable
:comment "Poor color picture quality"
; :comment and :url specifiers are optional after :mfg, :model, :desc,
; and at the top-level.

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane-plustek 5 "14 October 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane-plustek 5 "10 January 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-plustek
.SH NAME
sane-plustek \- SANE backend for Plustek parallel port and
@ -126,7 +126,7 @@ BrightScan OpticPro OpticPro P12
The Backend is able to support USB scanner based on the National
Semiconductor chipset LM9831, LM9832 and LM9833. The following tables
show various devices which are currently reported to work. If your
Plustek scanner has another Product ID, then the device is
Plustek scanner has another Product ID, then the device is
.B NOT
supported, as it contains unsupported ASICs inside.
.br
@ -209,7 +209,22 @@ USB Model: ASIC: Properties: Prod-ID
.br
----------------------------------------------------------
.br
UMAX 3400 LM9832 1200x2400dpi 42bit 2Mb 0x0060
UMAX 3400/2420 LM9832 600x1200dpi 42bit 512Kb 0x0060
.br
UMAX 5400 LM9832 1200x2400dpi 42bit 512Kb 0x0160
.PP
Vendor Epson - ID: 0x04B8
.br
----------------------------------------------------------
.br
USB Model: ASIC: Properties: Prod-ID
.br
----------------------------------------------------------
.br
Perfection 1250 LM9832 1200x2400dpi 42bit 512Kb 0x010F
.br
Perfection 1260 LM9832 1200x2400dpi 42bit 512Kb 0x011D
.PP
Vendor CANON - ID: 0x04A9
@ -220,9 +235,17 @@ USB Model: ASIC: Properties: Prod-ID
.br
----------------------------------------------------------
.br
CanoScan N650/656U LM9832 1200x2400dpi 48bit 512Kb 0x2206
CanoScan N650/656U LM9832 600x1200dpi 42bit 512Kb 0x2206
.br
CanoScan N670/676U LM9832 1200x2400dpi 48bit 512Kb 0x220D
CanoScan N1220U LM9832 1200x2400dpi 42bit 512Kb 0x2207
.br
CanoScan N670/676U LM9833 600x1200dpi 48bit 512Kb 0x220D
.br
CanoScan N1240U LM9833 1200x2400dpi 48bit 512Kb 0x220E
.br
CanoScan LIDE20 LM9833 600x1200dpi 48bit 512Kb 0x220D
.br
CanoScan LIDE30 LM9833 1200x2400dpi 48bit 512Kb 0x220E
.PP
.SH "OTHER PLUSTEK SCANNERS"
@ -233,7 +256,7 @@ and is supported by the
backend.
.br
Only the National Semiconductor LM9831/2 based devices of Plustek
are supported by this driver. Older versions of the U12, the UT12,
are supported by this driver. Older versions of the U12, the UT12,
the U1212 and U1248 (GrandTech chipset are not supported)
.PP
@ -455,7 +478,9 @@ tells the backend, that the following devicename (here
.I /dev/usbscanner
) has to be interpreted as USB scanner device. If vendor- and
product-id has not been specified, the backend tries to
detect this by its own.
detect this by its own. If device ist set to
.I auto
then the next matching device is used.
.PP
.B
The Options: