Added button support, did some cleanup, added IPC between

reader- and parent-process.
merge-requests/1/head
Gerhard Jaeger 2005-07-04 09:54:31 +00:00
rodzic 6002a6163d
commit 18764ad4a9
11 zmienionych plików z 2093 dodań i 1704 usunięć

Wyświetl plik

@ -87,7 +87,7 @@ typedef struct {
int id;
char *desc;
} TabDef, *pTabDef;
/** to allow different vendors...
*/
static TabDef usbVendors[] = {
@ -192,7 +192,8 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
}
usb_CheckAndCopyAdjs( dev );
DBG( _DBG_INFO, "Device WAF: 0x%08lx\n", dev->usbDev.Caps.workaroundFlag );
DBG( _DBG_INFO, "Device WAF : 0x%08lx\n", dev->usbDev.Caps.workaroundFlag );
DBG( _DBG_INFO, "Transferrate: %lu Bytes/s\n", dev->transferRate );
/* adjust data origin
*/
@ -269,7 +270,6 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
sParam.bSource = SOURCE_Reflection;
sParam.Origin.x = 0;
sParam.Origin.y = 0;
sParam.siThreshold = 0;
sParam.UserDpi.x = 150;
sParam.UserDpi.y = 150;
sParam.dMCLK = 4;
@ -536,18 +536,19 @@ usbGetList( DevList **devs )
/**
*/
static int usbDev_open( Plustek_Device *dev, DevList *devs )
static int usbDev_open( Plustek_Device *dev, DevList *devs, int keep_lock )
{
char dn[512];
char devStr[50];
int result;
int i;
int lc;
SANE_Int handle;
SANE_Byte version;
SANE_Word vendor, product;
SANE_Bool was_empty;
DevList *tmp;
char dn[512];
char devStr[50];
int result;
int i;
int lc;
SANE_Int handle;
SANE_Byte version;
SANE_Word vendor, product;
SANE_Bool was_empty;
SANE_Status status;
DevList *tmp;
DBG( _DBG_INFO, "usbDev_open(%s,%s) - %p\n",
dev->name, dev->usbId, (void*)devs );
@ -591,8 +592,19 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
return -1;
}
if( SANE_STATUS_GOOD != sanei_usb_open( dn, &handle ))
status = sanei_access_lock( dn, 5 );
if( SANE_STATUS_GOOD != status ) {
DBG( _DBG_ERROR, "sanei_access_lock failed: %d\n", status );
return -1;
}
status = sanei_usb_open( dn, &handle );
if( SANE_STATUS_GOOD != status ) {
DBG( _DBG_ERROR, "sanei_usb_open failed: %s (%d)\n",
strerror(errno), errno);
sanei_access_unlock( dev->sane.name );
return -1;
}
/* replace the old devname, so we are able to have multiple
* auto-detected devices
@ -603,10 +615,21 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
} else {
if( SANE_STATUS_GOOD != sanei_usb_open( dev->name, &handle ))
return -1;
status = sanei_access_lock( dev->sane.name, 5 );
if( SANE_STATUS_GOOD != status ) {
DBG( _DBG_ERROR, "sanei_access_lock failed: %d\n", status );
return -1;
}
status = sanei_usb_open( dev->name, &handle );
if( SANE_STATUS_GOOD != status ) {
DBG( _DBG_ERROR, "sanei_usb_open failed: %s (%d)\n",
strerror(errno), errno);
sanei_access_unlock( dev->sane.name );
return -1;
}
}
was_empty = SANE_FALSE;
result = sanei_usb_get_vendor_product( handle, &vendor, &product );
@ -623,8 +646,9 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
DBG( _DBG_ERROR, "Specified Vendor and Product ID "
"doesn't match with the ones\n"
"in the config file\n" );
sanei_access_unlock( dev->sane.name );
sanei_usb_close( handle );
return -1;
return -1;
}
} else {
sprintf( dev->usbId, "0x%04X-0x%04X", vendor, product );
@ -636,15 +660,16 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
DBG( _DBG_INFO, "Can't get vendor & product ID from driver...\n" );
/* if the ioctl stuff is not supported by the kernel and we have
* nothing specified, we have to give up...
*/
* nothing specified, we have to give up...
*/
if( dev->usbId[0] == '\0' ) {
DBG( _DBG_ERROR, "Cannot autodetect Vendor an Product ID, "
"please specify in config file.\n" );
sanei_access_unlock( dev->sane.name );
sanei_usb_close( handle );
return -1;
}
vendor = strtol( &dev->usbId[0], 0, 0 );
product = strtol( &dev->usbId[7], 0, 0 );
DBG( _DBG_INFO, "... using the specified: "
@ -655,18 +680,22 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
*/
if( !usb_IsDeviceInList( dev->usbId )) {
DBG( _DBG_ERROR, "Device >%s<, is not supported!\n", dev->usbId );
sanei_access_unlock( dev->sane.name );
sanei_usb_close( handle );
return -1;
}
if( SANE_STATUS_GOOD != usbio_DetectLM983x( handle, &version )) {
status = usbio_DetectLM983x( handle, &version );
if( SANE_STATUS_GOOD != status ) {
sanei_usb_close( handle );
sanei_access_unlock( dev->sane.name );
return -1;
}
if ((version < 3) || (version > 4)) {
DBG( _DBG_ERROR, "This is not a LM9831 or LM9832 chip based scanner.\n" );
sanei_usb_close( handle );
sanei_access_unlock( dev->sane.name );
return -1;
}
@ -693,8 +722,11 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
if( was_empty )
dev->usbId[0] = '\0';
if( handle >= 0 )
if( handle >= 0 ) {
if( !keep_lock )
sanei_access_unlock( dev->sane.name );
return handle;
}
} else {
@ -723,11 +755,14 @@ static int usbDev_open( Plustek_Device *dev, DevList *devs )
if( 0 == strncmp( Settings[i].pIDString, devStr, lc )) {
DBG( _DBG_INFO, "Device description for >%s< found.\n", devStr );
usb_initDev( dev, i, handle, vendor );
if( !keep_lock )
sanei_access_unlock( dev->sane.name );
return handle;
}
}
}
sanei_access_unlock( dev->sane.name );
sanei_usb_close( handle );
DBG( _DBG_ERROR, "No matching device found >%s<\n", devStr );
return -1;
@ -887,7 +922,6 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
dev->scanning.dwFlag |= SCANDEF_QualityScan;
}
dev->scanning.sParam.siThreshold = si->siBrightness;
dev->scanning.sParam.brightness = si->siBrightness;
dev->scanning.sParam.contrast = si->siContrast;
@ -1000,47 +1034,41 @@ static int usbDev_stopScan( Plustek_Device *dev )
*/
static int usbDev_startScan( Plustek_Device *dev )
{
pScanDef scanning = &dev->scanning;
static int iSkipLinesForADF = 0;
ScanDef *scan = &dev->scanning;
DBG( _DBG_INFO, "usbDev_startScan()\n" );
/* HEINER: Preview currently not working correctly */
#if 0
if( scanning->dwFlag & SCANDEF_QualityScan )
if( scan->dwFlag & SCANDEF_QualityScan )
dev->usbDev.a_bRegs[0x0a] = 0;
else
dev->usbDev.a_bRegs[0x0a] = 1;
#endif
dev->usbDev.a_bRegs[0x0a] = 0;
/* Allocate shading buffer */
if((dev->scanning.dwFlag & SCANDEF_Adf) &&
(dev->scanning.dwFlag & SCANDEF_ContinuousScan)) {
dev->scanning.fCalibrated = SANE_TRUE;
if((scan->dwFlag & SCANDEF_Adf) && (scan->dwFlag & SCANDEF_ContinuousScan)) {
scan->fCalibrated = SANE_TRUE;
} else {
dev->scanning.fCalibrated = SANE_FALSE;
iSkipLinesForADF = 0;
scan->fCalibrated = SANE_FALSE;
}
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( _SCANBUF_SIZE );
scan->sParam.PhyDpi.x = usb_SetAsicDpiX(dev,scan->sParam.UserDpi.x);
scan->sParam.PhyDpi.y = usb_SetAsicDpiY(dev,scan->sParam.UserDpi.y);
if( NULL != scanning->pScanBuffer ) {
/* Allocate shading/scan buffer */
scan->pScanBuffer = (u_char*)malloc( _SCANBUF_SIZE );
scanning->dwFlag |= SCANFLAG_StartScan;
usb_LampOn( dev, SANE_TRUE, SANE_TRUE );
if( scan->pScanBuffer == NULL )
return _E_ALLOC;
m_fStart = m_fFirst = SANE_TRUE;
m_fAutoPark =
(scanning->dwFlag & SCANFLAG_StillModule)?SANE_FALSE:SANE_TRUE;
usb_StopLampTimer( dev );
return 0;
}
return _E_ALLOC;
scan->dwFlag |= SCANFLAG_StartScan;
usb_LampOn( dev, SANE_TRUE, SANE_TRUE );
m_fStart = m_fFirst = SANE_TRUE;
m_fAutoPark = (scan->dwFlag&SCANFLAG_StillModule)?SANE_FALSE:SANE_TRUE;
usb_StopLampTimer( dev );
return 0;
}
/**
@ -1052,9 +1080,9 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf )
{
int result;
SANE_Bool use_alt_cal = SANE_FALSE;
pScanDef scanning = &dev->scanning;
pDCapsDef scaps = &dev->usbDev.Caps;
pHWDef hw = &dev->usbDev.HwSetting;
ScanDef *scan = &dev->scanning;
DCapsDef *scaps = &dev->usbDev.Caps;
HWDef *hw = &dev->usbDev.HwSetting;
DBG( _DBG_INFO, "usbDev_PrepareScan()\n" );
@ -1096,17 +1124,16 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf )
DBG( _DBG_INFO, "calibration done.\n" );
if( !( scanning->dwFlag & SCANFLAG_Scanning )) {
if( !( scan->dwFlag & SCANFLAG_Scanning )) {
usleep( 10 * 1000 );
if( !usb_SetScanParameters( dev, &scanning->sParam )) {
if( !usb_SetScanParameters( dev, &scan->sParam )) {
DBG( _DBG_ERROR, "Setting Scan Parameters failed!\n" );
return 0;
}
/*
* if we bypass the calibration step, we wait on lamp warmup here...
/* if we bypass the calibration step, we wait on lamp warmup here...
*/
if( scaps->workaroundFlag & _WAF_BYPASS_CALIBRATION ) {
if( !usb_Wait4Warmup( dev )) {
@ -1115,211 +1142,189 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf )
}
}
scanning->pbScanBufBegin = scanning->pScanBuffer;
scan->pbScanBufBegin = scan->pScanBuffer;
if((dev->caps.dwFlag & SFLAG_ADF) && (scaps->OpticDpi.x == 600))
scanning->dwLinesScanBuf = 8;
scan->dwLinesScanBuf = 8;
else
scanning->dwLinesScanBuf = 32;
scan->dwLinesScanBuf = 32;
/* gives faster feedback to the frontend ! */
scanning->dwLinesScanBuf = 2;
scan->dwBytesScanBuf = scan->dwLinesScanBuf *
scan->sParam.Size.dwPhyBytes;
scanning->dwBytesScanBuf = scanning->dwLinesScanBuf *
scanning->sParam.Size.dwPhyBytes;
scanning->dwNumberOfScanBufs = _SCANBUF_SIZE /
scanning->dwBytesScanBuf;
scanning->dwLinesPerScanBufs = scanning->dwNumberOfScanBufs *
scanning->dwLinesScanBuf;
scanning->pbScanBufEnd = scanning->pbScanBufBegin +
scanning->dwLinesPerScanBufs *
scanning->sParam.Size.dwPhyBytes;
scanning->dwRedShift = 0;
scanning->dwBlueShift = 0;
scanning->dwGreenShift = 0;
scan->dwNumberOfScanBufs = _SCANBUF_SIZE / scan->dwBytesScanBuf;
scan->dwLinesPerScanBufs = scan->dwNumberOfScanBufs *
scan->dwLinesScanBuf;
scan->pbScanBufEnd = scan->pbScanBufBegin +
scan->dwLinesPerScanBufs *
scan->sParam.Size.dwPhyBytes;
scan->dwRedShift = 0;
scan->dwBlueShift = 0;
scan->dwGreenShift = 0;
/* CCD scanner */
if( scanning->sParam.bChannels == 3 ) {
if( scan->sParam.bChannels == 3 ) {
scanning->dwLinesDiscard = (u_long)scaps->bSensorDistance *
scanning->sParam.PhyDpi.y / scaps->OpticDpi.y;
scan->dwLinesDiscard = (u_long)scaps->bSensorDistance *
scan->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;
scan->Red.pb = scan->pbScanBufBegin;
scan->Green.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Blue.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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;
scan->Red.pb = scan->pbScanBufBegin;
scan->Blue.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Green.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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;
scan->Green.pb = scan->pbScanBufBegin;
scan->Blue.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Red.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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;
scan->Green.pb = scan->pbScanBufBegin;
scan->Red.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Blue.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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_brg:
scan->Blue.pb = scan->pbScanBufBegin;
scan->Red.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Green.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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;
}
case SENSORORDER_bgr:
scan->Blue.pb = scan->pbScanBufBegin;
scan->Green.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->sParam.Size.dwPhyBytes;
scan->Red.pb = scan->pbScanBufBegin + scan->dwLinesDiscard *
scan->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);
/* double it for last channel */
scan->dwLinesDiscard <<= 1;
scan->dwGreenShift = (7UL+scan->sParam.bBitDepth) >> 3;
scan->Green.pb += scan->dwGreenShift;
scan->Blue.pb += (scan->dwGreenShift * 2);
if( scanning->dwFlag & SCANFLAG_bgr) {
if( scan->dwFlag & SCANFLAG_bgr) {
u_char *pb = scanning->Blue.pb;
u_char *pb = scan->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;
}
scan->Blue.pb = scan->Red.pb;
scan->Red.pb = pb;
scan->dwBlueShift = 0;
scan->dwRedShift = scan->dwGreenShift << 1;
} else {
scan->dwRedShift = 0;
scan->dwBlueShift = scan->dwGreenShift << 1;
}
} else {
} else {
/* this might be simple gray operation or AFE 1 channel op */
scanning->dwLinesDiscard = 0;
scanning->Green.pb = scanning->pbScanBufBegin;
/* this might be a simple gray operation or AFE 1 channel op */
scan->dwLinesDiscard = 0;
scan->Green.pb = scan->pbScanBufBegin;
if(( scanning->sParam.bDataType == SCANDATATYPE_Color ) &&
( hw->bReg_0x26 & _ONE_CH_COLOR )) {
if(( scan->sParam.bDataType == SCANDATATYPE_Color ) &&
( hw->bReg_0x26 & _ONE_CH_COLOR )) {
u_long len = scanning->sParam.Size.dwPhyBytes / 3;
u_long len = scan->sParam.Size.dwPhyBytes / 3;
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin + len;
scanning->Blue.pb = scanning->pbScanBufBegin + len * 2UL;
}
}
scan->Red.pb = scan->pbScanBufBegin;
scan->Green.pb = scan->pbScanBufBegin + len;
scan->Blue.pb = scan->pbScanBufBegin + len * 2UL;
}
}
/* set a funtion to process the RAW data... */
usb_GetImageProc( dev );
scanning->bLinesToSkip = (u_char)(scanning->sParam.PhyDpi.y / 50);
if( scanning->sParam.bSource == SOURCE_ADF )
scanning->dwFlag |= SCANFLAG_StillModule;
scan->bLinesToSkip = (u_char)(scan->sParam.PhyDpi.y / 50);
if( scan->sParam.bSource == SOURCE_ADF )
scan->dwFlag |= SCANFLAG_StillModule;
DBG( _DBG_INFO, "* scanning->dwFlag=0x%08lx\n", scanning->dwFlag );
DBG( _DBG_INFO, "* scan->dwFlag=0x%08lx\n", scan->dwFlag );
if( !usb_ScanBegin( dev,
(scanning->dwFlag&SCANFLAG_StillModule) ? SANE_FALSE:SANE_TRUE)) {
(scan->dwFlag&SCANFLAG_StillModule) ? SANE_FALSE:SANE_TRUE)) {
return _E_INTERNAL;
}
scanning->dwFlag |= SCANFLAG_Scanning;
scan->dwFlag |= SCANFLAG_Scanning;
if( scanning->sParam.UserDpi.y != scanning->sParam.PhyDpi.y ) {
if( scan->sParam.UserDpi.y != scan->sParam.PhyDpi.y ) {
if( scanning->sParam.UserDpi.y < scanning->sParam.PhyDpi.y ) {
if( scan->sParam.UserDpi.y < scan->sParam.PhyDpi.y ) {
scanning->wSumY = scanning->sParam.PhyDpi.y -
scanning->sParam.UserDpi.y;
scanning->dwFlag |= SCANFLAG_SampleY;
scan->wSumY = scan->sParam.PhyDpi.y - scan->sParam.UserDpi.y;
scan->dwFlag |= SCANFLAG_SampleY;
DBG( _DBG_INFO, "SampleY Flag set (%u != %u, wSumY=%u)\n",
scanning->sParam.UserDpi.y,
scanning->sParam.PhyDpi.y, scanning->wSumY );
scan->sParam.UserDpi.y, scan->sParam.PhyDpi.y, scan->wSumY );
}
}
}
dumpPicInit( &scanning->sParam, "plustek-pic.raw" );
dumpPicInit( &scan->sParam, "plustek-pic.raw" );
/* here the NT driver uses an extra reading thread...
* as the SANE stuff already forked the driver to read data, I think
* we should only read data by using a function...
* as the SANE stuff already forked the driver to read data, I think
* we should only read data by using a function...
*/
scanning->dwLinesUser = scanning->sParam.Size.dwLines;
if( !scanning->dwLinesUser )
scan->dwLinesUser = scan->sParam.Size.dwLines;
if( !scan->dwLinesUser )
return _E_BUFFER_TOO_SMALL;
if( !scanning->sParam.Size.dwLines )
return _E_NODATA;
if( scanning->sParam.Size.dwLines < scanning->dwLinesUser )
scanning->dwLinesUser = scanning->sParam.Size.dwLines;
if( scan->sParam.Size.dwLines < scan->dwLinesUser )
scan->dwLinesUser = scan->sParam.Size.dwLines;
scanning->sParam.Size.dwLines -= scanning->dwLinesUser;
if( scanning->dwFlag & SCANFLAG_BottomUp )
scanning->UserBuf.pb = buf + (scanning->dwLinesUser - 1) *
scanning->dwBytesLine;
scan->sParam.Size.dwLines -= scan->dwLinesUser;
if( scan->dwFlag & SCANFLAG_BottomUp )
scan->UserBuf.pb = buf + (scan->dwLinesUser - 1) * scan->dwBytesLine;
else
scanning->UserBuf.pb = buf;
scan->UserBuf.pb = buf;
DBG(_DBG_INFO,"Reading the data now!\n" );
DBG(_DBG_INFO,"PhyDpi.x = %u\n", scanning->sParam.PhyDpi.x );
DBG(_DBG_INFO,"PhyDpi.y = %u\n", scanning->sParam.PhyDpi.y );
DBG(_DBG_INFO,"UserDpi.x = %u\n", scanning->sParam.UserDpi.x );
DBG(_DBG_INFO,"UserDpi.y = %u\n", scanning->sParam.UserDpi.y );
DBG(_DBG_INFO,"NumberOfScanBufs = %lu\n",scanning->dwNumberOfScanBufs);
DBG(_DBG_INFO,"LinesPerScanBufs = %lu\n",scanning->dwLinesPerScanBufs);
DBG(_DBG_INFO,"dwPhyBytes = %lu\n",scanning->sParam.Size.dwPhyBytes);
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 );
DBG(_DBG_INFO,"dwLinesToSkip = %u\n", scanning->bLinesToSkip );
DBG(_DBG_INFO,"dwLinesUser = %lu\n",scanning->dwLinesUser );
DBG(_DBG_INFO,"dwBytesLine = %lu\n",scanning->dwBytesLine );
DBG(_DBG_INFO,"PhyDpi.x = %u\n", scan->sParam.PhyDpi.x );
DBG(_DBG_INFO,"PhyDpi.y = %u\n", scan->sParam.PhyDpi.y );
DBG(_DBG_INFO,"UserDpi.x = %u\n", scan->sParam.UserDpi.x );
DBG(_DBG_INFO,"UserDpi.y = %u\n", scan->sParam.UserDpi.y );
DBG(_DBG_INFO,"NumberOfScanBufs = %lu\n",scan->dwNumberOfScanBufs);
DBG(_DBG_INFO,"LinesPerScanBufs = %lu\n",scan->dwLinesPerScanBufs);
DBG(_DBG_INFO,"dwPhyBytes = %lu\n",scan->sParam.Size.dwPhyBytes);
DBG(_DBG_INFO,"dwPhyPixels = %lu\n",scan->sParam.Size.dwPhyPixels);
DBG(_DBG_INFO,"dwTotalBytes = %lu\n",scan->sParam.Size.dwTotalBytes);
DBG(_DBG_INFO,"dwPixels = %lu\n",scan->sParam.Size.dwPixels);
DBG(_DBG_INFO,"dwBytes = %lu\n",scan->sParam.Size.dwBytes);
DBG(_DBG_INFO,"dwValidPixels = %lu\n",scan->sParam.Size.dwValidPixels);
DBG(_DBG_INFO,"dwBytesScanBuf = %lu\n",scan->dwBytesScanBuf );
DBG(_DBG_INFO,"dwLinesDiscard = %lu\n",scan->dwLinesDiscard );
DBG(_DBG_INFO,"dwLinesToSkip = %u\n", scan->bLinesToSkip );
DBG(_DBG_INFO,"dwLinesUser = %lu\n",scan->dwLinesUser );
DBG(_DBG_INFO,"dwBytesLine = %lu\n",scan->dwBytesLine );
scanning->pbGetDataBuf = scanning->pbScanBufBegin;
scan->pbGetDataBuf = scan->pbScanBufBegin;
scanning->dwLinesToProcess = usb_ReadData( dev );
if( 0 == scanning->dwLinesToProcess )
scan->dwLinesToProcess = usb_ReadData( dev );
if( 0 == scan->dwLinesToProcess )
return _E_DATAREAD;
return 0;
@ -1329,76 +1334,72 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf )
*/
static int usbDev_ReadLine( Plustek_Device *dev )
{
int wrap;
u_long cur;
pScanDef scanning = &dev->scanning;
pHWDef hw = &dev->usbDev.HwSetting;
int wrap;
u_long cur;
ScanDef *scan = &dev->scanning;
HWDef *hw = &dev->usbDev.HwSetting;
cur = scanning->dwLinesUser;
cur = scan->dwLinesUser;
/* we stay within this sample loop until one line has been processed for
* the user...
*/
while( cur == scanning->dwLinesUser ) {
while( cur == scan->dwLinesUser ) {
if( usb_IsEscPressed()) {
DBG( _DBG_INFO, "readLine() - Cancel detected...\n" );
return _E_ABORT;
}
if( !(scanning->dwFlag & SCANFLAG_SampleY)) {
if( !(scan->dwFlag & SCANFLAG_SampleY)) {
scanning->pfnProcess( dev );
scan->pfnProcess( dev );
/* Adjust user buffer pointer */
scanning->UserBuf.pb += scanning->lBufAdjust;
scanning->dwLinesUser--;
scan->UserBuf.pb += scan->lBufAdjust;
scan->dwLinesUser--;
} else {
scanning->wSumY += scanning->sParam.UserDpi.y;
scan->wSumY += scan->sParam.UserDpi.y;
if( scanning->wSumY >= scanning->sParam.PhyDpi.y ) {
scanning->wSumY -= scanning->sParam.PhyDpi.y;
if( scan->wSumY >= scan->sParam.PhyDpi.y ) {
scan->wSumY -= scan->sParam.PhyDpi.y;
scanning->pfnProcess( dev );
scan->pfnProcess( dev );
/* Adjust user buffer pointer */
scanning->UserBuf.pb += scanning->lBufAdjust;
scanning->dwLinesUser--;
scan->UserBuf.pb += scan->lBufAdjust;
scan->dwLinesUser--;
}
}
/* Adjust get buffer pointers */
wrap = 0;
if( scanning->sParam.bDataType == SCANDATATYPE_Color ) {
if( scan->sParam.bDataType == SCANDATATYPE_Color ) {
scanning->Red.pb += scanning->sParam.Size.dwPhyBytes;
if( scanning->Red.pb >= scanning->pbScanBufEnd ) {
scanning->Red.pb = scanning->pbScanBufBegin +
scanning->dwRedShift;
scan->Red.pb += scan->sParam.Size.dwPhyBytes;
if( scan->Red.pb >= scan->pbScanBufEnd ) {
scan->Red.pb = scan->pbScanBufBegin + scan->dwRedShift;
wrap = 1;
}
scanning->Green.pb += scanning->sParam.Size.dwPhyBytes;
if( scanning->Green.pb >= scanning->pbScanBufEnd ) {
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwGreenShift;
scan->Green.pb += scan->sParam.Size.dwPhyBytes;
if( scan->Green.pb >= scan->pbScanBufEnd ) {
scan->Green.pb = scan->pbScanBufBegin + scan->dwGreenShift;
wrap = 1;
}
scanning->Blue.pb += scanning->sParam.Size.dwPhyBytes;
if( scanning->Blue.pb >= scanning->pbScanBufEnd ) {
scanning->Blue.pb = scanning->pbScanBufBegin +
scanning->dwBlueShift;
scan->Blue.pb += scan->sParam.Size.dwPhyBytes;
if( scan->Blue.pb >= scan->pbScanBufEnd ) {
scan->Blue.pb = scan->pbScanBufBegin + scan->dwBlueShift;
wrap = 1;
}
} else {
scanning->Green.pb += scanning->sParam.Size.dwPhyBytes;
if( scanning->Green.pb >= scanning->pbScanBufEnd )
scanning->Green.pb = scanning->pbScanBufBegin +
scanning->dwGreenShift;
scan->Green.pb += scan->sParam.Size.dwPhyBytes;
if( scan->Green.pb >= scan->pbScanBufEnd )
scan->Green.pb = scan->pbScanBufBegin + scan->dwGreenShift;
}
/* on any wrap-around of the get pointers in one channel mode
@ -1406,27 +1407,27 @@ static int usbDev_ReadLine( Plustek_Device *dev )
*/
if( wrap ) {
u_long len = scanning->sParam.Size.dwPhyBytes;
u_long len = scan->sParam.Size.dwPhyBytes;
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
if(scanning->sParam.bDataType == SCANDATATYPE_Color) {
if(scan->sParam.bDataType == SCANDATATYPE_Color) {
len /= 3;
}
scanning->Red.pb = scanning->pbScanBufBegin;
scanning->Green.pb = scanning->pbScanBufBegin + len;
scanning->Blue.pb = scanning->pbScanBufBegin + len * 2UL;
scan->Red.pb = scan->pbScanBufBegin;
scan->Green.pb = scan->pbScanBufBegin + len;
scan->Blue.pb = scan->pbScanBufBegin + len * 2UL;
}
}
/* line processed, check if we have to get more...
*/
scanning->dwLinesToProcess--;
scan->dwLinesToProcess--;
if( 0 == scanning->dwLinesToProcess ) {
if( 0 == scan->dwLinesToProcess ) {
scanning->dwLinesToProcess = usb_ReadData( dev );
if( 0 == scanning->dwLinesToProcess ) {
scan->dwLinesToProcess = usb_ReadData( dev );
if( 0 == scan->dwLinesToProcess ) {
if( usb_IsEscPressed())
return _E_ABORT;

Wyświetl plik

@ -35,6 +35,8 @@
* - added dHighSpeed to struct HwDefault
* - 0.49 - added a_bRegs, fModFirstHome and fLastScanIsAdf
* to struct DeviceDef
* - added CRYSTAL_FREQ
* - added IPCDef
* .
* <hr>
* This file is part of the SANE package.
@ -92,6 +94,9 @@
#define kCIS1240 9
#define kEPSON 10
/** 48MHz Quartz */
#define CRYSTAL_FREQ 48000000UL
/*********************************** plustek_types.h!!! ************************/
/* makes trouble with gcc3
@ -535,7 +540,6 @@ typedef struct
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 */
@ -643,6 +647,15 @@ typedef struct {
} ClkMotorDef, *pClkMotorDef;
/** for transferring some info between child and parent after calibration
*/
#define _MAX_SHAD 0x4000
#define _SHADING_BUF (_MAX_SHAD*3) /**< max size of the shading buffer */
typedef struct {
u_long transferRate;
} IPCDef;
#endif /* guard __PLUSTEK_USB_H__ */
/* END PLUSTEK-USB.H ........................................................*/

Wyświetl plik

@ -111,7 +111,7 @@ static int cano_PrepareToReadWhiteCal( Plustek_Device *dev )
}
break;
}
strip_state = 1;
return 0;
}
@ -133,7 +133,7 @@ static int cano_PrepareToReadBlackCal( Plustek_Device *dev )
usb_ModuleToHome( dev, SANE_TRUE );
usb_ModuleMove ( dev, MOVE_Forward,
(u_long)dev->usbDev.pSource->DarkShadOrgY );
(u_long)dev->usbDev.pSource->DarkShadOrgY );
dev->usbDev.a_bRegs[0x45] &= ~0x10;
strip_state = 0;
@ -152,7 +152,7 @@ static int cano_PrepareToReadBlackCal( Plustek_Device *dev )
*/
static int cano_LampOnAfterCalibration( Plustek_Device *dev )
{
pHWDef hw = &dev->usbDev.HwSetting;
HWDef *hw = &dev->usbDev.HwSetting;
switch (strip_state) {
case 2:
@ -232,9 +232,9 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
int res_r, res_g, res_b;
u_long dw, dwR, dwG, dwB, dwDiv, dwLoop1, dwLoop2;
RGBUShortDef max_rgb, min_rgb, tmp_rgb;
pDCapsDef scaps = &dev->usbDev.Caps;
pHWDef hw = &dev->usbDev.HwSetting;
u_char *scanbuf = dev->scanning.pScanBuffer;
DCapsDef *scaps = &dev->usbDev.Caps;
HWDef *hw = &dev->usbDev.HwSetting;
if( usb_IsEscPressed())
return SANE_FALSE;
@ -254,17 +254,17 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
/* define the strip to scan for coarse calibration; done at 300dpi */
m_ScanParam.Size.dwLines = 1;
m_ScanParam.Size.dwPixels = scaps->Normal.Size.x *
scaps->OpticDpi.x / 300UL;
scaps->OpticDpi.x / 300UL;
m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2;
if( m_ScanParam.bDataType == SCANDATATYPE_Color )
m_ScanParam.Size.dwBytes *=3;
m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart *
300UL / scaps->OpticDpi.x);
300UL / scaps->OpticDpi.x);
m_ScanParam.bCalibration = PARAM_Gain;
DBG( _DBG_INFO2, "* Coarse Calibration Strip:\n" );
DBG( _DBG_INFO2, "* Lines = %lu\n", m_ScanParam.Size.dwLines );
DBG( _DBG_INFO2, "* Pixels = %lu\n", m_ScanParam.Size.dwPixels );
@ -283,67 +283,67 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
}
for( i = 0; ; i++ ) {
m_ScanParam.dMCLK = dMCLK;
if( !usb_SetScanParameters( dev, &m_ScanParam )) {
return SANE_FALSE;
}
if( !usb_ScanBegin( dev, SANE_FALSE) ||
!usb_ScanReadImage( dev,pScanBuffer,m_ScanParam.Size.dwPhyBytes ) ||
!usb_ScanEnd( dev )) {
DBG( _DBG_ERROR, "* cano_AdjustLightsource() failed\n" );
return SANE_FALSE;
if( !usb_ScanBegin( dev, SANE_FALSE) ||
!usb_ScanReadImage( dev, scanbuf, m_ScanParam.Size.dwPhyBytes ) ||
!usb_ScanEnd( dev )) {
DBG( _DBG_ERROR, "* cano_AdjustLightsource() failed\n" );
return SANE_FALSE;
}
DBG( _DBG_INFO2, "* PhyBytes = %lu\n", m_ScanParam.Size.dwPhyBytes );
DBG( _DBG_INFO2, "* PhyPixels = %lu\n", m_ScanParam.Size.dwPhyPixels);
sprintf( tmp, "coarse-lamp-%u.raw", i );
dumpPicInit( &m_ScanParam, tmp );
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwPhyBytes );
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwPhyBytes );
if(usb_HostSwap())
usb_Swap((u_short *)pScanBuffer, m_ScanParam.Size.dwPhyBytes );
usb_Swap((u_short *)scanbuf, m_ScanParam.Size.dwPhyBytes );
sprintf( tmp, "coarse-lamp-swap%u.raw", i );
dumpPicInit( &m_ScanParam, tmp );
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwPhyBytes );
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwPhyBytes );
dwDiv = 10;
dwLoop1 = m_ScanParam.Size.dwPhyPixels/dwDiv;
tmp_rgb.Red = tmp_rgb.Green = tmp_rgb.Blue = 0;
/* find out the max pixel value for R, G, B */
for( dw = 0; dwLoop1; dwLoop1-- ) {
/* do some averaging... */
for (dwLoop2 = dwDiv, dwR = dwG = dwB = 0; dwLoop2; dwLoop2--, dw++) {
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
dwR += ((u_short*)pScanBuffer)[dw];
dwG += ((u_short*)pScanBuffer)
dwR += ((u_short*)scanbuf)[dw];
dwG += ((u_short*)scanbuf)
[dw+m_ScanParam.Size.dwPhyPixels+1];
dwB += ((u_short*)pScanBuffer)
dwB += ((u_short*)scanbuf)
[dw+(m_ScanParam.Size.dwPhyPixels+1)*2];
} else {
dwR += ((pRGBUShortDef)pScanBuffer)[dw].Red;
dwG += ((pRGBUShortDef)pScanBuffer)[dw].Green;
dwB += ((pRGBUShortDef)pScanBuffer)[dw].Blue;
dwR += ((pRGBUShortDef)scanbuf)[dw].Red;
dwG += ((pRGBUShortDef)scanbuf)[dw].Green;
dwB += ((pRGBUShortDef)scanbuf)[dw].Blue;
}
} else {
dwG += ((u_short*)pScanBuffer)[dw];
dwG += ((u_short*)scanbuf)[dw];
}
}
dwR = dwR / dwDiv;
dwG = dwG / dwDiv;
dwB = dwB / dwDiv;
if( tmp_rgb.Red < dwR )
tmp_rgb.Red = dwR;
if( tmp_rgb.Green < dwG )
@ -351,7 +351,7 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
if( tmp_rgb.Blue < dwB )
tmp_rgb.Blue = dwB;
}
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
DBG( _DBG_INFO2, "red_lamp_off = %u/%u/%u\n",
min_rgb.Red ,hw->red_lamp_off, max_rgb.Red );
@ -364,14 +364,14 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
DBG( _DBG_INFO2, "blue_lamp_off = %u/%u/%u\n",
min_rgb.Blue, hw->blue_lamp_off, max_rgb.Blue );
}
DBG(_DBG_INFO2, "CUR(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n",
tmp_rgb.Red, tmp_rgb.Red, tmp_rgb.Green,
tmp_rgb.Green, tmp_rgb.Blue, tmp_rgb.Blue );
res_r = 0;
res_g = 0;
res_b = 0;
/* bisect */
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
res_r = cano_adjLampSetting( &min_rgb.Red, &max_rgb.Red,
@ -396,9 +396,11 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
if( i >= 10 ) {
DBG(_DBG_INFO, "* 10 times limit reached, still too dark!!!\n");
break;
#if 0
} else {
DBG(_DBG_INFO2, "* CIS-Warmup, 1s!!!\n" );
sleep( 1 );
#endif
}
usb_AdjustLamps(dev);
@ -410,7 +412,7 @@ static int cano_AdjustLightsource( Plustek_Device *dev )
DBG( _DBG_INFO, "* green_lamp_off = %u\n", hw->green_lamp_off );
DBG( _DBG_INFO, "* blue_lamp_on = %u\n", hw->blue_lamp_on );
DBG( _DBG_INFO, "* blue_lamp_off = %u\n", hw->blue_lamp_off );
DBG( _DBG_INFO, "cano_AdjustLightsource() done.\n" );
return SANE_TRUE;
}
@ -435,7 +437,7 @@ cano_adjGainSetting( u_char *min, u_char *max, u_char *gain,u_long val )
if((*min+1) >= *max)
return 0;
return 1;
}
@ -455,15 +457,16 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
{
char tmp[40];
int i = 0, adj = 1;
pDCapsDef scaps = &dev->usbDev.Caps;
pHWDef hw = &dev->usbDev.HwSetting;
u_long dw;
u_char *scanbuf = dev->scanning.pScanBuffer;
DCapsDef *scaps = &dev->usbDev.Caps;
HWDef *hw = &dev->usbDev.HwSetting;
unsigned char max[3], min[3];
if( usb_IsEscPressed())
return SANE_FALSE;
bMaxITA = 0xff;
max[0] = max[1] = max[2] = 0x3f;
@ -478,25 +481,25 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
DBG( _DBG_INFO, "- function skipped, using frontend values!\n" );
return SANE_TRUE;
}
/* define the strip to scan for coarse calibration
* done at 300dpi
*/
m_ScanParam.Size.dwLines = 1; /* for gain */
m_ScanParam.Size.dwPixels = scaps->Normal.Size.x *
scaps->OpticDpi.x / 300UL;
m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2;
if( hw->bReg_0x26 & _ONE_CH_COLOR &&
m_ScanParam.bDataType == SCANDATATYPE_Color ) {
m_ScanParam.Size.dwBytes *=3;
}
m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart *
300UL / scaps->OpticDpi.x);
m_ScanParam.bCalibration = PARAM_Gain;
DBG( _DBG_INFO2, "Coarse Calibration Strip:\n" );
DBG( _DBG_INFO2, "Lines = %lu\n", m_ScanParam.Size.dwLines );
DBG( _DBG_INFO2, "Pixels = %lu\n", m_ScanParam.Size.dwPixels );
@ -506,38 +509,37 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
while( adj ) {
m_ScanParam.dMCLK = dMCLK;
if( !usb_SetScanParameters( dev, &m_ScanParam ))
return SANE_FALSE;
if( !usb_ScanBegin( dev, SANE_FALSE) ||
!usb_ScanReadImage(dev,pScanBuffer,m_ScanParam.Size.dwPhyBytes) ||
!usb_ScanEnd( dev )) {
if( !usb_ScanBegin( dev, SANE_FALSE) ||
!usb_ScanReadImage(dev,scanbuf,m_ScanParam.Size.dwPhyBytes) ||
!usb_ScanEnd( dev )) {
DBG( _DBG_ERROR, "cano_AdjustGain() failed\n" );
return SANE_FALSE;
}
DBG( _DBG_INFO2, "PhyBytes = %lu\n", m_ScanParam.Size.dwPhyBytes );
DBG( _DBG_INFO2, "PhyPixels = %lu\n", m_ScanParam.Size.dwPhyPixels );
sprintf( tmp, "coarse-gain-%u.raw", i++ );
dumpPicInit( &m_ScanParam, tmp );
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwPhyBytes );
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwPhyBytes );
if(usb_HostSwap())
usb_Swap((u_short *)pScanBuffer, m_ScanParam.Size.dwPhyBytes );
usb_Swap((u_short *)scanbuf, m_ScanParam.Size.dwPhyBytes );
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
RGBUShortDef max_rgb;
u_long dwR, dwG, dwB;
u_long dwDiv = 10;
u_long dwLoop1 = m_ScanParam.Size.dwPhyPixels/dwDiv, dwLoop2;
max_rgb.Red = max_rgb.Green = max_rgb.Blue = 0;
/* find out the max pixel value for R, G, B */
for( dw = 0; dwLoop1; dwLoop1-- ) {
@ -545,15 +547,15 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
for (dwLoop2 = dwDiv, dwR=dwG=dwB=0; dwLoop2; dwLoop2--, dw++) {
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
dwR += ((u_short*)pScanBuffer)[dw];
dwG += ((u_short*)pScanBuffer)
dwR += ((u_short*)scanbuf)[dw];
dwG += ((u_short*)scanbuf)
[dw+m_ScanParam.Size.dwPhyPixels+1];
dwB += ((u_short*)pScanBuffer)
dwB += ((u_short*)scanbuf)
[dw+(m_ScanParam.Size.dwPhyPixels+1)*2];
} else {
dwR += ((pRGBUShortDef)pScanBuffer)[dw].Red;
dwG += ((pRGBUShortDef)pScanBuffer)[dw].Green;
dwB += ((pRGBUShortDef)pScanBuffer)[dw].Blue;
dwR += ((pRGBUShortDef)scanbuf)[dw].Red;
dwG += ((pRGBUShortDef)scanbuf)[dw].Green;
dwB += ((pRGBUShortDef)scanbuf)[dw].Blue;
}
}
dwR = dwR / dwDiv;
@ -567,29 +569,29 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
if(max_rgb.Blue < dwB)
max_rgb.Blue = dwB;
}
DBG(_DBG_INFO2, "MAX(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n",
max_rgb.Red, max_rgb.Red, max_rgb.Green,
max_rgb.Green, max_rgb.Blue, max_rgb.Blue );
adj = cano_adjGainSetting(min , max ,dev->usbDev.a_bRegs+0x3b,max_rgb.Red );
adj += cano_adjGainSetting(min+1, max+1,dev->usbDev.a_bRegs+0x3c,max_rgb.Green);
adj += cano_adjGainSetting(min+2, max+2,dev->usbDev.a_bRegs+0x3d,max_rgb.Blue );
} else {
u_short w_max = 0;
for( dw = 0; dw < m_ScanParam.Size.dwPhyPixels; dw++ ) {
if( w_max < ((u_short*)pScanBuffer)[dw])
w_max = ((u_short*)pScanBuffer)[dw];
if( w_max < ((u_short*)scanbuf)[dw])
w_max = ((u_short*)scanbuf)[dw];
}
adj = cano_adjGainSetting(min,max,dev->usbDev.a_bRegs+0x3c,w_max);
dev->usbDev.a_bRegs[0x3b] = (dev->usbDev.a_bRegs[0x3d] = dev->usbDev.a_bRegs[0x3c]);
DBG(_DBG_INFO2, "MAX(G)= 0x%04x(%u)\n", w_max, w_max );
}
DBG( _DBG_INFO2, "REG[0x3b] = %u\n", dev->usbDev.a_bRegs[0x3b] );
DBG( _DBG_INFO2, "REG[0x3c] = %u\n", dev->usbDev.a_bRegs[0x3c] );
@ -651,19 +653,20 @@ static int cano_AdjustOffset( Plustek_Device *dev )
int i, adj;
u_long dw, dwPixels;
u_long dwSum[3];
signed char low[3] = {-32,-32,-32 };
signed char now[3] = { 0, 0, 0 };
signed char high[3] = { 31, 31, 31 };
pHWDef hw = &dev->usbDev.HwSetting;
pDCapsDef scaps = &dev->usbDev.Caps;
u_char *scanbuf = dev->scanning.pScanBuffer;
HWDef *hw = &dev->usbDev.HwSetting;
DCapsDef *scaps = &dev->usbDev.Caps;
if( usb_IsEscPressed())
return SANE_FALSE;
DBG( _DBG_INFO, "cano_AdjustOffset()\n" );
if((dev->adj.rofs != -1) &&
if((dev->adj.rofs != -1) &&
(dev->adj.gofs != -1) && (dev->adj.bofs != -1)) {
dev->usbDev.a_bRegs[0x38] = (dev->adj.rofs & 0x3f);
dev->usbDev.a_bRegs[0x39] = (dev->adj.gofs & 0x3f);
@ -679,115 +682,115 @@ static int cano_AdjustOffset( Plustek_Device *dev )
dwPixels = m_ScanParam.Size.dwPixels;
else
dwPixels = (u_long)(hw->bOpticBlackEnd - hw->bOpticBlackStart );
m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2;
if( hw->bReg_0x26 & _ONE_CH_COLOR &&
m_ScanParam.bDataType == SCANDATATYPE_Color ) {
m_ScanParam.Size.dwBytes *= 3;
}
m_ScanParam.Size.dwBytes *= 3;
}
m_ScanParam.Origin.x = (u_short)((u_long)hw->bOpticBlackStart * 300UL /
dev->usbDev.Caps.OpticDpi.x);
dev->usbDev.Caps.OpticDpi.x);
m_ScanParam.bCalibration = PARAM_Offset;
m_ScanParam.dMCLK = dMCLK;
if( !usb_SetScanParameters( dev, &m_ScanParam )) {
DBG( _DBG_ERROR, "cano_AdjustOffset() failed\n" );
return SANE_FALSE;
}
DBG( _DBG_INFO2, "S.dwPixels = %lu\n", m_ScanParam.Size.dwPixels );
DBG( _DBG_INFO2, "dwPixels = %lu\n", dwPixels );
DBG( _DBG_INFO2, "dwPhyBytes = %lu\n", m_ScanParam.Size.dwPhyBytes );
DBG( _DBG_INFO2, "dwPhyPixels = %lu\n", m_ScanParam.Size.dwPhyPixels );
for( i = 0, adj = 1; adj != 0; i++ ) {
if((!usb_ScanBegin(dev, SANE_FALSE)) ||
(!usb_ScanReadImage(dev,pScanBuffer,m_ScanParam.Size.dwPhyBytes)) ||
(!usb_ScanReadImage(dev,scanbuf,m_ScanParam.Size.dwPhyBytes)) ||
!usb_ScanEnd( dev )) {
DBG( _DBG_ERROR, "cano_AdjustOffset() failed\n" );
return SANE_FALSE;
}
sprintf( tmp, "coarse-off-%u.raw", i );
dumpPicInit( &m_ScanParam, tmp );
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwPhyBytes );
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwPhyBytes );
if(usb_HostSwap())
usb_Swap((u_short *)pScanBuffer, m_ScanParam.Size.dwPhyBytes );
usb_Swap((u_short *)scanbuf, m_ScanParam.Size.dwPhyBytes );
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
dwSum[0] = dwSum[1] = dwSum[2] = 0;
for (dw = 0; dw < dwPixels; dw++) {
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
dwSum[0] += ((u_short*)pScanBuffer)[dw];
dwSum[0] += ((u_short*)scanbuf)[dw];
dwSum[1] += ((u_short*)
pScanBuffer)[dw+m_ScanParam.Size.dwPhyPixels+1];
scanbuf)[dw+m_ScanParam.Size.dwPhyPixels+1];
dwSum[2] += ((u_short*)
pScanBuffer)[dw+(m_ScanParam.Size.dwPhyPixels+1)*2];
scanbuf)[dw+(m_ScanParam.Size.dwPhyPixels+1)*2];
} else {
dwSum[0] += ((pRGBUShortDef)pScanBuffer)[dw].Red;
dwSum[1] += ((pRGBUShortDef)pScanBuffer)[dw].Green;
dwSum[2] += ((pRGBUShortDef)pScanBuffer)[dw].Blue;
dwSum[0] += ((pRGBUShortDef)scanbuf)[dw].Red;
dwSum[1] += ((pRGBUShortDef)scanbuf)[dw].Green;
dwSum[2] += ((pRGBUShortDef)scanbuf)[dw].Blue;
}
}
DBG( _DBG_INFO2, "RedSum = %lu, ave = %lu\n",
dwSum[0], dwSum[0]/dwPixels );
dwSum[0], dwSum[0]/dwPixels );
DBG( _DBG_INFO2, "GreenSum = %lu, ave = %lu\n",
dwSum[1], dwSum[1] /dwPixels );
dwSum[1], dwSum[1] /dwPixels );
DBG( _DBG_INFO2, "BlueSum = %lu, ave = %lu\n",
dwSum[2], dwSum[2] /dwPixels );
dwSum[2], dwSum[2] /dwPixels );
/* do averaging for each channel */
dwSum[0] /= dwPixels;
dwSum[1] /= dwPixels;
dwSum[2] /= dwPixels;
adj = cano_GetNewOffset( dev, dwSum, 0, low, now, high );
adj |= cano_GetNewOffset( dev, dwSum, 1, low, now, high );
adj |= cano_GetNewOffset( dev, dwSum, 2, low, now, high );
DBG( _DBG_INFO2, "RedOff = %d/%d/%d\n",
(int)low[0],(int)now[0],(int)high[0]);
(int)low[0],(int)now[0],(int)high[0]);
DBG( _DBG_INFO2, "GreenOff = %d/%d/%d\n",
(int)low[1],(int)now[1],(int)high[1]);
(int)low[1],(int)now[1],(int)high[1]);
DBG( _DBG_INFO2, "BlueOff = %d/%d/%d\n",
(int)low[2],(int)now[2],(int)high[2]);
(int)low[2],(int)now[2],(int)high[2]);
} else {
dwSum[0] = 0;
for( dw = 0; dw < dwPixels; dw++ )
dwSum[0] += ((u_short*)pScanBuffer)[dw];
dwSum[0] += ((u_short*)scanbuf)[dw];
dwSum [0] /= dwPixels;
DBG( _DBG_INFO2, "Sum = %lu, ave = %lu\n",
dwSum[0], dwSum[0] /dwPixels );
DBG( _DBG_INFO2, "Sum=%lu, ave=%lu\n", dwSum[0],dwSum[0]/dwPixels);
adj = cano_GetNewOffset( dev, dwSum, 0, low, now, high );
dev->usbDev.a_bRegs[0x3a] = dev->usbDev.a_bRegs[0x39] = dev->usbDev.a_bRegs[0x38];
dev->usbDev.a_bRegs[0x3a] =
dev->usbDev.a_bRegs[0x39] = dev->usbDev.a_bRegs[0x38];
DBG( _DBG_INFO2, "GrayOff = %d/%d/%d\n",
(int)low[0],(int)now[0],(int)high[0]);
(int)low[0],(int)now[0],(int)high[0]);
}
DBG( _DBG_INFO2, "REG[0x38] = %u\n", dev->usbDev.a_bRegs[0x38] );
DBG( _DBG_INFO2, "REG[0x39] = %u\n", dev->usbDev.a_bRegs[0x39] );
DBG( _DBG_INFO2, "REG[0x3a] = %u\n", dev->usbDev.a_bRegs[0x3a] );
_UIO(sanei_lm983x_write(dev->fd, 0x38, &dev->usbDev.a_bRegs[0x38], 3, SANE_TRUE));
}
if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
dev->usbDev.a_bRegs[0x38] = now[0];
dev->usbDev.a_bRegs[0x39] = now[1];
@ -810,20 +813,21 @@ static int cano_AdjustOffset( Plustek_Device *dev )
static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
{
char tmp[40];
pScanParam pParam = &dev->scanning.sParam;
pScanDef scanning = &dev->scanning;
pDCapsDef scaps = &dev->usbDev.Caps;
pHWDef hw = &dev->usbDev.HwSetting;
ScanParam *param = &dev->scanning.sParam;
ScanDef *scan = &dev->scanning;
DCapsDef *scaps = &dev->usbDev.Caps;
HWDef *hw = &dev->usbDev.HwSetting;
u_char *scanbuf = scan->pScanBuffer;
u_short *bufp;
unsigned int i, j;
int step, stepW, val;
u_long red, green, blue, gray;
DBG( _DBG_INFO, "cano_AdjustDarkShading()\n" );
if( usb_IsEscPressed())
return SANE_FALSE;
m_ScanParam = scanning->sParam;
m_ScanParam = scan->sParam;
#if 0
if( m_ScanParam.PhyDpi.x > 75)
@ -834,47 +838,52 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
m_ScanParam.Origin.y = 0;
m_ScanParam.bBitDepth = 16;
m_ScanParam.UserDpi.y = scaps->OpticDpi.y;
m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2;
if( hw->bReg_0x26 & _ONE_CH_COLOR &&
m_ScanParam.bDataType == SCANDATATYPE_Color ) {
m_ScanParam.Size.dwBytes *= 3;
}
m_ScanParam.bCalibration = PARAM_DarkShading;
m_ScanParam.dMCLK = dMCLK;
sprintf( tmp, "fine-dark.raw" );
dumpPicInit( &m_ScanParam, tmp );
usb_SetScanParameters( dev, &m_ScanParam );
if( usb_ScanBegin( dev, SANE_FALSE ) &&
usb_ScanReadImage( dev, pScanBuffer, m_ScanParam.Size.dwTotalBytes)) {
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwTotalBytes );
usb_ScanReadImage( dev, scanbuf, m_ScanParam.Size.dwTotalBytes)) {
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwTotalBytes );
if(usb_HostSwap())
usb_Swap((u_short *)pScanBuffer, m_ScanParam.Size.dwTotalBytes);
usb_Swap((u_short *)scanbuf, m_ScanParam.Size.dwTotalBytes);
}
if (!usb_ScanEnd( dev )){
DBG( _DBG_ERROR, "cano_AdjustDarkShading() failed\n" );
return SANE_FALSE;
}
/* average the n lines, compute reg values */
if( scanning->sParam.bDataType == SCANDATATYPE_Color ) {
if( scan->sParam.bDataType == SCANDATATYPE_Color ) {
stepW = m_ScanParam.Size.dwPhyPixels;
step = m_ScanParam.Size.dwPhyPixels + 1;
if( hw->bReg_0x26 & _ONE_CH_COLOR )
step = m_ScanParam.Size.dwPhyPixels + 1;
else
step = (m_ScanParam.Size.dwPhyPixels*3) + 1;
for( i=0; i<m_ScanParam.Size.dwPhyPixels; i++ ) {
red = 0;
green = 0;
blue = 0;
bufp = ((u_short *)pScanBuffer)+i;
if( hw->bReg_0x26 & _ONE_CH_COLOR )
bufp = ((u_short *)scanbuf)+i;
else
bufp = ((u_short *)scanbuf)+(i*3);
for( j=0; j<m_ScanParam.Size.dwPhyLines; j++ ) {
@ -892,28 +901,28 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
}
}
val = ((int)(red/m_ScanParam.Size.dwPhyLines) + pParam->swOffset[0]);
val = ((int)(red/m_ScanParam.Size.dwPhyLines) + param->swOffset[0]);
if( val < 0 ) {
DBG( _DBG_INFO, "val < 0!!!!\n" );
val = 0;
}
a_wDarkShading[i] = (u_short)val;
val = ((int)(green/m_ScanParam.Size.dwPhyLines) + pParam->swOffset[1]);
val = ((int)(green/m_ScanParam.Size.dwPhyLines) + param->swOffset[1]);
if( val < 0 ) {
DBG( _DBG_INFO, "val < 0!!!!\n" );
val = 0;
}
a_wDarkShading[i+stepW] = (u_short)val;
val = ((int)(blue/m_ScanParam.Size.dwPhyLines) + pParam->swOffset[2]);
val = ((int)(blue/m_ScanParam.Size.dwPhyLines) + param->swOffset[2]);
if( val < 0 ) {
DBG( _DBG_INFO, "val < 0!!!!\n" );
val = 0;
}
a_wDarkShading[i+stepW*2] = (u_short)val;
}
if(usb_HostSwap())
usb_Swap(a_wDarkShading, m_ScanParam.Size.dwPhyPixels * 2 * 3 );
@ -923,12 +932,12 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
for( i=0; i<m_ScanParam.Size.dwPhyPixels; i++ ) {
gray = 0;
bufp = ((u_short *)pScanBuffer)+i;
bufp = ((u_short *)scanbuf)+i;
for( j=0; j<m_ScanParam.Size.dwPhyLines; j++) {
gray += *bufp; bufp+=step;
}
a_wDarkShading[i]= gray/j + pParam->swOffset[0];
a_wDarkShading[i]= gray/j + param->swOffset[0];
}
if(usb_HostSwap())
usb_Swap(a_wDarkShading, m_ScanParam.Size.dwPhyPixels * 2 );
@ -938,7 +947,7 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
memcpy( a_wDarkShading + m_ScanParam.Size.dwPhyPixels * 4,
a_wDarkShading, m_ScanParam.Size.dwPhyPixels * 2);
}
DBG( _DBG_INFO, "cano_AdjustDarkShading() done\n" );
return SANE_TRUE;
}
@ -950,20 +959,21 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
{
char tmp[40];
pScanParam pParam = &dev->scanning.sParam;
pScanDef scanning = &dev->scanning;
pDCapsDef scaps = &dev->usbDev.Caps;
pHWDef hw = &dev->usbDev.HwSetting;
ScanParam *param = &dev->scanning.sParam;
ScanDef *scan = &dev->scanning;
DCapsDef *scaps = &dev->usbDev.Caps;
HWDef *hw = &dev->usbDev.HwSetting;
u_char *scanbuf = scan->pScanBuffer;
u_short *bufp;
unsigned int i, j;
int step, stepW;
u_long red, green, blue, gray;
DBG( _DBG_INFO, "cano_AdjustWhiteShading()\n" );
if( usb_IsEscPressed())
return SANE_FALSE;
m_ScanParam = scanning->sParam;
m_ScanParam = scan->sParam;
#if 0
if( m_ScanParam.PhyDpi.x > 75)
m_ScanParam.Size.dwLines = 64;
@ -986,16 +996,21 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
m_ScanParam.dMCLK = dMCLK;
sprintf( tmp, "fine-white.raw" );
DBG( _DBG_INFO2, "FINE WHITE Calibration Strip: %s\n", tmp );
DBG( _DBG_INFO2, "Lines = %lu\n", m_ScanParam.Size.dwLines );
DBG( _DBG_INFO2, "Pixels = %lu\n", m_ScanParam.Size.dwPixels );
DBG( _DBG_INFO2, "Bytes = %lu\n", m_ScanParam.Size.dwBytes );
DBG( _DBG_INFO2, "Origin.X = %u\n", m_ScanParam.Origin.x );
dumpPicInit( &m_ScanParam, tmp );
if( usb_SetScanParameters( dev, &m_ScanParam ) &&
usb_ScanBegin( dev, SANE_FALSE ) &&
usb_ScanReadImage( dev, pScanBuffer, m_ScanParam.Size.dwTotalBytes)) {
dumpPic( tmp, pScanBuffer, m_ScanParam.Size.dwTotalBytes );
usb_ScanReadImage( dev, scanbuf, m_ScanParam.Size.dwTotalBytes)) {
dumpPic( tmp, scanbuf, m_ScanParam.Size.dwTotalBytes );
if(usb_HostSwap())
usb_Swap((u_short *)pScanBuffer, m_ScanParam.Size.dwTotalBytes);
usb_Swap((u_short *)scanbuf, m_ScanParam.Size.dwTotalBytes);
if (!usb_ScanEnd( dev )){
DBG( _DBG_ERROR, "cano_AdjustWhiteShading() failed\n" );
@ -1005,26 +1020,32 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
DBG( _DBG_ERROR, "cano_AdjustWhiteShading() failed\n" );
return SANE_FALSE;
}
/* average the n lines, compute reg values */
if( scanning->sParam.bDataType == SCANDATATYPE_Color ) {
if( scan->sParam.bDataType == SCANDATATYPE_Color ) {
stepW = m_ScanParam.Size.dwPhyPixels;
step = m_ScanParam.Size.dwPhyPixels + 1;
if( hw->bReg_0x26 & _ONE_CH_COLOR )
step = m_ScanParam.Size.dwPhyPixels + 1;
else
step = (m_ScanParam.Size.dwPhyPixels*3) + 1;
for( i=0; i<m_ScanParam.Size.dwPhyPixels; i++) {
for( i=0; i < m_ScanParam.Size.dwPhyPixels; i++ ) {
red = 0;
green = 0;
blue = 0;
bufp = ((u_short *)pScanBuffer)+i;
if( hw->bReg_0x26 & _ONE_CH_COLOR )
bufp = ((u_short *)scanbuf)+i;
else
bufp = ((u_short *)scanbuf)+(i*3);
for( j=0; j<m_ScanParam.Size.dwPhyLines; j++) {
for( j=0; j<m_ScanParam.Size.dwPhyLines; j++ ) {
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
red += *bufp; bufp+=step;
green += *bufp; bufp+=step;
blue += *bufp; bufp+=step;
red += *bufp; bufp+=step;
green += *bufp; bufp+=step;
blue += *bufp; bufp+=step;
} else {
red += bufp[0];
@ -1036,13 +1057,13 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
}
/* tweaked by the settings in swGain --> 1000/swGain[r,g,b] */
red = (65535.*1000./pParam->swGain[0]) * 16384.*m_ScanParam.Size.dwPhyLines/red;
green = (65535.*1000./pParam->swGain[1]) * 16384.*m_ScanParam.Size.dwPhyLines/green;
blue = (65535.*1000./pParam->swGain[2]) * 16384.*m_ScanParam.Size.dwPhyLines/blue;
red = (65535.*1000./param->swGain[0]) * 16384.*m_ScanParam.Size.dwPhyLines/red;
green = (65535.*1000./param->swGain[1]) * 16384.*m_ScanParam.Size.dwPhyLines/green;
blue = (65535.*1000./param->swGain[2]) * 16384.*m_ScanParam.Size.dwPhyLines/blue;
a_wWhiteShading[i] = (red > 65535? 65535:red );
a_wWhiteShading[i+stepW] = (green > 65535? 65535:green);
a_wWhiteShading[i+stepW*2] = (blue > 65535? 65535:blue );
a_wWhiteShading[i] = (red > 65535 ? 65535:red );
a_wWhiteShading[i+stepW] = (green > 65535 ? 65535:green);
a_wWhiteShading[i+stepW*2] = (blue > 65535 ? 65535:blue );
}
if(usb_HostSwap())
@ -1052,15 +1073,15 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
step = m_ScanParam.Size.dwPhyPixels + 1;
for( i=0; i<m_ScanParam.Size.dwPhyPixels; i++ ){
gray = 0;
bufp = ((u_short *)pScanBuffer)+i;
bufp = ((u_short *)scanbuf)+i;
for( j=0; j<m_ScanParam.Size.dwPhyLines; j++ ) {
gray += *bufp; bufp+=step;
}
gray = (65535.*1000./pParam->swGain[0]) * 16384.*j/gray;
a_wWhiteShading[i]= (gray > 65535? 65535:gray);
gray = (65535.*1000./param->swGain[0]) * 16384.*j/gray;
a_wWhiteShading[i]= (gray > 65535 ? 65535:gray);
}
if(usb_HostSwap())
usb_Swap(a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2 );
@ -1070,20 +1091,20 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
memcpy(a_wWhiteShading+ m_ScanParam.Size.dwPhyPixels * 4,
a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2);
}
DBG( _DBG_INFO, "cano_AdjustWhiteShading() done\n" );
return SANE_TRUE;
}
/**
/** the entry function for the CIS calibration stuff.
*/
static int cano_DoCalibration( Plustek_Device *dev )
{
pScanDef scanning = &dev->scanning;
pHWDef hw = &dev->usbDev.HwSetting;
pDCapsDef scaps = &dev->usbDev.Caps;
ScanDef *scan = &dev->scanning;
HWDef *hw = &dev->usbDev.HwSetting;
DCapsDef *scaps = &dev->usbDev.Caps;
if( SANE_TRUE == scanning->fCalibrated )
if( SANE_TRUE == scan->fCalibrated )
return SANE_TRUE;
DBG( _DBG_INFO, "cano_DoCalibration()\n" );
@ -1094,7 +1115,8 @@ static int cano_DoCalibration( Plustek_Device *dev )
}
/* Don't allow calibration settings from the other driver to confuse our use of
a few of its functions */
* a few of its functions.
*/
scaps->workaroundFlag &= ~_WAF_SKIP_WHITEFINE;
scaps->workaroundFlag &= ~_WAF_SKIP_FINE;
scaps->workaroundFlag &= ~_WAF_BYPASS_CALIBRATION;
@ -1102,21 +1124,21 @@ static int cano_DoCalibration( Plustek_Device *dev )
/* Set the shading position to undefined */
strip_state = 0;
usb_PrepareCalibration( dev );
usb_SetMCLK( dev, &scanning->sParam );
if( !scanning->skipCoarseCalib ) {
usb_SetMCLK( dev, &scan->sParam );
if( !scan->skipCoarseCalib ) {
DBG( _DBG_INFO2, "###### ADJUST LAMP (COARSE)#######\n" );
if( cano_PrepareToReadWhiteCal(dev))
return SANE_FALSE;
dev->usbDev.a_bRegs[0x45] &= ~0x10;
if( !cano_AdjustLightsource(dev)) {
DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" );
return _E_INTERNAL;
}
DBG( _DBG_INFO2, "###### ADJUST OFFSET (COARSE) ####\n" );
DBG( _DBG_INFO2, "###### ADJUST OFFSET (COARSE) ####\n" );
if(cano_PrepareToReadBlackCal(dev))
return SANE_FALSE;
@ -1151,10 +1173,10 @@ static int cano_DoCalibration( Plustek_Device *dev )
DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" );
if(cano_PrepareToReadWhiteCal(dev))
return SANE_FALSE;
if(!usb_ModuleToHome( dev, SANE_TRUE ))
return SANE_FALSE;
if( !usb_ModuleMove(dev, MOVE_Forward,
(u_long)dev->usbDev.pSource->ShadingOriginY)) {
return _E_INTERNAL;
@ -1166,13 +1188,12 @@ static int cano_DoCalibration( Plustek_Device *dev )
/* Lamp on if it's not */
cano_LampOnAfterCalibration(dev);
strip_state=0;
/*
* home the sensor after calibration
strip_state = 0;
/* home the sensor after calibration
*/
usb_ModuleToHome( dev, SANE_TRUE );
scanning->fCalibrated = SANE_TRUE;
scan->fCalibrated = SANE_TRUE;
DBG( _DBG_INFO, "cano_DoCalibration() done\n" );
DBG( _DBG_INFO, "-------------------------\n" );

Wyświetl plik

@ -575,7 +575,7 @@ static DCapsDef Cap0x04B8_0x010F =
static DCapsDef Cap0x1606_0x0060 =
{
/* Normal */
{{ 0, 105 }, 0, -1, {2550, 3508}, { 100, 100 }, COLOR_BW },
{{ 30, 105 }, 15, -1, {2550, 3508}, { 100, 100 }, COLOR_BW },
/* Positive */
{{ 700, 760 }, 650, -1, {1200, 1500}, { 150, 150 }, COLOR_TRUE24 },
/* Negative */
@ -684,7 +684,7 @@ static DCapsDef Cap0x04A9_0x220D =
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE, _NO_MIO
};
/* Canon N1240U
/* Canon N1240U/LiDE30
*/
static DCapsDef Cap0x04A9_0x220E =
{
@ -1865,7 +1865,7 @@ static HWDef Hw0x1606_0x0060 =
0x44, /* misc io12 (reg 0x59) */
0x45, /* misc io34 (reg 0x5a) */
0x7c, /* misc io56 (reg 0x5b) */
0x74, /* misc io56 (reg 0x5b) */
0, /* test mode ADC Output CODE MSB (reg 0x5c) */
0, /* test mode ADC Output CODE LSB (reg 0x5d) */
0, /* test mode (reg 0x5e) */
@ -2103,7 +2103,7 @@ static HWDef Hw0x04A9_0x2208 =
_GREEN_CH,
0, /* bReg 0x27 color mode */
1, /* bReg 0x29 illumination mode */
/* illumination mode settings (not used for CCD devices) */
{ 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0 },
@ -2113,7 +2113,7 @@ static HWDef Hw0x04A9_0x2208 =
33, /* bOpticBlackEnd (reg 0x1d) */
64, /* wActivePixelsStart (reg 0x1e + 0x1f) */
5440, /* wLineEnd (reg 0x20 + 0x21) */
16383, /* red lamp on (reg 0x2c + 0x2d) */
1, /* red lamp off (reg 0x2e + 0x2f) */
0, /* green lamp on (reg 0x30 + 0x31) */
@ -2144,139 +2144,139 @@ static HWDef Hw0x04A9_0x2208 =
/** Canon 670/676/LiDE20 */
static HWDef Hw0x04A9_0x220D =
{
0.86, /* dMaxMotorSpeed (Max_Speed) */
0.243, /* dMaxMoveSpeed (Max_Speed) */
0.86, /* dMaxMotorSpeed (Max_Speed) */
0.243, /* dMaxMoveSpeed (Max_Speed) */
0.0, /* dHighSpeed */
100, /* dIntegrationTimeLowLamp */
100, /* dIntegrationTimeHighLamp */
1200, /* wMotorDpi (Full step DPI) */
512, /* wRAMSize (KB) */
3.75, /* dMinIntegrationTimeLowres (ms) */
5.75, /* dMinIntegrationTimeHighres (ms) */
0, /* wGreenPWMDutyCycleLow (reg 0x2a + 0x2b) */
0, /* wGreenPWMDutyCycleHigh (reg 0x2a + 0x2b) */
100, /* dIntegrationTimeLowLamp */
100, /* dIntegrationTimeHighLamp */
1200, /* wMotorDpi (Full step DPI) */
512, /* wRAMSize (KB) */
3.75, /* dMinIntegrationTimeLowres (ms) */
5.75, /* dMinIntegrationTimeHighres (ms) */
0, /* wGreenPWMDutyCycleLow (reg 0x2a + 0x2b) */
0, /* wGreenPWMDutyCycleHigh (reg 0x2a + 0x2b) */
0x15, /* bSensorConfiguration (0x0b) */
0x4c, /* sensor control settings (reg 0x0c) */
0x2f, /* sensor control settings (reg 0x0d) */
0x00, /* sensor control settings (reg 0x0e) */
0x15, /* bSensorConfiguration (0x0b) */
0x4c, /* sensor control settings (reg 0x0c) */
0x2f, /* sensor control settings (reg 0x0d) */
0x00, /* sensor control settings (reg 0x0e) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* mono (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* mono (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* color (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* color (reg 0x0f to 0x18) */
(_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */
(_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */
0x00, /* bReg 0x27 color mode */
2, /* bReg 0x29 illumination mode (runtime) */
0x00, /* bReg 0x27 color mode */
2, /* bReg 0x29 illumination mode (runtime) */
{ 3, 0, 0, 23, 1800, 0, 0 },
{ 2, 23, 3800, 23, 3300, 23, 2700 },
{ 3, 0, 0, 23, 1800, 0, 0 },
{ 2, 23, 3800, 23, 3300, 23, 2700 },
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
0, /* bOpticBlackStart (reg 0x1c) */
0, /* bOpticBlackEnd (reg 0x1d) */
75, /* wActivePixelsStart (reg 0x1e + 0x1f) */
6074, /* wLineEnd (reg 0x20 + 0x21) */
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
0, /* bOpticBlackStart (reg 0x1c) */
0, /* bOpticBlackEnd (reg 0x1d) */
75, /* wActivePixelsStart (reg 0x1e + 0x1f) */
6074, /* wLineEnd (reg 0x20 + 0x21) */
23, /* red lamp on (reg 0x2c + 0x2d) */
3800, /* red lamp off (reg 0x2e + 0x2f) */
23, /* green lamp on (reg 0x30 + 0x31) */
3300, /* green lamp off (reg 0x32 + 0x33) */
23, /* blue lamp on (reg 0x34 + 0x35) */
2700, /* blue lamp off (reg 0x36 + 0x37) */
23, /* red lamp on (reg 0x2c + 0x2d) */
3800, /* red lamp off (reg 0x2e + 0x2f) */
23, /* green lamp on (reg 0x30 + 0x31) */
3300, /* green lamp off (reg 0x32 + 0x33) */
23, /* blue lamp on (reg 0x34 + 0x35) */
2700, /* blue lamp off (reg 0x36 + 0x37) */
3, /* stepper motor control (reg 0x45) */
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
0x3f, /* steps to reverse when buffer is full reg 0x50) */
0xfc, /* acceleration profile (reg 0x51) */
0, /* lines to process (reg 0x54) */
0x0f, /* kickstart (reg 0x55) */
0x08, /* pwm freq (reg 0x56) */
0x1f, /* pwm duty cycle (reg 0x57) */
3, /* stepper motor control (reg 0x45) */
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
0x3f, /* steps to reverse when buffer is full reg 0x50) */
0xfc, /* acceleration profile (reg 0x51) */
0, /* lines to process (reg 0x54) */
0x0f, /* kickstart (reg 0x55) */
0x08, /* pwm freq (reg 0x56) */
0x1f, /* pwm duty cycle (reg 0x57) */
0x04, /* Paper sense (reg 0x58) */
0x04, /* Paper sense (reg 0x58) */
0x66, /* misc io12 (reg 0x59) */
0x16, /* misc io34 (reg 0x5a) */
0x91, /* misc io56 (reg 0x5b) */
0x01, /* test mode ADC Output CODE MSB (reg 0x5c) */
0, /* test mode ADC Output CODE LSB (reg 0x5d) */
0, /* test mode (reg 0x5e) */
_LM9833,
MODEL_CANON600,
2.0
0x66, /* misc io12 (reg 0x59) */
0x16, /* misc io34 (reg 0x5a) */
0x91, /* misc io56 (reg 0x5b) */
0x01, /* test mode ADC Output CODE MSB (reg 0x5c) */
0, /* test mode ADC Output CODE LSB (reg 0x5d) */
0, /* test mode (reg 0x5e) */
_LM9833,
MODEL_CANON600,
2.0
};
/** Canon N1240U */
/** Canon N1240U/LiDE30 */
static HWDef Hw0x04A9_0x220E =
{
0.72, /* dMaxMotorSpeed (Max_Speed) */
0.36, /* dMaxMoveSpeed (Max_Speed) */
0.72, /* dMaxMotorSpeed (Max_Speed) */
0.30, /* dMaxMoveSpeed (Max_Speed) */
0.0, /* dHighSpeed */
100, /* wIntegrationTimeLowLamp */
100, /* wIntegrationTimeHighLamp */
1200, /* wMotorDpi (Full step DPI) */
512, /* wRAMSize (KB) */
3.75, /* dMinIntegrationTimeLowres (ms) */
5.75, /* dMinIntegrationTimeHighres (ms) */
0, /* wGreenPWMDutyCycleLow (reg 0x2a + 0x2b) */
0, /* wGreenPWMDutyCycleHigh (reg 0x2a + 0x2b) */
100, /* wIntegrationTimeLowLamp */
100, /* wIntegrationTimeHighLamp */
1200, /* wMotorDpi (Full step DPI) */
512, /* wRAMSize (KB) */
3.75, /* dMinIntegrationTimeLowres (ms) */
5.75, /* dMinIntegrationTimeHighres (ms) */
0, /* wGreenPWMDutyCycleLow (reg 0x2a + 0x2b) */
0, /* wGreenPWMDutyCycleHigh (reg 0x2a + 0x2b) */
0x15, /* bSensorConfiguration (0x0b) */
0x4c, /* sensor control settings (reg 0x0c) */
0x2f, /* sensor control settings (reg 0x0d) */
0x00, /* sensor control settings (reg 0x0e) */
0x15, /* bSensorConfiguration (0x0b) */
0x4c, /* sensor control settings (reg 0x0c) */
0x2f, /* sensor control settings (reg 0x0d) */
0x00, /* sensor control settings (reg 0x0e) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* mono (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* mono (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* color (reg 0x0f to 0x18) */
{0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05},
/* color (reg 0x0f to 0x18) */
(_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */
(_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */
0x00, /* bReg 0x27 color mode */
2, /* bReg 0x29 illumination mode */
{ 3, 0, 0, 23, 4000, 0, 0 },
{ 2, 23, 16383, 23, 6500, 23, 4900 },
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
0, /* bOpticBlackStart (reg 0x1c) */
0, /* bOpticBlackEnd (reg 0x1d) */
52, /* wActivePixelsStart (reg 0x1e + 0x1f) */
10586, /* wLineEnd (reg 0x20 + 0x21) */
0x00, /* bReg 0x27 color mode */
2, /* bReg 0x29 illumination mode */
23, /* red lamp on (reg 0x2c + 0x2d) */
16383, /* red lamp off (reg 0x2e + 0x2f) */
23, /* green lamp on (reg 0x30 + 0x31) */
6500, /* green lamp off (reg 0x32 + 0x33) */
23, /* blue lamp on (reg 0x34 + 0x35) */
4900, /* blue lamp off (reg 0x36 + 0x37) */
{ 3, 0, 0, 23, 4000, 0, 0 },
{ 2, 23, 16383, 23, 6500, 23, 4900 },
3, /* stepper motor control (reg 0x45) */
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
0x20, /* steps to reverse when buffer is full reg 0x50) */
0xfc, /* acceleration profile (reg 0x51) */
0, /* lines to process (reg 0x54) */
0x0f, /* kickstart (reg 0x55) */
0x08, /* pwm freq (reg 0x56) */
0x1f, /* pwm duty cycle (reg 0x57) */
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
0, /* bOpticBlackStart (reg 0x1c) */
0, /* bOpticBlackEnd (reg 0x1d) */
52, /* wActivePixelsStart (reg 0x1e + 0x1f) */
10586, /* wLineEnd (reg 0x20 + 0x21) */
0x04, /* Paper sense (reg 0x58) */
23, /* red lamp on (reg 0x2c + 0x2d) */
16383, /* red lamp off (reg 0x2e + 0x2f) */
23, /* green lamp on (reg 0x30 + 0x31) */
6500, /* green lamp off (reg 0x32 + 0x33) */
23, /* blue lamp on (reg 0x34 + 0x35) */
4900, /* blue lamp off (reg 0x36 + 0x37) */
0x66, /* misc io12 (reg 0x59) */
0x16, /* misc io34 (reg 0x5a) */
0x91, /* misc io56 (reg 0x5b) */
0x01, /* test mode ADC Output CODE MSB (reg 0x5c) */
0, /* test mode ADC Output CODE LSB (reg 0x5d) */
0, /* test mode (reg 0x5e) */
_LM9833,
MODEL_CANON1200,
2.0
3, /* stepper motor control (reg 0x45) */
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
0x20, /* steps to reverse when buffer is full reg 0x50) */
0xfc, /* acceleration profile (reg 0x51) */
0, /* lines to process (reg 0x54) */
0x0f, /* kickstart (reg 0x55) */
0x08, /* pwm freq (reg 0x56) */
0x1f, /* pwm duty cycle (reg 0x57) */
0x04, /* Paper sense (reg 0x58) */
0x66, /* misc io12 (reg 0x59) */
0x16, /* misc io34 (reg 0x5a) */
0x91, /* misc io56 (reg 0x5b) */
0x01, /* test mode ADC Output CODE MSB (reg 0x5c) */
0, /* test mode ADC Output CODE LSB (reg 0x5d) */
0, /* test mode (reg 0x5e) */
_LM9833,
MODEL_CANON1200,
2.0
};
/******************** all available combinations *****************************/

Wyświetl plik

@ -42,7 +42,8 @@
* - added UMAX3450 TPA autodetection
* - 0.49 - a_bRegs is now part of the device structure
* - fixed problem in backtracking, when speedup is enabled
* .
* - added usb_UpdateButtonStatus()
* .
* <hr>
* This file is part of the SANE package.
*
@ -95,8 +96,6 @@
/* HEINER: check the tick counts 'cause 1 tick on NT is about 10ms */
static u_long dwCrystalFrequency = 48000000UL;
/** the NatSemi 983x is a big endian chip, and the line protocol data all
* arrives big-endian. This determines if we need to swap to host-order
*/
@ -258,33 +257,31 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay )
/* calculate the current speed */
ffs = regs[0x48] * 256 + regs[0x49];
speed = ((double)dwCrystalFrequency) /(double)((u_long)mclk_div * 32UL *
speed = ((double)CRYSTAL_FREQ) /(double)((u_long)mclk_div * 32UL *
(u_long)mch * (u_long)ffs * hw->wMotorDpi);
DBG( _DBG_INFO2, ">>>> CURRENT MCLK_DIV= %u\n", mclk_div );
DBG( _DBG_INFO2, ">>>> MCH = %u\n", mch );
DBG( _DBG_INFO2, ">>>> FFS = %u\n", ffs );
DBG( _DBG_INFO2, ">>>> HIGH-SPEED = %.3f (%.3f)\n",
speed, hw->dHighSpeed);
/* disabled ? */
if((hw->dHighSpeed == 0.0) || (dev->adj.disableSpeedup != 0)) {
DBG( _DBG_INFO2, " * Speedup disabled or not available!\n" );
min_ffs = 0xffff;
maxf = 0.0;
if( !stay )
return SANE_TRUE;
} else {
min_ffs = (u_short)(dwCrystalFrequency /((u_long)mclk_div * 32UL *
min_ffs = (u_short)(CRYSTAL_FREQ /((u_long)mclk_div * 32UL *
(u_long)mch * hw->dHighSpeed * hw->wMotorDpi));
maxf = (ffs - min_ffs)/4;
if( maxf > 100.0 )
maxf = 100.0;
if( maxf < 5.0 )
maxf = 5.0;
}
DBG( _DBG_INFO2, ">>>> MIN_FFS = %u (%.3f)\n", min_ffs, maxf);
DBG( _DBG_INFO2, ">>>> CURRENT MCLK_DIV = %u\n", mclk_div );
DBG( _DBG_INFO2, ">>>> MCH = %u\n", mch );
DBG( _DBG_INFO2, ">>>> FFS = %u\n", ffs );
DBG( _DBG_INFO2, ">>>> HIGH-SPEED = %.3f (%.3f)\n",
speed, hw->dHighSpeed);
DBG( _DBG_INFO2, ">>>> MIN_FFS = %u (%.3f)\n", min_ffs, maxf);
}
gettimeofday( &start_time, NULL );
dwTicks = start_time.tv_sec + to;
@ -418,7 +415,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
mclk_div = clk->mclk_fast;
wFastFeedStepSize = (u_short)(dwCrystalFrequency /
wFastFeedStepSize = (u_short)(CRYSTAL_FREQ /
((u_long)mclk_div * 8UL * 1 *
dMaxMoveSpeed * 4 * hw->wMotorDpi));
@ -633,7 +630,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
/* Compute fast feed step size, use equation 3 and equation 8
* assumptions: MCLK = 6, Lineratemode (CM=1)
*/
wFastFeedStepSize = (u_short)(dwCrystalFrequency / (mclk_div * 8 * 1 *
wFastFeedStepSize = (u_short)(CRYSTAL_FREQ / (mclk_div * 8 * 1 *
hw->dMaxMotorSpeed * 4 * hw->wMotorDpi));
regs[0x48] = (u_char)(wFastFeedStepSize >> 8);
regs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
@ -702,7 +699,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
if (!value)
return TRUE;
}
wFastFeedStepSize = (WORD)(dwCrystalFrequency / (6UL * 8UL * 1 * Device.HwSetting.dMaxMotorSpeed * 4 *
wFastFeedStepSize = (WORD)(CRYSTAL_FREQ /
(6UL * 8UL * 1 * Device.HwSetting.dMaxMotorSpeed * 4 *
Device.HwSetting.wMotorDpi) * 60 / 78);
regs[0x48] = (u_char)(wFastFeedStepSize >> 8);
regs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
@ -1520,7 +1518,7 @@ static SANE_Bool usb_HasTPA( Plustek_Device *dev )
return SANE_TRUE;
} else
DBG( _DBG_INFO, "EPSON-TPA NOT detected\n" );
if( dev->adj.enableTpa ) {
DBG( _DBG_INFO, "EPSON-TPA usage forced\n" );
return SANE_TRUE;
@ -1557,4 +1555,75 @@ static SANE_Bool usb_HasTPA( Plustek_Device *dev )
return SANE_FALSE;
}
/** function for reading the button states
*/
static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s )
{
u_char mio[3];
SANE_Byte val, mask;
int i, j, bc;
int handle = -1;
SANE_Status status;
Plustek_Device *dev = s->hw;
if (dev->usbDev.Caps.bButtons == 0)
return SANE_FALSE;
status = sanei_access_lock( dev->sane.name, 3 );
if( SANE_STATUS_GOOD != status )
return SANE_FALSE;
if( -1 == dev->fd ) {
status = sanei_usb_open(dev->sane.name, &handle);
if( SANE_STATUS_GOOD != status ) {
sanei_access_unlock( dev->sane.name );
return SANE_FALSE;
}
dev->fd = handle;
}
/* we have to check all 6 misc I/O ports for input configuration*/
mio[0] = dev->usbDev.HwSetting.bReg_0x59;
mio[1] = dev->usbDev.HwSetting.bReg_0x5a;
mio[2] = dev->usbDev.HwSetting.bReg_0x5b;
usbio_ReadReg( dev->fd, 0x07, &val );
if( val == 0 ) {
/* first read clears the status... */
usbio_ReadReg( dev->fd, 0x02, &val );
val >>= 2;
bc = 0;
for( i = 0; i < 3; i++ ) {
DBG( _DBG_INFO2, "Checking MISC IO[%u]=0x%02x\n", i, mio[i] );
mask = 0x01;
for( j = 0; j < 2; j++ ) {
if((mio[i] & mask) == 0) {
DBG( _DBG_INFO2, "* port %u configured as input,"
" status: %s (%u)\n", (i*2)+j+1,
((val & 1)?"PRESSED":"RELEASED"), (OPT_BUTTON_0 + bc));
s->val[OPT_BUTTON_0 + bc].w = val & 1;
bc++;
}
val >>= 1;
mask <<= 4;
}
}
} else {
DBG( _DBG_INFO2, "Scanner NOT idle: 0x%02x\n", val );
}
if( -1 != handle ) {
dev->fd = -1;
sanei_usb_close( handle );
}
sanei_access_unlock( dev->sane.name );
return SANE_TRUE;
}
/* END PLUSTEK-USBHW.C ......................................................*/

Plik diff jest za duży Load Diff

Wyświetl plik

@ -19,7 +19,7 @@
* - 0.46 - no changes
* - 0.47 - cleanup work
* - 0.48 - added support for binary from color scans
* - 0.49 - no changes
* - 0.49 - changed usb_MapDownload
* .
* <hr>
* This file is part of the SANE package.
@ -62,15 +62,15 @@
* <hr>
*/
#define _MAP_SIZE 4096U
#define _MAP_SIZE 4096
static SANE_Byte a_bMap[_MAP_SIZE * 3];
/** adjust acording to brightness and contrast
*/
static void usb_MapAdjust( pPlustek_Device dev )
static void usb_MapAdjust( Plustek_Device *dev )
{
u_long i, tabLen;
int i, tabLen;
double b, c, tmp;
tabLen = _MAP_SIZE;
@ -113,13 +113,13 @@ static void usb_MapAdjust( pPlustek_Device dev )
/**
*/
static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
static SANE_Bool usb_MapDownload( Plustek_Device *dev )
{
pScanDef scanning = &dev->scanning;
pDCapsDef sc = &dev->usbDev.Caps;
int color, maxColor;
int i, iThreshold;
int color;
int i, threshold;
SANE_Byte value;
SANE_Bool fInverse = 0;
@ -137,22 +137,7 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
/* 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;
} else {
color = 1;
maxColor = 2;
}
#else
_VAR_NOT_USED( bDataType );
color = 0;
maxColor = 3;
#endif
for( ; color < maxColor; color++) {
for( color = 0; color < 3; color++) {
/* select color */
value = (color << 2)+2;
@ -166,21 +151,21 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
if((scanning->sParam.bDataType == SCANDATATYPE_BW) ||
(scanning->fGrayFromColor > 7 )) {
iThreshold = (int)((double)scanning->sParam.siThreshold *
threshold = (int)((double)scanning->sParam.brightness *
(_MAP_SIZE/200.0)) + (_MAP_SIZE/2);
iThreshold = _MAP_SIZE - iThreshold;
if(iThreshold < 0)
iThreshold = 0;
if(iThreshold > (int)_MAP_SIZE)
iThreshold = _MAP_SIZE;
threshold = _MAP_SIZE - threshold;
if(threshold < 0)
threshold = 0;
if(threshold > (int)_MAP_SIZE)
threshold = _MAP_SIZE;
DBG(_DBG_INFO, "* Threshold is at %u siThresh=%i\n",
iThreshold, scanning->sParam.siThreshold );
DBG(_DBG_INFO, "* Threshold is at %u brightness=%i\n",
threshold, scanning->sParam.brightness );
for(i = 0; i < iThreshold; i++)
for(i = 0; i < threshold; i++)
a_bMap[color*_MAP_SIZE + i] = 0;
for(i = iThreshold; i < (int)_MAP_SIZE; i++)
for(i = threshold; i < _MAP_SIZE; i++)
a_bMap[color*_MAP_SIZE + i] = 255;
fInverse = 1;
@ -202,7 +187,7 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
DBG( _DBG_INFO, "* Inverting Map\n" );
for( i = 0; i < (int)_MAP_SIZE; i++, pMap++ )
for( i = 0; i < _MAP_SIZE; i++, pMap++ )
map[i] = ~*pMap;
sanei_lm983x_write( dev->fd, 0x06, map, _MAP_SIZE, SANE_FALSE );
@ -211,12 +196,11 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType )
DBG( _DBG_INFO, "* downloading map %u...\n", color );
sanei_lm983x_write( dev->fd, 0x06, a_bMap+color*_MAP_SIZE,
_MAP_SIZE, SANE_FALSE );
}
}
} /* for each color */
DBG( _DBG_INFO, "usb_MapDownload() done.\n" );
return SANE_TRUE;
}

Wyświetl plik

@ -26,6 +26,7 @@
* - 0.48 - minor fixes
* - 0.49 - a_bRegs is now part of the device structure
* - using now PhyDpi.y as selector for the motor MCLK range
* - changed usb_MapDownload prototype
* .
* <hr>
* This file is part of the SANE package.
@ -70,7 +71,7 @@
/** array used to get motor-settings and mclk-settings
*/
static int dpi_ranges[] = { 75,100,150,200,300,400,600,800,1200,2400 };
static int dpi_ranges[] = { 75,100,150,200,300,400,600,800,1200,2400 };
static u_char bMaxITA;
@ -327,7 +328,7 @@ static void usb_GetScanRect( Plustek_Device *dev, pScanParam pParam )
/* Convert pixels to physical dpi based */
pParam->Size.dwValidPixels = pParam->Size.dwPixels *
pParam->PhyDpi.x / pParam->UserDpi.x;
pParam->PhyDpi.x / pParam->UserDpi.x;
/* HEINER: check ADF stuff... */
#if 0
@ -493,7 +494,7 @@ static void usb_PresetStepSize( Plustek_Device *dev, pScanParam pParam )
pHWDef hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
ssize = (u_short)((double)dwCrystalFrequency / ( mclkdiv * 8.0 *
ssize = (u_short)((double)CRYSTAL_FREQ / ( mclkdiv * 8.0 *
(double)m_bCM * hw->dMaxMotorSpeed * 4.0 * (double)hw->wMotorDpi));
regs[0x46] = _HIBYTE( ssize );
@ -553,6 +554,79 @@ static void usb_GetDPD( Plustek_Device *dev )
regs[0x53] = (u_char)(dpd & 0xFF);
}
#define MCLKDIV_SCALING 2
#define _MIN(a,b) ((a) < (b) ? (a) : (b))
#define _MAX(a,b) ((a) > (b) ? (a) : (b))
/**
*/
static int usb_GetMCLKDiv( Plustek_Device *dev )
{
int j, pixelbits, pixelsperline, r;
int minmclk, maxmclk, mclkdiv;
double hdpi, min_int_time;
u_char *regs = dev->usbDev.a_bRegs;
HWDef *hw = &dev->usbDev.HwSetting;
DBG( _DBG_INFO, "usb_GetMCLKDiv()\n" );
r = 8; /* line rate */
if ((regs[0x26] & 7) == 0)
r = 24; /* pixel rate */
/*use high or low res min integration time */
min_int_time = ((regs[0x9]&7) > 2 ? hw->dMinIntegrationTimeLowres:
hw->dMinIntegrationTimeHighres);
minmclk = (int)ceil((double) MCLKDIV_SCALING * CRYSTAL_FREQ *
min_int_time /((double)1000. * r * m_wLineLength));
minmclk = _MAX(minmclk,MCLKDIV_SCALING);
maxmclk = (int)(32.5*MCLKDIV_SCALING + .5);
DBG(_DBG_INFO2,"- lower mclkdiv limit=%f\n",(double)minmclk/MCLKDIV_SCALING);
DBG(_DBG_INFO2,"- upper mclkdiv limit=%f\n",(double)maxmclk/MCLKDIV_SCALING);
/* get the bits per pixel */
switch (regs[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 = regs[0x9] & 0x7;
hdpi = ((j&1)*.5+1)*(j&2?2:1)*(j&4?4:1);
pixelsperline = (int)((256*regs[0x24]+regs[0x25]-256*regs[0x22]-regs[0x23])
*pixelbits/(hdpi * 8));
mclkdiv = (int)ceil((double)MCLKDIV_SCALING * pixelsperline * CRYSTAL_FREQ
/((double) 8. * m_wLineLength * dev->transferRate));
DBG( _DBG_INFO2, "- hdpi = %.3f\n", hdpi );
DBG( _DBG_INFO2, "- pixelbits = %u\n", pixelbits );
DBG( _DBG_INFO2, "- pixelsperline = %u\n", pixelsperline );
DBG( _DBG_INFO2, "- linelen = %u\n", m_wLineLength );
DBG( _DBG_INFO2, "- transferrate = %lu\n", dev->transferRate );
DBG( _DBG_INFO2, "- MCLK Divider = %u\n", mclkdiv/MCLKDIV_SCALING );
mclkdiv = _MAX(mclkdiv,minmclk);
mclkdiv = _MIN(mclkdiv,maxmclk);
DBG( _DBG_INFO2, "- Current MCLK Divider = %u\n", mclkdiv/MCLKDIV_SCALING );
if( dev->transferRate == 2000000 ) {
while (mclkdiv * hdpi < 6.*MCLKDIV_SCALING) {
mclkdiv++;
}
DBG( _DBG_INFO2, "- HIGHSPEED MCLK Divider = %u\n",
mclkdiv/MCLKDIV_SCALING );
}
return mclkdiv;
}
/** 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)
@ -568,6 +642,11 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
DBG( _DBG_INFO, "usb_GetMCLKDivider()\n" );
if( dev->transferRate == 2000000 ) {
int mclkdiv = usb_GetMCLKDiv(dev);
pParam->dMCLK = (double)mclkdiv/MCLKDIV_SCALING;
}
m_dMCLKDivider = pParam->dMCLK;
if (m_dHDPIDivider*m_dMCLKDivider >= 5.3/*6*/)
@ -576,7 +655,9 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
m_bIntTimeAdjust = ceil( 5.3/*6.0*/ / (m_dHDPIDivider*m_dMCLKDivider));
if( pParam->bCalibration == PARAM_Scan ) {
usb_GetMCLKDiv(dev);
/* Compare Integration with USB speed to find the best ITA value */
if( pParam->bBitDepth > 8 ) {
@ -594,7 +675,7 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
if(((hw->motorModel == MODEL_HP) && (sCaps->bCCD == kNECSLIM))/* ||
( regs[0x26] & _ONE_CH_COLOR )*/) {
bMaxITA = (u_char)floor((m_dMCLKDivider + 1) / 2.0);
bMaxITA = (u_char)floor((m_dMCLKDivider + 1) / 2.0);
DBG( _DBG_INFO2, "* MaxITA (HP) = %u\n", bMaxITA );
if( m_bIntTimeAdjust > bMaxITA ) {
@ -605,7 +686,7 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
}
}
DBG( _DBG_INFO2, "* Integration Time Adjust = %u (HDPI=%.3f,MCLKD=%.3f)\n",
m_bIntTimeAdjust, m_dHDPIDivider, m_dMCLKDivider );
m_bIntTimeAdjust, m_dHDPIDivider, m_dMCLKDivider );
regs[0x08] = (u_char)((m_dMCLKDivider - 1) * 2);
regs[0x19] = m_bIntTimeAdjust;
@ -629,7 +710,7 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
* high lamp PWM, use equation 4
*/
dMaxIntegrationTime = hw->dIntegrationTimeHighLamp;
dMaxMCLKDivider = (double)dwCrystalFrequency * dMaxIntegrationTime /
dMaxMCLKDivider = (double)CRYSTAL_FREQ * dMaxIntegrationTime /
(1000 * 8 * m_bCM * m_wLineLength);
/* Determine lamp PWM setting */
@ -666,7 +747,7 @@ static void usb_GetStepSize( Plustek_Device *dev, pScanParam pParam )
m_wStepSize = (u_short)(((u_long) pParam->PhyDpi.y * m_wLineLength *
m_bLineRateColor) / (4 * hw->wMotorDpi));
}
if (m_wStepSize < 2)
m_wStepSize = 2;
@ -780,7 +861,7 @@ static void usb_GetLineLength( Plustek_Device *dev )
m_wLineLength = tr / m_bLineRateColor;
DBG( _DBG_INFO2, "* LineLength=%d, LineRateColor=%u\n",
m_wLineLength, m_bLineRateColor );
m_wLineLength, m_bLineRateColor );
}
/** usb_GetMotorParam
@ -888,15 +969,15 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
}
else /* if(pParam->PhyDpi.x <= 600) */
{
/* HEINER: check ADF stuff... */
#if 0
/* HEINER: check ADF stuff... */
#if 0
if(ScanInf.m_fADF)
{
regs[0x56] = 8;
regs[0x57] = 48;
}
else
#endif
#endif
{
regs[0x56] = 64; /* 2; */
regs[0x57] = 4; /* 48; */
@ -980,15 +1061,14 @@ static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam )
regs[0x4e] = (u_char)floor((m_dwPauseLimit*512.0)/(2.0*hw->wDRAMSize));
if( regs[0x4e] > 1 ) {
if( regs[0x4e] > 1 ) {
regs[0x4e]--;
if(regs[0x4e] > 1)
regs[0x4e]--;
} else
regs[0x4e] = 1;
/*
* resume, when buffer is 2/8 kbytes full (512k/2M memory)
/* resume, when buffer is 2/8 kbytes full (512k/2M memory)
*/
regs[0x4f] = 1;
@ -1103,7 +1183,7 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
if( m_dMCLKDivider < 1.0)
m_dMCLKDivider = 1.0;
m_wFastFeedStepSize = (u_short)(dwCrystalFrequency /
m_wFastFeedStepSize = (u_short)(CRYSTAL_FREQ /
(m_dMCLKDivider * 8 * m_bCM * hw->dMaxMoveSpeed *
4 * hw->wMotorDpi));
/* CIS special ;-) */
@ -1168,11 +1248,23 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
memset( &regs[0x03], 0, 3 );
memset( &regs[0x5f], 0, 0x7f-0x5f+1 );
if(pParam->bCalibration == PARAM_Scan && pParam->bSource != SOURCE_ADF) {
u_short scansteps = (u_short)ceil((double)(pParam->Size.dwPhyLines + 10)*
hw->wMotorDpi / pParam->PhyDpi.y);
DBG( _DBG_INFO, "* Scansteps=%u (%lu*%u/%u)\n", scansteps,
pParam->Size.dwPhyLines, hw->wMotorDpi, pParam->PhyDpi.y );
#if 1
regs[0x4c] = _HIBYTE(scansteps);
regs[0x4d] = _LOBYTE(scansteps);
#endif
}
/* set the merlin registers */
_UIO(sanei_lm983x_write( dev->fd, 0x03, &regs[0x03], 3, SANE_TRUE));
_UIO(sanei_lm983x_write( dev->fd, 0x08, &regs[0x08], 0x7f - 0x08+1, SANE_TRUE));
usleep( 100 );
usleep( 100 );
if( !usbio_WriteReg( dev->fd, 0x07, 0 ))
return SANE_FALSE;
@ -1198,7 +1290,7 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park )
/* Disable home sensor during scan, or the chassis cannot move */
value = ((m_pParam->bCalibration == PARAM_Scan &&
m_pParam->bSource == SOURCE_ADF)? (regs[0x58] & ~7): 0);
m_pParam->bSource == SOURCE_ADF)? (regs[0x58] & ~7): 0);
if(!usbio_WriteReg( dev->fd, 0x58, value ))
return SANE_FALSE;
@ -1237,7 +1329,7 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park )
/* Download map & Shading data */
if(( m_pParam->bCalibration == PARAM_Scan &&
!usb_MapDownload( dev, m_pParam->bDataType)) ||
!usb_MapDownload( dev )) ||
!usb_DownloadShadingData( dev, m_pParam->bCalibration ))
return SANE_FALSE;
@ -1254,9 +1346,11 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park )
dumpregs( dev->fd, NULL );
inches = (u_short)((m_pParam->Origin.y *300UL)/hw->wMotorDpi);
DBG( _DBG_INFO2, ">>> INC=%u, DOY=%u\n", inches, sc->Normal.DataOrigin.y );
DBG( _DBG_INFO2, ">>> INCH=%u, DOY=%u\n", inches, sc->Normal.DataOrigin.y );
if( inches > sc->Normal.DataOrigin.y )
usb_WaitPos( dev, 150, SANE_FALSE );
DBG( _DBG_INFO, "usb_ScanBegin() done.\n" );
return SANE_TRUE;
}
@ -1269,7 +1363,6 @@ static SANE_Bool usb_ScanEnd( Plustek_Device *dev )
DBG( _DBG_INFO, "usbDev_ScanEnd(), start=%u, park=%u\n",
m_fStart, m_fAutoPark );
usbio_ReadReg( dev->fd, 0x07, &value );
if( value == 3 || value != 2 )
usbio_WriteReg( dev->fd, 0x07, 0 );
@ -1284,7 +1377,6 @@ static SANE_Bool usb_ScanEnd( Plustek_Device *dev )
usb_ModuleToHome( dev, SANE_FALSE );
}
return SANE_TRUE;
}
@ -1300,8 +1392,7 @@ static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev )
u_char a_bBand[3];
long dwTicks;
struct timeval t;
u_char *regs = dev->usbDev.a_bRegs;
u_char *regs = dev->usbDev.a_bRegs;
DBG( _DBG_INFO, "usb_IsDataAvailableInDRAM()\n" );
@ -1413,7 +1504,6 @@ static SANE_Bool usb_ScanReadImage( Plustek_Device *dev,
return TRUE;
}
#endif
res = sanei_lm983x_read(dev->fd, 0x00, (u_char *)pBuf, dwSize, SANE_FALSE);
/* check for pressed ESC button, as sanei_lm983x_read() may take some time
@ -1424,17 +1514,16 @@ static SANE_Bool usb_ScanReadImage( Plustek_Device *dev,
}
DBG( _DBG_READ, "usb_ScanReadImage() done, result: %d\n", res );
if( SANE_STATUS_GOOD == res ) {
return SANE_TRUE;
}
DBG( _DBG_ERROR, "usb_ScanReadImage() failed\n" );
return SANE_FALSE;
}
/**
/** calculate the number of pixels per line and lines out of a given
* crop-area. The size of the area is given on a 300dpi base!
*/
static void usb_GetImageInfo( Plustek_Device *dev, pImgDef pInfo, pWinInfo pSize )
{
@ -1443,6 +1532,8 @@ static void usb_GetImageInfo( Plustek_Device *dev, pImgDef pInfo, pWinInfo pSize
pSize->dwPixels = (u_long)pInfo->crArea.cx * pInfo->xyDpi.x / 300UL;
pSize->dwLines = (u_long)pInfo->crArea.cy * pInfo->xyDpi.y / 300UL;
DBG( _DBG_INFO2,"Area: cx=%u, cy=%u\n",pInfo->crArea.cx,pInfo->crArea.cy);
switch( pInfo->wDataType ) {
case COLOR_TRUE48:

Wyświetl plik

@ -73,6 +73,8 @@
* split scanmode and bit-depth
* - 0.49 - improved multi-device capability
* - tweaked some device settings
* - added button support
* - moved AFE stuff to enhanced options
*.
* <hr>
* This file is part of the SANE package.
@ -148,8 +150,10 @@
#include "../include/sane/sanei.h"
#include "../include/sane/saneopts.h"
#define BACKEND_VERSION "0.49-4"
#define BACKEND_VERSION "0.49-5"
#define BACKEND_NAME plustek
#include "../include/sane/sanei_access.h"
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_config.h"
#include "../include/sane/sanei_thread.h"
@ -305,6 +309,7 @@ drvclose( Plustek_Device *dev )
/* don't check the return values, simply do it */
usbDev_stopScan( dev );
usbDev_close ( dev );
sanei_access_unlock( dev->sane.name );
}
dev->fd = -1;
@ -405,6 +410,10 @@ static int reader_process( void *args )
struct SIGACTION act;
sigset_t ignore_set;
Plustek_Scanner *scanner = (Plustek_Scanner *)args;
#ifdef USE_IPC
IPCDef ipc;
Plustek_Device *dev = scanner->hw;
#endif
if( sanei_thread_is_forked()) {
DBG( _DBG_PROC, "reader_process started (forked)\n" );
@ -447,10 +456,22 @@ static int reader_process( void *args )
return SANE_STATUS_IO_ERROR;
}
/* here we read all data from the driver... */
/* prepare for scanning: speed-test, warmup, calibration */
buf = scanner->buf;
status = usbDev_Prepare( scanner->hw, buf );
#ifdef USE_IPC
/* prepare IPC structure */
memset( &ipc, 0, sizeof(ipc));
ipc.transferRate = DEFAULT_RATE;
if( dev->transferRate > 0 && dev->transferRate != DEFAULT_RATE )
ipc.transferRate = dev->transferRate;
/* write ipc back to parent in any case... */
write( scanner->w_pipe, &ipc, sizeof(ipc));
#endif
/* on success, we read all data from the driver... */
if( 0 == status ) {
for( line = 0; line < scanner->params.lines; line++ ) {
@ -471,7 +492,7 @@ static int reader_process( void *args )
scanner->w_pipe = -1;
if((int)status < 0 ) {
DBG( _DBG_ERROR, "read failed, status = %i, errno %i\n",
DBG( _DBG_ERROR,"reader_process: read failed, status = %i, errno %i\n",
(int)status, lerrn );
if( _E_ABORT == (int)status )
return SANE_STATUS_CANCELLED;
@ -527,6 +548,7 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
sanei_thread_sendsig( scanner->reader_pid, SIGKILL );
#endif
}
scanner->reader_pid = 0;
DBG( _DBG_PROC,"reader_process killed\n");
#ifndef HAVE_SETITIMER
@ -580,8 +602,8 @@ static SANE_Status initGammaSettings( Plustek_Scanner *s )
for( j = 0; j < s->gamma_length; j++ ) {
val = (s->gamma_range.max *
pow((double) j / ((double)s->gamma_length - 1.0),
1.0 / gamma ));
pow((double)j / (double)(s->gamma_length-1.0),
1.0 / gamma ));
if( val > s->gamma_range.max )
val = s->gamma_range.max;
@ -636,7 +658,6 @@ static SANE_Status init_options( Plustek_Scanner *s )
s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
/* "Scan Mode" group: */
s->opt[OPT_MODE_GROUP].name = "scanmode-group";
s->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan Mode");
s->opt[OPT_MODE_GROUP].desc = "";
s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
@ -721,7 +742,6 @@ static SANE_Status init_options( Plustek_Scanner *s )
s->val[OPT_PREVIEW].w = 0;
/* "Geometry" group: */
s->opt[OPT_GEOMETRY_GROUP].name = "geometry-group";
s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
s->opt[OPT_GEOMETRY_GROUP].desc = "";
s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
@ -831,7 +851,6 @@ static SANE_Status init_options( Plustek_Scanner *s )
s->opt[OPT_EXT_MODE].cap |= SANE_CAP_INACTIVE;
/* "Device settings" group: */
s->opt[OPT_DEVICE_GROUP].name = "device-settings";
s->opt[OPT_DEVICE_GROUP].title = SANE_I18N("Device-Settings");
s->opt[OPT_DEVICE_GROUP].desc = "";
s->opt[OPT_DEVICE_GROUP].type = SANE_TYPE_GROUP;
@ -873,11 +892,10 @@ static SANE_Status init_options( Plustek_Scanner *s )
s->val[OPT_LAMPOFF_TIMER].w = adj->lampOff;
/* "Analog Frontend" group*/
s->opt[OPT_AFE_GROUP].name = "afe-group";
s->opt[OPT_AFE_GROUP].title = SANE_I18N("Analog frontend");
s->opt[OPT_AFE_GROUP].desc = "";
s->opt[OPT_AFE_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_AFE_GROUP].cap = 0;
s->opt[OPT_AFE_GROUP].cap = SANE_CAP_ADVANCED;
s->opt[OPT_OVR_REDGAIN].name = "red-gain";
s->opt[OPT_OVR_REDGAIN].title = SANE_I18N("Red gain");
@ -958,6 +976,31 @@ static SANE_Status init_options( Plustek_Scanner *s )
s->opt[OPT_OVR_BLUE_LOFF].cap |= SANE_CAP_INACTIVE;
}
/* "Button" group*/
s->opt[OPT_BUTTON_GROUP].title = SANE_I18N("Buttons");
s->opt[OPT_BUTTON_GROUP].desc = "";
s->opt[OPT_BUTTON_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_BUTTON_GROUP].cap = SANE_CAP_ADVANCED;
/* scanner buttons */
for( i = OPT_BUTTON_0; i <= OPT_BUTTON_LAST; i++ ) {
s->opt[i].name = "button";
s->opt[i].title = SANE_I18N("Scanner button");
s->opt[i].desc = SANE_I18N("This options reflects the front pannel "
"scanner button pressed by the user.");
s->opt[i].type = SANE_TYPE_BOOL;
s->opt[i].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
if (i - OPT_BUTTON_0 >= dev->usbDev.Caps.bButtons )
s->opt[i].cap |= SANE_CAP_INACTIVE;
s->opt[i].unit = SANE_UNIT_NONE;
s->opt[i].size = sizeof (SANE_Word);
s->opt[i].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[i].constraint.range = 0;
s->val[i].w = SANE_FALSE;
}
usb_UpdateButtonStatus( s );
return SANE_STATUS_GOOD;
}
@ -1153,6 +1196,7 @@ static SANE_Status attach( const char *dev_name,
dev->sane.vendor = "Plustek";
dev->initialized = -1; /* will be used as index too */
dev->calFile = NULL;
dev->transferRate = DEFAULT_RATE;
memcpy( &dev->adj, &cnf->adj, sizeof(AdjDef));
@ -1176,7 +1220,7 @@ static SANE_Status attach( const char *dev_name,
#endif
/* go ahead and open the scanner device */
handle = usbDev_open( dev, usbDevs );
handle = usbDev_open( dev, usbDevs, SANE_FALSE );
if( handle < 0 ) {
DBG( _DBG_ERROR,"open failed: %d\n", handle );
return SANE_STATUS_IO_ERROR;
@ -1205,8 +1249,8 @@ static SANE_Status attach( const char *dev_name,
DBG( _DBG_INFO, "Model : %s\n", dev->sane.model );
DBG( _DBG_INFO, "Flags : 0x%08lx\n", dev->caps.dwFlag );
dev->max_x = dev->caps.wMaxExtentX*MM_PER_INCH/_MEASURE_BASE;
dev->max_y = dev->caps.wMaxExtentY*MM_PER_INCH/_MEASURE_BASE;
dev->max_x = SANE_FIX(dev->caps.wMaxExtentX*MM_PER_INCH/_MEASURE_BASE);
dev->max_y = SANE_FIX(dev->caps.wMaxExtentY*MM_PER_INCH/_MEASURE_BASE);
/* calculate the size of the resolution list +
* one more to avoid a buffer overflow, then allocate it...
@ -1216,7 +1260,7 @@ static SANE_Status attach( const char *dev_name,
sizeof (SANE_Int));
if (NULL == dev->res_list) {
DBG( _DBG_ERROR, "alloc fail, resolution problem\n" );
DBG( _DBG_ERROR, "calloc failed: %s\n", strerror(errno));
usbDev_close(dev);
return SANE_STATUS_INVAL;
}
@ -1229,10 +1273,10 @@ static SANE_Status attach( const char *dev_name,
}
/* set the limits */
dev->dpi_range.min = _DEF_DPI;
dev->dpi_range.max = dev->usbDev.Caps.OpticDpi.x * 2;
dev->x_range.max = SANE_FIX(dev->max_x);
dev->y_range.max = SANE_FIX(dev->max_y);
dev->dpi_range.min = _DEF_DPI;
dev->dpi_range.max = dev->usbDev.Caps.OpticDpi.x * 2;
dev->x_range.max = SANE_FIX(dev->max_x);
dev->y_range.max = SANE_FIX(dev->max_y);
dev->fd = handle;
drvclose( dev );
@ -1296,6 +1340,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
sanei_lm983x_init();
#endif
sanei_thread_init();
sanei_access_init(STRINGIFY(BACKEND_NAME));
#if defined PACKAGE && defined VERSION
DBG( _DBG_INFO, "Plustek backend V"BACKEND_VERSION", part of "
@ -1328,7 +1373,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
}
while( sanei_config_read( str, sizeof(str), fp)) {
DBG( _DBG_SANE_INIT, ">%s<\n", str );
if( str[0] == '#') /* ignore line comments */
continue;
@ -1342,7 +1387,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
int ival;
double dval;
ival = -1;
decodeVal( str, "warmup", _INT, &config.adj.warmup, &ival);
decodeVal( str, "lampOff", _INT, &config.adj.lampOff, &ival);
@ -1359,7 +1404,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
decodeVal( str, "red_lampoff", _INT, &config.adj.rlampoff,&ival);
decodeVal( str, "green_lampoff", _INT, &config.adj.glampoff,&ival);
decodeVal( str, "blue_lampoff", _INT, &config.adj.blampoff,&ival);
ival = 0;
decodeVal( str, "enableTPA", _INT, &config.adj.enableTpa, &ival);
decodeVal( str, "cacheCalData",
@ -1397,9 +1442,9 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
/* check for sections: */
} else if( 0 == strncmp( str, _SECTION, strlen(_SECTION))) {
char *tmp;
/* new section, try and attach previous device */
if( config.devName[0] != '\0' ) {
attach( config.devName, &config, 0 );
@ -1409,7 +1454,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
" ignored!\n" );
}
}
/* re-initialize the configuration structure */
init_config_struct( &config );
@ -1417,12 +1462,12 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
decodeUsbIDs( str, &tmp );
DBG( _DBG_SANE_INIT, "... next device\n" );
continue;
continue;
} else if( SANE_TRUE == decodeDevName( str, config.devName )) {
continue;
}
/* ignore other stuff... */
DBG( _DBG_SANE_INIT, "ignoring >%s<\n", str );
}
@ -1497,15 +1542,15 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only )
/* already called, so cleanup */
if( devlist )
free( devlist );
free( devlist );
devlist = malloc((num_devices + 1) * sizeof (devlist[0]));
if ( NULL == devlist )
return SANE_STATUS_NO_MEM;
return SANE_STATUS_NO_MEM;
i = 0;
for (dev = first_dev; i < num_devices; dev = dev->next)
devlist[i++] = &dev->sane;
devlist[i++] = &dev->sane;
devlist[i++] = 0;
*device_list = devlist;
@ -1520,20 +1565,20 @@ sane_open( SANE_String_Const devicename, SANE_Handle* handle )
SANE_Status status;
Plustek_Device *dev;
Plustek_Scanner *s;
CnfDef config;
CnfDef config;
DBG( _DBG_SANE_INIT, "sane_open - %s\n", devicename );
if( devicename[0] ) {
for( dev = first_dev; dev; dev = dev->next ) {
for( dev = first_dev; dev; dev = dev->next ) {
if( strcmp( dev->sane.name, devicename ) == 0 )
break;
}
}
if( !dev ) {
memset( &config, 0, sizeof(CnfDef));
status = attach( devicename, &config, &dev );
if( SANE_STATUS_GOOD != status )
return status;
@ -1544,11 +1589,11 @@ sane_open( SANE_String_Const devicename, SANE_Handle* handle )
}
if( !dev )
return SANE_STATUS_INVAL;
return SANE_STATUS_INVAL;
s = malloc (sizeof (*s));
if( NULL == s )
return SANE_STATUS_NO_MEM;
return SANE_STATUS_NO_MEM;
memset(s, 0, sizeof (*s));
s->r_pipe = -1;
@ -1561,9 +1606,8 @@ sane_open( SANE_String_Const devicename, SANE_Handle* handle )
/* insert newly opened handle into list of open handles: */
s->next = first_handle;
first_handle = s;
*handle = s;
*handle = s;
return SANE_STATUS_GOOD;
}
@ -1672,6 +1716,18 @@ sane_control_option( SANE_Handle handle, SANE_Int option,
*(SANE_Word *)value = s->val[option].w;
break;
case OPT_BUTTON_0:
usb_UpdateButtonStatus( s );
case OPT_BUTTON_1:
case OPT_BUTTON_2:
case OPT_BUTTON_3:
case OPT_BUTTON_4:
/* copy the button state */
*(SANE_Word*)value = s->val[option].w;
/* clear the button state */
s->val[option].w = SANE_FALSE;
break;
case OPT_CONTRAST:
case OPT_BRIGHTNESS:
*(SANE_Word *)value =
@ -2129,9 +2185,9 @@ sane_start( SANE_Handle handle )
/* open the driver and get some information about the scanner
*/
dev->fd = usbDev_open( dev, NULL );
dev->fd = usbDev_open( dev, NULL, SANE_TRUE );
if( dev->fd < 0 ) {
DBG( _DBG_ERROR,"sane_start: open failed: %d\n", errno );
DBG( _DBG_ERROR, "sane_start: open failed: %d\n", errno);
if( errno == EBUSY )
return SANE_STATUS_DEVICE_BUSY;
@ -2142,6 +2198,7 @@ sane_start( SANE_Handle handle )
result = usbDev_getCaps( dev );
if( result < 0 ) {
DBG( _DBG_ERROR, "usbDev_getCaps() failed(%d)\n", result);
sanei_access_unlock( dev->sane.name );
usbDev_close( dev );
return SANE_STATUS_IO_ERROR;
}
@ -2207,6 +2264,7 @@ sane_start( SANE_Handle handle )
if( result < 0 ) {
DBG( _DBG_ERROR, "usbDev_getCropInfo() failed(%d)\n", result );
usbDev_close( dev );
sanei_access_unlock( dev->sane.name );
return SANE_STATUS_IO_ERROR;
}
@ -2235,6 +2293,7 @@ sane_start( SANE_Handle handle )
if( result < 0 ) {
DBG( _DBG_ERROR, "usbDev_setScanEnv() failed(%d)\n", result );
usbDev_close( dev );
sanei_access_unlock( dev->sane.name );
return SANE_STATUS_IO_ERROR;
}
@ -2253,6 +2312,7 @@ sane_start( SANE_Handle handle )
if( result < 0 ) {
DBG( _DBG_ERROR, "usbDev_startScan() failed(%d)\n", result );
usbDev_close( dev );
sanei_access_unlock( dev->sane.name );
return SANE_STATUS_IO_ERROR;
}
@ -2265,6 +2325,7 @@ sane_start( SANE_Handle handle )
if( NULL == s->buf ) {
DBG( _DBG_ERROR, "realloc failed\n" );
usbDev_close( dev );
sanei_access_unlock( dev->sane.name );
return SANE_STATUS_NO_MEM;
}
@ -2285,10 +2346,11 @@ sane_start( SANE_Handle handle )
}
/* create reader routine as new process */
s->bytes_read = 0;
s->r_pipe = fds[0];
s->w_pipe = fds[1];
s->reader_pid = sanei_thread_begin( reader_process, s );
s->bytes_read = 0;
s->r_pipe = fds[0];
s->w_pipe = fds[1];
s->ipc_read_done = SANE_FALSE;
s->reader_pid = sanei_thread_begin( reader_process, s );
cancelRead = SANE_FALSE;
@ -2318,9 +2380,43 @@ sane_read( SANE_Handle handle, SANE_Byte *data,
{
Plustek_Scanner *s = (Plustek_Scanner*)handle;
ssize_t nread;
#ifdef USE_IPC
static IPCDef ipc;
unsigned char *buf;
static unsigned long c = 0;
#endif
*length = 0;
#ifdef USE_IPC
/* first try and read IPC... */
if( !s->ipc_read_done ) {
buf = (unsigned char*)&ipc;
for( c = 0; c < sizeof(ipc); ) {
nread = read( s->r_pipe, buf, sizeof(ipc));
if( nread < 0 ) {
if( EAGAIN != errno ) {
do_cancel( s, SANE_TRUE );
return SANE_STATUS_IO_ERROR;
} else {
return SANE_STATUS_GOOD;
}
} else {
c += nread;
buf += nread;
if( c == sizeof(ipc)) {
s->ipc_read_done = SANE_TRUE;
break;
}
}
}
s->hw->transferRate = ipc.transferRate;
DBG( _DBG_INFO, "IPC: Transferrate = %lu Bytes/s\n",
ipc.transferRate );
}
#endif
/* here we read all data from the driver... */
nread = read( s->r_pipe, data, max_length );
DBG( _DBG_READ, "sane_read - read %ld bytes\n", (long)nread );

Wyświetl plik

@ -53,6 +53,8 @@
* - removed function pointer
* - added OPT_BIT_DEPTH
* - 0.49 - added typedef struct DevList
* - added button stuff
* - added transferRate to struct Plustek_Device
* .
* <hr>
* This file is part of the SANE package.
@ -109,6 +111,7 @@
#define _MEASURE_BASE 300UL
#define _DEF_DPI 50
#define DEFAULT_RATE 1000000
/** the default image size
*/
@ -227,6 +230,13 @@ enum {
OPT_OVR_RED_LOFF,
OPT_OVR_GREEN_LOFF,
OPT_OVR_BLUE_LOFF,
OPT_BUTTON_GROUP,
OPT_BUTTON_0,
OPT_BUTTON_1,
OPT_BUTTON_2,
OPT_BUTTON_3,
OPT_BUTTON_4,
OPT_BUTTON_LAST = OPT_BUTTON_4,
NUM_OPTIONS
};
@ -323,6 +333,7 @@ typedef struct Plustek_Device
int fd; /* device handle */
char *name; /* (to avoid compiler warnings!)*/
char *calFile; /* for saving calibration data */
unsigned long transferRate; /* detected USB-Speed in Bytes/s*/
SANE_Device sane; /* info struct */
SANE_Int max_x; /* max XY-extension of the scan-*/
SANE_Int max_y; /* area */
@ -364,10 +375,11 @@ typedef struct Plustek_Scanner
int r_pipe; /* pipe to reader process */
int w_pipe; /* pipe from reader process */
unsigned long bytes_read; /* number of bytes currently read*/
pPlustek_Device hw; /* pointer to current device */
Plustek_Device *hw; /* pointer to current device */
Option_Value val[NUM_OPTIONS];
SANE_Byte *buf; /* the image buffer */
SANE_Bool scanning; /* TRUE during scan-process */
SANE_Bool ipc_read_done; /* TRUE after ipc has been red */
SANE_Parameters params; /* for keeping the parameter */
/************************** gamma tables *********************************/