diff --git a/ChangeLog b/ChangeLog index 8c71565d3..ab04ac442 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-5-28 Gerhard Jaeger + + * doc/sane-plustek_pp.man: Fixed typo. + * doc/sane-plustek.man: Update. + * doc/descriptions/plustek.desc: Update. + * backend/plustek.c backend/plustek.h backend/plustek-usb.c + backend/plustek-usbcal.c backend/plustek-usbcalfile.c + backend/plustek-usbdevs.c backend/plustek-usb.h + backend/plustek-usbhw.c backend/plustek-usbimg.c + backend/plustek-usbio.c backend/plustek-usbmap.c + backend/plustek-usbscan.c backend/plustek-usbshading.c: + Added support for CIS-based sheetfed scanners, namely + TravelScan662. + Added support for saving calibration data for CIS + devices - should speedup CanoScan devices. + 2006-05-28 Wittawat Yamwong * backend/pixma.h: Added #define ENODATA and EPROTO to let the @@ -74,7 +90,7 @@ do_cmd() - simplify timeout handling * backend/fujitsu-scsi.h: increase default timeoutes -2006-05-15 Stéphane Voltz +2006-05-15 St�hane Voltz * backend/genesys_devices.c backend/genesys_gl646.c: tuned HP 2300 geometry description and added a safeguard against failed origin @@ -118,7 +134,7 @@ * backend/genesys_devices.c: Increase length of acceleration slopes for Canon LiDE 35/40/50/60 -2006-04-21 Stéphane Voltz +2006-04-21 St�hane Voltz * backend/genesys.c: add workraound with issue related to asic reset and data scan amount @@ -254,7 +270,7 @@ * doc/descriptions/unsupported.desc: Added Microtek ScanMaker 4850 II and Plustek OpticPro ST 64+. -2006-03-12 Stéphane Voltz +2006-03-12 St�hane Voltz * backend/genesys_gl646.c: removed now unneeded #ifdef in gl646_send_gamma_table. diff --git a/backend/plustek-usb.c b/backend/plustek-usb.c index 6bb4d8b89..e3ccc869e 100644 --- a/backend/plustek-usb.c +++ b/backend/plustek-usb.c @@ -7,7 +7,7 @@ * @brief The interface functions to the USB driver stuff. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -43,6 +43,8 @@ * - 0.50 - minor fix for startup reset * removed unnecessary calls to usbio_ResetLM983x() * 1200DPI CIS devices don't use GrayFromColor any longer + * - 0.51 - added Syscan to the vendor list + * - added SCANFLAG_Calibration handling * . *
* This file is part of the SANE package. @@ -90,22 +92,23 @@ typedef struct { int id; char *desc; + char *desc_alt; } TabDef, *pTabDef; /** to allow different vendors... */ static TabDef usbVendors[] = { - { 0x07B3, "Plustek" }, - { 0x0400, "Mustek" }, /* this in fact is not correct */ - /* but is used for the BearPaws */ - { 0x0458, "KYE/Genius" }, - { 0x03F0, "Hewlett-Packard" }, - { 0x04B8, "Epson" }, - { 0x04A9, "Canon" }, - { 0x1606, "UMAX" }, - { 0x049F, "Compaq" }, - { 0xFFFF, NULL } + { 0x07B3, "Plustek", NULL }, + { 0x0400, "NSC", "Mustek" }, + { 0x0458, "KYE/Genius", NULL }, + { 0x03F0, "Hewlett-Packard", NULL }, + { 0x04B8, "Epson", NULL }, + { 0x04A9, "Canon", NULL }, + { 0x1606, "UMAX", NULL }, + { 0x049F, "Compaq", NULL }, + { 0x0A82, "Syscan", NULL }, + { 0xFFFF, NULL, NULL } }; /** we use at least 8 megs for scanning... */ @@ -170,7 +173,8 @@ static void usb_CheckAndCopyAdjs( Plustek_Device *dev ) /** * assign the values to the structures used by the currently found scanner */ -static void usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) +static void +usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) { char *ptr; char tmp_str1[PATH_MAX]; @@ -252,6 +256,9 @@ static void usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) if( usbVendors[i].id == vendor ) { dev->sane.vendor = usbVendors[i].desc; + if (dev->usbDev.Caps.workaroundFlag & _WAF_USE_ALT_DESC ) + if (usbVendors[i].desc_alt ) + dev->sane.vendor = usbVendors[i].desc_alt; DBG( _DBG_INFO, "Vendor adjusted to: >%s<\n", dev->sane.vendor ); break; } @@ -285,15 +292,16 @@ static void usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) } if( NULL == ptr ) { - sprintf( tmp_str2, "/tmp/%s-%s.cal", + sprintf( tmp_str2, "/tmp/%s-%s", dev->sane.vendor, tmp_str1 ); } else { - sprintf( tmp_str2, "%s/.sane/%s-%s.cal", + sprintf( tmp_str2, "%s/.sane/%s-%s", ptr, dev->sane.vendor, tmp_str1 ); } dev->calFile = strdup( tmp_str2 ); - DBG( _DBG_INFO, "Calibration file-name set to:\n" ); - DBG( _DBG_INFO, ">%s<\n", dev->calFile ); + DBG( _DBG_INFO, "Calibration file-names set to:\n" ); + DBG( _DBG_INFO, ">%s-coarse.cal<\n", dev->calFile ); + DBG( _DBG_INFO, ">%s-fine.cal<\n", dev->calFile ); /* initialize the ASIC registers */ usb_SetScanParameters( dev, &sParam ); @@ -860,57 +868,67 @@ static int usbDev_setMap( Plustek_Device *dev, SANE_Word *map, /** */ -static int usbDev_setScanEnv( Plustek_Device *dev, ScanInfo *si ) +static int +usbDev_setScanEnv( Plustek_Device *dev, ScanInfo *si ) { + ScanDef *scan = &dev->scanning; DCapsDef *caps = &dev->usbDev.Caps; DBG( _DBG_INFO, "usbDev_setScanEnv()\n" ); /* clear all the stuff */ - memset( &dev->scanning, 0, sizeof(ScanDef)); + memset( scan, 0, sizeof(ScanDef)); if((si->ImgDef.dwFlag & SCANDEF_Adf) && (si->ImgDef.dwFlag & SCANDEF_ContinuousScan)) { - dev->scanning.sParam.dMCLK = dMCLK_ADF; + scan->sParam.dMCLK = dMCLK_ADF; } /* Save necessary informations */ - dev->scanning.fGrayFromColor = 0; + scan->fGrayFromColor = 0; - if( si->ImgDef.wDataType == COLOR_256GRAY ) { + /* for some devices and settings, we tweak the physical settings + * how to get the image - but not in calibration mode + */ + if((si->ImgDef.dwFlag & SCANFLAG_Calibration) == 0) { - if( !(si->ImgDef.dwFlag & SCANDEF_Adf) && !usb_IsCISDevice(dev) && - (dev->usbDev.Caps.OpticDpi.x == 1200 && si->ImgDef.xyDpi.x <= 300)) { - dev->scanning.fGrayFromColor = 2; - si->ImgDef.wDataType = COLOR_TRUE24; - DBG( _DBG_INFO, "* Gray from color set!\n" ); - } + if( si->ImgDef.wDataType == COLOR_256GRAY ) { - if( caps->workaroundFlag & _WAF_GRAY_FROM_COLOR ) { - DBG( _DBG_INFO, "* Gray(8-bit) from color set!\n" ); - dev->scanning.fGrayFromColor = 2; - si->ImgDef.wDataType = COLOR_TRUE24; - } + if( !(si->ImgDef.dwFlag & SCANDEF_Adf) && !usb_IsCISDevice(dev) && + (caps->OpticDpi.x == 1200 && si->ImgDef.xyDpi.x <= 300)) { + scan->fGrayFromColor = 2; + si->ImgDef.wDataType = COLOR_TRUE24; + DBG( _DBG_INFO, "* Gray from color set!\n" ); + } - } else if ( si->ImgDef.wDataType == COLOR_GRAY16 ) { - if( caps->workaroundFlag & _WAF_GRAY_FROM_COLOR ) { - DBG( _DBG_INFO, "* Gray(16-bit) from color set!\n" ); - dev->scanning.fGrayFromColor = 2; - si->ImgDef.wDataType = COLOR_TRUE48; - } - } else if ( si->ImgDef.wDataType == COLOR_BW ) { - if( caps->workaroundFlag & _WAF_BIN_FROM_COLOR ) { - DBG( _DBG_INFO, "* Binary from color set!\n" ); - dev->scanning.fGrayFromColor = 10; - si->ImgDef.wDataType = COLOR_TRUE24; + if( caps->workaroundFlag & _WAF_GRAY_FROM_COLOR ) { + DBG( _DBG_INFO, "* Gray(8-bit) from color set!\n" ); + scan->fGrayFromColor = 2; + si->ImgDef.wDataType = COLOR_TRUE24; + } + + } else if ( si->ImgDef.wDataType == COLOR_GRAY16 ) { + if( caps->workaroundFlag & _WAF_GRAY_FROM_COLOR ) { + DBG( _DBG_INFO, "* Gray(16-bit) from color set!\n" ); + scan->fGrayFromColor = 2; + si->ImgDef.wDataType = COLOR_TRUE48; + } + + } else if ( si->ImgDef.wDataType == COLOR_BW ) { + if( caps->workaroundFlag & _WAF_BIN_FROM_COLOR ) { + DBG( _DBG_INFO, "* Binary from color set!\n" ); + scan->fGrayFromColor = 10; + si->ImgDef.wDataType = COLOR_TRUE24; + } } } - usb_SaveImageInfo( dev, &si->ImgDef ); - usb_GetImageInfo ( dev, &si->ImgDef, &dev->scanning.sParam.Size ); - /* Flags */ - dev->scanning.dwFlag = si->ImgDef.dwFlag & - (SCANFLAG_bgr | SCANFLAG_BottomUp | + usb_SaveImageInfo( dev, &si->ImgDef ); + usb_GetImageInfo ( dev, &si->ImgDef, &scan->sParam.Size ); + + /* mask the flags */ + scan->dwFlag = si->ImgDef.dwFlag & + (SCANFLAG_bgr | SCANFLAG_BottomUp | SCANFLAG_Calibration | SCANFLAG_DWORDBoundary | SCANFLAG_RightAlign | SCANFLAG_StillModule | SCANDEF_Adf | SCANDEF_ContinuousScan); @@ -918,27 +936,27 @@ static int usbDev_setScanEnv( Plustek_Device *dev, ScanInfo *si ) DBG( _DBG_INFO, "* Preview Mode set!\n" ); } else { DBG( _DBG_INFO, "* Preview Mode NOT set!\n" ); - dev->scanning.dwFlag |= SCANDEF_QualityScan; + scan->dwFlag |= SCANDEF_QualityScan; } - dev->scanning.sParam.brightness = si->siBrightness; - dev->scanning.sParam.contrast = si->siContrast; + scan->sParam.brightness = si->siBrightness; + scan->sParam.contrast = si->siContrast; - if( dev->scanning.sParam.bBitDepth <= 8 ) - dev->scanning.dwFlag &= ~SCANFLAG_RightAlign; + if( scan->sParam.bBitDepth <= 8 ) + scan->dwFlag &= ~SCANFLAG_RightAlign; - if( dev->scanning.dwFlag & SCANFLAG_DWORDBoundary ) { - if( dev->scanning.fGrayFromColor && dev->scanning.fGrayFromColor < 10) - dev->scanning.dwBytesLine = (dev->scanning.sParam.Size.dwBytes / 3 + 3) & 0xfffffffcUL; + if( scan->dwFlag & SCANFLAG_DWORDBoundary ) { + if( scan->fGrayFromColor && scan->fGrayFromColor < 10) + scan->dwBytesLine = (scan->sParam.Size.dwBytes / 3 + 3) & 0xfffffffcUL; else - dev->scanning.dwBytesLine = (dev->scanning.sParam.Size.dwBytes + 3UL) & 0xfffffffcUL; + scan->dwBytesLine = (scan->sParam.Size.dwBytes + 3UL) & 0xfffffffcUL; } else { - if( dev->scanning.fGrayFromColor && dev->scanning.fGrayFromColor < 10) - dev->scanning.dwBytesLine = dev->scanning.sParam.Size.dwBytes / 3; + if( scan->fGrayFromColor && scan->fGrayFromColor < 10) + scan->dwBytesLine = scan->sParam.Size.dwBytes / 3; else - dev->scanning.dwBytesLine = dev->scanning.sParam.Size.dwBytes; + scan->dwBytesLine = scan->sParam.Size.dwBytes; } /* on CIS based devices we have to reconfigure the illumination @@ -946,72 +964,73 @@ static int usbDev_setScanEnv( Plustek_Device *dev, ScanInfo *si ) */ usb_AdjustCISLampSettings( dev, SANE_TRUE ); - if( dev->scanning.dwFlag & SCANFLAG_BottomUp) - dev->scanning.lBufAdjust = -(long)dev->scanning.dwBytesLine; + if( scan->dwFlag & SCANFLAG_BottomUp) + scan->lBufAdjust = -(long)scan->dwBytesLine; else - dev->scanning.lBufAdjust = dev->scanning.dwBytesLine; + scan->lBufAdjust = scan->dwBytesLine; /* LM9831 has a BUG in 16-bit mode, * so we generate pseudo 16-bit data from 8-bit */ - if( dev->scanning.sParam.bBitDepth > 8 ) { + if( scan->sParam.bBitDepth > 8 ) { if( _LM9831 == dev->usbDev.HwSetting.chip ) { - dev->scanning.sParam.bBitDepth = 8; - dev->scanning.dwFlag |= SCANFLAG_Pseudo48; - dev->scanning.sParam.Size.dwBytes >>= 1; + scan->sParam.bBitDepth = 8; + scan->dwFlag |= SCANFLAG_Pseudo48; + scan->sParam.Size.dwBytes >>= 1; } } /* Source selection */ - if( dev->scanning.sParam.bSource == SOURCE_Reflection ) { + if( scan->sParam.bSource == SOURCE_Reflection ) { - dev->usbDev.pSource = &dev->usbDev.Caps.Normal; - dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + + dev->usbDev.pSource = &caps->Normal; + scan->sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Normal.lLeft; - dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + + scan->sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Normal.lUp; - } else if( dev->scanning.sParam.bSource == SOURCE_Transparency ) { + } else if( scan->sParam.bSource == SOURCE_Transparency ) { - dev->usbDev.pSource = &dev->usbDev.Caps.Positive; - dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + + dev->usbDev.pSource = &caps->Positive; + scan->sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Positive.lLeft; - dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + + scan->sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Positive.lUp; - } else if( dev->scanning.sParam.bSource == SOURCE_Negative ) { + } else if( scan->sParam.bSource == SOURCE_Negative ) { - dev->usbDev.pSource = &dev->usbDev.Caps.Negative; - dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + + dev->usbDev.pSource = &caps->Negative; + scan->sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Negative.lLeft; - dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + + scan->sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Negative.lUp; } else { dev->usbDev.pSource = &dev->usbDev.Caps.Adf; - dev->scanning.sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + + scan->sParam.Origin.x += dev->usbDev.pSource->DataOrigin.x + (u_long)dev->usbDev.Normal.lLeft; - dev->scanning.sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + + scan->sParam.Origin.y += dev->usbDev.pSource->DataOrigin.y + (u_long)dev->usbDev.Normal.lUp; } - if( dev->scanning.sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { - if( dev->scanning.dwFlag & SCANDEF_ContinuousScan ) + if( scan->dwFlag & SCANDEF_ContinuousScan ) dev->usbDev.fLastScanIsAdf = SANE_TRUE; else dev->usbDev.fLastScanIsAdf = SANE_FALSE; } - return 0; + return 0; } /** */ -static int usbDev_stopScan( Plustek_Device *dev ) +static int +usbDev_stopScan( Plustek_Device *dev ) { DBG( _DBG_INFO, "usbDev_stopScan()\n" ); @@ -1031,7 +1050,8 @@ static int usbDev_stopScan( Plustek_Device *dev ) /** */ -static int usbDev_startScan( Plustek_Device *dev ) +static int +usbDev_startScan( Plustek_Device *dev ) { ScanDef *scan = &dev->scanning; DBG( _DBG_INFO, "usbDev_startScan()\n" ); @@ -1066,6 +1086,10 @@ static int usbDev_startScan( Plustek_Device *dev ) m_fStart = m_fFirst = SANE_TRUE; m_fAutoPark = (scan->dwFlag&SCANFLAG_StillModule)?SANE_FALSE:SANE_TRUE; + if( usb_IsSheetFedDevice(dev)) + if(usb_InCalibrationMode(dev)) + m_fAutoPark = SANE_FALSE; + usb_StopLampTimer( dev ); return 0; } @@ -1075,7 +1099,8 @@ static int usbDev_startScan( Plustek_Device *dev ) * first we perform the calibration step, and then we read the image * line for line */ -static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf ) +static int +usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf ) { int result; SANE_Bool use_alt_cal = SANE_FALSE; @@ -1088,13 +1113,11 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf ) /* check the current position of the sensor and move it back * to it's home position if necessary... */ - usb_ModuleStatus( dev ); + if( !usb_IsSheetFedDevice(dev)) + usb_SensorStatus( dev ); - /* the CanoScan CIS devices need special handling... */ - if((dev->usbDev.vendor == 0x04A9) && - (dev->usbDev.product==0x2206 || dev->usbDev.product==0x2207 || - dev->usbDev.product==0x220D || dev->usbDev.product==0x220E || - dev->usbDev.product==0x2220)) { + /* CIS devices need special handling... */ + if( usb_IsCISDevice(dev)) { use_alt_cal = SANE_TRUE; } else { @@ -1116,15 +1139,17 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf ) if( SANE_TRUE != result ) { DBG( _DBG_ERROR, "calibration failed!!!\n" ); - return result; + return _E_ABORT; } if( dev->adj.cacheCalData ) usb_SaveCalData( dev ); DBG( _DBG_INFO, "calibration done.\n" ); + if( usb_InCalibrationMode(dev)) + return 0; - if( !( scan->dwFlag & SCANFLAG_Scanning )) { + if( !(scan->dwFlag & SCANFLAG_Scanning)) { usleep( 10 * 1000 ); @@ -1342,7 +1367,8 @@ static int usbDev_Prepare( Plustek_Device *dev, SANE_Byte *buf ) /** as the name says, read one line... */ -static int usbDev_ReadLine( Plustek_Device *dev ) +static int +usbDev_ReadLine( Plustek_Device *dev ) { int wrap; u_long cur; diff --git a/backend/plustek-usb.h b/backend/plustek-usb.h index 9b42a6b71..98dd17c0a 100644 --- a/backend/plustek-usb.h +++ b/backend/plustek-usb.h @@ -7,7 +7,7 @@ * @brief Main defines for the USB devices. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -40,6 +40,10 @@ * - 0.50 - cleanup * - removed obsolete _WAF_BLACKFINE * - added MODEL_CANON_LIDE25 + * - 0.51 - added _WAF_MISC_IO_BUTTONS plus _BUTTON stuff + * - added _WAF_USE_ALT_DESC + * - added DEVCAPSFLAG_SheetFed + * - added dpi_thresh and lineend to motor structure * . *
* This file is part of the SANE package. @@ -181,9 +185,6 @@ typedef struct { #define GAIN_Target 65535UL -#define DRAM_UsedByAsic8BitMode 216 /* in KB */ -#define DRAM_UsedByAsic16BitMode 196 /*192*/ /* in KB */ - /** Chip-types */ typedef enum _CHIPSET { @@ -229,7 +230,8 @@ enum _DEVCAPSFLAG DEVCAPSFLAG_Negative = 0x0004, DEVCAPSFLAG_TPA = 0x0006, DEVCAPSFLAG_Adf = 0x0008, - DEVCAPSFLAG_LargeTPA = 0x0010 + DEVCAPSFLAG_LargeTPA = 0x0010, + DEVCAPSFLAG_SheetFed = 0x0020 }; /** to allow some workarounds */ @@ -244,7 +246,9 @@ enum _WORKAROUNDS _WAF_SKIP_FINE = 0x00000020, /* skip the fine calbration */ _WAF_SKIP_WHITEFINE = 0x00000040, /* skip the fine white calbration */ _WAF_BIN_FROM_COLOR = 0x00000080, /* generate binary & gray images */ - _WAF_GRAY_FROM_COLOR = 0x00000100 /* from color scans */ + _WAF_GRAY_FROM_COLOR = 0x00000100, /* from color scans */ + _WAF_MISC_IO_BUTTONS = 0x00000200, /* special handling for buttons */ + _WAF_USE_ALT_DESC = 0x00000400 /* use alternate manufacturer */ }; /** for lamps connected to the misc I/O pins*/ @@ -259,14 +263,27 @@ enum _LAMPS _MIO6 = 0x0020 }; +#define _BUTTON_SHIFT 16 +#define _BUTTON_MASK 0xFF0000 +#define _TPA_SHIFT 8 +#define _TPA_MASK 0xFF00 + +enum _BUTTONS +{ + _NO_BUTTON = 0, + _PORT0 = ((_MIO1 | _MIO2) << _BUTTON_SHIFT), + _PORT1 = ((_MIO3 | _MIO4) << _BUTTON_SHIFT), + _PORT2 = ((_MIO5 | _MIO6) << _BUTTON_SHIFT) +}; + /** for encoding a misc I/O register as TPA */ -#define _TPA(register) ((u_long)(register << 16)) +#define _TPA(register) ((u_long)(register << _TPA_SHIFT)) /** Mask to check for available TPA */ -#define _HAS_TPA(flag) (flag & 0xFFFF0000) +#define _HAS_TPA(flag) (flag & _TPA_MASK) /** Get the TPA misc I/O register */ -#define _GET_TPALAMP(flag) (flag >> 16) +#define _GET_TPALAMP(flag) ((flag >> _TPA_SHIFT) & 0xFF) /** motor types */ typedef enum @@ -284,6 +301,7 @@ typedef enum MODEL_CANON_LIDE25, /**< for CanoScan LiDE25 */ MODEL_UMAX, /**< for UMAX 3400/3450 */ MODEL_UMAX1200, /**< for UMAX 5400 */ + MODEL_TSCAN, /**< for Syscan Travelscan */ MODEL_LAST } eModelDef; @@ -325,10 +343,11 @@ enum SCANFLAG SCANFLAG_DWORDBoundary = 0x00020000, SCANFLAG_RightAlign = 0x00040000, SCANFLAG_StillModule = 0x00080000, - SCANFLAG_StartScan = 0x40000000, - SCANFLAG_Scanning = 0x20020000, SCANFLAG_Pseudo48 = 0x08000000, - SCANFLAG_SampleY = 0x04000000 + SCANFLAG_SampleY = 0x04000000, + SCANFLAG_Calibration = 0x10000000, + SCANFLAG_Scanning = 0x20020000, + SCANFLAG_StartScan = 0x40000000 }; typedef struct Origins @@ -347,7 +366,6 @@ typedef struct SrcAttr short DarkShadOrgY; /**< if the device has a dark calibration strip */ XY Size; /**< Scanning width/height, in 300 DPI base. */ XY MinDpi; /**< Minimum dpi supported for scanning */ - u_char bMinDataType; /**< Minimum data type supports */ } SrcAttrDef; @@ -635,14 +653,17 @@ typedef struct { u_char pwm_duty_fast; /**< PWM duty during fast movement */ u_char mclk_fast; /**< MCLK during fast movement */ - /** - * here we define some ranges for better supporting - * non-Plustek devices with it's different hardware - * we can set the MCLK and the motor PWM stuff for color - * and gray modes (8bit and 14/16bit modes) - * 0 1 2 3 4 5 6 7 8 9 - * <= 75 <=100 <=150 <=200 <=300 <=400 <=600 <= 800 <=1200 <=2400DPI - */ + u_short dpi_thresh; + u_short lineend; + + /** + * here we define some ranges for better supporting + * non-Plustek devices with it's different hardware + * we can set the MCLK and the motor PWM stuff for color + * and gray modes (8bit and 14/16bit modes) + * 0 1 2 3 4 5 6 7 8 9 + * <= 75 <=100 <=150 <=200 <=300 <=400 <=600 <= 800 <=1200 <=2400DPI + */ MDef motor_sets[_MAX_CLK]; /**< motor PWM settings during scan */ double color_mclk_8[_MAX_CLK]; /**< MCLK settings for color scan */ double color_mclk_16[_MAX_CLK]; /**< MCLK settings for color (16bit) scan*/ diff --git a/backend/plustek-usbcal.c b/backend/plustek-usbcal.c index 47cc0ea18..7feb48369 100644 --- a/backend/plustek-usbcal.c +++ b/backend/plustek-usbcal.c @@ -7,7 +7,7 @@ * @brief Calibration routines for CanoScan CIS devices. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger
+ * Copyright (C) 2001-2006 Gerhard Jaeger
* Large parts Copyright (C) 2003 Christopher Montgomery * * Montys' comment: @@ -45,6 +45,8 @@ * lamp coarse calibration * - added also speedtest * - fixed segfault in fine calibration + * - 0.51 - added fine calibration cache + * - usb_SwitchLamp() now really switches off the sensor * * This file is part of the SANE package. * @@ -97,20 +99,29 @@ static int strip_state = 0; /** depending on the strip state, the sensor is moved to the shading position * and the lamp ist switched on */ -static int cano_PrepareToReadWhiteCal( Plustek_Device *dev ) +static int +cano_PrepareToReadWhiteCal( Plustek_Device *dev, SANE_Bool mv2shading_pos ) { - HWDef *hw = &dev->usbDev.HwSetting; + SANE_Bool goto_shading_pos = SANE_TRUE; + HWDef *hw = &dev->usbDev.HwSetting; switch (strip_state) { case 0: - if(!usb_ModuleToHome( dev, SANE_TRUE )) { - DBG( _DBG_ERROR, "cano_PrepareToReadWhiteCal() failed\n" ); - return _E_LAMP_NOT_IN_POS; + if( !usb_IsSheetFedDevice(dev)) { + if(!usb_ModuleToHome( dev, SANE_TRUE )) { + DBG( _DBG_ERROR, "cano_PrepareToReadWhiteCal() failed\n" ); + return _E_LAMP_NOT_IN_POS; + } + } else { + goto_shading_pos = mv2shading_pos; } - if( !usb_ModuleMove(dev, MOVE_Forward, - (u_long)dev->usbDev.pSource->ShadingOriginY)) { - DBG( _DBG_ERROR, "cano_PrepareToReadWhiteCal() failed\n" ); - return _E_LAMP_NOT_IN_POS; + + if( goto_shading_pos ) { + if( !usb_ModuleMove(dev, MOVE_Forward, + (u_long)dev->usbDev.pSource->ShadingOriginY)) { + DBG( _DBG_ERROR, "cano_PrepareToReadWhiteCal() failed\n" ); + return _E_LAMP_NOT_IN_POS; + } } break; case 2: @@ -127,12 +138,14 @@ static int cano_PrepareToReadWhiteCal( Plustek_Device *dev ) return 0; } -/** +/** also here, depending on the strip state, the sensor will be moved to + * the shading position and the lamp will be switched off */ -static int cano_PrepareToReadBlackCal( Plustek_Device *dev ) +static int +cano_PrepareToReadBlackCal( Plustek_Device *dev ) { if( strip_state == 0 ) - if(cano_PrepareToReadWhiteCal(dev)) + if(cano_PrepareToReadWhiteCal(dev, SANE_FALSE)) return SANE_FALSE; if( strip_state != 2 ) { @@ -142,7 +155,8 @@ static int cano_PrepareToReadBlackCal( Plustek_Device *dev ) */ if( dev->usbDev.pSource->DarkShadOrgY >= 0 ) { - usb_ModuleToHome( dev, SANE_TRUE ); + if( !usb_IsSheetFedDevice(dev)) + usb_ModuleToHome( dev, SANE_TRUE ); usb_ModuleMove ( dev, MOVE_Forward, (u_long)dev->usbDev.pSource->DarkShadOrgY ); dev->usbDev.a_bRegs[0x45] &= ~0x10; @@ -159,9 +173,10 @@ static int cano_PrepareToReadBlackCal( Plustek_Device *dev ) return 0; } -/** +/** according to the strip-state we switch the lamp on */ -static int cano_LampOnAfterCalibration( Plustek_Device *dev ) +static int +cano_LampOnAfterCalibration( Plustek_Device *dev ) { HWDef *hw = &dev->usbDev.HwSetting; @@ -231,10 +246,11 @@ cano_adjLampSetting( u_short *min, u_short *max, u_short *off, u_short val ) * [Monty changes]: On the CanoScan at least, the default lamp * settings are several *hundred* percent too high and vary from * scanner-to-scanner by 20-50%. This is only for CIS devices - * where the lamp_off parameter is adjustable; I'd make it more general, + * where the lamp_off parameter is adjustable; I'd make it more general, * but I only have the CIS hardware to test. */ -static int cano_AdjustLightsource( Plustek_Device *dev ) +static int +cano_AdjustLightsource( Plustek_Device *dev ) { char tmp[40]; int i; @@ -250,17 +266,16 @@ static int cano_AdjustLightsource( Plustek_Device *dev ) DBG( _DBG_INFO, "cano_AdjustLightsource()\n" ); - if( !(hw->bReg_0x26 & _ONE_CH_COLOR)) { + if( !usb_IsCISDevice(dev)) { DBG( _DBG_INFO, "- function skipped, CCD device!\n" ); - - if( !usb_Wait4Warmup( dev )) { - DBG( _DBG_ERROR, "cano_AdjustLightsource() - CANCEL detected\n" ); - return SANE_FALSE; - } - return SANE_TRUE; + + /* HEINER: we might have to tweak the PWM for the lamps */ + return SANE_TRUE; } - /* define the strip to scan for coarse calibration; done at 300dpi */ + /* define the strip to scan for coarse calibration + * done at optical resolution. + */ m_ScanParam.Size.dwLines = 1; m_ScanParam.Size.dwPixels = scaps->Normal.Size.x * scaps->OpticDpi.x / 300UL; @@ -341,7 +356,8 @@ static int cano_AdjustLightsource( Plustek_Device *dev ) for (dwLoop2 = dwDiv, dwR = dwG = dwB = 0; dwLoop2; dwLoop2--, dw++) { if( m_ScanParam.bDataType == SCANDATATYPE_Color ) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + + if( usb_IsCISDevice(dev)) { dwR += ((u_short*)scanbuf)[dw]; dwG += ((u_short*)scanbuf) [dw+m_ScanParam.Size.dwPhyPixels+1]; @@ -410,7 +426,7 @@ static int cano_AdjustLightsource( Plustek_Device *dev ) if((res_r == 10) && (res_g == 10) && (res_b == 10)) break; - /* we raise the gain for channel, that have been limited */ + /* we raise the gain for channels, that have been limited */ #ifdef _TWEAK_GAIN if( res_r == 10 ) { if( dev->usbDev.a_bRegs[0x3b] < 0xf) @@ -436,7 +452,7 @@ static int cano_AdjustLightsource( Plustek_Device *dev ) DBG(_DBG_INFO, "* 10 times limit reached, still too dark!!!\n"); break; } - usb_AdjustLamps(dev); + usb_AdjustLamps(dev, SANE_TRUE); } DBG( _DBG_INFO, "* red_lamp_on = %u\n", hw->red_lamp_on ); @@ -486,7 +502,8 @@ cano_adjGainSetting( u_char *min, u_char *max, u_char *gain,u_long val ) * * adjLightsource, above, steals most of this function's thunder. */ -static SANE_Bool cano_AdjustGain( Plustek_Device *dev ) +static SANE_Bool +cano_AdjustGain( Plustek_Device *dev ) { char tmp[40]; int i = 0, adj = 1; @@ -524,10 +541,8 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev ) m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2; - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color) m_ScanParam.Size.dwBytes *=3; - } m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart * 300UL / scaps->OpticDpi.x); @@ -579,7 +594,7 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev ) /* do some averaging... */ for (dwLoop2 = dwDiv, dwR=dwG=dwB=0; dwLoop2; dwLoop2--, dw++) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { dwR += ((u_short*)scanbuf)[dw]; dwG += ((u_short*)scanbuf) [dw+m_ScanParam.Size.dwPhyPixels+1]; @@ -636,8 +651,9 @@ static SANE_Bool cano_AdjustGain( Plustek_Device *dev ) /** */ -static int cano_GetNewOffset( Plustek_Device *dev, u_long *val, int channel, - signed char *low, signed char *now, signed char *high ) +static int +cano_GetNewOffset( Plustek_Device *dev, u_long *val, int channel, + signed char *low, signed char *now, signed char *high ) { /* if we're too black, we're likely off the low end */ if( val[channel] <= 16 ) { @@ -677,7 +693,8 @@ static int cano_GetNewOffset( Plustek_Device *dev, u_long *val, int channel, Plustek's example code disagrees with NatSemi's docs; going by the docs works better, I will assume the docs are correct. --Monty */ -static int cano_AdjustOffset( Plustek_Device *dev ) +static int +cano_AdjustOffset( Plustek_Device *dev ) { char tmp[40]; int i, adj; @@ -709,17 +726,15 @@ static int cano_AdjustOffset( Plustek_Device *dev ) m_ScanParam.Size.dwLines = 1; m_ScanParam.Size.dwPixels = scaps->Normal.Size.x*scaps->OpticDpi.x/300UL; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) dwPixels = m_ScanParam.Size.dwPixels; else - dwPixels = (u_long)(hw->bOpticBlackEnd - hw->bOpticBlackStart ); + 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 ) { + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color) m_ScanParam.Size.dwBytes *= 3; - } m_ScanParam.Origin.x = (u_short)((u_long)hw->bOpticBlackStart * 300UL / dev->usbDev.Caps.OpticDpi.x); @@ -759,7 +774,7 @@ static int cano_AdjustOffset( Plustek_Device *dev ) for (dw = 0; dw < dwPixels; dw++) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { r = ((u_short*)scanbuf)[dw]; g = ((u_short*)scanbuf)[dw+m_ScanParam.Size.dwPhyPixels+1]; @@ -841,15 +856,13 @@ static int cano_AdjustOffset( Plustek_Device *dev ) /** usb_AdjustDarkShading * fine calibration part 1 - * */ -static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev ) +static SANE_Bool +cano_AdjustDarkShading( Plustek_Device *dev, u_short cal_dpi ) { char tmp[40]; 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; @@ -860,27 +873,8 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev ) if( usb_IsEscPressed()) return SANE_FALSE; - m_ScanParam = scan->sParam; - -#if 0 - if( m_ScanParam.PhyDpi.x > 75) - m_ScanParam.Size.dwLines = 64; - else -#endif - m_ScanParam.Size.dwLines = 32; - - 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; - } - + usb_PrepareFineCal( dev, &m_ScanParam, cal_dpi ); m_ScanParam.bCalibration = PARAM_DarkShading; - m_ScanParam.dMCLK = dMCLK; sprintf( tmp, "fine-dark.raw" ); dumpPicInit( &m_ScanParam, tmp ); @@ -903,7 +897,7 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev ) if( scan->sParam.bDataType == SCANDATATYPE_Color ) { stepW = m_ScanParam.Size.dwPhyPixels; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) step = m_ScanParam.Size.dwPhyPixels + 1; else step = (m_ScanParam.Size.dwPhyPixels*3) + 1; @@ -913,14 +907,14 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev ) red = 0; green = 0; blue = 0; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) bufp = ((u_short *)scanbuf)+i; else bufp = ((u_short *)scanbuf)+(i*3); for( j=0; jbReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { red += *bufp; bufp+=step; green += *bufp; bufp+=step; blue += *bufp; bufp+=step; @@ -991,13 +985,12 @@ static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev ) * fine calibration part 2 - read the white calibration area and calculate * the gain coefficient for each pixel */ -static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) +static SANE_Bool +cano_AdjustWhiteShading( Plustek_Device *dev, u_short cal_dpi ) { char tmp[40]; 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; @@ -1008,27 +1001,8 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) if( usb_IsEscPressed()) return SANE_FALSE; - m_ScanParam = scan->sParam; -#if 0 - if( m_ScanParam.PhyDpi.x > 75) - m_ScanParam.Size.dwLines = 64; - else -#endif - m_ScanParam.Size.dwLines = 32; - - 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; - } - + usb_PrepareFineCal( dev, &m_ScanParam, cal_dpi ); m_ScanParam.bCalibration = PARAM_WhiteShading; - m_ScanParam.dMCLK = dMCLK; sprintf( tmp, "fine-white.raw" ); DBG( _DBG_INFO2, "FINE WHITE Calibration Strip: %s\n", tmp ); @@ -1060,7 +1034,7 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) if( scan->sParam.bDataType == SCANDATATYPE_Color ) { stepW = m_ScanParam.Size.dwPhyPixels; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) step = m_ScanParam.Size.dwPhyPixels + 1; else step = (m_ScanParam.Size.dwPhyPixels*3) + 1; @@ -1070,14 +1044,14 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) red = 0; green = 0; blue = 0; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) bufp = ((u_short *)scanbuf)+i; else bufp = ((u_short *)scanbuf)+(i*3); for( j=0; jbReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { red += *bufp; bufp+=step; green += *bufp; bufp+=step; blue += *bufp; bufp+=step; @@ -1099,8 +1073,6 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) a_wWhiteShading[i+stepW*2] = (blue > 65535 ? 65535:blue ); } - if(usb_HostSwap()) - usb_Swap(a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2 * 3 ); } else { step = m_ScanParam.Size.dwPhyPixels + 1; @@ -1117,8 +1089,6 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) a_wWhiteShading[i]= (gray > 65535 ? 65535:gray); } - if(usb_HostSwap()) - usb_Swap(a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2 ); memcpy( a_wWhiteShading + m_ScanParam.Size.dwPhyPixels, a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2); @@ -1126,6 +1096,11 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2); } + if(usb_HostSwap()) + usb_Swap(a_wWhiteShading, m_ScanParam.Size.dwPhyPixels * 2 * 3 ); + + usb_SaveCalSetShading( dev, &m_ScanParam ); + usb_line_statistics( "White", a_wWhiteShading, m_ScanParam.Size.dwPhyPixels, scan->sParam.bDataType == SCANDATATYPE_Color?1:0); @@ -1135,8 +1110,11 @@ static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev ) /** the entry function for the CIS calibration stuff. */ -static int cano_DoCalibration( Plustek_Device *dev ) +static int +cano_DoCalibration( Plustek_Device *dev ) { + u_short dpi, idx, idx_end; + SANE_Bool skip_fine; ScanDef *scan = &dev->scanning; HWDef *hw = &dev->usbDev.HwSetting; DCapsDef *scaps = &dev->usbDev.Caps; @@ -1147,18 +1125,24 @@ static int cano_DoCalibration( Plustek_Device *dev ) DBG( _DBG_INFO, "cano_DoCalibration()\n" ); if( _IS_PLUSTEKMOTOR(hw->motorModel)){ - DBG( _DBG_ERROR, "altCalibration can't work with this Plustek motor control setup\n" ); + DBG( _DBG_ERROR, "altCalibration can't work with this " + "Plustek motor control setup\n" ); return SANE_FALSE; /* can't cal this */ } /* Don't allow calibration settings from the other driver to confuse our use of * a few of its functions. */ - scaps->workaroundFlag &= ~_WAF_SKIP_WHITEFINE; - scaps->workaroundFlag &= ~_WAF_SKIP_FINE; - scaps->workaroundFlag &= ~_WAF_BYPASS_CALIBRATION; + scaps->workaroundFlag &= ~_WAF_SKIP_WHITEFINE; + scaps->workaroundFlag &= ~_WAF_SKIP_FINE; + scaps->workaroundFlag &= ~_WAF_BYPASS_CALIBRATION; - usb_SpeedTest( dev ); + if( !dev->adj.cacheCalData ) + usb_SpeedTest( dev ); + + /* here we handle that warmup stuff for CCD devices */ + if( !usb_AutoWarmup( dev )) + return SANE_FALSE; /* Set the shading position to undefined */ strip_state = 0; @@ -1167,14 +1151,18 @@ static int cano_DoCalibration( Plustek_Device *dev ) usb_SetMCLK( dev, &scan->sParam ); if( !scan->skipCoarseCalib ) { + + if( !usb_Wait4ScanSample( dev )) + return SANE_FALSE; + DBG( _DBG_INFO2, "###### ADJUST LAMP (COARSE)#######\n" ); - if( cano_PrepareToReadWhiteCal(dev)) + if( cano_PrepareToReadWhiteCal(dev, SANE_TRUE)) return SANE_FALSE; dev->usbDev.a_bRegs[0x45] &= ~0x10; if( !cano_AdjustLightsource(dev)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); - return _E_INTERNAL; + return SANE_FALSE; } DBG( _DBG_INFO2, "###### ADJUST OFFSET (COARSE) ####\n" ); @@ -1183,46 +1171,96 @@ static int cano_DoCalibration( Plustek_Device *dev ) if( !cano_AdjustOffset(dev)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); - return _E_INTERNAL; + return SANE_FALSE; } DBG( _DBG_INFO2, "###### ADJUST GAIN (COARSE)#######\n" ); - if(cano_PrepareToReadWhiteCal(dev)) + if(cano_PrepareToReadWhiteCal(dev, SANE_FALSE)) return SANE_FALSE; if( !cano_AdjustGain(dev)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); - return _E_INTERNAL; + return SANE_FALSE; } } else { strip_state = 1; DBG( _DBG_INFO2, "###### COARSE calibration skipped #######\n" ); } - DBG( _DBG_INFO2, "###### ADJUST DARK (FINE) ########\n" ); - if(cano_PrepareToReadBlackCal(dev)) - return SANE_FALSE; + skip_fine = SANE_FALSE; + idx_end = 2; + if( dev->adj.cacheCalData || usb_IsSheetFedDevice(dev)) { - dev->usbDev.a_bRegs[0x45] |= 0x10; - if( !cano_AdjustDarkShading(dev)) { - DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); - return _E_INTERNAL; + skip_fine = usb_FineShadingFromFile(dev); + + /* we recalibrate in any case ! */ + if( usb_InCalibrationMode(dev)) { + skip_fine = SANE_FALSE; + idx_end = DIVIDER+1; + + } else if( usb_IsSheetFedDevice(dev)) { + + /* we only to the calibration upon request !*/ + if( !skip_fine ) { + DBG( _DBG_INFO2, "SHEET-FED device, skip fine calibration!\n" ); + skip_fine = SANE_TRUE; + scaps->workaroundFlag |= _WAF_BYPASS_CALIBRATION; + } + } } - DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" ); - if(cano_PrepareToReadWhiteCal(dev)) - return SANE_FALSE; + if( !skip_fine ) { - if(!usb_ModuleToHome( dev, SANE_TRUE )) - return SANE_FALSE; + for( idx = 1; idx < idx_end; idx++ ) { - if( !usb_ModuleMove(dev, MOVE_Forward, - (u_long)dev->usbDev.pSource->ShadingOriginY)) { - return _E_INTERNAL; - } - if( !cano_AdjustWhiteShading(dev)) { - DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); - return _E_INTERNAL; + dpi = 0; + if( usb_InCalibrationMode(dev)) + dpi = usb_get_res( scaps->OpticDpi.x, idx ); + + DBG( _DBG_INFO2, "###### ADJUST DARK (FINE) ########\n" ); + if(cano_PrepareToReadBlackCal(dev)) + return SANE_FALSE; + + dev->usbDev.a_bRegs[0x45] |= 0x10; + if( !cano_AdjustDarkShading(dev, dpi)) { + DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); + return SANE_FALSE; + } + + DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" ); + if(cano_PrepareToReadWhiteCal(dev, SANE_FALSE)) + return SANE_FALSE; + + if( !usb_IsSheetFedDevice(dev)) { + if(!usb_ModuleToHome( dev, SANE_TRUE )) + return SANE_FALSE; + + if( !usb_ModuleMove(dev, MOVE_Forward, + (u_long)dev->usbDev.pSource->ShadingOriginY)) { + return SANE_FALSE; + } + } + if( !cano_AdjustWhiteShading(dev, dpi)) { + DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); + return SANE_FALSE; + } + + /* force to go back */ + strip_state = 0; + } + } else { + DBG( _DBG_INFO2, "###### FINE calibration skipped #######\n" ); + + dev->usbDev.a_bRegs[0x45] |= 0x10; + strip_state = 2; + + m_ScanParam = scan->sParam; + usb_GetPhyPixels( dev, &m_ScanParam ); + + usb_line_statistics( "Dark", a_wDarkShading, m_ScanParam.Size.dwPhyPixels, + m_ScanParam.bDataType == SCANDATATYPE_Color?1:0); + usb_line_statistics( "White", a_wWhiteShading, m_ScanParam.Size.dwPhyPixels, + m_ScanParam.bDataType == SCANDATATYPE_Color?1:0); } /* Lamp on if it's not */ @@ -1231,7 +1269,8 @@ static int cano_DoCalibration( Plustek_Device *dev ) /* home the sensor after calibration */ - usb_ModuleToHome( dev, SANE_TRUE ); + if( !usb_IsSheetFedDevice(dev)) + usb_ModuleToHome( dev, SANE_TRUE ); scan->fCalibrated = SANE_TRUE; DBG( _DBG_INFO, "cano_DoCalibration() done\n" ); @@ -1241,9 +1280,9 @@ static int cano_DoCalibration( Plustek_Device *dev ) DBG( _DBG_INFO, "REG[0x3c] = %u\n", dev->usbDev.a_bRegs[0x3c] ); DBG( _DBG_INFO, "REG[0x3d] = %u\n", dev->usbDev.a_bRegs[0x3d] ); DBG( _DBG_INFO, "Static Offset:\n" ); - DBG( _DBG_INFO, "REG[0x38] = %u\n", dev->usbDev.a_bRegs[0x38] ); - DBG( _DBG_INFO, "REG[0x39] = %u\n", dev->usbDev.a_bRegs[0x39] ); - DBG( _DBG_INFO, "REG[0x3a] = %u\n", dev->usbDev.a_bRegs[0x3a] ); + DBG( _DBG_INFO, "REG[0x38] = %i\n", dev->usbDev.a_bRegs[0x38] ); + DBG( _DBG_INFO, "REG[0x39] = %i\n", dev->usbDev.a_bRegs[0x39] ); + DBG( _DBG_INFO, "REG[0x3a] = %i\n", dev->usbDev.a_bRegs[0x3a] ); DBG( _DBG_INFO, "-------------------------\n" ); return SANE_TRUE; diff --git a/backend/plustek-usbcalfile.c b/backend/plustek-usbcalfile.c index b90d24285..8f2f87cde 100644 --- a/backend/plustek-usbcalfile.c +++ b/backend/plustek-usbcalfile.c @@ -6,7 +6,7 @@ /** @file plustek-usbcalfile.c * @brief Functions for saving/restoring calibration settings * - * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.46 - first version @@ -14,6 +14,8 @@ * - 0.48 - no changes * - 0.49 - a_bRegs is now part of the device structure * - 0.50 - cleanup + * - 0.51 - added functions for saving, reading and restoring + * fine calibration data * . *
* This file is part of the SANE package. @@ -55,7 +57,7 @@ * If you do not wish that, delete this exception notice. *
*/ - + typedef struct { u_long red_light_on; u_long red_light_off; @@ -65,10 +67,10 @@ typedef struct { u_long blue_light_off; u_long green_pwm_duty; -} LightCtrl, *pLightCtrl; +} LightCtrl; typedef struct { - u_short version; + u_short version; u_short red_gain; u_short green_gain; @@ -80,9 +82,14 @@ typedef struct { LightCtrl light; -} CalData, *pCalData; +} CalData; -#define _PT_CF_VERSION 0x0001 +/* our shading buffers */ +static u_short a_wWhiteShading[_SHADING_BUF] = {0}; +static u_short a_wDarkShading[_SHADING_BUF] = {0}; + +/* the version the the calibration files */ +#define _PT_CF_VERSION 0x0002 /** function to read a text file and returns the string which starts which * 'id' string. @@ -93,7 +100,8 @@ typedef struct { * @param res - where to store the result upon success * @return SANE_TRUE on success, SANE_FALSE on any error */ -static SANE_Bool usb_ReadSpecLine( FILE *fp, char *id, char* res ) +static SANE_Bool +usb_ReadSpecLine( FILE *fp, char *id, char* res ) { char tmp[1024]; char *ptr; @@ -107,12 +115,13 @@ static SANE_Bool usb_ReadSpecLine( FILE *fp, char *id, char* res ) /* roam through the file and examine each line... */ while( !feof( fp )) { + memset( tmp, 0, sizeof(tmp)); if( NULL != fgets( tmp, 1024, fp )) { if( 0 == strncmp( tmp, id, strlen(id))) { ptr = &tmp[strlen(id)]; - if( '\0' == *ptr ) + if( '\0' == *ptr ) break; strcpy( res, ptr ); @@ -121,23 +130,28 @@ static SANE_Bool usb_ReadSpecLine( FILE *fp, char *id, char* res ) } } } - return SANE_FALSE; } -/** +/** function to read data from a file and excluding certain stuff like + * the version lines + * @param fp - file pointer of file to read + * @param except - what to exclude + * @return Pointer to the allocated memory for the data, NULL on any error. */ -static char *usb_ReadOtherLines( FILE *fp, char *except ) +static char* +usb_ReadOtherLines( FILE *fp, char *except ) { char tmp[1024]; char *ptr, *ptr_base; + int ignore; int len; if( 0 != fseek( fp, 0L, SEEK_END)) return NULL; len = ftell(fp); - + /* rewind file pointer */ if( 0 != fseek( fp, 0L, SEEK_SET)) return NULL; @@ -148,34 +162,141 @@ static char *usb_ReadOtherLines( FILE *fp, char *except ) ptr = (char*)malloc(len); if( NULL == ptr ) return NULL; - - ptr_base = ptr; + + ptr_base = ptr; *ptr = '\0'; + ignore = 0; + /* roam through the file and examine each line... */ while( !feof( fp )) { if( NULL != fgets( tmp, 1024, fp )) { - if( 0 == strncmp( tmp, "version=", 8 )) + /* we ignore the version line... */ + if( 0 == strncmp( tmp, "version=", 8 )) continue; - if( 0 != strncmp( tmp, except, strlen(except))) { + if( !ignore ) { + if(0 != strncmp(tmp, except, strlen(except))) { - if( strlen( tmp ) > 0 ) { - strcpy( ptr, tmp ); - ptr += strlen(tmp); - *ptr = '\0'; + if( strlen( tmp ) > 0 ) { + strcpy( ptr, tmp ); + ptr += strlen(tmp); + *ptr = '\0'; + } + } else { + ignore = 1; } } + + /* newline in tmp string resets ignore flag */ + if( strrchr(tmp, '\n')) { + ignore = 0; + } } } - return ptr_base; + return ptr_base; } /** */ -static void usb_RestoreCalData( Plustek_Device *dev, CalData *cal ) +static SANE_Bool +usb_ReadSamples( FILE *fp, char *which, u_long *dim, u_short *buffer ) { + char *p, *next, *rb; + char tmp[1024+30]; + int ignore, diml, c; + u_long val; + + /* rewind file pointer */ + if( 0 != fseek( fp, 0L, SEEK_SET)) + return SANE_FALSE; + + ignore = 0; + diml = 0; + c = 0; + rb = tmp; + *dim = 0; + + /* roam through the file and examine each line... */ + while( !feof( fp )) { + + if( NULL != fgets( rb, 1024, fp )) { + + /* we ignore the version line... */ + if( 0 == strncmp( tmp, "version=", 8 )) + continue; + + p = tmp; + if( !ignore && diml == 0) { + if(0 == strncmp(tmp, which, strlen(which))) { + + /* get dimension */ + diml = strtol(&tmp[strlen(which)], NULL, 10); + p = strchr( &tmp[strlen(which)], ':' ); + p++; + } else { + ignore = 1; + } + } + + /* parse the values... */ + if( !ignore ) { + + rb = tmp; + while( *p ) { + val = strtoul( p, &next, 10 ); + + /* check for error condition */ + if( val == 0 ) { + if( p == next ) { + if( c+1 == diml ) { + *dim = diml; + return SANE_TRUE; + } + break; + } + } + + buffer[c] = (u_short)val; + + /* more values? */ + if( *next == ',') { + p = next+1; + c++; + } else { + p = next; + } + /* reached the end? */ + if( *next == '\0' ) { + + /* we probably have only parsed a part of a value + * so we copy that back to the input buffer and + * parse it the next time... + */ + if( c < diml ) { + sprintf( tmp, "%u", buffer[c] ); + rb = &tmp[strlen(tmp)]; + } + } + } + } + + /* newline in tmp string resets ignore flag */ + if( strrchr(tmp, '\n')) { + ignore = 0; + } + } + } + return SANE_FALSE; +} + +/** + */ +static void +usb_RestoreCalData( Plustek_Device *dev, CalData *cal ) +{ + HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; regs[0x3b] = (u_char)cal->red_gain; @@ -202,11 +323,19 @@ static void usb_RestoreCalData( Plustek_Device *dev, CalData *cal ) regs[0x35] = _LOBYTE((u_short)cal->light.blue_light_on); regs[0x36] = _HIBYTE((u_short)cal->light.blue_light_off); regs[0x37] = _LOBYTE((u_short)cal->light.blue_light_off); + + hw->red_lamp_on = (u_short)cal->light.red_light_on; + hw->red_lamp_off = (u_short)cal->light.red_light_off; + hw->green_lamp_on = (u_short)cal->light.green_light_on; + hw->green_lamp_off = (u_short)cal->light.green_light_off; + hw->blue_lamp_on = (u_short)cal->light.blue_light_on; + hw->blue_lamp_off = (u_short)cal->light.blue_light_off; } /** */ -static void usb_CreatePrefix( Plustek_Device *dev, char *pfx ) +static void +usb_CreatePrefix( Plustek_Device *dev, char *pfx, SANE_Bool add_bitdepth ) { char bd[5]; ScanDef *scanning = &dev->scanning; @@ -226,12 +355,14 @@ static void usb_CreatePrefix( Plustek_Device *dev, char *pfx ) else strcat( pfx, "gray" ); - strcat( pfx, bd ); + if( add_bitdepth ) + strcat( pfx, bd ); } /** function to read and set the calibration data from external file */ -static SANE_Bool usb_ReadAndSetCalData( Plustek_Device *dev ) +static SANE_Bool +usb_ReadAndSetCalData( Plustek_Device *dev ) { char pfx[20]; char tmp[1024]; @@ -243,17 +374,23 @@ static SANE_Bool usb_ReadAndSetCalData( Plustek_Device *dev ) DBG( _DBG_INFO, "usb_ReadAndSetCalData()\n" ); + if( usb_InCalibrationMode(dev)) { + DBG( _DBG_INFO, "- we are in calibration mode!\n" ); + return SANE_FALSE; + } + if( NULL == dev->calFile ) { DBG( _DBG_ERROR, "- No calibration filename set!\n" ); return SANE_FALSE; } - DBG( _DBG_INFO, "- Reading calibration data from file\n"); - DBG( _DBG_INFO, " %s\n", dev->calFile ); + sprintf( tmp, "%s-coarse.cal", dev->calFile ); + DBG( _DBG_INFO, "- Reading coarse calibration data from file\n"); + DBG( _DBG_INFO, " %s\n", tmp ); - fp = fopen( dev->calFile, "r" ); + fp = fopen( tmp, "r" ); if( NULL == fp ) { - DBG( _DBG_ERROR, "File %s not found\n", dev->calFile ); + DBG( _DBG_ERROR, "File %s not found\n", tmp ); return SANE_FALSE; } @@ -277,7 +414,7 @@ static SANE_Bool usb_ReadAndSetCalData( Plustek_Device *dev ) return SANE_FALSE; } - usb_CreatePrefix( dev, pfx ); + usb_CreatePrefix( dev, pfx, SANE_TRUE ); ret = SANE_FALSE; if( usb_ReadSpecLine( fp, pfx, tmp )) { @@ -307,12 +444,13 @@ static SANE_Bool usb_ReadAndSetCalData( Plustek_Device *dev ) /** */ -static void usb_PrepCalData( Plustek_Device *dev, CalData *cal ) +static void +usb_PrepCalData( Plustek_Device *dev, CalData *cal ) { u_char *regs = dev->usbDev.a_bRegs; memset( cal, 0, sizeof(CalData)); - cal->version = _PT_CF_VERSION; + cal->version = _PT_CF_VERSION; cal->red_gain = (u_short)regs[0x3b]; cal->green_gain = (u_short)regs[0x3c]; @@ -333,9 +471,11 @@ static void usb_PrepCalData( Plustek_Device *dev, CalData *cal ) /** function to save/update the calibration data */ -static void usb_SaveCalData( Plustek_Device *dev ) +static void +usb_SaveCalData( Plustek_Device *dev ) { char pfx[20]; + char fn[1024]; char tmp[1024]; char set_tmp[1024]; char *other_tmp; @@ -356,11 +496,14 @@ static void usb_SaveCalData( Plustek_Device *dev ) DBG( _DBG_ERROR, "- No calibration filename set!\n" ); return; } - DBG( _DBG_INFO, "- Saving calibration data to file\n" ); - DBG( _DBG_INFO, " %s\n", dev->calFile ); + + sprintf( fn, "%s-coarse.cal", dev->calFile ); + DBG( _DBG_INFO, "- Saving coarse calibration data to file\n" ); + DBG( _DBG_INFO, " %s\n", fn ); usb_PrepCalData ( dev, &cal ); - usb_CreatePrefix( dev, pfx ); + usb_CreatePrefix( dev, pfx, SANE_TRUE ); + DBG( _DBG_INFO2, "- PFX: >%s<\n", pfx ); sprintf( set_tmp, "%s%u,%u,%u,%u,%u,%u," "%lu,%lu,%lu,%lu,%lu,%lu,%lu\n", pfx, @@ -374,7 +517,7 @@ static void usb_SaveCalData( Plustek_Device *dev ) /* read complete old file if compatible... */ other_tmp = NULL; - fp = fopen( dev->calFile, "r+" ); + fp = fopen( fn, "r+" ); if( NULL != fp ) { if( usb_ReadSpecLine( fp, "version=", tmp )) { @@ -383,6 +526,7 @@ static void usb_SaveCalData( Plustek_Device *dev ) if( 1 == sscanf( tmp, "0x%04hx", &version )) { if( version == cal.version ) { + DBG( _DBG_INFO, "- Versions do match\n" ); /* read the rest... */ @@ -398,9 +542,9 @@ static void usb_SaveCalData( Plustek_Device *dev ) } fclose( fp ); } - fp = fopen( dev->calFile, "w+" ); + fp = fopen( fn, "w+" ); if( NULL == fp ) { - DBG( _DBG_ERROR, "- Cannot create file %s\n", dev->calFile ); + DBG( _DBG_ERROR, "- Cannot create file %s\n", fn ); DBG( _DBG_ERROR, "- -> %s\n", strerror(errno)); if( other_tmp ) free( other_tmp ); @@ -420,4 +564,275 @@ static void usb_SaveCalData( Plustek_Device *dev ) DBG( _DBG_INFO, "usb_SaveCalData() done.\n" ); } +/** + */ +static void +usb_SaveFineCalData( Plustek_Device *dev, int dpi, + u_short *dark, u_short *white, u_long vals ) +{ + char pfx[30]; + char fn[1024]; + char tmp[1024]; + char *other_tmp; + u_short version; + u_long i; + FILE *fp; + + if( NULL == dev->calFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return; + } + + sprintf( fn, "%s-fine.cal", dev->calFile ); + DBG( _DBG_INFO, "- Saving fine calibration data to file\n" ); + DBG( _DBG_INFO, " %s\n", fn ); + + usb_CreatePrefix( dev, pfx, SANE_FALSE ); + sprintf( tmp, "%s:%u", pfx, dpi ); + strcpy( pfx, tmp ); + DBG( _DBG_INFO2, "- PFX: >%s<\n", pfx ); + + /* read complete old file if compatible... */ + other_tmp = NULL; + fp = fopen( fn, "r+" ); + if( NULL != fp ) { + + if( usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + + if( 1 == sscanf( tmp, "0x%04hx", &version )) { + + if( version == _PT_CF_VERSION ) { + DBG( _DBG_INFO, "- Versions do match\n" ); + + /* read the rest... */ + other_tmp = usb_ReadOtherLines( fp, pfx ); + } else { + DBG( _DBG_INFO2, "- Versions do not match (0x%04x)\n", version ); + } + } else { + DBG( _DBG_INFO2, "- cannot decode version\n" ); + } + } else { + DBG( _DBG_INFO2, "- Version not found\n" ); + } + fclose( fp ); + } + + fp = fopen( fn, "w+" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "- Cannot create file %s\n", fn ); + return; + } + + /* rewrite the file again... */ + fprintf( fp, "version=0x%04X\n", _PT_CF_VERSION ); + + if( other_tmp ) { + fprintf( fp, "%s", other_tmp ); + free( other_tmp ); + } + + fprintf( fp, "%s:dark:dim=%lu:", pfx, vals ); + for( i=0; icalFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return SANE_FALSE; + } + + sprintf( tmp, "%s-fine.cal", dev->calFile ); + DBG( _DBG_INFO, "- Reading fine calibration data from file\n"); + DBG( _DBG_INFO, " %s\n", tmp ); + + *dim_d = *dim_w = 0; + + fp = fopen( tmp, "r" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "File %s not found\n", tmp ); + return SANE_FALSE; + } + + /* check version */ + if( !usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_ERROR, "Could not find version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + if( 1 != sscanf( tmp, "0x%04hx", &version )) { + DBG( _DBG_ERROR, "Could not decode version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + if( version != _PT_CF_VERSION ) { + DBG( _DBG_ERROR, "Versions do not match!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + usb_CreatePrefix( dev, pfx, SANE_FALSE ); + + sprintf( tmp, "%s:%u:%s:dim=", pfx, dpi, "dark" ); + if( !usb_ReadSamples( fp, tmp, dim_d, dark )) { + DBG( _DBG_ERROR, "Error reading dark-calibration data!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + sprintf( tmp, "%s:%u:%s:dim=", pfx, dpi, "white" ); + if( !usb_ReadSamples( fp, tmp, dim_w, white )) { + DBG( _DBG_ERROR, "Error reading white-calibration data!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + fclose( fp ); + return SANE_TRUE; +} + +/** + */ +static void +usb_get_shading_part(u_short *buf, u_long offs, u_long src_len, int dst_len) +{ + u_short *p_src, *p_dst; + int i, j; + + if (src_len == 0 || dst_len == 0) + return; + + p_dst = buf; + for (i=0; i<3; i++) { + + p_src = buf + src_len * i + offs; + + for (j=0; jscanning; + ScanParam *sp = &scan->sParam; + u_short xdpi; + u_long dim_w, dim_d, offs; + + xdpi = usb_SetAsicDpiX( dev, sp->UserDpi.x ); + + if( !usb_ReadFineCalData( dev, xdpi, &dim_d, a_wDarkShading, + &dim_w, a_wWhiteShading)) { + return SANE_FALSE; + } + + /* now we need to get the correct part of the line... */ + dim_d /= 3; + dim_w /= 3; + + offs = ((u_long)sp->Origin.x * xdpi) / 300; + + usb_GetPhyPixels( dev, sp ); + + DBG( _DBG_INFO2, "FINE Calibration from file:\n" ); + DBG( _DBG_INFO2, "XDPI = %u\n", xdpi ); + DBG( _DBG_INFO2, "Dim = %lu\n", dim_d ); + DBG( _DBG_INFO2, "Pixels = %lu\n", sp->Size.dwPixels ); + DBG( _DBG_INFO2, "PhyPixels = %lu\n", sp->Size.dwPhyPixels ); + DBG( _DBG_INFO2, "Origin.X = %u\n", sp->Origin.x ); + DBG( _DBG_INFO2, "Offset = %lu\n", offs ); + + usb_get_shading_part(a_wDarkShading, offs, dim_d, sp->Size.dwPhyPixels); + usb_get_shading_part(a_wWhiteShading, offs, dim_w, sp->Size.dwPhyPixels); + + return SANE_TRUE; +} + +/** function to save the fine calibration results and to set the correct part + * of the calibration buffers for storing in the device + * @param dev - the almigthy device structure + * @param tmp_sp - intermediate scan parameter + */ +static void +usb_SaveCalSetShading( Plustek_Device *dev, ScanParam *tmp_sp ) +{ + ScanParam *sp = &dev->scanning.sParam; + u_short xdpi; + u_long offs; + + if( !dev->adj.cacheCalData ) + return; + + /* save the values */ + xdpi = usb_SetAsicDpiX( dev, tmp_sp->UserDpi.x ); + + usb_SaveFineCalData( dev, xdpi, a_wDarkShading, + a_wWhiteShading, tmp_sp->Size.dwPixels*3 ); + + /* now we need to get the correct part of the line... */ + xdpi = usb_SetAsicDpiX( dev, sp->UserDpi.x ); + offs = ((u_long)sp->Origin.x * xdpi) / 300; + usb_GetPhyPixels( dev, sp ); + + DBG( _DBG_INFO2, "FINE Calibration area after saving:\n" ); + DBG( _DBG_INFO2, "XDPI = %u\n", xdpi ); + DBG( _DBG_INFO2, "Dim = %lu\n", tmp_sp->Size.dwPixels ); + DBG( _DBG_INFO2, "Pixels = %lu\n", sp->Size.dwPixels ); + DBG( _DBG_INFO2, "PhyPixels = %lu\n", sp->Size.dwPhyPixels ); + DBG( _DBG_INFO2, "Origin.X = %u\n", sp->Origin.x ); + DBG( _DBG_INFO2, "Offset = %lu\n", offs ); + + if (!usb_InCalibrationMode(dev)) { + + usb_get_shading_part( a_wDarkShading, offs, + tmp_sp->Size.dwPixels, sp->Size.dwPhyPixels ); + usb_get_shading_part( a_wWhiteShading, offs, + tmp_sp->Size.dwPixels, sp->Size.dwPhyPixels ); + + memcpy( tmp_sp, sp, sizeof(ScanParam)); + tmp_sp->bBitDepth = 16; + + usb_GetPhyPixels( dev, tmp_sp ); + } +} + /* END PLUSTEK-USBCALFILE.C .................................................*/ diff --git a/backend/plustek-usbdevs.c b/backend/plustek-usbdevs.c index 378b83745..c10a22893 100644 --- a/backend/plustek-usbdevs.c +++ b/backend/plustek-usbdevs.c @@ -7,7 +7,7 @@ * @brief Here we have our USB device definitions. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -62,6 +62,9 @@ * - fixed CanoScan N650U settings * - fixed CanoScan N670U settings, see (bugreport #302738) * - added high-speed setting for HP2200 + * - 0.51 - tweaked CanoScan N1220U settings again + * - added settings for Syscan Travelscan 662 + * - tweaked settings for Bearpaw 1200 * *
* This file is part of the SANE package. @@ -124,15 +127,13 @@ static DCapsDef Cap0x07B3_0x0017_0 = {0, 93}, /* DataOrigin (X: 0, Y: 8mm from home) */ 0, -1, /* ShadingOriginY, DarkShadOrgY */ {2550, 3508}, /* Size */ - {50, 50}, /* MinDpi */ - COLOR_BW /* bMinDataType */ + {50, 50} /* MinDpi */ }, { /* Positive */ {1040 + 15, 744 - 32},/* DataOrigin (X: 7cm + 1.8cm, Y: 8mm + 5.5cm)*/ 543, -1, /* ShadingOriginY (Y: 8mm + 3.8cm) */ {473, 414}, /* Size (X: 4cm, Y: 3.5cm) */ - {150, 150}, /* MinDpi */ - COLOR_TRUE24 /* bMinDataType */ + {150, 150} /* MinDpi */ }, { /* Negative */ {1004 + 55, 744 + 12}, /* DataOrigin (X: 7cm + 1.5cm, Y: 8mm + 5.5cm)*/ @@ -143,15 +144,13 @@ static DCapsDef Cap0x07B3_0x0017_0 = /*543*/, -1, /* ShadingOriginY (Y: 8mm + 3.8cm) */ {567, 414}, /* Size (X: 4.8cm, Y: 3.5cm) */ - {150, 150}, /* MinDpi */ - COLOR_TRUE24 /* bMinDataType */ + {150, 150} /* MinDpi */ }, { /* Adf */ {0, 95}, /* DataOrigin (X: 0, Y: 8mm from home) */ 0, -1, /* ShadingOriginY, DarkShadOrgY */ {2550, 3508}, /* Size */ - {50, 50}, /* MinDpi */ - COLOR_BW /* bMinDataType */ + {50, 50} /* MinDpi */ }, {600, 600}, /* OpticDpi */ DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, /* wFlags */ @@ -169,10 +168,10 @@ static DCapsDef Cap0x07B3_0x0017_0 = */ static DCapsDef Cap0x07B3_0x0015_0 = { - {{0, 93}, 0, -1, {2550, 3508}, {50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, {473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, {567, 414}, {150, 150}, COLOR_TRUE24 }, - {{0, 95}, 0, -1, {2550, 3508}, {50, 50}, COLOR_BW }, + {{0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, {473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, {567, 414}, {150, 150}}, + {{0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, 0, SENSORORDER_rgb, @@ -184,10 +183,10 @@ static DCapsDef Cap0x07B3_0x0015_0 = */ static DCapsDef Cap0x07B3_0x0014_0 = { - {{0, 93}, 0, -1, {2550, 3508}, {50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, {473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, {567, 414}, {150, 150}, COLOR_TRUE24 }, - {{0, 95}, 0, -1, {2550, 3508}, {50, 50}, COLOR_BW }, + {{0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, {473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, {567, 414}, {150, 150}}, + {{0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, 0, SENSORORDER_rgb, @@ -199,10 +198,10 @@ static DCapsDef Cap0x07B3_0x0014_0 = */ static DCapsDef Cap0x07B3_0x0007_0 = { - {{0, 124}, 36, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{1040, 744}, 543, -1, { 473, 414 }, {150, 150}, COLOR_TRUE24 }, - {{1004, 744}, 543, -1, { 567, 414 }, {150, 150}, COLOR_TRUE24 }, - {{0, 95}, 0, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, + {{0, 124}, 36, -1, {2550, 3508}, { 50, 50 }}, + {{1040, 744}, 543, -1, { 473, 414 }, {150, 150}}, + {{1004, 744}, 543, -1, { 567, 414 }, {150, 150}}, + {{0, 95}, 0, -1, {2550, 3508}, { 50, 50 }}, {600, 600}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -214,10 +213,10 @@ static DCapsDef Cap0x07B3_0x0007_0 = */ static DCapsDef Cap0x07B3_0x0005_2 = { - {{ 0, 64}, 0, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 64}, 0, -1, {2550, 3508}, { 50, 50 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {600, 600}, 0, SENSORORDER_rgb, @@ -229,10 +228,10 @@ static DCapsDef Cap0x07B3_0x0005_2 = */ static DCapsDef Cap0x07B3_0x0007_4 = { - {{ 0, 111 - 4 }, 0, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{1040 + 5, 744 - 32}, 543, -1, { 473, 414 }, {150, 150}, COLOR_TRUE24 }, - {{1040 - 20, 768 }, 543, -1, { 567, 414 }, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95 }, 0, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, + {{ 0, 111 - 4 }, 0, -1, {2550, 3508}, { 50, 50 }}, + {{1040 + 5, 744 - 32}, 543, -1, { 473, 414 }, {150, 150}}, + {{1040 - 20, 768 }, 543, -1, { 567, 414 }, {150, 150}}, + {{ 0, 95 }, 0, -1, {2550, 3508}, { 50, 50 }}, {1200, 1200}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -244,10 +243,10 @@ static DCapsDef Cap0x07B3_0x0007_4 = */ static DCapsDef Cap0x07B3_0x0005_4 = { - {{ 0, 111 - 4 }, 0, -1, {2550, 3508}, {50, 50}, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 111 - 4 }, 0, -1, {2550, 3508}, {50, 50}}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -259,26 +258,25 @@ static DCapsDef Cap0x07B3_0x0005_4 = */ static DCapsDef Cap0x07B3_0x000F_0 = { - {{ 0, 130}, 12, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{1040, 744}, 543, -1, { 473, 414 }, {150, 150}, COLOR_TRUE24 }, - {{1004, 744}, 543, -1, { 567, 414 }, {150, 150}, COLOR_TRUE24 }, - {{ 0, 244}, 12, -1, {2550, 4200}, { 50, 50 }, COLOR_BW }, + {{ 0, 130}, 12, -1, {2550, 3508}, { 50, 50 }}, + {{1040, 744}, 543, -1, { 473, 414 }, {150, 150}}, + {{1004, 744}, 543, -1, { 567, 414 }, {150, 150}}, + {{ 0, 244}, 12, -1, {2550, 4200}, { 50, 50 }}, {600, 600}, DEVCAPSFLAG_Normal + DEVCAPSFLAG_Adf, SENSORORDER_rgb, 4, 5, kNEC3799, 0x0F, _WAF_NONE, _NO_MIO }; - /* Plustek Model: ??? * KH: NS9831 + TPA + Button + NEC3799 */ static DCapsDef Cap0x07B3_0x0013_0 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 30, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 30, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -287,13 +285,13 @@ static DCapsDef Cap0x07B3_0x0013_0 = /* Plustek Model: U24 * KH: NS9831 + Button + NEC3799 - */ +// */ static DCapsDef Cap0x07B3_0x0011_0 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, 0, SENSORORDER_rgb, @@ -305,10 +303,10 @@ static DCapsDef Cap0x07B3_0x0011_0 = */ static DCapsDef Cap0x07B3_0x0010_0 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, 0, SENSORORDER_rgb, @@ -320,10 +318,10 @@ static DCapsDef Cap0x07B3_0x0010_0 = */ static DCapsDef Cap0x07B3_0x0013_4 = { - {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -335,10 +333,10 @@ static DCapsDef Cap0x07B3_0x0013_4 = */ static DCapsDef Cap0x07B3_0x0011_4 = { - {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 - 20}, 543, -1 ,{ 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 - 20}, 543, -1 ,{ 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -350,10 +348,10 @@ static DCapsDef Cap0x07B3_0x0011_4 = */ static DCapsDef Cap0x07B3_0x0010_4 = { - {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 /*114*/}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -365,10 +363,10 @@ static DCapsDef Cap0x07B3_0x0010_4 = */ static DCapsDef Cap0x07B3_0x000F_4 = { - {{ 0, 107}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1040 + 5, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1040 - 20, 768}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 244}, 0, -1, {2550, 4200}, { 50, 50}, COLOR_BW }, + {{ 0, 107}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1040 + 5, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1040 - 20, 768}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 244}, 0, -1, {2550, 4200}, { 50, 50}}, {1200, 1200}, DEVCAPSFLAG_Normal + DEVCAPSFLAG_Adf, SENSORORDER_rgb, @@ -380,10 +378,10 @@ static DCapsDef Cap0x07B3_0x000F_4 = */ static DCapsDef Cap0x07B3_0x0016_4 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 954, 422}, 272, -1, { 624, 1940}, {150, 150}, COLOR_TRUE24 }, - {{1120, 438}, 275, -1, { 304, 1940}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 954, 422}, 272, -1, { 624, 1940}, {150, 150}}, + {{1120, 438}, 275, -1, { 304, 1940}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -395,10 +393,10 @@ static DCapsDef Cap0x07B3_0x0016_4 = */ static DCapsDef Cap0x07B3_0x0017_4 = { - {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1025 /*1055*/, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1048 /*1024*/, 754/*724*/}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1025 /*1055*/, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1048 /*1024*/, 754/*724*/}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -410,10 +408,10 @@ static DCapsDef Cap0x07B3_0x0017_4 = */ static DCapsDef Cap0x07B3_0x0015_4 = { - {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -425,10 +423,10 @@ static DCapsDef Cap0x07B3_0x0015_4 = */ static DCapsDef Cap0x07B3_0x0014_4 = { - {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 99 - 6}, 0, -1, {2550, 3508}, { 50, 50}}, + {{ 1055, 744 - 84}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 - 20}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -440,10 +438,10 @@ static DCapsDef Cap0x07B3_0x0014_4 = */ static DCapsDef Cap0x07B3_0x0014_1 = { - {{ 0, 93}, 0, -1, {3600, 5100}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {3600, 5100}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {400, 400}, 0, SENSORORDER_rgb, @@ -455,10 +453,10 @@ static DCapsDef Cap0x07B3_0x0014_1 = */ static DCapsDef Cap0x07B3_0x0012_0 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 20, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, 0, SENSORORDER_rgb, @@ -470,10 +468,10 @@ static DCapsDef Cap0x07B3_0x0012_0 = */ static DCapsDef Cap0x07B3_0x0017_2 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 1004, 744}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{ 1004, 744}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_bgr, @@ -485,10 +483,10 @@ static DCapsDef Cap0x07B3_0x0017_2 = */ static DCapsDef Cap0x07B3_0x0017_3 = { - {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1004 + 30, 744 + 32}, 543, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, + {{ 0, 93}, 0, -1, {2550, 3508}, { 50, 50}}, + {{1040 + 15, 744 - 32}, 543, -1, { 473, 414}, {150, 150}}, + {{1004 + 30, 744 + 32}, 543, -1, { 567, 414}, {150, 150}}, + {{ 0, 95}, 0, -1, {2550, 3508}, { 50, 50}}, {600, 600}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -498,10 +496,10 @@ static DCapsDef Cap0x07B3_0x0017_3 = /* Model: HP Scanjet 2100c */ static DCapsDef Cap0x03F0_0x0505 = { - {{ 0, 65}, 10, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */ - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */ - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No ADF */ + {{ 0, 65}, 10, -1, {2550, 3508}, { 50, 50}}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {600, 600}, 0, SENSORORDER_rgb, @@ -514,13 +512,13 @@ static DCapsDef Cap0x03F0_0x0505 = static DCapsDef Cap0x03F0_0x0605 = { /* DataOrigin (x, y), ShadingOriginY */ - {{ 0, 209}, 40, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */ - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */ - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No ADF */ - {600, 600}, /* Motor can handle 1200 DPI */ + {{ 0, 209}, 40, -1, {2550, 3508}, { 50, 50}}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {600, 600}, 0, - SENSORORDER_rgb, + SENSORORDER_rgb, 4, 2, kNECSLIM, 0x00, _WAF_NONE, _NO_MIO }; @@ -529,15 +527,17 @@ static DCapsDef Cap0x03F0_0x0605 = */ static DCapsDef Cap0x0400_0x1000_0 = { - {{ 0, 130}, 20, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 130}, 20, -1, {2550, 3508}, { 50, 50 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {600, 600}, 0, SENSORORDER_rgb, - 4, - 5, kNEC8861, 0x00, _WAF_NONE, _NO_MIO + 8, + 5, kNEC8861, 0x00, + _WAF_MISC_IO_LAMPS | _WAF_USE_ALT_DESC, + _MIO5 }; /* Mustek BearPaw 2400 @@ -545,17 +545,17 @@ static DCapsDef Cap0x0400_0x1000_0 = */ static DCapsDef Cap0x0400_0x1001_0 = { - {{ 0, 130/*209*/}, 35/*20*/, -1, {2550, 3508}, { 50, 50 }, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 130/*209*/}, 35/*20*/, -1, {2550, 3508}, { 50, 50 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, { 600, 600 }, /*{ 1200, 1200 }, */ 0, SENSORORDER_rgb, 4,/*16*/ /* sensor distance */ 5, /* number of buttons */ kSONY548, /* CCD type */ - 0, _WAF_NONE, _NO_MIO + 0, _WAF_USE_ALT_DESC, _NO_MIO }; /* Epson Perfection/Photo1250 (thanks to Gene Heskett and Reinhard Max) @@ -565,12 +565,12 @@ static DCapsDef Cap0x0400_0x1001_0 = static DCapsDef Cap0x04B8_0x010F = { /* Normal */ - {{ 25, 85}, 10, -1, {2550, 3508}, { 100, 100 }, COLOR_BW }, + {{ 25, 85}, 10, -1, {2550, 3508}, { 100, 100 }}, /* Positive */ - {{ 1100, 972}, 720, -1, { 473, 414}, { 150, 150 }, COLOR_TRUE24 }, + {{ 1100, 972}, 720, -1, { 473, 414}, { 150, 150 }}, /* Negative */ - {{ 1116, 1049}, 720, -1, { 567, 414}, { 150, 150 }, COLOR_TRUE24 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 1116, 1049}, 720, -1, { 567, 414}, { 150, 150 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -587,12 +587,12 @@ static DCapsDef Cap0x04B8_0x010F = static DCapsDef Cap0x1606_0x0060 = { /* Normal */ - {{ 30, 105 }, 15, -1, {2550, 3508}, { 100, 100 }, COLOR_BW }, + {{ 30, 105 }, 15, -1, {2550, 3508}, { 100, 100 }}, /* Positive */ - {{ 700, 760 }, 650, -1, {1200, 1500}, { 150, 150 }, COLOR_TRUE24 }, + {{ 700, 760 }, 650, -1, {1200, 1500}, { 150, 150 }}, /* Negative */ - {{ 700, 760 }, 650, -1, {1200, 1500}, { 150, 150 }, COLOR_TRUE24 }, - {{ 0, 0 }, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 700, 760 }, 650, -1, {1200, 1500}, { 150, 150 }}, + {{ 0, 0 }, 0, -1, {0, 0}, { 0, 0 }}, {600, 600}, DEVCAPSFLAG_LargeTPA, SENSORORDER_bgr, @@ -608,10 +608,10 @@ static DCapsDef Cap0x1606_0x0060 = */ static DCapsDef Cap0x1606_0x0160 = { - {{ 30, 165}, 0, -1, {2550, 3508}, {100, 100}, COLOR_BW }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, + {{ 30, 165}, 0, -1, {2550, 3508}, {100, 100}}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_bgr, @@ -627,10 +627,10 @@ static DCapsDef Cap0x1606_0x0160 = */ static DCapsDef Cap0x04A9_0x2206 = { - {{ 0, 90}, 45, 10, {2550, 3508}, {75, 75}, COLOR_GRAY16 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 90}, 45, 10, {2550, 3508}, {75, 75}}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, {600, 600}, 0, SENSORORDER_rgb, @@ -645,10 +645,10 @@ static DCapsDef Cap0x04A9_0x2206 = */ static DCapsDef Cap0x04A9_0x2207 = { - {{ 0, 85}, 45, 10, {2550, 3508}, {75, 75}, COLOR_BW }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 85}, 45, 10, {2550, 3508}, {75, 75}}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -663,10 +663,10 @@ static DCapsDef Cap0x04A9_0x2207 = */ static DCapsDef Cap0x04A9_0x2208 = { - {{ 45, 125}, 15, -1, {2550, 3508}, { 50, 50}, COLOR_BW }, - {{1060, 744}, 510, -1, { 473, 414}, {150, 150}, COLOR_TRUE24 }, - {{1082, 842}, 610, -1, { 567, 414}, {150, 150}, COLOR_TRUE24 }, - {{ 0, 0}, 0, 0, { 0, 0}, { 0, 0}, 0 }, + {{ 45, 125}, 15, -1, {2550, 3508}, { 50, 50}}, + {{1060, 744}, 510, -1, { 473, 414}, {150, 150}}, + {{1082, 842}, 610, -1, { 567, 414}, {150, 150}}, + {{ 0, 0}, 0, 0, { 0, 0}, { 0, 0}}, {600, 600}, DEVCAPSFLAG_Positive + DEVCAPSFLAG_Negative, SENSORORDER_rgb, @@ -682,10 +682,10 @@ static DCapsDef Cap0x04A9_0x2208 = */ static DCapsDef Cap0x04A9_0x220D = { - {{ 0, 110}, 45, -1, {2550, 3508}, {75, 75}, COLOR_GRAY16 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 110}, 45, -1, {2550, 3508}, {75, 75}}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, {600, 600}, 0, SENSORORDER_rgb, @@ -700,10 +700,10 @@ static DCapsDef Cap0x04A9_0x220D = */ static DCapsDef Cap0x04A9_0x220E = { - {{ 0, 100}, 50, 10, {2550, 3508}, {75, 75}, COLOR_BW }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 100}, 50, 10, {2550, 3508}, {75, 75}}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -718,10 +718,10 @@ static DCapsDef Cap0x04A9_0x220E = */ static DCapsDef Cap0x04A9_0x2220 = { - {{ 0, 100}, 50, 10, {2550, 3508}, {75, 75}, COLOR_BW }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 100}, 50, 10, {2550, 3508}, {75, 75}}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, {1200, 1200}, 0, SENSORORDER_rgb, @@ -732,14 +732,34 @@ static DCapsDef Cap0x04A9_0x2220 = _WAF_MISC_IO_LAMPS, _NO_MIO }; +/* Syscan TravelScan 662 A6 sheet-fed scanner + */ +static DCapsDef Cap0x0A82_0x6620 = +{ + {{ 0, 0}, 100, -1, {1226, 3508}, { 75, 75 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }}, + {600, 600}, + DEVCAPSFLAG_SheetFed, + SENSORORDER_rgb, + 8, + 1, + kNEC8861, /* use default settings during calibration */ + 0, /* not used here... */ + (_WAF_MISC_IO_LAMPS | _WAF_MISC_IO_BUTTONS | + _WAF_BIN_FROM_COLOR | _WAF_GRAY_FROM_COLOR), + _MIO5 + _PORT1 +}; + /******************* additional Hardware descriptions ************************/ /** U24, UT12 and UT16 */ static HWDef Hw0x07B3_0x0017_0 = { - 1.5, /* dMaxMotorSpeed (Max_Speed) */ - 1.2, /* dMaxMoveSpeed (Max_Speed) */ + 1.5, /* dMaxMotorSpeed */ + 1.2, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 9, /* dIntegrationTimeLowLamp */ 9, /* dIntegrationTimeHighLamp */ @@ -1390,8 +1410,8 @@ static HWDef Hw0x07B3_0x0017_3 = */ static HWDef Hw0x03F0_0x0505 = { - 1.05, /* dMaxMotorSpeed (Max_Speed) */ - 1.05, /* dMaxMoveSpeed (Max_Speed) */ + 1.05, /* dMaxMotorSpeed */ + 1.05, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 6, /* dIntegrationTimeLowLamp */ 8, /* dIntegrationTimeHighLamp */ @@ -1458,8 +1478,8 @@ static HWDef Hw0x03F0_0x0505 = /** HP Scanjet 2200C */ static HWDef Hw0x03F0_0x0605 = { - 1.05, /* dMaxMotorSpeed (Max_Speed) */ - 1.05, /* dMaxMoveSpeed (Max_Speed) */ + 1.05, /* dMaxMotorSpeed */ + 1.05, /* dMaxMoveSpeed */ 2.2, /* dHighSpeed */ 6, /* dIntegrationTimeLowLamp */ 8, /* dIntegrationTimeHighLamp */ @@ -1525,8 +1545,8 @@ static HWDef Hw0x03F0_0x0605 = /** Mustek BearPaw 1200 */ static HWDef Hw0x0400_0x1000_0 = { - 1.25, /* ok dMaxMotorSpeed (Max_Speed) */ - 1.25, /* ok dMaxMoveSpeed (Max_Speed) */ + 1.75, /* ok dMaxMotorSpeed */ + 1.25, /* ok dMaxMoveSpeed */ 0.0, /* ok dHighSpeed */ 12, /* ok dIntegrationTimeLowLamp */ 12, /* ok dIntegrationTimeHighLamp */ @@ -1572,20 +1592,20 @@ static HWDef Hw0x0400_0x1000_0 = 0x0d, /* ok Paper sense (reg 0x58) */ 0x44, /* ok misc io12 (reg 0x59) */ 0x44, /* ok misc io34 (reg 0x5a) */ - 0x4f, /* ok misc io56 (reg 0x5b) */ + 0x16, /* ok misc io56 (reg 0x5b) */ 0, /* ok test mode ADC Output CODE MSB (reg 0x5c) */ 0, /* ok test mode ADC Output CODE LSB (reg 0x5d) */ 0, /* ok test mode (reg 0x5e) */ _LM9831, MODEL_MUSTEK600, - 1.0 + 1.5 }; /** Mustek BearPaw 1200 (LM9832) */ static HWDef Hw0x0400_0x1001_1 = { - 1.25, /* ok dMaxMotorSpeed (Max_Speed) */ - 1.25, /* ok dMaxMoveSpeed (Max_Speed) */ + 1.25, /* ok dMaxMotorSpeed */ + 1.25, /* ok dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 12, /* ok dIntegrationTimeLowLamp */ 12, /* ok dIntegrationTimeHighLamp */ @@ -1631,20 +1651,20 @@ static HWDef Hw0x0400_0x1001_1 = 0x0d, /* ok Paper sense (reg 0x58) */ 0x44, /* ok misc io12 (reg 0x59) */ 0x44, /* ok misc io34 (reg 0x5a) */ - 0x4f, /* ok misc io56 (reg 0x5b) */ + 0x16, /* ok misc io56 (reg 0x5b) */ 0, /* ok test mode ADC Output CODE MSB (reg 0x5c) */ 0, /* ok test mode ADC Output CODE LSB (reg 0x5d) */ 0, /* ok test mode (reg 0x5e) */ _LM9832, MODEL_MUSTEK600, - 1.0 + 1.5 }; /** BearPaw 2400 */ static HWDef Hw0x0400_0x1001_0 = { - 1.0/*1.8*/, /* ok dMaxMotorSpeed (Max_Speed) */ - 0.9/*1.8*/, /* ok dMaxMoveSpeed (Max_Speed) */ + 1.0/*1.8*/, /* ok dMaxMotorSpeed */ + 0.9/*1.8*/, /* ok dMaxMoveSpeed */ 0.0, /* ok dHighSpeed */ 12, /* ok dIntegrationTimeLowLamp */ 12, /* ok dIntegrationTimeHighLamp */ @@ -1666,49 +1686,49 @@ static HWDef Hw0x0400_0x1001_0 = /* {5, 14, 12, 15, 18, 21, 0, 0, 0, 9 },*/ {1, 4, 4, 5, 6, 7, 0, 0, 0, 3 }, - _GREEN_CH, /* bReg_0x26 color mode - bits 4 and 5 */ - 0, /* bReg 0x27 color mode */ - 1, /* bReg 0x29 illumination mode */ + _GREEN_CH, /* bReg_0x26 color mode - bits 4 and 5 */ + 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 }, - 257, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ - 13, /* bOpticBlackStart (reg 0x1c) */ - 60, /* bOpticBlackEnd (reg 0x1d) */ - 10, /* wActivePixelsStart (reg 0x1e + 0x1f) */ -5416 /* 11000*/, /* wLineEnd (reg 0x20 + 0x21) */ + 257, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ + 13, /* bOpticBlackStart (reg 0x1c) */ + 60, /* bOpticBlackEnd (reg 0x1d) */ + 10, /* wActivePixelsStart (reg 0x1e + 0x1f) */ +5416 /* 11000*/, /* wLineEnd (reg 0x20 + 0x21) */ - 1, /* ok red lamp on (reg 0x2c + 0x2d) */ - 16383, /* ok red lamp off (reg 0x2e + 0x2f) */ - 1, /* ok green lamp on (reg 0x30 + 0x31) */ - 16383, /* ok green lamp off (reg 0x32 + 0x33) */ - 1, /* ok blue lamp on (reg 0x34 + 0x35) */ - 16383, /* ok blue lamp off (reg 0x36 + 0x37) */ + 1, /* ok red lamp on (reg 0x2c + 0x2d) */ + 16383, /* ok red lamp off (reg 0x2e + 0x2f) */ + 1, /* ok green lamp on (reg 0x30 + 0x31) */ + 16383, /* ok green lamp off (reg 0x32 + 0x33) */ + 1, /* ok blue lamp on (reg 0x34 + 0x35) */ + 16383, /* ok blue lamp off (reg 0x36 + 0x37) */ - 0x03, /* ok stepper motor control (reg 0x45) */ - 0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */ - 0x1e, /* steps to reverse on buffer full (reg 0x50) */ - 0xfc, /* ok acceleration profile (reg 0x51) */ - 0x03, /* ok lines to process (reg 0x54) */ - 0x13, /* Kickstart 0x55 */ - 2, /* PWM frequency 0x56 */ - 32, /* PWM duty cycle 0x57 */ - 0x15, /* paper sense 0x58 */ - 0x44, /* misc I/O 0x59 */ - 0x44, /* misc I/O 0x5a, */ - 0x46, /* misc I/O 0x5b */ - 0, 0, 0,/* test registers, set to 0 (0x5c, 0x5d, 0x5e) */ + 0x03, /* ok stepper motor control (reg 0x45) */ + 0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */ + 0x1e, /* steps to reverse on buffer full (reg 0x50) */ + 0xfc, /* ok acceleration profile (reg 0x51) */ + 0x03, /* ok lines to process (reg 0x54) */ + 0x13, /* Kickstart 0x55 */ + 2, /* PWM frequency 0x56 */ + 32, /* PWM duty cycle 0x57 */ + 0x15, /* paper sense 0x58 */ + 0x44, /* misc I/O 0x59 */ + 0x44, /* misc I/O 0x5a, */ + 0x46, /* misc I/O 0x5b */ + 0, 0, 0,/* test registers, set to 0 (0x5c, 0x5d, 0x5e) */ _LM9832, - MODEL_MUSTEK1200, + MODEL_MUSTEK1200, 1.0 }; /** EPSON Perfection/Photo 1250 */ static HWDef Hw0x04B8_0x010F = { - 0.8, /* dMaxMotorSpeed (Max_Speed) */ - 0.8, /* dMaxMoveSpeed (Max_Speed) */ + 0.8, /* dMaxMotorSpeed */ + 0.8, /* dMaxMoveSpeed */ 4.1, /* dHighSpeed */ 12, /* dIntegrationTimeLowLamp */ 12, /* dIntegrationTimeHighLamp */ @@ -1773,8 +1793,8 @@ static HWDef Hw0x04B8_0x010F = /** EPSON Perfection/Photo 1260 */ static HWDef Hw0x04B8_0x011D = { - 0.9, /* dMaxMotorSpeed (Max_Speed) */ - 0.8, /* dMaxMoveSpeed (Max_Speed) */ + 0.9, /* dMaxMotorSpeed */ + 0.8, /* dMaxMoveSpeed */ 4.1, /* dHighSpeed */ 12, /* dIntegrationTimeLowLamp */ 12, /* dIntegrationTimeHighLamp */ @@ -1839,8 +1859,8 @@ static HWDef Hw0x04B8_0x011D = /** Umax 3400/3450 */ static HWDef Hw0x1606_0x0060 = { - 1.5, /* dMaxMotorSpeed (Max_Speed) */ - 0.8, /* dMaxMoveSpeed (Max_Speed) */ + 1.5, /* dMaxMotorSpeed */ + 0.8, /* dMaxMoveSpeed */ 2.75, /* dHighSpeed */ 9, /* dIntegrationTimeLowLamp */ 9, /* dIntegrationTimeHighLamp */ @@ -1906,8 +1926,8 @@ static HWDef Hw0x1606_0x0060 = /** Umax 5400 */ static HWDef Hw0x1606_0x0160 = { - 1.1, /* dMaxMotorSpeed (Max_Speed) */ - 0.9, /* dMaxMoveSpeed (Max_Speed) */ + 1.1, /* dMaxMotorSpeed */ + 0.9, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 9, /* dIntegrationTimeLowLamp */ 9, /* dIntegrationTimeHighLamp */ @@ -1975,8 +1995,8 @@ static HWDef Hw0x1606_0x0160 = /** Canon N650U/N656U */ static HWDef Hw0x04A9_0x2206 = { - 0.86, /* dMaxMotorSpeed (Max_Speed) */ - 0.243, /* dMaxMoveSpeed (Max_Speed) */ + 0.86, /* dMaxMotorSpeed */ + 0.243, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 100, /* dIntegrationTimeLowLamp */ 100, /* dIntegrationTimeHighLamp */ @@ -2044,8 +2064,8 @@ static HWDef Hw0x04A9_0x2206 = /** Canon N1220U */ static HWDef Hw0x04A9_0x2207 = { - 0.72, /* dMaxMotorSpeed (Max_Speed) */ - 0.36, /* dMaxMoveSpeed (Max_Speed) */ + 0.72, /* dMaxMotorSpeed */ + 0.36, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 100, /* wIntegrationTimeLowLamp */ 100, /* wIntegrationTimeHighLamp */ @@ -2112,8 +2132,8 @@ static HWDef Hw0x04A9_0x2207 = /** Canon D660U */ static HWDef Hw0x04A9_0x2208 = { - 1.2, /* dMaxMotorSpeed (Max_Speed) */ - 1.1, /* dMaxMoveSpeed (Max_Speed) */ + 1.2, /* dMaxMotorSpeed */ + 1.1, /* dMaxMoveSpeed */ 2.75, /* dHighSpeed */ 9, /* dIntegrationTimeLowLamp */ 9, /* dIntegrationTimeHighLamp */ @@ -2175,8 +2195,8 @@ 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 */ + 0.243, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 100, /* dIntegrationTimeLowLamp */ 100, /* dIntegrationTimeHighLamp */ @@ -2244,8 +2264,8 @@ static HWDef Hw0x04A9_0x220D = /** Canon N1240U/LiDE30 */ static HWDef Hw0x04A9_0x220E = { - 0.72, /* dMaxMotorSpeed (Max_Speed) */ - 0.30, /* dMaxMoveSpeed (Max_Speed) */ + 0.72, /* dMaxMotorSpeed */ + 0.30, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 100, /* wIntegrationTimeLowLamp */ 100, /* wIntegrationTimeHighLamp */ @@ -2262,10 +2282,10 @@ static HWDef Hw0x04A9_0x220E = 0x00, /* sensor control settings (reg 0x0e) */ {0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05}, - /* mono (reg 0x0f to 0x18) */ + /* mono (reg 0x0f to 0x18) */ {0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x05}, - /* color (reg 0x0f to 0x18) */ + /* color (reg 0x0f to 0x18) */ (_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */ @@ -2313,8 +2333,8 @@ static HWDef Hw0x04A9_0x220E = /** Canon LiDE25 */ static HWDef Hw0x04A9_0x2220 = { - 0.70, /* dMaxMotorSpeed (Max_Speed) */ - 0.25, /* dMaxMoveSpeed (Max_Speed) */ + 0.70, /* dMaxMotorSpeed */ + 0.25, /* dMaxMoveSpeed */ 0.0, /* dHighSpeed */ 100, /* wIntegrationTimeLowLamp */ 100, /* wIntegrationTimeHighLamp */ @@ -2331,10 +2351,10 @@ static HWDef Hw0x04A9_0x2220 = 0x00, /* sensor control settings (reg 0x0e) */ {0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x07}, - /* mono (reg 0x0f to 0x18) */ + /* mono (reg 0x0f to 0x18) */ {0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x07}, - /* color (reg 0x0f to 0x18) */ + /* color (reg 0x0f to 0x18) */ (_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */ @@ -2379,6 +2399,76 @@ static HWDef Hw0x04A9_0x2220 = 2.0 }; +/** TravelScan 662 */ +static HWDef Hw0x0A82_0x6620 = +{ + 0.72, /* dMaxMotorSpeed */ + 0.188, /* dMaxMoveSpeed */ + 0.0, /* dHighSpeed */ + 100, /* wIntegrationTimeLowLamp */ + 100, /* wIntegrationTimeHighLamp */ + 740, /* wMotorDpi (Full step DPI) */ + 512, /* wRAMSize (KB) */ + 3.75, /* dMinIntegrationTimeLowres (ms) */ + 5.75, /* dMinIntegrationTimeHighres (ms) */ + 3000, /* wGreenPWMDutyCycleLow (reg 0x2a + 0x2b) */ + 3000, /* wGreenPWMDutyCycleHigh (reg 0x2a + 0x2b) */ + + 0x0d, /* bSensorConfiguration (0x0b) */ + 0x00, /* sensor control settings (reg 0x0c) */ + 0x25, /* sensor control settings (reg 0x0d) */ + 0x00, /* sensor control settings (reg 0x0e) */ + + {0x18, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07}, + /* mono (reg 0x0f to 0x18) */ + + {0x18, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07}, + /* color (reg 0x0f to 0x18) */ + + (_BLUE_CH | _ONE_CH_COLOR), /* bReg_0x26 color mode */ + + 0x00, /* bReg 0x27 color mode */ + 2, /* bReg 0x29 illumination mode */ + + { 3, 0, 0, 10, 450, 0, 0 }, + { 2, 10, 1000, 10, 880, 10, 630 }, + + 1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ + 1, /* bOpticBlackStart (reg 0x1c) */ + 2, /* bOpticBlackEnd (reg 0x1d) */ + 0x17, /* wActivePixelsStart (reg 0x1e + 0x1f) */ + 2600, /* wLineEnd (reg 0x20 + 0x21) */ + + 10, /* red lamp on (reg 0x2c + 0x2d) */ + 1000, /* red lamp off (reg 0x2e + 0x2f) */ + 10, /* green lamp on (reg 0x30 + 0x31) */ + 880, /* green lamp off (reg 0x32 + 0x33) */ + 10, /* blue lamp on (reg 0x34 + 0x35) */ + 630, /* blue lamp off (reg 0x36 + 0x37) */ + + 3, /* stepper motor control (reg 0x45) */ + 0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */ + + 0, /* steps to reverse when buffer is full reg 0x50) */ + 0, /* acceleration profile (reg 0x51) */ + 0, /* lines to process (reg 0x54) */ + 0x09, /* kickstart (reg 0x55) */ + 0x02, /* pwm freq (reg 0x56) */ + 0x16, /* pwm duty cycle (reg 0x57) */ + + 0x01, /* Paper sense (reg 0x58) */ + + 0x0e, /* misc io12 (reg 0x59) */ + 0x96, /* misc io34 (reg 0x5a) */ + 0x01, /* 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) */ + _LM9833, + MODEL_TSCAN, + 1.8 +}; + /******************** all available combinations *****************************/ /** here we have all supported devices and their settings... @@ -2450,6 +2540,9 @@ static SetDef Settings[] = {"0x04A9-0x220E", &Cap0x04A9_0x220E, &Hw0x04A9_0x220E, "N1240U/LiDE30" }, {"0x04A9-0x2220", &Cap0x04A9_0x2220, &Hw0x04A9_0x2220, "LiDE25" }, + /* SYSCAN... */ + {"0x0A82-0x6620", &Cap0x0A82_0x6620, &Hw0x0A82_0x6620, "TravelScan 662" }, + /* Please add other devices here... * The first entry is a string, composed out of the vendor and product id, * it's used by the driver to select the device settings. For other devices @@ -2484,7 +2577,7 @@ static ClkMotorDef Motors[] = { { MODEL_KaoHsiung, 64, 20, 6, /* PWM, PWM_Duty, MCLK for fast move */ - + 0, 0, /* for lineend adjustment, here disabled */ /* Motor settings (PWM and PWM_Duty) */ {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, @@ -2496,7 +2589,7 @@ static ClkMotorDef Motors[] = { { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 } }, - { MODEL_HuaLien, 64, 20, 6, + { MODEL_HuaLien, 64, 20, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, @@ -2508,7 +2601,7 @@ static ClkMotorDef Motors[] = { { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 } }, - { MODEL_Tokyo600, 4, 4, 6, + { MODEL_Tokyo600, 4, 4, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, @@ -2520,23 +2613,27 @@ static ClkMotorDef Motors[] = { { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 } }, - { MODEL_MUSTEK600, 4, 4, 6, + { MODEL_MUSTEK600, 4, 4, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }}, /* Color mode MCLK settings */ +#if 0 { 3.5, 3.5, 3.5, 4.0, 6.0, 8.0, 11.5, 11.5, 11.5, 11.5 }, { 3.5, 3.5, 3.5, 4.0, 6.0, 8.0, 11.5, 11.5, 11.5, 11.5 }, +#else + { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, + { 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 11.5, 11.5, 11.5, 11.5 }, +#endif /* Gray mode MCLK settings */ { 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 11.5, 11.5, 11.5, 11.5 }, { 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 11.5, 11.5, 11.5, 11.5 } }, - { MODEL_MUSTEK1200, 2, 32, 3, + { MODEL_MUSTEK1200, 2, 32, 3, 0, 0, /* Motor settings (PWM and PWM_Duty) */ /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }}, /* Color mode MCLK settings */ @@ -2548,41 +2645,36 @@ static ClkMotorDef Motors[] = { }, /* settings good for the HP models (tested with 2200)*/ - { MODEL_HP, 8, 60, 6, + { MODEL_HP, 8, 60, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }}, - /* Color mode MCLK settings */ { 4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 6.0, 6.0, 6.0, 6.0 }, { 4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 6.0, 6.0, 6.0, 6.0 }, - /* Gray mode MCLK settings */ { 8.0, 8.0, 8.0, 8.0, 8.0, 13.0, 13.0, 13.0, 13.0, 13.0 }, { 8.0, 8.0, 8.0, 8.0, 8.0, 13.0, 13.0, 13.0, 13.0, 13.0 } }, - { MODEL_CANON600, 8, 31, 6, + { MODEL_CANON600, 8, 31, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, /* Color mode MCLK settings */ { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, - /* Gray mode MCLK settings */ { 12.5, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0 }, { 12.5, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0 } }, - { MODEL_CANON1200, 8, 31, 3, + { MODEL_CANON1200, 8, 31, 3, 0, 0, /* Motor settings (PWM and PWM_Duty) */ /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, /* Color mode MCLK settings */ @@ -2594,7 +2686,7 @@ static ClkMotorDef Motors[] = { }, /* settings good for the UMAX models (tested with 3400) */ - { MODEL_UMAX, 16, 4, 6, + { MODEL_UMAX, 16, 4, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }}, @@ -2606,7 +2698,7 @@ static ClkMotorDef Motors[] = { { 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5 } }, - { MODEL_UMAX1200, 16, 4, 6, + { MODEL_UMAX1200, 16, 4, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ {{ 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }}, @@ -2619,11 +2711,10 @@ static ClkMotorDef Motors[] = { }, /* settings good for the EPSON models */ - { MODEL_EPSON, 2, 1, 6, + { MODEL_EPSON, 2, 1, 6, 0, 0, /* Motor settings (PWM and PWM_Duty) */ /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }}, /* Color mode MCLK settings */ @@ -2634,11 +2725,10 @@ static ClkMotorDef Motors[] = { { 6.0, 6.0, 6.0, 6.0, 6.0, 8.0, 9.0, 9.0, 18.0, 18.0 } }, - { MODEL_CANONCCD1200, 2, 31, 6, + { MODEL_CANONCCD1200, 2, 31, 3, 0, 0, /* Motor settings (PWM and PWM_Duty) */ /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }, { 2, 31, 1 }}, /* Color mode MCLK settings */ @@ -2649,11 +2739,10 @@ static ClkMotorDef Motors[] = { { 6.5, 6.5, 6.5, 7.0, 8.0, 8.0, 8.0, 10.0, 10.0, 10.0 } }, - { MODEL_CANON_LIDE25, 8, 31, 3, + { MODEL_CANON_LIDE25, 8, 31, 3, 0, 0, /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, /* Color mode MCLK settings */ @@ -2662,6 +2751,21 @@ static ClkMotorDef Motors[] = { /* Gray mode MCLK settings */ { 8.5, 7.0, 5.0, 4.0, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5 }, { 7.5, 6.5, 6.0, 6.0, 6.0, 6.0, 8.0, 12.0, 12.0, 12.0 } + }, + + { MODEL_TSCAN, 2, 22, 6, 75, 4000, + /* Motor settings (PWM and PWM_Duty) */ + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }, + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }, { 2, 22, 1 }}, + /* Color mode MCLK settings */ + /* Color mode MCLK settings */ + { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, + { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, + /* Gray mode MCLK settings */ + { 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0 }, + { 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0, 16.0 }, } }; diff --git a/backend/plustek-usbhw.c b/backend/plustek-usbhw.c index 0965c56dd..a0c5eaea7 100644 --- a/backend/plustek-usbhw.c +++ b/backend/plustek-usbhw.c @@ -7,7 +7,7 @@ * @brief Functions to control the scanner hardware. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -46,6 +46,8 @@ * - 0.50 - added button support for Plustek/Genius devices * - changed behaviour of usb_IsScannerReady * - added special misc I/O setup for CIS devices (usb_ResetRegisters) + * - 0.51 - change usb_AdjustLamps() and use it now in usb_switchLamp() + * - added usb_Wait4ScanSample() and usb_InCalibrationMode() * . *
* This file is part of the SANE package. @@ -97,12 +99,11 @@ #define DEV_LampPositive 4 #define DEV_LampNegative 5 -/* HEINER: check the tick counts 'cause 1 tick on NT is about 10ms */ - /** 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 */ -static SANE_Bool usb_HostSwap( void ) +static SANE_Bool +usb_HostSwap( void ) { u_short pattern = 0xfeed; /* deadbeef */ unsigned char *bytewise = (unsigned char *)&pattern; @@ -118,17 +119,42 @@ static SANE_Bool usb_HostSwap( void ) /** as the name says.. */ -static void usb_Swap( u_short *pw, u_long dwBytes ) +static void +usb_Swap( u_short *pw, u_long dwBytes ) { for( dwBytes /= 2; dwBytes--; pw++ ) _SWAP(((u_char*) pw)[0], ((u_char*)pw)[1]); } +/** + * This function is used to detect a cancel condition, + * our ESC key is the SIGUSR1 signal. It is sent by the backend when the + * cancel button has been pressed + * + * @param - none + * @return the function returns SANE_TRUE if a cancel condition has been + * detected, if not, it returns SANE_FALSE + */ +static SANE_Bool +usb_IsEscPressed( void ) +{ + sigset_t sigs; + + sigpending( &sigs ); + if( sigismember( &sigs, SIGUSR1 )) { + DBG( _DBG_INFO, "SIGUSR1 is pending --> Cancel detected\n" ); + return SANE_TRUE; + } + + return SANE_FALSE; +} + /** usb_GetMotorSet * according to the model, the function returns the address of * the corresponding entry of the Motor table */ -static ClkMotorDef *usb_GetMotorSet( eModelDef model ) +static ClkMotorDef* +usb_GetMotorSet( eModelDef model ) { int i; @@ -146,7 +172,8 @@ static ClkMotorDef *usb_GetMotorSet( eModelDef model ) * @param fOn - SANE_TRUE means motor on, SANE_FALSE means motor off * @return always SANE_TRUE */ -static SANE_Bool usb_MotorOn( Plustek_Device *dev, SANE_Bool fOn ) +static SANE_Bool +usb_MotorOn( Plustek_Device *dev, SANE_Bool fOn ) { if( fOn ) dev->usbDev.a_bRegs[0x45] |= 0x10; @@ -159,14 +186,35 @@ static SANE_Bool usb_MotorOn( Plustek_Device *dev, SANE_Bool fOn ) /** */ -static SANE_Bool usb_IsCISDevice( Plustek_Device *dev ) +static SANE_Bool +usb_IsCISDevice( Plustek_Device *dev ) { return ( dev->usbDev.HwSetting.bReg_0x26 & _ONE_CH_COLOR ); } +/** + */ +static SANE_Bool +usb_IsSheetFedDevice( Plustek_Device *dev ) +{ + return ( dev->usbDev.Caps.wFlags & DEVCAPSFLAG_SheetFed ); +} + +/** + */ +static SANE_Bool +usb_InCalibrationMode( Plustek_Device *dev ) +{ + if((dev->scanning.dwFlag & SCANFLAG_Calibration) == 0) + return SANE_FALSE; + + return SANE_TRUE; +} + /** check if scanner is ready */ -static SANE_Bool usb_IsScannerReady( Plustek_Device *dev ) +static SANE_Bool +usb_IsScannerReady( Plustek_Device *dev ) { u_char value; double len; @@ -217,7 +265,8 @@ static SANE_Bool usb_IsScannerReady( Plustek_Device *dev ) /** */ -static SANE_Bool usb_SensorAdf( int handle ) +static SANE_Bool +usb_SensorAdf( int handle ) { u_char value; @@ -228,19 +277,56 @@ static SANE_Bool usb_SensorAdf( int handle ) /** */ -static SANE_Bool usb_SensorPaper( int handle ) +static SANE_Bool +usb_SensorPaper( Plustek_Device *dev ) { - u_char value; + u_char val, mask = 0x02; - usbio_ReadReg( handle, 0x02, &value ); + usbio_ReadReg( dev->fd, 0x02, &val ); - return (value & 0x02); + if( usb_IsSheetFedDevice(dev)) + mask = 0x08; + + return (val & mask); +} + +/** function for sheet-fed devices, to make sure, that there's + * something to scan + */ +static SANE_Bool +usb_Wait4ScanSample( Plustek_Device *dev ) +{ + struct timeval start_time, t2; + + /* we wait about 10s for something to scan... */ + if( !usb_IsSheetFedDevice(dev)) + return SANE_TRUE; + + DBG( _DBG_INFO2, "Waiting for something to scan...\n" ); + gettimeofday( &start_time, NULL ); + do { + + gettimeofday( &t2, NULL ); + if( t2.tv_sec > start_time.tv_sec + 10 ) { + DBG( _DBG_ERROR, "Nothing to scan!!!\n" ); + return SANE_FALSE; + } + if( usb_IsEscPressed()) + return SANE_FALSE; + } + while( !usb_SensorPaper( dev )); + + /* just a little delay, to make sure the paper is taken by the scanner */ + usleep(100* 1000); + DBG( _DBG_INFO2, "... okay, scanning now!\n" ); + return SANE_TRUE; } /** function to move the sensor and to speed it up to a certain speed until * the position is reached */ -static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) +static SANE_Bool +usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) { SANE_Bool retval; u_char value, mclk_div, mch; @@ -344,17 +430,14 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) return retval; } -/** - * Home sensor always on when backward move. - * dwStep is steps to move and based on 300 dpi, but - * if the action is MOVE_Both, it becomes the times - * to repeatly move the module around the scanner and - * 0 means forever. +/** function to move the sensor or if sheet-fed device, to move the paper. + * In moving backward-mode, the home sensor is always turned on. + * @param action - what to do + * @param steps - steps to move, based on 300dpi, 0 means move forever */ -static SANE_Bool usb_ModuleMove( Plustek_Device *dev, - u_char bAction, u_long dwStep ) +static SANE_Bool +usb_ModuleMove( Plustek_Device *dev, u_char action, u_long dwStep ) { - SANE_Status res; SANE_Bool retval; u_char bReg2, reg7, mclk_div; u_short wFastFeedStepSize; @@ -363,10 +446,10 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; - if( bAction != MOVE_ToPaperSensor && - bAction != MOVE_EjectAllPapers && - bAction != MOVE_SkipPaperSensor && - bAction != MOVE_ToShading && !dwStep ) { + if( action != MOVE_ToPaperSensor && + action != MOVE_EjectAllPapers && + action != MOVE_SkipPaperSensor && + action != MOVE_ToShading && !dwStep ) { return SANE_TRUE; } @@ -376,35 +459,51 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, return SANE_FALSE; } - if( bAction == MOVE_EjectAllPapers ) { + if( action == MOVE_EjectAllPapers ) { double d = hw->dMaxMoveSpeed; - hw->dMaxMoveSpeed += 0.6; + hw->dMaxMoveSpeed += 0.8; /* was 0.6 */ + DBG( _DBG_INFO2, "Ejecting paper...\n" ); + retval = SANE_TRUE; do { - if( usb_SensorPaper(dev->fd) && - !usb_ModuleMove(dev,MOVE_SkipPaperSensor, 0 )) { + if( usb_SensorPaper(dev) && + !usb_ModuleMove(dev,MOVE_SkipPaperSensor, 0 )) { + hw->dMaxMoveSpeed = d; return SANE_FALSE; } if( usb_SensorAdf(dev->fd) && - !usb_ModuleMove(dev,MOVE_ToPaperSensor, 0 )) { + !usb_ModuleMove(dev,MOVE_ToPaperSensor, 0 )) { + hw->dMaxMoveSpeed = d; return SANE_FALSE; - } + } - } while( usb_SensorPaper(dev->fd)); + if( usb_IsEscPressed()) { + retval = SANE_FALSE; + break; + } + } while( usb_SensorPaper(dev)); - if(!usb_ModuleMove( dev, MOVE_Forward, 300 * 3)) - return SANE_FALSE; + /* when the paper is beyond the sensor, we move another 300 steps + * to make sure, that the scanned sheet is out of the scanner + * BUT: not at startup + */ + if (dev->initialized >= 0) { + if(!usb_ModuleMove( dev, MOVE_Forward, 300 /* *3 */)) { + hw->dMaxMoveSpeed = d; + return SANE_FALSE; + } + } usbio_WriteReg( dev->fd, 0x07, 0); usbio_WriteReg( dev->fd, 0x58, regs[0x58]); usbio_ReadReg( dev->fd, 0x02, &bReg2 ); hw->dMaxMoveSpeed = d; - - return SANE_TRUE; + DBG( _DBG_INFO2, "...done\n" ); + return retval; } usbio_WriteReg( dev->fd, 0x0a, 0 ); @@ -412,7 +511,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, /* Compute fast feed step size, use equation 3 and equation 8 */ dMaxMoveSpeed = hw->dMaxMoveSpeed; - if( bAction == MOVE_ToShading ) { + if( action == MOVE_ToShading ) { if( hw->dMaxMoveSpeed > 0.5 ) dMaxMoveSpeed = hw->dMaxMoveSpeed - 0.5; } @@ -476,12 +575,12 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, if( !usbio_WriteReg(dev->fd, 0x45, regs[0x45] )) return SANE_FALSE; - if( bAction == MOVE_Forward || bAction == MOVE_ToShading ) + if( action == MOVE_Forward || action == MOVE_ToShading ) reg7 = 5; - else if( bAction == MOVE_Backward ) + else if( action == MOVE_Backward ) reg7 = 6; - else if( bAction == MOVE_ToPaperSensor || bAction == MOVE_EjectAllPapers || - bAction == MOVE_SkipPaperSensor ) { + else if( action == MOVE_ToPaperSensor || action == MOVE_EjectAllPapers || + action == MOVE_SkipPaperSensor ) { reg7 = 1; } else { return SANE_TRUE; @@ -489,21 +588,21 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, retval = SANE_FALSE; + /* start the sensor... */ if( usbio_WriteReg( dev->fd, 0x07, reg7 )) { - long dwTicks; + long secs; struct timeval start_time, t2; - res = gettimeofday( &start_time, NULL ); + /* at least we move 20 seconds before timeout... */ + gettimeofday( &start_time, NULL ); + secs = start_time.tv_sec + 20; - /* 20000 NT-Ticks means 200s */ - dwTicks = start_time.tv_sec + 200; + if( action == MOVE_ToPaperSensor ) { - if( bAction == MOVE_ToPaperSensor ) { + for(;;) { - for(;;) { - - if( usb_SensorPaper( dev->fd )) { + if( usb_SensorPaper( dev )) { usbio_WriteReg( dev->fd, 0x07, 0 ); usbio_WriteReg( dev->fd, 0x58, regs[0x58] ); usbio_ReadReg ( dev->fd, 0x02, &bReg2 ); @@ -511,14 +610,14 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, } gettimeofday(&t2, NULL); - if( t2.tv_sec > dwTicks ) + if( t2.tv_sec > secs ) break; } - } else if( bAction == MOVE_SkipPaperSensor ) { + } else if( action == MOVE_SkipPaperSensor ) { - for(;;) { + for(;;) { - if( usb_SensorPaper( dev->fd )) { + if( !usb_SensorPaper( dev )) { usbio_WriteReg( dev->fd, 0x07, 0 ); usbio_WriteReg( dev->fd, 0x58, regs[0x58] ); usbio_ReadReg ( dev->fd, 0x02, &bReg2 ); @@ -526,8 +625,8 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, } gettimeofday(&t2, NULL); - if( t2.tv_sec > dwTicks ) - break; + if( t2.tv_sec > secs ) + break; } } else { @@ -545,7 +644,8 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev, /** */ -static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) +static SANE_Bool +usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) { u_char mclk_div; u_char value; @@ -553,10 +653,13 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; + if( usb_IsSheetFedDevice(dev)) { + return usb_ModuleMove( dev, MOVE_EjectAllPapers, 0 ); + } + /* Check if merlin is ready for setting command */ usbio_WriteReg( dev->fd, 0x58, hw->bReg_0x58 ); usbio_ReadReg ( dev->fd, 2, &value ); - if( value & 1 ) { dev->usbDev.fModFirstHome = SANE_FALSE; return SANE_TRUE; @@ -590,7 +693,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) regs[0x56] = clk->pwm_fast; regs[0x57] = clk->pwm_duty_fast; - mclk_div = clk->mclk_fast; + mclk_div = clk->mclk_fast; } else { @@ -719,7 +822,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) /** */ -static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF ) +static SANE_Bool +usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF ) { DCapsDef *sCaps = &dev->usbDev.Caps; HWDef *hw = &dev->usbDev.HwSetting; @@ -760,39 +864,61 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF ) return SANE_TRUE; } -/** function to adjust the lamp settings of a device +/** function to adjust the lamp settings of a CIS device without tweaking + * the driver-device settings + * @param dev - our almitghty device structure + * @param on - switch the lamp on or off */ -static SANE_Bool usb_AdjustLamps( Plustek_Device *dev ) +static SANE_Bool +usb_AdjustLamps( Plustek_Device *dev, SANE_Bool on ) { HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; - regs[0x2c] = _HIBYTE(hw->red_lamp_on); - regs[0x2d] = _LOBYTE(hw->red_lamp_on); - regs[0x2e] = _HIBYTE(hw->red_lamp_off); - regs[0x2f] = _LOBYTE(hw->red_lamp_off); + if( !usb_IsCISDevice(dev)) + return SANE_TRUE; - regs[0x30] = _HIBYTE(hw->green_lamp_on); - regs[0x31] = _LOBYTE(hw->green_lamp_on); - regs[0x32] = _HIBYTE(hw->green_lamp_off); - regs[0x33] = _LOBYTE(hw->green_lamp_off); + DBG(_DBG_INFO2, "usb_AdjustLamps(%u)\n", on ); - regs[0x34] = _HIBYTE(hw->blue_lamp_on); - regs[0x35] = _LOBYTE(hw->blue_lamp_on); - regs[0x36] = _HIBYTE(hw->blue_lamp_off); - regs[0x37] = _LOBYTE(hw->blue_lamp_off); + if( on ) { + regs[0x2c] = _HIBYTE(hw->red_lamp_on); + regs[0x2d] = _LOBYTE(hw->red_lamp_on); + regs[0x2e] = _HIBYTE(hw->red_lamp_off); + regs[0x2f] = _LOBYTE(hw->red_lamp_off); - return sanei_lm983x_write( dev->fd, 0x2c, + regs[0x30] = _HIBYTE(hw->green_lamp_on); + regs[0x31] = _LOBYTE(hw->green_lamp_on); + regs[0x32] = _HIBYTE(hw->green_lamp_off); + regs[0x33] = _LOBYTE(hw->green_lamp_off); + + regs[0x34] = _HIBYTE(hw->blue_lamp_on); + regs[0x35] = _LOBYTE(hw->blue_lamp_on); + regs[0x36] = _HIBYTE(hw->blue_lamp_off); + regs[0x37] = _LOBYTE(hw->blue_lamp_off); + + } else { + memset( ®s[0x2c], 0, 12 ); + + regs[0x2c] = 0x3f; + regs[0x2d] = 0xff; + regs[0x30] = 0x3f; + regs[0x31] = 0xff; + regs[0x34] = 0x3f; + regs[0x35] = 0xff; + } + + return sanei_lm983x_write( dev->fd, 0x2c, ®s[0x2c], 0x37-0x2c+1, SANE_TRUE ); } /** */ -static void usb_AdjustCISLampSettings( Plustek_Device *dev, SANE_Bool on ) +static void +usb_AdjustCISLampSettings( Plustek_Device *dev, SANE_Bool on ) { HWDef *hw = &dev->usbDev.HwSetting; - if( !(hw->bReg_0x26 & _ONE_CH_COLOR)) + if( !usb_IsCISDevice(dev)) return; DBG( _DBG_INFO2, "AdjustCISLamps(%u)\n", on ); @@ -854,17 +980,18 @@ static void usb_AdjustCISLampSettings( Plustek_Device *dev, SANE_Bool on ) } dev->usbDev.a_bRegs[0x29] = hw->bReg_0x29; - usb_AdjustLamps( dev ); + usb_AdjustLamps( dev, on ); } /** according to the flag field, we return the register and - * it's maks to turn on/off the lamp. + * it's mask to turn on/off the lamp. * @param flag - field to check * @param reg - pointer to a var to receive the register value * @param msk - pointer to a var to receive the mask value * @return Nothing */ -static void usb_GetLampRegAndMask( u_long flag, SANE_Byte *reg, SANE_Byte *msk ) +static void +usb_GetLampRegAndMask( u_long flag, SANE_Byte *reg, SANE_Byte *msk ) { if( _MIO6 == ( _MIO6 & flag )) { *reg = 0x5b; @@ -905,14 +1032,14 @@ static void usb_GetLampRegAndMask( u_long flag, SANE_Byte *reg, SANE_Byte *msk ) * for the normal lamp, or DEV_LampTPA for negative/transparency * lamp */ -static int usb_GetLampStatus( Plustek_Device *dev ) +static int +usb_GetLampStatus( Plustek_Device *dev ) { - int iLampStatus = 0; - u_char *regs = dev->usbDev.a_bRegs; - HWDef *hw = &dev->usbDev.HwSetting; - DCapsDef *sc = &dev->usbDev.Caps; - SANE_Byte reg, msk, val; - + int iLampStatus = 0; + u_char *regs = dev->usbDev.a_bRegs; + HWDef *hw = &dev->usbDev.HwSetting; + DCapsDef *sc = &dev->usbDev.Caps; + SANE_Byte reg, msk, val; if( NULL == hw ) { DBG( _DBG_ERROR, "NULL-Pointer detected: usb_GetLampStatus()\n" ); @@ -928,6 +1055,7 @@ static int usb_GetLampStatus( Plustek_Device *dev ) usbio_ReadReg( dev->fd, 0x29, ® ); if( reg & 3 ) iLampStatus |= DEV_LampReflection; + } else { /* check if the lamp is on */ @@ -948,9 +1076,10 @@ static int usb_GetLampStatus( Plustek_Device *dev ) iLampStatus |= DEV_LampTPA; } + /* CanoScan D660U extra vaganza... */ if((dev->usbDev.vendor == 0x04A9) && (dev->usbDev.product==0x2208)) { sanei_lm983x_read( dev->fd, 0x29, ®s[0x29], 3, SANE_TRUE ); - DBG( _DBG_INFO, "[29]=0x%02x, [2A]=0x%02x, [2B]=0x%02x\n", + DBG( _DBG_INFO, "[29]=0x%02x, [2A]=0x%02x, [2B]=0x%02x\n", regs[0x29], regs[0x2a], regs[0x2b] ); } } @@ -982,8 +1111,8 @@ static int usb_GetLampStatus( Plustek_Device *dev ) /** usb_switchLampX * used for all devices that use some misc I/O pins to switch the lamp */ -static SANE_Bool usb_switchLampX( Plustek_Device *dev, - SANE_Bool on, SANE_Bool tpa ) +static SANE_Bool +usb_switchLampX( Plustek_Device *dev, SANE_Bool on, SANE_Bool tpa ) { SANE_Byte reg, msk; DCapsDef *sc = &dev->usbDev.Caps; @@ -1013,7 +1142,8 @@ static SANE_Bool usb_switchLampX( Plustek_Device *dev, /** usb_switchLamp * used for all devices that use some misc I/O pins to switch the lamp */ -static SANE_Bool usb_switchLamp( Plustek_Device *dev, SANE_Bool on ) +static SANE_Bool +usb_switchLamp( Plustek_Device *dev, SANE_Bool on ) { SANE_Bool result; @@ -1023,12 +1153,16 @@ static SANE_Bool usb_switchLamp( Plustek_Device *dev, SANE_Bool on ) } else { result = usb_switchLampX( dev, on, SANE_FALSE ); } + + /* to switch off CIS, we need to tweak the lampoff/on regs */ + usb_AdjustLamps( dev, on ); return result; } /** usb_LedOn */ -static void usb_LedOn( Plustek_Device *dev, SANE_Bool fOn ) +static void +usb_LedOn( Plustek_Device *dev, SANE_Bool fOn ) { u_char value; @@ -1049,7 +1183,8 @@ static void usb_LedOn( Plustek_Device *dev, SANE_Bool fOn ) /** usb_FillLampRegs * set all the registers controlling the lamps */ -static void usb_FillLampRegs( Plustek_Device *dev ) +static void +usb_FillLampRegs( Plustek_Device *dev ) { HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; @@ -1075,8 +1210,8 @@ static void usb_FillLampRegs( Plustek_Device *dev ) /** usb_LampOn */ -static SANE_Bool usb_LampOn( Plustek_Device *dev, - SANE_Bool fOn, SANE_Bool fResetTimer ) +static SANE_Bool +usb_LampOn( Plustek_Device *dev, SANE_Bool fOn, SANE_Bool fResetTimer ) { DCapsDef *sc = &dev->usbDev.Caps; ScanDef *scanning = &dev->scanning; @@ -1210,7 +1345,8 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev, * it should contain all we need * @return - Nothing */ -static void usb_ResetRegisters( Plustek_Device *dev ) +static void +usb_ResetRegisters( Plustek_Device *dev ) { int linend; @@ -1224,7 +1360,11 @@ static void usb_ResetRegisters( Plustek_Device *dev ) memcpy( regs+0x0f, &hw->bReg_0x0f_Color, 10 ); regs[0x1a] = _HIBYTE( hw->StepperPhaseCorrection ); regs[0x1b] = _LOBYTE( hw->StepperPhaseCorrection ); + #if 0 + regs[0x1c] = hw->bOpticBlackStart; + regs[0x1d] = hw->bOpticBlackEnd; + regs[0x1e] = _HIBYTE( hw->wActivePixelsStart ); regs[0x1f] = _LOBYTE( hw->wActivePixelsStart ); #endif @@ -1232,7 +1372,7 @@ static void usb_ResetRegisters( Plustek_Device *dev ) regs[0x21] = _LOBYTE( hw->wLineEnd ); regs[0x22] = _HIBYTE( hw->bOpticBlackStart ); - regs[0x22] = _LOBYTE( hw->bOpticBlackStart ); + regs[0x23] = _LOBYTE( hw->bOpticBlackStart ); linend = hw->bOpticBlackStart + hw->wLineEnd; if( linend < (hw->wLineEnd-20)) @@ -1282,9 +1422,11 @@ static void usb_ResetRegisters( Plustek_Device *dev ) regs[0x59], regs[0x5a], regs[0x5b] ); } -/** usb_ModuleStatus +/** function which checks if we are already in home position or not. + * */ -static SANE_Bool usb_ModuleStatus( Plustek_Device *dev ) +static SANE_Bool +usb_SensorStatus( Plustek_Device *dev ) { u_char value; HWDef *hw = &dev->usbDev.HwSetting; @@ -1295,12 +1437,11 @@ static SANE_Bool usb_ModuleStatus( Plustek_Device *dev ) return SANE_TRUE; #endif + /* read the status register */ _UIO( usbio_ReadReg( dev->fd, 2, &value )); - - if( value & 1 ) { + if( value & 1 ) { _UIO( usbio_ReadReg( dev->fd, 0x7, &value)); - if( value ) { usbio_WriteReg( dev->fd, 0x07, 0 ); @@ -1319,15 +1460,17 @@ static SANE_Bool usb_ModuleStatus( Plustek_Device *dev ) _UIO( usbio_ReadReg( dev->fd, 0x7, &value )); - if( !(value & 2)) + if( !(value & 2)) { usb_ModuleToHome( dev, SANE_FALSE ); + } return SANE_FALSE; } /** */ -static void usb_LampSwitch( Plustek_Device *dev, SANE_Bool sw ) +static void +usb_LampSwitch( Plustek_Device *dev, SANE_Bool sw ) { int handle = -1; @@ -1355,10 +1498,11 @@ static Plustek_Device *dev_xxx = NULL; /** ISR to switch lamp off after time has elapsed */ -static void usb_LampTimerIrq( int sig ) +static void +usb_LampTimerIrq( int sig ) { if( NULL == dev_xxx ) - return; + return; _VAR_NOT_USED( sig ); DBG( _DBG_INFO, "LAMP OFF!!!\n" ); @@ -1368,7 +1512,8 @@ static void usb_LampTimerIrq( int sig ) /** usb_StartLampTimer */ -static void usb_StartLampTimer( Plustek_Device *dev ) +static void +usb_StartLampTimer( Plustek_Device *dev ) { sigset_t block, pause_mask; struct sigaction s; @@ -1414,7 +1559,8 @@ static void usb_StartLampTimer( Plustek_Device *dev ) /** usb_StopLampTimer */ -static void usb_StopLampTimer( Plustek_Device *dev ) +static void +usb_StopLampTimer( Plustek_Device *dev ) { sigset_t block, pause_mask; @@ -1435,38 +1581,15 @@ static void usb_StopLampTimer( Plustek_Device *dev ) DBG( _DBG_INFO, "Lamp-Timer stopped\n" ); } -/** - * This function is used to detect a cancel condition, - * our ESC key is the SIGUSR1 signal. It is sent by the backend when the - * cancel button has been pressed - * - * @param - none - * @return the function returns SANE_TRUE if a cancel condition has been - * detected, if not, it returns SANE_FALSE - */ -static SANE_Bool usb_IsEscPressed( void ) -{ - sigset_t sigs; - - sigpending( &sigs ); - if( sigismember( &sigs, SIGUSR1 )) { - DBG( _DBG_INFO, "SIGUSR1 is pending --> Cancel detected\n" ); - return SANE_TRUE; - } - - return SANE_FALSE; -} - /** wait until warmup has been done */ -static SANE_Bool usb_Wait4Warmup( Plustek_Device *dev ) +static SANE_Bool +usb_Wait4Warmup( Plustek_Device *dev ) { u_long dw; struct timeval t; - HWDef *hw = &dev->usbDev.HwSetting; - - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { DBG(_DBG_INFO,"Warmup: skipped for CIS devices\n" ); return SANE_TRUE; } @@ -1499,7 +1622,8 @@ static SANE_Bool usb_Wait4Warmup( Plustek_Device *dev ) /** function for TPA autodection (EPSON & UMAX devices) */ -static SANE_Bool usb_HasTPA( Plustek_Device *dev ) +static SANE_Bool +usb_HasTPA( Plustek_Device *dev ) { static char model[] = { "3450" }; u_char val; @@ -1559,7 +1683,8 @@ static SANE_Bool usb_HasTPA( Plustek_Device *dev ) /** function for reading the button states */ -static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s ) +static SANE_Bool +usb_UpdateButtonStatus( Plustek_Scanner *s ) { u_char mio[3]; SANE_Byte val, mask; @@ -1628,7 +1753,17 @@ static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s ) /* the generic section... */ val >>= 2; - bc = 0; + bc = 0; + + /* only use the "valid" ports, that reflect a button */ + if( _WAF_MISC_IO_BUTTONS & caps->workaroundFlag ) { + if((caps->lamp & _PORT0) == 0) + mio[0] = 0xff; + if((caps->lamp & _PORT1) == 0) + mio[1] = 0xff; + if((caps->lamp & _PORT2) == 0) + mio[2] = 0xff; + } for( i = 0; i < 3; i++ ) { @@ -1661,4 +1796,5 @@ static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s ) sanei_access_unlock( dev->sane.name ); return SANE_TRUE; } + /* END PLUSTEK-USBHW.C ......................................................*/ diff --git a/backend/plustek-usbimg.c b/backend/plustek-usbimg.c index 208dfad5d..82f52a304 100644 --- a/backend/plustek-usbimg.c +++ b/backend/plustek-usbimg.c @@ -7,7 +7,7 @@ * @brief Image processing functions for copying and scaling image lines. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -26,10 +26,12 @@ * - 0.47 - added big-endian/little endian stuff * - 0.48 - fixed usb_ColorDuplicateGray16() and * usb_ColorScaleGray16() - * - added usb_BWScaleFromColor() and usb_BWDuplicateFromColor + * - added usb_BWScaleFromColor() and usb_BWDuplicateFromColor() * - cleanup * - 0.49 - a_bRegs is now part of the device structure * - 0.50 - cleanup + * - 0.51 - added usb_ColorDuplicateGray16_2(), usb_ColorScaleGray16_2() + * usb_BWScaleFromColor_2() and usb_BWDuplicateFromColor_2() * . *
* This file is part of the SANE package. @@ -579,7 +581,7 @@ static void usb_ColorDuplicateGray16( Plustek_Device *dev ) ScanDef *scan = &dev->scanning; SANE_Bool swap = usb_HostSwap(); - usb_AverageColorByte( dev ); + usb_AverageColorWord( dev ); if (scan->sParam.bSource == SOURCE_ADF) { next = -1; @@ -628,6 +630,71 @@ static void usb_ColorDuplicateGray16( Plustek_Device *dev ) } } +/** + */ +static void usb_ColorDuplicateGray16_2( Plustek_Device *dev ) +{ + int next; + u_char ls; + u_long dw, pixels; + HiLoDef tmp; + ScanDef *scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); + + usb_AverageColorWord( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) { + next = -1; + pixels = scan->sParam.Size.dwPixels - 1; + } else { + next = 1; + pixels = 0; + } + if( scan->dwFlag & SCANFLAG_RightAlign ) + ls = Shift; + else + ls = 0; + + switch(scan->fGrayFromColor) { + case 1: + if( swap ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + tmp = *((HiLoDef*)&scan->Red.pw[dw]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + scan->UserBuf.pw[pixels] = scan->Red.pw[dw] >> ls; + } + } + break; + case 2: + if( swap ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + tmp = *((HiLoDef*)&scan->Green.pw[dw]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + scan->UserBuf.pw[pixels] = scan->Green.pw[dw] >> ls; + } + } + break; + case 3: + if( swap ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + tmp = *((HiLoDef*)&scan->Blue.pw[dw]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, pixels += next) { + scan->UserBuf.pw[pixels] = scan->Blue.pw[dw] >> ls; + } + } + break; + } +} + /** */ static void usb_GrayDuplicate8( Plustek_Device *dev ) @@ -735,7 +802,7 @@ static void usb_BWDuplicate( Plustek_Device *dev ) } /** generate binary data from one of the three color inputs according to the - * value in fGrayFromColor + * value in fGrayFromColor (CCD version) */ static void usb_BWDuplicateFromColor( Plustek_Device *dev ) { @@ -776,6 +843,46 @@ static void usb_BWDuplicateFromColor( Plustek_Device *dev ) } } +/** generate binary data from one of the three color inputs according to the + * value in fGrayFromColor (CIS version) + */ +static void usb_BWDuplicateFromColor_2( Plustek_Device *dev ) +{ + int next; + u_char d, *dest, *src; + u_short j; + u_long pixels; + ScanDef *scan = &dev->scanning; + + if( scan->sParam.bSource == SOURCE_ADF ) { + dest = scan->UserBuf.pb + scan->sParam.Size.dwPixels - 1; + next = -1; + } else { + dest = scan->UserBuf.pb; + next = 1; + } + + switch(scan->fGrayFromColor) { + case 1: src = scan->Red.pb; break; + case 3: src = scan->Blue.pb; break; + default: src = scan->Green.pb; break; + } + + d = j = 0; + for( pixels = scan->sParam.Size.dwPixels; pixels; pixels--, src++ ) { + + if( *src != 0 ) + d |= BitTable[j]; + j++; + if( j == 8 ) { + *dest = d; + dest += next; + + d = j = 0; + } + } +} + /************************** the scaling functions ****************************/ /** @@ -954,6 +1061,97 @@ static void usb_ColorScaleGray16( Plustek_Device *dev ) } } +/** + */ +static void usb_ColorScaleGray16_2( Plustek_Device *dev ) +{ + u_char ls; + int izoom, ddax, next; + u_long dw, pixels, bitsput; + HiLoDef tmp; + SANE_Bool swap = usb_HostSwap(); + ScanDef *scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + dw = scan->sParam.Size.dwPixels; + + if( scan->sParam.bSource == SOURCE_ADF ) { + next = -1; + pixels = scan->sParam.Size.dwPixels - 1; + } else { + next = 1; + pixels = 0; + } + + izoom = usb_GetScaler( scan ); + + if( scan->dwFlag & SCANFLAG_RightAlign ) + ls = Shift; + else + ls = 0; + + switch( scan->fGrayFromColor ) { + + case 1: + for( bitsput = 0, ddax = 0; dw; bitsput++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dw > 0)) { + if( swap ) { + tmp = *((HiLoDef*)&scan->Red.pw[bitsput]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } else { + scan->UserBuf.pw[pixels] = scan->Red.pw[dw] >> ls; + } + pixels += next; + ddax += izoom; + dw--; + } + } + break; + + case 2: + for( bitsput = 0, ddax = 0; dw; bitsput++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dw > 0)) { + if( swap ) { + tmp = *((HiLoDef*)&scan->Green.pw[bitsput]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } else { + scan->UserBuf.pw[pixels] = scan->Green.pw[bitsput] >> ls; + } + pixels += next; + ddax += izoom; + dw--; + } + } + break; + + case 3: + for( bitsput = 0, ddax = 0; dw; bitsput++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dw > 0)) { + if( swap ) { + tmp = *((HiLoDef*)&scan->Blue.pw[bitsput]); + scan->UserBuf.pw[pixels] = _HILO2WORD(tmp) >> ls; + } else { + scan->UserBuf.pw[pixels] = scan->Blue.pw[bitsput] >> ls; + } + pixels += next; + ddax += izoom; + dw--; + } + } + break; + } +} + /** here we copy and scale from scanner world to user world... */ static void usb_ColorScale8( Plustek_Device *dev ) @@ -1300,6 +1498,55 @@ static void usb_BWScaleFromColor( Plustek_Device *dev ) } } +/** + */ +static void usb_BWScaleFromColor_2( Plustek_Device *dev ) +{ + u_char d, *dest, *src; + u_short j; + u_long pixels; + int izoom, ddax, next; + ScanDef *scan = &dev->scanning; + + if (scan->sParam.bSource == SOURCE_ADF) { + dest = scan->UserBuf.pb + scan->sParam.Size.dwPixels - 1; + next = -1; + } else { + dest = scan->UserBuf.pb; + next = 1; + } + + /* setup the source buffer */ + switch(scan->fGrayFromColor) { + case 1: src = scan->Red.pb; break; + case 3: src = scan->Blue.pb; break; + default: src = scan->Green.pb; break; + } + + izoom = usb_GetScaler( scan ); + ddax = 0; + + d = j = 0; + for( pixels = scan->sParam.Size.dwPixels; pixels; src++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (pixels > 0)) { + + if( *src != 0 ) + d |= BitTable[j]; + j++; + if( j == 8 ) { + *dest = d; + dest += next; + d = j = 0; + } + ddax += izoom; + pixels--; + } + } +} + /** */ static void usb_GrayScale8( Plustek_Device *dev ) @@ -1455,8 +1702,13 @@ static void usb_GetImageProc( Plustek_Device *dev ) DBG( _DBG_INFO, "ImageProc is: ColorScale16\n" ); } if (scan->fGrayFromColor) { - scan->pfnProcess = usb_ColorScaleGray16; - DBG( _DBG_INFO, "ImageProc is: ColorScaleGray16\n" ); + if( usb_IsCISDevice(dev)){ + scan->pfnProcess = usb_ColorScaleGray16_2; + DBG( _DBG_INFO, "ImageProc is: ColorScaleGray16_2\n" ); + } else { + scan->pfnProcess = usb_ColorScaleGray16; + DBG( _DBG_INFO, "ImageProc is: ColorScaleGray16\n" ); + } } } else if (scan->dwFlag & SCANFLAG_Pseudo48) { scan->pfnProcess = usb_ColorScalePseudo16; @@ -1464,9 +1716,14 @@ static void usb_GetImageProc( Plustek_Device *dev ) } else if (scan->fGrayFromColor) { - if( usb_IsCISDevice(dev)){ - scan->pfnProcess = usb_ColorScaleGray_2; - DBG( _DBG_INFO, "ImageProc is: ColorScaleGray_2\n" ); + if( usb_IsCISDevice(dev)){ + if (scan->fGrayFromColor > 7 ) { + scan->pfnProcess = usb_BWScaleFromColor_2; + DBG( _DBG_INFO, "ImageProc is: BWScaleFromColor_2\n" ); + } else { + scan->pfnProcess = usb_ColorScaleGray_2; + DBG( _DBG_INFO, "ImageProc is: ColorScaleGray_2\n" ); + } } else { if (scan->fGrayFromColor > 7 ) { scan->pfnProcess = usb_BWScaleFromColor; @@ -1517,7 +1774,7 @@ static void usb_GetImageProc( Plustek_Device *dev ) case SCANDATATYPE_Color: if (scan->sParam.bBitDepth > 8) { - if( usb_IsCISDevice(dev)){ + if( usb_IsCISDevice(dev)){ scan->pfnProcess = usb_ColorDuplicate16_2; DBG( _DBG_INFO, "ImageProc is: ColorDuplicate16_2\n" ); } else { @@ -1525,16 +1782,26 @@ static void usb_GetImageProc( Plustek_Device *dev ) DBG( _DBG_INFO, "ImageProc is: ColorDuplicate16\n" ); } if (scan->fGrayFromColor) { - scan->pfnProcess = usb_ColorDuplicateGray16; - DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray16\n" ); + if( usb_IsCISDevice(dev)){ + scan->pfnProcess = usb_ColorDuplicateGray16_2; + DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray16_2\n" ); + } else { + scan->pfnProcess = usb_ColorDuplicateGray16; + DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray16\n" ); + } } } else if (scan->dwFlag & SCANFLAG_Pseudo48) { scan->pfnProcess = usb_ColorDuplicatePseudo16; DBG( _DBG_INFO, "ImageProc is: ColorDuplicatePseudo16\n" ); } else if (scan->fGrayFromColor) { - if( usb_IsCISDevice(dev)){ - scan->pfnProcess = usb_ColorDuplicateGray_2; - DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray_2\n" ); + if( usb_IsCISDevice(dev)){ + if (scan->fGrayFromColor > 7 ) { + scan->pfnProcess = usb_BWDuplicateFromColor_2; + DBG( _DBG_INFO, "ImageProc is: BWDuplicateFromColor_2\n" ); + } else { + scan->pfnProcess = usb_ColorDuplicateGray_2; + DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray_2\n" ); + } } else { if (scan->fGrayFromColor > 7 ) { scan->pfnProcess = usb_BWDuplicateFromColor; diff --git a/backend/plustek-usbio.c b/backend/plustek-usbio.c index d98fb9848..77ecb9d4f 100644 --- a/backend/plustek-usbio.c +++ b/backend/plustek-usbio.c @@ -7,7 +7,7 @@ * @brief Some I/O stuff. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * History: @@ -26,6 +26,7 @@ * - 0.50 - usbio_DetectLM983x() now returns error if register * could not be red * - usbio_ResetLM983x() checks for reg7 value before writing + * - 0.51 - allow dumpRegs to be called without valid fd * . *
* This file is part of the SANE package. @@ -165,37 +166,38 @@ static void dumpregs( int fd, SANE_Byte *cmp ) buf[0] = '\0'; - usbio_ReadReg(fd, 0x01, ®s[0x01]); - usbio_ReadReg(fd, 0x02, ®s[0x02]); - usbio_ReadReg(fd, 0x03, ®s[0x03]); - usbio_ReadReg(fd, 0x04, ®s[0x04]); - usbio_ReadReg(fd, 0x07, ®s[0x07]); + if( fd >= 0 ) { + usbio_ReadReg(fd, 0x01, ®s[0x01]); + usbio_ReadReg(fd, 0x02, ®s[0x02]); + usbio_ReadReg(fd, 0x03, ®s[0x03]); + usbio_ReadReg(fd, 0x04, ®s[0x04]); + usbio_ReadReg(fd, 0x07, ®s[0x07]); - sanei_lm983x_read( fd, 0x08, ®s[0x8], 0x80-0x8, SANE_TRUE ); + sanei_lm983x_read( fd, 0x08, ®s[0x8], 0x80-0x8, SANE_TRUE ); - for( i = 0x0; i < 0x80; i++ ) { + for( i = 0x0; i < 0x80; i++ ) { - if((i%16) ==0 ) { + if((i%16) ==0 ) { - if( buf[0] ) - DBG( _DBG_DREGS, "%s\n", buf ); - sprintf( buf, "0x%02x:", i ); + if( buf[0] ) + DBG( _DBG_DREGS, "%s\n", buf ); + sprintf( buf, "0x%02x:", i ); + } + + if((i%8)==0) + strcat( buf, " "); + + /* the dataport read returns with "0 Bytes read", of course. */ + if((i == 0) || (i == 5) || (i == 6)) + strcat( buf, "XX "); + else { + + sprintf( b2, "%02x ", regs[i]); + strcat( buf, b2 ); + } } - - if((i%8)==0) - strcat( buf, " "); - - /* the dataport read returns with "0 Bytes read", of course. */ - if((i == 0) || (i == 5) || (i == 6)) - strcat( buf, "XX "); - else { - - sprintf( b2, "%02x ", regs[i]); - strcat( buf, b2 ); - } - + DBG( _DBG_DREGS, "%s\n", buf ); } - DBG( _DBG_DREGS, "%s\n", buf ); if( cmp ) { diff --git a/backend/plustek-usbmap.c b/backend/plustek-usbmap.c index accf61815..343cec75a 100644 --- a/backend/plustek-usbmap.c +++ b/backend/plustek-usbmap.c @@ -7,7 +7,7 @@ * @brief Creating and manipulating lookup tables. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -21,6 +21,7 @@ * - 0.48 - added support for binary from color scans * - 0.49 - changed usb_MapDownload * - 0.50 - cleanup + * - 0.51 - no changes * . *
* This file is part of the SANE package. diff --git a/backend/plustek-usbscan.c b/backend/plustek-usbscan.c index c1ea0eb09..fe20a211a 100644 --- a/backend/plustek-usbscan.c +++ b/backend/plustek-usbscan.c @@ -7,7 +7,7 @@ * @brief Scanning... * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -28,6 +28,7 @@ * - using now PhyDpi.y as selector for the motor MCLK range * - changed usb_MapDownload prototype * - 0.50 - cleanup + * - 0.51 - added usb_get_res() and usb_GetPhyPixels() * . *
* This file is part of the SANE package. @@ -70,6 +71,8 @@ *
*/ +#define DIVIDER 8 + /** array used to get motor-settings and mclk-settings */ static int dpi_ranges[] = { 75,100,150,200,300,400,600,800,1200,2400 }; @@ -100,7 +103,8 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device*, u_char ); * @param val2 - second parameter * @return val1 if val1 < val2, else val1 */ -static u_long usb_min( u_long val1, u_long val2 ) +static u_long +usb_min( u_long val1, u_long val2 ) { if( val1 > val2 ) return val2; @@ -112,13 +116,30 @@ static u_long usb_min( u_long val1, u_long val2 ) * @param val2 - second parameter * @return val1 if val1 > val2, else val2 */ -static u_long usb_max( u_long val1, u_long val2 ) +static u_long +usb_max( u_long val1, u_long val2 ) { if( val1 > val2 ) return val1; return val2; } +/** function to get the possible resolution for a specific base resolution, + * according to the dividers a LM983x offers. + * @param base - scanners optical resolution + * @param idx - which divider to use + */ +static u_short +usb_get_res( u_short base, u_short idx ) +{ + double div_list[DIVIDER] = { 12.0, 8.0, 6.0, 4.0, 3.0, 2.0, 1.5, 1.0 }; + + if( idx == 0 || idx > DIVIDER ) + return 0; + + return (u_short)((double)base/div_list[idx-1]); +} + /** Set the horizontal DPI divider. * Affected registers:
* 0x09 - Horizontal DPI divider HDPI_DIV
@@ -128,7 +149,8 @@ static u_long usb_max( u_long val1, u_long val2 ) * @param xdpi - user specified horizontal resolution * @return - the function returns the "normalized" horizontal resolution. */ -static u_short usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi ) +static u_short +usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi ) { u_short res; ScanDef *scanning = &dev->scanning; @@ -205,7 +227,8 @@ static u_short usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi ) * @param ydpi - user specified vertical resolution * @return - */ -static u_short usb_SetAsicDpiY( Plustek_Device *dev, u_short ydpi ) +static u_short +usb_SetAsicDpiY( Plustek_Device *dev, u_short ydpi ) { ScanDef *scanning = &dev->scanning; DCapsDef *sCaps = &dev->usbDev.Caps; @@ -257,7 +280,8 @@ static u_short usb_SetAsicDpiY( Plustek_Device *dev, u_short ydpi ) * @param pParam - pointer to the current scan parameters * @return - Nothing */ -static void usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) { HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; @@ -269,9 +293,9 @@ static void usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) regs[0x26] = hw->bReg_0x26 & 0x7; /* if set to one channel color, we select the blue channel - * as input source, this is the default, but I don't know - * what happens, if we deselect this - */ + * as input source, this is the default, but I don't know + * what happens, if we deselect this + */ if( regs[0x26] & _ONE_CH_COLOR ) regs[0x26] |= (_BLUE_CH | 0x01); @@ -290,7 +314,7 @@ static void usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) memcpy( ®s[0x0f], hw->bReg_0x0f_Mono, 10 ); break; } - + regs[0x27] = hw->bReg_0x27; if( pParam->bBitDepth > 8 ) { @@ -301,6 +325,45 @@ static void usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) } } +/** + * Data output from NS983X should be times of 2-byte and every line + * will append 2 status bytes + */ +static void +usb_GetPhyPixels( Plustek_Device *dev, ScanParam *sp ) +{ + sp->Size.dwValidPixels = sp->Size.dwPixels * sp->PhyDpi.x / sp->UserDpi.x; + + if (sp->bBitDepth == 1) { + + /* Pixels should be times of 16 */ + sp->Size.dwPhyPixels = + (sp->Size.dwValidPixels + 15UL) & 0xfffffff0UL; + sp->Size.dwPhyBytes = sp->Size.dwPhyPixels / 8UL + 2UL; + + } else if (sp->bBitDepth == 8) { + + /* Pixels should be times of 2 */ + sp->Size.dwPhyPixels = (sp->Size.dwValidPixels + 1UL) & 0xfffffffeUL; + sp->Size.dwPhyBytes = sp->Size.dwPhyPixels * sp->bChannels + 2UL; + + /* need to be adjusted fo CIS devices in color mode */ + if(usb_IsCISDevice( dev ) && (sp->bDataType == SCANDATATYPE_Color)) { + sp->Size.dwPhyBytes *= 3; + } + } + else /* sp->bBitDepth == 16 */ + { + sp->Size.dwPhyPixels = sp->Size.dwValidPixels; + sp->Size.dwPhyBytes = sp->Size.dwPhyPixels * 2 * sp->bChannels + 2UL; + + /* need to be adjusted fo CIS devices in color mode */ + if(usb_IsCISDevice( dev ) && (sp->bDataType == SCANDATATYPE_Color)) { + sp->Size.dwPhyBytes *= 3; + } + } +} + /** Calculate basic image settings like the number of physical bytes per line * etc... * Affected registers:
@@ -313,7 +376,8 @@ static void usb_SetColorAndBits( Plustek_Device *dev, ScanParam *pParam ) * @param pParam - pointer to the current scan parameters * @return - Nothing */ -static void usb_GetScanRect( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_GetScanRect( Plustek_Device *dev, ScanParam *sp ) { u_short wDataPixelStart, wLineEnd; @@ -322,75 +386,35 @@ static void usb_GetScanRect( Plustek_Device *dev, ScanParam *pParam ) u_char *regs = dev->usbDev.a_bRegs; /* Convert pixels to physical dpi based */ - pParam->Size.dwValidPixels = pParam->Size.dwPixels * - pParam->PhyDpi.x / pParam->UserDpi.x; - -/* HEINER: check ADF stuff... */ -#if 0 - if(pParam->bCalibration != PARAM_Gain && - pParam->bCalibration != PARAM_Offset && ScanInf.m_fADF) - wDataPixelStart = 2550 * sCaps->OpticDpi.x / 300UL - - (u_short)(m_dHDPIDivider * pParam->Size.dwValidPixels + 0.5); - else -#endif - wDataPixelStart = (u_short)((u_long) pParam->Origin.x * - sCaps->OpticDpi.x / 300UL); - - /* Data output from NS983X should be times of 2-byte and every line - * will append 2 status bytes - */ - if (pParam->bBitDepth == 1) - { - /* Pixels should be times of 16 */ - pParam->Size.dwPhyPixels = - (pParam->Size.dwValidPixels + 15UL) & 0xfffffff0UL; - pParam->Size.dwPhyBytes = pParam->Size.dwPhyPixels / 8UL + 2UL; - } - else if (pParam->bBitDepth == 8) - { - /* Pixels should be times of 2 */ - pParam->Size.dwPhyPixels = - (pParam->Size.dwValidPixels + 1UL) & 0xfffffffeUL; - pParam->Size.dwPhyBytes = - pParam->Size.dwPhyPixels * pParam->bChannels + 2UL; - - if((hw->bReg_0x26 & _ONE_CH_COLOR) && - (pParam->bDataType == SCANDATATYPE_Color)) { - pParam->Size.dwPhyBytes *= 3; - } - } - else /* pParam->bBitDepth == 16 */ - { - pParam->Size.dwPhyPixels = pParam->Size.dwValidPixels; - pParam->Size.dwPhyBytes = - pParam->Size.dwPhyPixels * 2 * pParam->bChannels + 2UL; - - if((hw->bReg_0x26 & _ONE_CH_COLOR) && - (pParam->bDataType == SCANDATATYPE_Color)) { - pParam->Size.dwPhyBytes *= 3; - } - } + usb_GetPhyPixels( dev, sp ); /* Compute data start pixel */ - wDataPixelStart = (u_short)((u_long)pParam->Origin.x * - sCaps->OpticDpi.x / 300UL); +#if 0 +/* HEINER: check ADF stuff... */ + if(sp->bCalibration != PARAM_Gain && + sp->bCalibration != PARAM_Offset && ScanInf.m_fADF) + wDataPixelStart = 2550 * sCaps->OpticDpi.x / 300UL - + (u_short)(m_dHDPIDivider * sp->Size.dwValidPixels + 0.5); + else +#endif + wDataPixelStart = (u_short)((u_long)sp->Origin.x * + sCaps->OpticDpi.x / 300UL); /* during the calibration steps, we read the entire CCD data */ - if((pParam->bCalibration != PARAM_Gain) && - (pParam->bCalibration != PARAM_Offset)) { + if((sp->bCalibration != PARAM_Gain)&&(sp->bCalibration != PARAM_Offset)) { /* HEINER: check ADF stuff... */ #if 0 if(ScanInf.m_fADF) { wDataPixelStart = 2550 * sCaps->OpticDpi.x / 300UL - - (u_short)(m_dHDPIDivider * pParam->Size.dwValidPixels + 0.5); + (u_short)(m_dHDPIDivider * sp->Size.dwValidPixels + 0.5); } #endif wDataPixelStart += hw->wActivePixelsStart; } wLineEnd = wDataPixelStart + (u_short)(m_dHDPIDivider * - pParam->Size.dwPhyPixels + 0.5); + sp->Size.dwPhyPixels + 0.5); DBG( _DBG_INFO2, "* DataPixelStart=%u, LineEnd=%u\n", wDataPixelStart, wLineEnd ); @@ -414,76 +438,77 @@ static void usb_GetScanRect( Plustek_Device *dev, ScanParam *pParam ) wLineEnd-wDataPixelStart, m_dHDPIDivider); /* Y origin */ - if( pParam->bCalibration == PARAM_Scan ) { + if( sp->bCalibration == PARAM_Scan ) { if( hw->motorModel == MODEL_Tokyo600 ) { - if(pParam->PhyDpi.x <= 75) - pParam->Origin.y += 20; - else if(pParam->PhyDpi.x <= 100) + if(sp->PhyDpi.x <= 75) + sp->Origin.y += 20; + else if(sp->PhyDpi.x <= 100) { - if (pParam->bDataType == SCANDATATYPE_Color) - pParam->Origin.y += 0; + if (sp->bDataType == SCANDATATYPE_Color) + sp->Origin.y += 0; else - pParam->Origin.y -= 6; + sp->Origin.y -= 6; } - else if(pParam->PhyDpi.x <= 150) + else if(sp->PhyDpi.x <= 150) { - if (pParam->bDataType == SCANDATATYPE_Color) - pParam->Origin.y -= 0; + if (sp->bDataType == SCANDATATYPE_Color) + sp->Origin.y -= 0; } - else if(pParam->PhyDpi.x <= 200) + else if(sp->PhyDpi.x <= 200) { - if (pParam->bDataType == SCANDATATYPE_Color) - pParam->Origin.y -= 10; + if (sp->bDataType == SCANDATATYPE_Color) + sp->Origin.y -= 10; else - pParam->Origin.y -= 4; + sp->Origin.y -= 4; } - else if(pParam->PhyDpi.x <= 300) + else if(sp->PhyDpi.x <= 300) { - if (pParam->bDataType == SCANDATATYPE_Color) - pParam->Origin.y += 16; + if (sp->bDataType == SCANDATATYPE_Color) + sp->Origin.y += 16; else - pParam->Origin.y -= 18; + sp->Origin.y -= 18; } - else if(pParam->PhyDpi.x <= 400) + else if(sp->PhyDpi.x <= 400) { - if (pParam->bDataType == SCANDATATYPE_Color) - pParam->Origin.y += 15; - else if(pParam->bDataType == SCANDATATYPE_BW) - pParam->Origin.y += 4; + if (sp->bDataType == SCANDATATYPE_Color) + sp->Origin.y += 15; + else if(sp->bDataType == SCANDATATYPE_BW) + sp->Origin.y += 4; } - else /* if(pParam->PhyDpi.x <= 600) */ + else /* if(sp->PhyDpi.x <= 600) */ { - if (pParam->bDataType == SCANDATATYPE_Gray) - pParam->Origin.y += 4; + if (sp->bDataType == SCANDATATYPE_Gray) + sp->Origin.y += 4; } } /* Add gray mode offset (Green offset, we assume the CCD are * always be RGB or BGR order). */ - if (pParam->bDataType != SCANDATATYPE_Color) - pParam->Origin.y += (u_long)(300UL * + if (sp->bDataType != SCANDATATYPE_Color) + sp->Origin.y += (u_long)(300UL * sCaps->bSensorDistance / sCaps->OpticDpi.y); } - pParam->Origin.y=(u_short)((u_long)pParam->Origin.y * hw->wMotorDpi/300UL); + sp->Origin.y=(u_short)((u_long)sp->Origin.y * hw->wMotorDpi/300UL); /* Something wrong, but I can not find it. */ if( hw->motorModel == MODEL_HuaLien && sCaps->OpticDpi.x == 600) - pParam->Origin.y = pParam->Origin.y * 297 / 298; + sp->Origin.y = sp->Origin.y * 297 / 298; DBG(_DBG_INFO2,"* Full Steps to Skip at Start = 0x%04x\n", - pParam->Origin.y); + sp->Origin.y); - regs[0x4a] = _HIBYTE( pParam->Origin.y ); - regs[0x4b] = _LOBYTE( pParam->Origin.y ); + regs[0x4a] = _HIBYTE( sp->Origin.y ); + regs[0x4b] = _LOBYTE( sp->Origin.y ); } /** preset scan stepsize and fastfeed stepsize */ -static void usb_PresetStepSize( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_PresetStepSize( Plustek_Device *dev, ScanParam *pParam ) { u_short ssize; double mclkdiv = pParam->dMCLK; @@ -503,7 +528,8 @@ static void usb_PresetStepSize( Plustek_Device *dev, ScanParam *pParam ) /** calculate default phase difference DPD */ -static void usb_GetDPD( Plustek_Device *dev ) +static void +usb_GetDPD( Plustek_Device *dev ) { int qtcnt; /* quarter speed count count reg 51 b2..3 */ int hfcnt; /* half speed count reg 51 b0..1 */ @@ -556,7 +582,8 @@ static void usb_GetDPD( Plustek_Device *dev ) /** */ -static int usb_GetMCLKDiv( Plustek_Device *dev ) +static int +usb_GetMCLKDiv( Plustek_Device *dev ) { int j, pixelbits, pixelsperline, r; int minmclk, maxmclk, mclkdiv; @@ -627,7 +654,8 @@ static int usb_GetMCLKDiv( Plustek_Device *dev ) * at least we give the master clock divider and adjust the step size * and integration time (for 14/16 bit modes) */ -static double usb_GetMCLKDivider( Plustek_Device *dev, ScanParam *pParam ) +static double +usb_GetMCLKDivider( Plustek_Device *dev, ScanParam *pParam ) { double dMaxIntegrationTime; double dMaxMCLKDivider; @@ -729,9 +757,10 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, ScanParam *pParam ) /** calculate the step size of each scan step */ -static void usb_GetStepSize( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_GetStepSize( Plustek_Device *dev, ScanParam *pParam ) { - HWDef *hw = &dev->usbDev.HwSetting; + HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; /* Compute step size using equation 1 */ @@ -758,7 +787,8 @@ static void usb_GetStepSize( Plustek_Device *dev, ScanParam *pParam ) /** */ -static void usb_GetLineLength( Plustek_Device *dev ) +static void +usb_GetLineLength( Plustek_Device *dev, ScanParam *param ) { /* [note] * The ITA in this moment is always 0, it will be changed later when we @@ -767,21 +797,22 @@ static void usb_GetLineLength( Plustek_Device *dev ) * never call again, maybe we remove all factor with ITA here. */ int tr; - int tpspd; /* turbo/preview mode speed reg 0a b2..3 */ - int tpsel; /* turbo/preview mode select reg 0a b0..1 */ - int gbnd; /* guardband duration reg 0e b4..7 */ - int dur; /* pulse duration reg 0e b0..3 */ - int ntr; /* number of tr pulses reg 0d b7 */ - int afeop; /* scan mode, 0=pixel rate, 1=line rate, */ - /* 4=1 channel mode a, 5=1 channel mode b, reg 26 b0..2 */ - int ctmode; /* CIS tr timing mode reg 19 b0..1 */ - int tp; /* tpspd or 1 if tpsel=0 */ - int b; /* if ctmode=0, (ntr+1)*((2*gbnd)+dur+1), otherwise 1 */ - int tradj; /* ITA */ + int tpspd; /* turbo/preview mode speed reg 0a b2..3 */ + int tpsel; /* turbo/preview mode select reg 0a b0..1 */ + int gbnd; /* guardband duration reg 0e b4..7 */ + int dur; /* pulse duration reg 0e b0..3 */ + int ntr; /* number of tr pulses reg 0d b7 */ + int afeop; /* scan mode, 0=pixel rate, 1=line rate, */ + /* 4=1 channel mode a, 5=1 channel mode b, reg 26 b0..2 */ + int ctmode; /* CIS tr timing mode reg 19 b0..1 */ + int tp; /* tpspd or 1 if tpsel=0 */ + int b; /* if ctmode=0, (ntr+1)*((2*gbnd)+dur+1), otherwise 1 */ + int tradj; /* ITA */ int en_tradj; - - HWDef *hw = &dev->usbDev.HwSetting; - u_char *regs = dev->usbDev.a_bRegs; + u_short le; + HWDef *hw = &dev->usbDev.HwSetting; + ClkMotorDef *motor = usb_GetMotorSet( hw->motorModel ); + u_char *regs = dev->usbDev.a_bRegs; tpspd = (regs[0x0a] & 0x0c) >> 2; /* turbo/preview mode speed */ tpsel = regs[0x0a] & 3; /* turbo/preview mode select */ @@ -819,8 +850,21 @@ static void usb_GetLineLength( Plustek_Device *dev ) } if( ctmode == 2 ) /* CIS mode scanner */ b = 3; - - tr = m_bLineRateColor * (hw->wLineEnd + tp * (b + 3 - ntr)); + + /* it might be necessary to tweak this value, to keep the + * MCLK constant - see some sheet-fed devices + */ + le = hw->wLineEnd; + if (motor->dpi_thresh != 0) { + if( param->PhyDpi.y <= motor->dpi_thresh) { + le = motor->lineend; + DBG( _DBG_INFO2, "* Adjusting lineend: %u\n", le); + } + regs[0x20] = _HIBYTE( le ); + regs[0x21] = _LOBYTE( le ); + } + + tr = m_bLineRateColor * (le + tp * (b + 3 - ntr)); if( tradj == 0 ) { if( ctmode == 0 ) @@ -833,7 +877,7 @@ static void usb_GetLineLength( Plustek_Device *dev ) if( afeop != 0 ) { le_phi = (tradj + 1) / 2 + 1 + 6; - num_byteclk = ((le_phi + 8 * hw->wLineEnd + 8 * b + 4) / + num_byteclk = ((le_phi + 8 * le + 8 * b + 4) / (8 * tradj)) + 1; num_mclkf = 8 * tradj * num_byteclk; tr_fast_pix = num_byteclk; @@ -842,14 +886,14 @@ static void usb_GetLineLength( Plustek_Device *dev ) else /* 3 channel pixel rate color */ { le_phi = (tradj + 1) / 2 + 1 + 10 + 12; - num_byteclk = ((le_phi + 3 * 8 * hw->wLineEnd + 3 * 8 * b + 3 * 4) / + num_byteclk = ((le_phi + 3 * 8 * le + 3 * 8 * b + 3 * 4) / (3 * 8 * tradj)) + 1; num_mclkf = 3 * 8 * tradj * num_byteclk; tr_fast_pix = num_byteclk; extra_pix = (num_mclkf - le_phi) % (3 * 8); } - tr = b + hw->wLineEnd + 4 + tr_fast_pix; + tr = b + le + 4 + tr_fast_pix; if (extra_pix == 0) tr++; tr *= m_bLineRateColor; @@ -863,7 +907,8 @@ static void usb_GetLineLength( Plustek_Device *dev ) /** usb_GetMotorParam * registers 0x56, 0x57 */ -static void usb_GetMotorParam( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_GetMotorParam( Plustek_Device *dev, ScanParam *pParam ) { int idx, i; ClkMotorDef *clk; @@ -872,14 +917,14 @@ static void usb_GetMotorParam( Plustek_Device *dev, ScanParam *pParam ) HWDef *hw = &dev->usbDev.HwSetting; u_char *regs = dev->usbDev.a_bRegs; - if( !_IS_PLUSTEKMOTOR(hw->motorModel)) { - + if (!_IS_PLUSTEKMOTOR(hw->motorModel)) { + clk = usb_GetMotorSet( hw->motorModel ); md = clk->motor_sets; - idx = 0; + idx = 0; for( i = 0; i < _MAX_CLK; i++ ) { if( pParam->PhyDpi.y <= dpi_ranges[i] ) - break; + break; idx++; } if( idx >= _MAX_CLK ) @@ -900,44 +945,44 @@ static void usb_GetMotorParam( Plustek_Device *dev, ScanParam *pParam ) regs[0x44] = md[idx].scan_lines_per_line; DBG( _DBG_INFO2, "* Line Skipping : 0x43=0x%02x, 0x44=0x%02x\n", - regs[0x43], regs[0x44] ); + regs[0x43], regs[0x44] ); } } + } else { - } else { - if( sCaps->OpticDpi.x == 1200 ) { + if( sCaps->OpticDpi.x == 1200 ) { - switch( hw->motorModel ) { + switch( hw->motorModel ) { - case MODEL_HuaLien: - case MODEL_KaoHsiung: - default: - if(pParam->PhyDpi.x <= 200) - { - regs[0x56] = 1; - regs[0x57] = 48; /* 63; */ - } - else if(pParam->PhyDpi.x <= 300) - { - regs[0x56] = 2; /* 8; */ - regs[0x57] = 48; /* 56; */ - } - else if(pParam->PhyDpi.x <= 400) - { - regs[0x56] = 8; - regs[0x57] = 48; - } - else if(pParam->PhyDpi.x <= 600) - { - regs[0x56] = 2; /* 10; */ - regs[0x57] = 48; /* 56; */ - } - else /* pParam->PhyDpi.x == 1200) */ - { - regs[0x56] = 1; /* 8; */ - regs[0x57] = 48; /* 56; */ - } - break; + case MODEL_HuaLien: + case MODEL_KaoHsiung: + default: + if(pParam->PhyDpi.x <= 200) + { + regs[0x56] = 1; + regs[0x57] = 48; /* 63; */ + } + else if(pParam->PhyDpi.x <= 300) + { + regs[0x56] = 2; /* 8; */ + regs[0x57] = 48; /* 56; */ + } + else if(pParam->PhyDpi.x <= 400) + { + regs[0x56] = 8; + regs[0x57] = 48; + } + else if(pParam->PhyDpi.x <= 600) + { + regs[0x56] = 2; /* 10; */ + regs[0x57] = 48; /* 56; */ + } + else /* pParam->PhyDpi.x == 1200) */ + { + regs[0x56] = 1; /* 8; */ + regs[0x57] = 48; /* 56; */ + } + break; } } else { switch ( hw->motorModel ) { @@ -1007,14 +1052,15 @@ static void usb_GetMotorParam( Plustek_Device *dev, ScanParam *pParam ) } } } - + DBG( _DBG_INFO2, "* MOTOR-Settings: PWM=0x%02x, PWM_DUTY=0x%02x\n", regs[0x56], regs[0x57] ); } /** */ -static void usb_GetPauseLimit( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_GetPauseLimit( Plustek_Device *dev, ScanParam *pParam ) { int coeffsize, scaler; HWDef *hw = &dev->usbDev.HwSetting; @@ -1074,7 +1120,8 @@ static void usb_GetPauseLimit( Plustek_Device *dev, ScanParam *pParam ) /** usb_GetScanLinesAndSize */ -static void usb_GetScanLinesAndSize( Plustek_Device *dev, ScanParam *pParam ) +static void +usb_GetScanLinesAndSize( Plustek_Device *dev, ScanParam *pParam ) { DCapsDef *sCaps = &dev->usbDev.Caps; @@ -1100,7 +1147,8 @@ static void usb_GetScanLinesAndSize( Plustek_Device *dev, ScanParam *pParam ) /** function to preset/reset the merlin registers */ -static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) +static SANE_Bool +usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) { static u_char reg8, reg38[6], reg48[2]; @@ -1126,8 +1174,8 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) } /* - * calculate the basic settings... - */ + * calculate the basic settings... + */ pParam->PhyDpi.x = usb_SetAsicDpiX( dev, pParam->UserDpi.x ); pParam->PhyDpi.y = usb_SetAsicDpiY( dev, pParam->UserDpi.y ); @@ -1169,7 +1217,7 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) pParam->bSource == SOURCE_ADF && dev->usbDev.fLastScanIsAdf )) { DBG( _DBG_INFO2, "* Scan calculations...\n" ); - usb_GetLineLength ( dev ); + usb_GetLineLength ( dev, pParam ); usb_GetStepSize ( dev, pParam ); usb_GetDPD ( dev ); usb_GetMCLKDivider( dev, pParam ); @@ -1209,7 +1257,7 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) usb_GetPauseLimit( dev, pParam ); /* For ADF .... */ - if(pParam->bCalibration == PARAM_Scan && pParam->bSource == SOURCE_ADF) { + if(pParam->bCalibration == PARAM_Scan && pParam->bSource == SOURCE_ADF) { if( dev->usbDev.fLastScanIsAdf ) { @@ -1245,19 +1293,21 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) memset( ®s[0x03], 0, 3 ); memset( ®s[0x5f], 0, 0x7f-0x5f+1 ); - /* we limit the possible scansteps to avoid, that the sensors bumps - * against the scanbed - */ - if(pParam->bCalibration == PARAM_Scan && pParam->bSource != SOURCE_ADF) { + if( !usb_IsSheetFedDevice(dev)) { + /* we limit the possible scansteps to avoid, that the sensors bumps + * against the scanbed - not necessary for sheet-fed devices + */ + if(pParam->bCalibration==PARAM_Scan && pParam->bSource!=SOURCE_ADF) { - u_long lines = pParam->Size.dwPhyLines + scan->bLinesToSkip + - scan->dwLinesDiscard + 5; - u_short scansteps = (u_short)ceil((double)lines* - hw->wMotorDpi / pParam->PhyDpi.y); - DBG( _DBG_INFO, "* Scansteps=%u (%lu*%u/%u)\n", scansteps, lines, - hw->wMotorDpi, pParam->PhyDpi.y ); - regs[0x4c] = _HIBYTE(scansteps); - regs[0x4d] = _LOBYTE(scansteps); + u_long lines = pParam->Size.dwPhyLines + scan->bLinesToSkip + + scan->dwLinesDiscard + 5; + u_short scansteps = (u_short)ceil((double)lines* + hw->wMotorDpi / pParam->PhyDpi.y); + DBG( _DBG_INFO, "* Scansteps=%u (%lu*%u/%u)\n", scansteps, lines, + hw->wMotorDpi, pParam->PhyDpi.y ); + regs[0x4c] = _HIBYTE(scansteps); + regs[0x4d] = _LOBYTE(scansteps); + } } /* set the merlin registers */ @@ -1275,7 +1325,8 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, ScanParam *pParam ) /** */ -static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) +static SANE_Bool +usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) { u_char value; u_short inches; @@ -1285,6 +1336,9 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) DBG( _DBG_INFO, "usb_ScanBegin()\n" ); + if( !usb_Wait4ScanSample( dev )) + return SANE_FALSE; + /* save the request for usb_ScanEnd () */ m_fAutoPark = auto_park; @@ -1299,7 +1353,7 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) if( !usb_IsScannerReady(dev)) return SANE_FALSE; - /* Flush cache - only LM9831 (Source: National Semiconductors */ + /* Flush cache - only LM9831 (Source: National Semiconductors) */ if( _LM9831 == hw->chip ) { for(;;) { @@ -1357,7 +1411,8 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) /** usb_ScanEnd * stop all the processing stuff and reposition sensor back home */ -static SANE_Bool usb_ScanEnd( Plustek_Device *dev ) +static SANE_Bool +usb_ScanEnd( Plustek_Device *dev ) { u_char value; @@ -1382,7 +1437,8 @@ static SANE_Bool usb_ScanEnd( Plustek_Device *dev ) /** */ -static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev ) +static SANE_Bool +usb_IsDataAvailableInDRAM( Plustek_Device *dev ) { /* Compute polling timeout * Height (Inches) / MaxScanSpeed (Inches/Second) = Seconds to move the @@ -1435,8 +1491,8 @@ static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev ) /** */ -static SANE_Bool usb_ScanReadImage( Plustek_Device *dev, - void *pBuf, u_long dwSize ) +static SANE_Bool +usb_ScanReadImage( Plustek_Device *dev, void *pBuf, u_long dwSize ) { static u_long dwBytes = 0; u_char *regs = dev->usbDev.a_bRegs; @@ -1525,7 +1581,8 @@ static SANE_Bool usb_ScanReadImage( Plustek_Device *dev, /** 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, ImgDef *pInfo, WinInfo *pSize ) +static void +usb_GetImageInfo( Plustek_Device *dev, ImgDef *pInfo, WinInfo *pSize ) { DBG( _DBG_INFO, "usb_GetImageInfo()\n" ); @@ -1566,7 +1623,8 @@ static void usb_GetImageInfo( Plustek_Device *dev, ImgDef *pInfo, WinInfo *pSize /** */ -static void usb_SaveImageInfo( Plustek_Device *dev, ImgDef *pInfo ) +static void +usb_SaveImageInfo( Plustek_Device *dev, ImgDef *pInfo ) { HWDef *hw = &dev->usbDev.HwSetting; ScanParam *pParam = &dev->scanning.sParam; @@ -1622,6 +1680,34 @@ static void usb_SaveImageInfo( Plustek_Device *dev, ImgDef *pInfo ) pParam->bSource = SOURCE_ADF; else pParam->bSource = SOURCE_Reflection; + + /* it seems, that we need to adjust the Origin.x when we have a + * sheetfed device to avoid stripes in the resulting pictures + */ + if( usb_IsSheetFedDevice(dev)) { + + int step, div, org, xdpi; + + xdpi = usb_SetAsicDpiX( dev, pParam->UserDpi.x ); + + if ((xdpi * 2) <= 300) + div = 300; + else if ((xdpi * 2) <= 600) + div = 600; + else if ((xdpi * 2) <= 1200) + div = 1200; + else + div = 2400; + + step = div / xdpi; + org = pParam->Origin.x; + + pParam->Origin.x = (pParam->Origin.x / step) * step; + + if (org != pParam->Origin.x) + DBG(_DBG_INFO, "* Origin.x adjusted: %i -> %i\n", + org, pParam->Origin.x); + } } /* END PLUSTEK-USBSCAN.C ....................................................*/ diff --git a/backend/plustek-usbshading.c b/backend/plustek-usbshading.c index 67af2be9e..4e304a02e 100644 --- a/backend/plustek-usbshading.c +++ b/backend/plustek-usbshading.c @@ -7,7 +7,7 @@ * @brief Calibration routines. * * Based on sources acquired from Plustek Inc.
- * Copyright (C) 2001-2005 Gerhard Jaeger + * Copyright (C) 2001-2006 Gerhard Jaeger * * History: * - 0.40 - starting version of the USB support @@ -30,6 +30,7 @@ * - using now PhyDpi.y as selector for the motor MCLK range * - 0.50 - readded kCIS670 to add 5% extra to LiDE20 fine calibration * - fixed line statistics and added data output + * - 0.51 - added fine calibration cache * . *
* This file is part of the SANE package. @@ -85,9 +86,6 @@ #define SWAP_COARSE #define SWAP_FINE -static u_short a_wWhiteShading[_SHADING_BUF] = {0}; -static u_short a_wDarkShading[_SHADING_BUF] = {0}; - /************************** static variables *********************************/ static RGBUShortDef Gain_Hilight; @@ -183,7 +181,7 @@ static void usb_line_statistics( char *cmt, u_short* buf, if( tmp < lbd ) cld++; } - DBG( _DBG_INFO2, "Color[%u] (%s): %lu pixels " + DBG( _DBG_INFO2, "Color[%u] (%s): %lu all " "min=%u(%lu) max=%u(%lu) ave=%u\n", i, cmt, dim_x, mid, imid, mad, imad, aved); DBG( _DBG_INFO2, "5%%: low@%u (count=%lu), upper@%u (count=%lu)\n", @@ -191,6 +189,51 @@ static void usb_line_statistics( char *cmt, u_short* buf, } } +/** + */ +static void +usb_PrepareFineCal( Plustek_Device *dev, ScanParam *tmp_sp, u_short cal_dpi ) +{ + ScanParam *sp = &dev->scanning.sParam; + DCapsDef *scaps = &dev->usbDev.Caps; + + *tmp_sp = *sp; + + if( dev->adj.cacheCalData ) { + + DBG( _DBG_INFO2, "* Cal-cache active, tweaking scanparams" + " - DPI=%u!\n", cal_dpi ); + + tmp_sp->UserDpi.x = usb_SetAsicDpiX(dev, sp->UserDpi.x ); + if( cal_dpi != 0 ) + tmp_sp->UserDpi.x = cal_dpi; + + tmp_sp->PhyDpi = scaps->OpticDpi; + tmp_sp->Origin.x = 0; + tmp_sp->Size.dwPixels = scaps->Normal.Size.x * + usb_SetAsicDpiX(dev, tmp_sp->UserDpi.x)/ 300UL; + } + +#if 0 + if( tmp_sp->PhyDpi.x > 75) + tmp_sp->Size.dwLines = 64; + else +#endif + tmp_sp->Size.dwLines = 32; + + tmp_sp->Origin.y = 0; + tmp_sp->bBitDepth = 16; + + tmp_sp->UserDpi.y = scaps->OpticDpi.y; + tmp_sp->Size.dwBytes = tmp_sp->Size.dwPixels * 2 * tmp_sp->bChannels; + + if( usb_IsCISDevice(dev) && (tmp_sp->bDataType == SCANDATATYPE_Color)) { + tmp_sp->Size.dwBytes *= 3; + } + + tmp_sp->dMCLK = dMCLK; +} + /** */ static double usb_GetMCLK( Plustek_Device *dev, ScanParam *param ) @@ -231,7 +274,7 @@ static double usb_GetMCLK( Plustek_Device *dev, ScanParam *param ) /** usb_SetMCLK * get the MCLK out of our table */ -static void usb_SetMCLK( Plustek_Device *dev, ScanParam *param ) +static void usb_SetMCLK( Plustek_Device *dev, ScanParam *param ) { HWDef *hw = &dev->usbDev.HwSetting; @@ -280,7 +323,7 @@ static SANE_Bool usb_SetDarkShading( Plustek_Device *dev, u_char channel, return SANE_FALSE; } - /** usb_SetWhiteShading +/** usb_SetWhiteShading * download the white shading data to Merlins' DRAM */ static SANE_Bool usb_SetWhiteShading( Plustek_Device *dev, u_char channel, @@ -380,7 +423,7 @@ static void usb_GetSWOffsetGain( Plustek_Device *dev ) param->swGain[0] = 960; param->swGain[1] = 970; param->swGain[2] = 1000; - } else if (param->PhyDpi.x <= 300) { + } else if (param->PhyDpi.x <= 300) { param->swOffset[0] = 700; param->swOffset[1] = 600; param->swOffset[2] = 400; @@ -702,7 +745,7 @@ static SANE_Bool adjLampSetting( Plustek_Device *dev, int channel, u_long max, *l_off = l_on + lamp_on; DBG( _DBG_INFO2, "lamp(%u) adjust (-3%%): %i %i\n", channel, l_on, *l_off ); - adj = SANE_TRUE; + adj = SANE_TRUE; } /* if the image was too dull, increase lamp by 1% */ @@ -768,10 +811,8 @@ static SANE_Bool usb_AdjustGain( Plustek_Device *dev, int fNegative ) m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color) m_ScanParam.Size.dwBytes *= 3; - } m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart * 300UL / scaps->OpticDpi.x); @@ -917,8 +958,8 @@ TOGAIN: /* do some averaging... */ for (dwLoop2 = dwDiv, dwR = dwG = dwB = 0; - dwLoop2; dwLoop2--, dw++) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + dwLoop2; dwLoop2--, dw++) { + if( usb_IsCISDevice(dev)) { dwR += ((u_short*)scanbuf)[dw]; dwG += ((u_short*)scanbuf)[dw+m_ScanParam.Size.dwPhyPixels+1]; dwB += ((u_short*)scanbuf)[dw+(m_ScanParam.Size.dwPhyPixels+1)*2]; @@ -958,7 +999,7 @@ TOGAIN: * for adjusting the gain */ tmp_rgb = max_rgb; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) tmp_rgb = min_rgb; DBG(_DBG_INFO2, "CUR(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n", @@ -977,7 +1018,7 @@ TOGAIN: SANE_Bool adj = SANE_FALSE; /* on CIS devices, we can control the lamp off settings */ - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { /* m_dwIdealGain = IDEAL_GainNormal; */ @@ -998,7 +1039,7 @@ TOGAIN: /* on any adjustment, set the registers... */ if( adj ) { - usb_AdjustLamps( dev ); + usb_AdjustLamps( dev, SANE_TRUE ); if( i < _MAX_GAIN_LOOPS ) goto TOGAIN; @@ -1075,7 +1116,7 @@ TOGAIN: } w_tmp = w_max; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) w_tmp = w_min; regs[0x3b] = @@ -1093,7 +1134,7 @@ TOGAIN: SANE_Bool adj = SANE_FALSE; /* on CIS devices, we can control the lamp off settings */ - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { if( adjLampSetting( dev, CHANNEL_green, w_tmp, m_dwIdealGain, hw->green_lamp_on, &hw->green_lamp_off )) { @@ -1102,7 +1143,7 @@ TOGAIN: /* on any adjustment, set the registers... */ if( adj ) { - usb_AdjustLamps( dev ); + usb_AdjustLamps( dev, SANE_TRUE ); if( i < _MAX_GAIN_LOOPS ) goto TOGAIN; @@ -1233,7 +1274,7 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev ) m_ScanParam.Size.dwLines = 1; m_ScanParam.Size.dwPixels = 2550; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) dwPixels = m_ScanParam.Size.dwPixels; else dwPixels = (u_long)(hw->bOpticBlackEnd - hw->bOpticBlackStart ); @@ -1241,10 +1282,8 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev ) m_ScanParam.Size.dwPixels = 2550; m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color ) m_ScanParam.Size.dwBytes *= 3; - } m_ScanParam.Origin.x = (u_short)((u_long)hw->bOpticBlackStart * 300UL / dev->usbDev.Caps.OpticDpi.x); @@ -1257,7 +1296,7 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev ) regs[0x38] = regs[0x39] = regs[0x3a] = 0; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { /* * if we have dark shading strip, there's no need to switch * the lamp off @@ -1389,7 +1428,7 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev ) DBG( _DBG_INFO, "usb_AdjustOffset() done.\n" ); /* switch it on again on CIS based scanners */ - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { if( dev->usbDev.pSource->DarkShadOrgY < 0 ) { regs[0x29] = hw->bReg_0x29; @@ -1547,13 +1586,10 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev ) DBG( _DBG_INFO2, "* MCLK = %f (scanparam-MCLK=%f)\n", dMCLK, scanning->sParam.dMCLK ); - m_ScanParam = scanning->sParam; - m_ScanParam.Origin.y = 0; - m_ScanParam.UserDpi.y = scaps->OpticDpi.y; + usb_PrepareFineCal( dev, &m_ScanParam, 0 ); + m_ScanParam.Size.dwLines = 1; /* for gain */ - m_ScanParam.bBitDepth = 16; m_ScanParam.bCalibration = PARAM_DarkShading; - m_ScanParam.dMCLK = dMCLK; if( _LM9831 == hw->chip ) { @@ -1570,14 +1606,9 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev ) 2UL * m_ScanParam.bChannels; m_dwPixels = scanning->sParam.Size.dwPixels * m_ScanParam.UserDpi.x / scanning->sParam.UserDpi.x; - } else { - m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * - 2 * m_ScanParam.bChannels; - } - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { - m_ScanParam.Size.dwBytes *= 3; + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color ) + m_ScanParam.Size.dwBytes *= 3; } /* if we have dark shading strip, there's no need to switch @@ -1634,7 +1665,7 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev ) if( m_ScanParam.bDataType == SCANDATATYPE_Color ) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { usb_GetDarkShading( dev, a_wDarkShading, (HiLoDef*)scanbuf, m_ScanParam.Size.dwPhyPixels, 1, @@ -1845,6 +1876,8 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) if( usb_IsEscPressed()) return SANE_FALSE; + usb_PrepareFineCal( dev, &m_ScanParam, 0 ); + if( m_ScanParam.PhyDpi.x > 75) shading_lines = 64; else @@ -1854,29 +1887,8 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) hilight = 4; shadow = 4; - m_ScanParam = scan->sParam; - m_ScanParam.Origin.y = 0; - m_ScanParam.bBitDepth = 16; - -/* HEINER: check ADF stuff... */ -#if 0 - if( ScanInf.m_fADF ) { - /* avoid ADF WhiteShading big noise */ - m_ScanParam.UserDpi.y = Device.Caps.OpticDpi.y - 200; - } else { -#endif - m_ScanParam.UserDpi.y = scaps->OpticDpi.y; -/* } */ - m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * - m_ScanParam.bChannels; - - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { - m_ScanParam.Size.dwBytes *= 3; - } - m_ScanParam.bCalibration = PARAM_WhiteShading; - m_ScanParam.dMCLK = dMCLK; + m_ScanParam.Size.dwLines = shading_lines; if( _LM9831 == hw->chip ) { @@ -1888,24 +1900,15 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) m_ScanParam.Origin.x = m_ScanParam.Origin.x % (u_short)m_dHDPIDivider; m_ScanParam.Size.dwPixels = (u_long)scaps->Normal.Size.x * m_ScanParam.UserDpi.x / 300UL; m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2UL * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { + if( usb_IsCISDevice(dev) && m_ScanParam.bDataType == SCANDATATYPE_Color ) m_ScanParam.Size.dwBytes *= 3; - } + m_dwPixels = scan->sParam.Size.dwPixels * m_ScanParam.UserDpi.x / scan->sParam.UserDpi.x; - dw = (u_long)(hw->wDRAMSize - DRAM_UsedByAsic16BitMode) * 1024UL; - m_ScanParam.Size.dwLines = shading_lines; + dw = (u_long)(hw->wDRAMSize - 196 /*192 KiB*/) * 1024UL; for( dwLines = dw / m_ScanParam.Size.dwBytes; dwLines < m_ScanParam.Size.dwLines; m_ScanParam.Size.dwLines>>=1); - } else { - m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR && - m_ScanParam.bDataType == SCANDATATYPE_Color ) { - m_ScanParam.Size.dwBytes *= 3; - } - m_ScanParam.Size.dwLines = shading_lines; } /* goto the correct position again... */ @@ -1932,7 +1935,7 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) DBG(_DBG_INFO2,"TotalBytes = %lu\n",m_ScanParam.Size.dwTotalBytes); if( _LM9831 == hw->chip ) { /* Delay for white shading hold for 9831-1200 scanner */ - usleep(250 * 10000); + usleep(900000); } if( usb_ScanReadImage( dev, pBuf + dwRead, @@ -1940,7 +1943,7 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) if( _LM9831 == hw->chip ) { /* Delay for white shading hold for 9831-1200 scanner */ - usleep(10 * 1000); + usleep(10000); } if( 0 == dwRead ) { @@ -1967,7 +1970,7 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) * from RRRRRRR.... GGGGGGGG.... BBBBBBBBB, create RGB RGB RGB ... * to use the following code, originally written for CCD devices... */ - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { u_short *dest, *src; u_long dww; @@ -2179,6 +2182,9 @@ static SANE_Bool usb_AdjustWhiteShading( Plustek_Device *dev ) } } } + + usb_SaveCalSetShading( dev, &m_ScanParam ); + if( scan->sParam.bSource != SOURCE_Negative ) { usb_line_statistics( "White", a_wWhiteShading, m_ScanParam.Size.dwPhyPixels, scan->sParam.bDataType == SCANDATATYPE_Color?1:0); @@ -2214,15 +2220,15 @@ static void usb_ResizeWhiteShading( double dAmp, u_short *pwShading, int iGain ) } #ifdef SWAP_FINE - if( usb_HostSwap()) { + if( usb_HostSwap()) usb_Swap( pwShading, m_ScanParam.Size.dwPhyPixels ); - } #endif } /** do the base settings for calibration scans */ -static void usb_PrepareCalibration( Plustek_Device *dev ) +static void +usb_PrepareCalibration( Plustek_Device *dev ) { ScanDef *scan = &dev->scanning; DCapsDef *scaps = &dev->usbDev.Caps; @@ -2259,11 +2265,35 @@ static void usb_PrepareCalibration( Plustek_Device *dev ) if( dev->adj.cacheCalData ) if( usb_ReadAndSetCalData( dev )) scan->skipCoarseCalib = SANE_TRUE; + + /* as sheet-fed device we use the cached values, or + * perform the calibration upon request + */ + if( usb_IsSheetFedDevice(dev)) { + if( !scan->skipCoarseCalib && !usb_InCalibrationMode(dev)) { + + DBG(_DBG_INFO2,"SHEET-FED device, skip coarse calibration!\n"); + scan->skipCoarseCalib = SANE_TRUE; + + regs[0x3b] = 0x0a; + regs[0x3c] = 0x0a; + regs[0x3d] = 0x0a; + + /* use frontend values... */ + if((dev->adj.rgain != -1) && + (dev->adj.ggain != -1) && (dev->adj.bgain != -1)) { + setAdjGain( dev->adj.rgain, ®s[0x3b] ); + setAdjGain( dev->adj.ggain, ®s[0x3c] ); + setAdjGain( dev->adj.bgain, ®s[0x3d] ); + } + } + } } /** */ -static SANE_Bool usb_SpeedTest( Plustek_Device *dev ) +static SANE_Bool +usb_SpeedTest( Plustek_Device *dev ) { int i; double s, e, r, tr; @@ -2303,7 +2333,7 @@ static SANE_Bool usb_SpeedTest( Plustek_Device *dev ) m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) m_ScanParam.Size.dwBytes *= 3; m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart * @@ -2347,7 +2377,8 @@ static SANE_Bool usb_SpeedTest( Plustek_Device *dev ) /** read the white calibration strip until the lamp seems to be stable * the timed warmup will be used, when the warmup time is set to -1 */ -static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) +static SANE_Bool +usb_AutoWarmup( Plustek_Device *dev ) { int i, stable_count; ScanDef *scanning = &dev->scanning; @@ -2369,13 +2400,17 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) DBG( _DBG_INFO, "#########################\n" ); DBG( _DBG_INFO, "usb_AutoWarmup()\n" ); + if( usb_IsCISDevice(dev)) { + DBG( _DBG_INFO, "- function skipped, CIS device!\n" ); + return SANE_TRUE; + } + if( dev->adj.warmup >= 0 ) { - DBG( _DBG_INFO, "... using timed warmup: %ds\n", dev->adj.warmup ); + DBG( _DBG_INFO, "- using timed warmup: %ds\n", dev->adj.warmup ); if( !usb_Wait4Warmup( dev )) { - DBG( _DBG_ERROR, "usb_AutoWarmup() - CANCEL detected\n" ); + DBG( _DBG_ERROR, "- CANCEL detected\n" ); return SANE_FALSE; } - DBG( _DBG_INFO, "usb_AutoWarmup() done.\n" ); return SANE_TRUE; } @@ -2395,7 +2430,7 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) m_ScanParam.Size.dwBytes = m_ScanParam.Size.dwPixels * 2 * m_ScanParam.bChannels; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) m_ScanParam.Size.dwBytes *= 3; m_ScanParam.Origin.x = (u_short)((u_long) hw->wActivePixelsStart * @@ -2443,7 +2478,7 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) curR = curG = curB = 0; for( dw = start; dw < end; dw++ ) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)) { curR += ((u_short*)scanbuf)[dw]; curG += ((u_short*)scanbuf)[dw+m_ScanParam.Size.dwPhyPixels+1]; curB += ((u_short*)scanbuf)[dw+(m_ScanParam.Size.dwPhyPixels+1)*2]; @@ -2463,7 +2498,7 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) DBG( _DBG_INFO2, "%i/%i-AVE(R,G,B)= %lu(%ld), %lu(%ld), %lu(%ld)\n", i, stable_count, curR, diffR, curG, diffG, curB, diffB ); - /* we consider the lamp to be stable, + /* we consider the lamp to be stable, * when the diffs are less than thresh for at least 3 loops */ if((diffR < thresh) && (diffG < thresh) && (diffB < thresh)) { @@ -2487,12 +2522,14 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev ) /** */ -static int usb_DoIt( Plustek_Device *dev ) +static int +usb_DoIt( Plustek_Device *dev ) { - ScanDef *scanning = &dev->scanning; + SANE_Bool skip_fine; + ScanDef *scan = &dev->scanning; DBG( _DBG_INFO, "Settings done, so start...\n" ); - if( !scanning->skipCoarseCalib ) { + if( !scan->skipCoarseCalib ) { DBG( _DBG_INFO2, "###### ADJUST GAIN (COARSE)#######\n" ); if( !usb_AdjustGain(dev, 0)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); @@ -2506,22 +2543,43 @@ static int usb_DoIt( Plustek_Device *dev ) } else { DBG( _DBG_INFO2, "Coarse Calibration skipped, using saved data\n" ); } - DBG( _DBG_INFO2, "###### ADJUST DARK (FINE) ########\n" ); - if( !usb_AdjustDarkShading(dev)) { - DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); - return _E_INTERNAL; + + skip_fine = SANE_FALSE; + if( dev->adj.cacheCalData ) { + skip_fine = usb_FineShadingFromFile(dev); } - DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" ); - if( !usb_AdjustWhiteShading(dev)) { - DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); - return _E_INTERNAL; + + if( !skip_fine ) { + DBG( _DBG_INFO2, "###### ADJUST DARK (FINE) ########\n" ); + if( !usb_AdjustDarkShading(dev)) { + DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); + return _E_INTERNAL; + } + DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" ); + if( !usb_AdjustWhiteShading(dev)) { + DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); + return _E_INTERNAL; + } + } else { + DBG( _DBG_INFO2, "###### FINE calibration skipped #######\n" ); + + m_ScanParam = scan->sParam; + usb_GetPhyPixels( dev, &m_ScanParam ); + + usb_line_statistics( "Dark", a_wDarkShading, m_ScanParam.Size.dwPhyPixels, + m_ScanParam.bDataType == SCANDATATYPE_Color?1:0); + usb_line_statistics( "White", a_wWhiteShading, m_ScanParam.Size.dwPhyPixels, + m_ScanParam.bDataType == SCANDATATYPE_Color?1:0); + +/* dev->usbDev.a_bRegs[0x45] &= ~0x10;*/ } return 0; } /** usb_DoCalibration */ -static int usb_DoCalibration( Plustek_Device *dev ) +static int +usb_DoCalibration( Plustek_Device *dev ) { int result; ScanDef *scanning = &dev->scanning; @@ -2926,9 +2984,9 @@ static int usb_DoCalibration( Plustek_Device *dev ) DBG( _DBG_INFO, "REG[0x3c] = %u\n", regs[0x3c] ); DBG( _DBG_INFO, "REG[0x3d] = %u\n", regs[0x3d] ); DBG( _DBG_INFO, "Static Offset:\n" ); - DBG( _DBG_INFO, "REG[0x38] = %u\n", regs[0x38] ); - DBG( _DBG_INFO, "REG[0x39] = %u\n", regs[0x39] ); - DBG( _DBG_INFO, "REG[0x3a] = %u\n", regs[0x3a] ); + DBG( _DBG_INFO, "REG[0x38] = %i\n", regs[0x38] ); + DBG( _DBG_INFO, "REG[0x39] = %i\n", regs[0x39] ); + DBG( _DBG_INFO, "REG[0x3a] = %i\n", regs[0x3a] ); DBG( _DBG_INFO, "MCLK = %.2f\n", scanning->sParam.dMCLK ); DBG( _DBG_INFO, "-----------------------\n" ); return SANE_TRUE; @@ -2949,7 +3007,7 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what ) DBG( _DBG_INFO, "usb_DownloadShadingData(%u)\n", what ); channel = CHANNEL_green; - if( hw->bReg_0x26 & _ONE_CH_COLOR ) + if( usb_IsCISDevice(dev)) channel = CHANNEL_blue; switch( what ) { diff --git a/doc/descriptions/plustek.desc b/doc/descriptions/plustek.desc index d7a791438..ecd20fa0c 100644 --- a/doc/descriptions/plustek.desc +++ b/doc/descriptions/plustek.desc @@ -3,7 +3,7 @@ ; :backend "plustek" -:version "0.50" +:version "0.51" :manpage "sane-plustek" ; backend's web page :url "http://www.gjaeger.de/scanner/plustek/" @@ -16,7 +16,6 @@ :url "http://www.plustek.de/" :url "http://www.plustek.com/" -;name models for above-specified mfg. :model "OpticPro U12" :interface "USB" :usbid "0x07b3" "0x0010" @@ -56,32 +55,32 @@ :model "Colorpage HR6 V2" :interface "USB" -:usbid "0x0458" "0x2007" +:usbid "0x0458" "0x2007" :status :complete :model "Colorpage HR6 V2" :interface "USB" -:usbid "0x0458" "0x2008" +:usbid "0x0458" "0x2008" :status :complete :model "Colorpage HR7" :interface "USB" -:usbid "0x0458" "0x2013" +:usbid "0x0458" "0x2013" :status :complete :model "Colorpage HR6A" :interface "USB" -:usbid "0x0458" "0x2009" +:usbid "0x0458" "0x2009" :status :untested :model "Colorpage HR7LE" :interface "USB" -:usbid "0x0458" "0x2015" +:usbid "0x0458" "0x2015" :status :untested :model "Colorpage HR6X" :interface "USB" -:usbid "0x0458" "0x2016" +:usbid "0x0458" "0x2016" :status :untested ;* MUSTEK *********************************************************************************** @@ -91,19 +90,19 @@ :model "BearPaw 1200" :interface "USB" -:usbid "0x0400" "0x1000" +:usbid "0x0400" "0x1000" :status :complete :comment "both product versions are supported, see backends' man-page" :model "BearPaw 1200" :interface "USB" -:usbid "0x0400" "0x1001" +:usbid "0x0400" "0x1001" :status :complete :comment "both product versions are supported, see backends' man-page" :model "BearPaw 2400" :interface "USB" -:usbid "0x0400" "0x1001" +:usbid "0x0400" "0x1001" :status :complete ;* Hewlett-Packard ************************************************************************** @@ -113,12 +112,12 @@ :model "ScanJet 2100C" :interface "USB" -:usbid "0x03f0" "0x0505" +:usbid "0x03f0" "0x0505" :status :complete :model "ScanJet 2200C" :interface "USB" -:usbid "0x03f0" "0x0605" +:usbid "0x03f0" "0x0605" :status :complete ;* EPSON ******************************************************************************************* @@ -128,48 +127,42 @@ :model "Perfection 1250" :interface "USB" -:usbid "0x04b8" "0x010f" +:usbid "0x04b8" "0x010f" :status :complete :model "Perfection 1250Photo" :interface "USB" -:usbid "0x04b8" "0x010f" +:usbid "0x04b8" "0x010f" :status :good :comment "TPA scans not perfect" :model "Perfection 1260" :interface "USB" -:usbid "0x04b8" "0x011d" +:usbid "0x04b8" "0x011d" :status :complete :model "Perfection 1260Photo" :interface "USB" -:usbid "0x04b8" "0x011d" +:usbid "0x04b8" "0x011d" :status :good :comment "TPA scans not perfect" ;* UMAX ************************************************************************************* -:mfg "UMAX" +:mfg "Umax" :url "http://www.umax.com/" :model "UMAX 3400" :interface "USB" :usbid "0x1606" "0x0050" :status :complete -:comment "there are some UMAX 3400 sold outside the U.S. with product id 0x0050 which are not supported, as they use another chipset than the LM983x" +:comment "there are some UMAX 3400 outside the U.S. which are not supported, as they use another chipset than the LM983x" :model "UMAX 3400" :interface "USB" :usbid "0x1606" "0x0060" :status :complete -:comment "there are some UMAX 3400 sold outside the U.S. with product id 0x0050 which are not supported, as they use another chipset than the LM983x" - -:model "UMAX Astranet ia101" -:interface "USB" -:usbid "0x1606" "0x0050" -:status :complete -:comment "seems to be a renamed UMAX 3400" +:comment "there are some UMAX 3400 outside the U.S. which are not supported, as they use another chipset than the LM983x" :model "UMAX Astranet ia101" :interface "USB" @@ -184,7 +177,7 @@ :model "UMAX 5400" :interface "USB" -:usbid "0x1606" "0x0160" +:usbid "0x1606" "0x0160" :status :complete ;* COMPAQ ****************************************************************************************** @@ -198,6 +191,7 @@ :status :complete :comment "Identical to UMAX 3400" + ;* CANON ******************************************************************************************* :mfg "Canon" @@ -205,41 +199,41 @@ :model "CanoScan N650U/N656U" :interface "USB" -:usbid "0x04a9" "0x2206" +:usbid "0x04a9" "0x2206" :status :complete :model "CanoScan N1220U" :interface "USB" -:usbid "0x04a9" "0x2207" +:usbid "0x04a9" "0x2207" :status :complete -:model "CanoScan N670U/N676U" +:model "CanoScan N670U/N676U/LiDE20" :interface "USB" -:usbid "0x04a9" "0x220d" +:usbid "0x04a9" "0x220d" :status :complete -:model "CanoScan N1240U" +:model "CanoScan N1240U/LiDE30" :interface "USB" -:usbid "0x04a9" "0x220e" -:status :complete - -:model "CanoScan LiDE20" -:interface "USB" -:usbid "0x04a9" "0x220d" +:usbid "0x04a9" "0x220e" :status :complete :model "CanoScan LiDE25" :interface "USB" -:usbid "0x04a9" "0x2220" +:usbid "0x04a9" "0x2220" :status :good -:model "CanoScan LiDE30" -:interface "USB" -:usbid "0x04a9" "0x220e" -:status :complete - :model "CanoScan D660U" :interface "USB" -:usbid "0x04a9" "0x2208" +:usbid "0x04a9" "0x2208" :status :good :comment "TPA scans not perfect" + +;* SYSCAN ******************************************************************************************* + +:mfg "Syscan" +:url "http://www.syscaninc.com" + +:model "TravelScan 662" +:interface "USB" +:usbid "0x0a82" "0x6620" +:status :complete diff --git a/doc/sane-plustek.man b/doc/sane-plustek.man index 07ca49b00..ffd54ff6f 100644 --- a/doc/sane-plustek.man +++ b/doc/sane-plustek.man @@ -1,4 +1,4 @@ -.TH sane-plustek 5 "08 August 2005" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.TH sane-plustek 5 "09 April 2006" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" .IX sane-plustek .SH NAME sane-plustek \- SANE backend for LM983[1/2/3] based @@ -142,6 +142,18 @@ CanoScan LIDE25 LM9833 1200x2400dpi 48bit 512Kb 0x2220 CanoScan LIDE30 LM9833 1200x2400dpi 48bit 512Kb 0x220E .fi .ft R +.PP + +Vendor Syscan \- ID: 0x0A82 +.br +.ft CR +.nf +---------------------------------------------------------- +USB Model: ASIC: Properties: Prod-ID +---------------------------------------------------------- +Travelscan 662 LM9833 600x1200dpi 48bit 512Kb 0x6620 +.fi +.ft R .SH "OTHER PLUSTEK SCANNERS" For parallelport device support see the @@ -247,8 +259,8 @@ option invertNegatives b option cacheCalData b .RS .I b -0 --> do not save coarse calibration results, -1 --> save results of coarse calibration in ~/.sane/ directory +0 --> do not save calibration results, +1 --> save results of calibration in ~/.sane/ directory .RE .PP option altCalibration b @@ -447,11 +459,11 @@ For problem reports it should be enough the set the verbosity to * The driver does not support these manic scalings up to 16 times the physical resolution. The only scaling is done on resolutions between the physical resolution -of the CDD-sensor and the stepper motor i.e. you have a -600x1200 dpi scanner and you are scanning using 800dpi, -so scaling is necessary, because the sensor only delivers -600dpi but the motor is capable of performing 1200dpi -steps. +of the CCD-/CIS-sensor and the stepper motor i.e. you +have a 600x1200 dpi scanner and you are scanning using +800dpi, so scaling is necessary, because the sensor only +delivers 600dpi but the motor is capable to perform +1200dpi steps. .PP * Plusteks' model policy is somewhat inconsistent. They sell technically different devices under the diff --git a/doc/sane-plustek_pp.man b/doc/sane-plustek_pp.man index 4197491cf..dbfdcc666 100644 --- a/doc/sane-plustek_pp.man +++ b/doc/sane-plustek_pp.man @@ -488,7 +488,7 @@ to other printers too, using bidirectional protocol * The driver does not support these manic scalings up to 16 times the physical resolution. The only scaling is done on resolutions between the physical resolution -of the CDD-sensor and the stepper motor i.e. you have a +of the CCD-sensor and the stepper motor i.e. you have a 600x1200 dpi scanner and you are scanning using 800dpi, so scaling is necessary, because the sensor only delivers 600dpi but the motor is capable to perform 800dpi steps.