From 6c660815d34400f12313f803efc81c1d41b884e8 Mon Sep 17 00:00:00 2001 From: Gerhard Jaeger Date: Wed, 14 Jan 2004 19:10:43 +0000 Subject: [PATCH] bump up version, fixed device autodetection and corrupted pictures, improved model-detection. --- backend/u12-ccd.c | 1 + backend/u12-hw.c | 30 +++++-- backend/u12-hwdef.h | 9 ++- backend/u12-if.c | 137 ++++++++++++++++++-------------- backend/u12-image.c | 180 +++++++++++++++++++++++++++++------------- backend/u12-io.c | 94 +++++++++++++++++----- backend/u12-map.c | 1 + backend/u12-motor.c | 16 ++-- backend/u12-scanner.h | 2 +- backend/u12-shading.c | 7 +- backend/u12-tpa.c | 1 + backend/u12.c | 68 ++++++++-------- backend/u12.h | 10 ++- 13 files changed, 365 insertions(+), 191 deletions(-) diff --git a/backend/u12-ccd.c b/backend/u12-ccd.c index d2e870a55..cf31c9ffd 100644 --- a/backend/u12-ccd.c +++ b/backend/u12-ccd.c @@ -6,6 +6,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - no changes * . *
* This file is part of the SANE package. diff --git a/backend/u12-hw.c b/backend/u12-hw.c index f93af35cc..78d484914 100644 --- a/backend/u12-hw.c +++ b/backend/u12-hw.c @@ -5,6 +5,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - cleanup * . *
* This file is part of the SANE package. @@ -133,6 +134,7 @@ static void u12hw_InitiateComponentModel( U12_Device *dev ) switch( dev->PCBID ) { + /* typical for Plustek OpticPro U12 and 1212U */ case _PLUSTEK_SCANNER: DBG( _DBG_INFO, "We have a Plustek Scanner ;-)\n" ); break; @@ -147,6 +149,7 @@ static void u12hw_InitiateComponentModel( U12_Device *dev ) u12hw_ButtonSetup( dev, 4 ); break; + /* typical for Plustek OpticPro UT12 */ case _SCANNER4ButtonTPA: DBG( _DBG_INFO, "Scanner has 4 Buttons & TPA\n" ); dev->Tpa = SANE_TRUE; @@ -159,6 +162,7 @@ static void u12hw_InitiateComponentModel( U12_Device *dev ) u12hw_ButtonSetup( dev, 5 ); break; + /* typical for Genius Colorpage HR6 */ case _SCANNER5ButtonTPA: DBG( _DBG_INFO, "Scanner has 5 Buttons & TPA\n" ); dev->ModelOriginY += 20; @@ -583,12 +587,20 @@ static SANE_Status u12hw_CheckDevice( U12_Device *dev ) { #ifndef _FAKE_DEVICE SANE_Byte tmp; + SANE_Byte rb[8]; + int c; - if( !u12io_IsConnected( dev->fd )) { +#if 1 + if( !u12io_IsConnected( dev )) { if( !u12io_OpenScanPath( dev )) return SANE_STATUS_IO_ERROR; } +#else + u12io_IsConnected( dev ); + if( !u12io_OpenScanPath( dev )) + return SANE_STATUS_IO_ERROR; +#endif /* some setup stuff... */ tmp = u12io_GetExtendedStatus( dev ); @@ -601,15 +613,21 @@ static SANE_Status u12hw_CheckDevice( U12_Device *dev ) DBG( _DBG_INFO, "* TPA lamp is ON\n" ); } - u12io_DataToRegister( dev, REG_PLLPREDIV, 1 ); - u12io_DataToRegister( dev, REG_PLLMAINDIV, 0x20 ); - u12io_DataToRegister( dev, REG_PLLPOSTDIV, 2 ); - u12io_DataToRegister( dev, REG_CLOCKSELECTOR, 2 ); + c = 0; + _SET_REG( rb, c, REG_PLLPREDIV, 1 ); + _SET_REG( rb, c, REG_PLLMAINDIV, 0x20 ); + _SET_REG( rb, c, REG_PLLPOSTDIV, 2 ); + _SET_REG( rb, c, REG_CLOCKSELECTOR, 2 ); + u12io_DataToRegs( dev, rb, c ); - if( !dev->initialized ) +#if 0 + return u12hw_Memtest( dev ); +#else + if( !dev->initialized ) return u12hw_Memtest( dev ); else return SANE_STATUS_GOOD; +#endif #else _VAR_NOT_USED( dev ); return SANE_STATUS_GOOD; diff --git a/backend/u12-hwdef.h b/backend/u12-hwdef.h index 877e00912..ac86cf582 100644 --- a/backend/u12-hwdef.h +++ b/backend/u12-hwdef.h @@ -5,6 +5,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - change _DEF_BW_THRESHOLD * . *
* This file is part of the SANE package. @@ -236,11 +237,11 @@ _MotorHQuarterStep + _MotorPowerEnable) /* Register RegConfiguration (Addr: 0x1e) */ -#define _P98_CCD_TYPE_ID 0x07 -#define _P98_NEC_MACHINE 0x08 -#define _P98_PCBID 0xF0 +#define _P98_CCD_TYPE_ID 0x07 +#define _P98_NEC_MACHINE 0x08 +#define _P98_PCBID 0xF0 -#define _DEF_BW_THRESHOLD 111 /* default B/W mode threshold value */ +#define _DEF_BW_THRESHOLD 128 /* default B/W mode threshold value */ #define _NUMBER_OF_SCANSTEPS 64 /* Asic spec.: up to 64 scan steps */ #define _SCANSTATE_BYTES (_NUMBER_OF_SCANSTEPS/2) diff --git a/backend/u12-if.c b/backend/u12-if.c index 9ba94837f..baa659ee4 100644 --- a/backend/u12-if.c +++ b/backend/u12-if.c @@ -5,6 +5,9 @@ * * History: * - 0.01 - initial version + * - 0.02 - added model tweaking + * - fixed autodetection bug + * - added line-scaling stuff * . *
* This file is part of the SANE package. @@ -77,7 +80,7 @@ static TabDef u12Vendors[] = { /** list of supported devices */ static DevDesc u12Devices[] = { - { "0x07B3-0x0001", "U12" }, + { "0x07B3-0x0001", "1212U/U12" }, { "0x0458-0x2004", "Colorpage HR6" }, { NULL, NULL } }; @@ -139,6 +142,7 @@ static SANE_Status u12_initDev( U12_Device *dev, int handle, int vendor ) static void u12if_shutdown( U12_Device *dev ) { SANE_Int handle; + TimerDef timer; DBG( _DBG_INFO, "Shutdown called (dev->fd=%d, %s)\n", dev->fd, dev->sane.name ); @@ -149,9 +153,22 @@ static void u12if_shutdown( U12_Device *dev ) u12hw_PutToIdleMode( dev ); + if( !(u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER)) { + + u12motor_PositionModuleToHome( dev ); + + u12io_StartTimer( &timer, _SECOND * 20); + do { + if( u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER) { + break; + } + } while( !u12io_CheckTimer( &timer )); + } + DBG( _DBG_INFO, "* Home position reached.\n" ); + if( 0 != dev->adj.lampOffOnEnd ) { - DBG( _DBG_INFO, "Switching lamp off...\n" ); + DBG( _DBG_INFO, "* Switching lamp off...\n" ); dev->regs.RD_ScanControl &= ~_SCAN_LAMPS_ON; u12io_DataToRegister(dev,REG_SCANCONTROL, dev->regs.RD_ScanControl ); } @@ -165,24 +182,37 @@ static void u12if_shutdown( U12_Device *dev ) #if 0 usb_StopLampTimer( dev ); #endif + DBG( _DBG_INFO, "Shutdown done.\n" ); } /** This function checks wether a device, described by a given - * string(vendor and product ID), is support by this backend or not + * string(vendor and product ID), is supported by this backend or not * * @param usbIdStr - sting consisting out of product and vendor ID * format: "0xVVVV-0xPPPP" VVVV = Vendor ID, PPP = Product ID * @returns; SANE_TRUE if supported, SANE_FALSE if not */ -static SANE_Bool u12if_IsDeviceSupported( char *usbIdStr ) +static SANE_Bool u12if_IsDeviceSupported( U12_Device *dev ) { + int i; +#if 0 /* Plustek U12, UT12, U1212, U12B */ - if( !strcmp( usbIdStr, "0x07B3-0x0001" )) + if( !strcmp( dev->usbId, "0x07B3-0x0001" )) return SANE_TRUE; /* Genius Colorpage Vivid III V2 */ - if( !strcmp( usbIdStr, "0x0458-0x2004" )) + if( !strcmp( dev->usbId, "0x0458-0x2004" )) { return SANE_TRUE; + } +#else + for( i = 0; NULL != u12Devices[i].name; i++ ) { + + if( !strcmp( dev->usbId, u12Devices[i].vp )) { + dev->sane.model = u12Devices[i].name; + return SANE_TRUE; + } + } +#endif return SANE_FALSE; } @@ -219,9 +249,9 @@ static SANE_Bool usbDev_autodetect( SANE_Word *vendor, SANE_Word *product ) for( i = 0; NULL != u12Devices[i].name; i++ ) { - v = strtol( &(u12Devices[i].name)[0], 0, 0 ); - p = strtol( &(u12Devices[i].name)[7], 0, 0 ); - DBG( _DBG_INFO, "Checking for 0x%04x-0x%04x\n", v, p ); + v = strtol( &(u12Devices[i].vp)[0], 0, 0 ); + p = strtol( &(u12Devices[i].vp)[7], 0, 0 ); + DBG( _DBG_INFO, "* checking for 0x%04x-0x%04x\n", v, p ); sanei_usb_find_devices( v, p, u12if_usbattach ); @@ -229,6 +259,7 @@ static SANE_Bool usbDev_autodetect( SANE_Word *vendor, SANE_Word *product ) *vendor = v; *product = p; + DBG( _DBG_INFO, "* using device >%s<\n", USB_devname ); return SANE_TRUE; } } @@ -280,8 +311,9 @@ static int u12if_open( U12_Device *dev ) } } - if( SANE_STATUS_GOOD != sanei_usb_open( USB_devname, &handle )) - return -1; + if( SANE_STATUS_GOOD != sanei_usb_open( USB_devname, &handle )) { + return -1; + } /* replace the old devname, so we are able to have multiple * auto-detected devices @@ -342,7 +374,7 @@ static int u12if_open( U12_Device *dev ) /* before accessing the scanner, check if supported! */ - if( !u12if_IsDeviceSupported( dev->usbId )) { + if( !u12if_IsDeviceSupported( dev )) { DBG( _DBG_ERROR, "Device >%s<, is not supported!\n", dev->usbId ); sanei_usb_close( handle ); return -1; @@ -371,6 +403,11 @@ static int u12if_open( U12_Device *dev ) return -1; } + if( _PLUSTEK_VENID == vendor ) { + if( dev->Tpa ) + dev->sane.model = "UT12"; + } + dev->initialized = SANE_TRUE; return handle; } @@ -455,19 +492,6 @@ static SANE_Status u12if_setScanEnv( U12_Device *dev, ImgDef *img ) return res; } -/** - */ -static SANE_Status u12if_stopScan( U12_Device *dev ) -{ - DBG( _DBG_INFO, "u12if_stopScan()\n" ); - - u12motor_ToHomePosition( dev ); - - dev->DataInf.dwAppLinesPerArea = 0; - dev->DataInf.dwScanFlag &= ~_SCANDEF_SCANNING; - return SANE_STATUS_GOOD; -} - /** */ static SANE_Status u12if_startScan( U12_Device *dev ) @@ -478,6 +502,21 @@ static SANE_Status u12if_startScan( U12_Device *dev ) return SANE_STATUS_GOOD; } +/** + */ +static SANE_Status u12if_stopScan( U12_Device *dev ) +{ + DBG( _DBG_INFO, "u12if_stopScan()\n" ); + + u12motor_ToHomePosition( dev, SANE_FALSE ); +#if 0 + u12io_SoftwareReset( dev ); +#endif + dev->DataInf.dwAppLinesPerArea = 0; + dev->DataInf.dwScanFlag &= ~_SCANDEF_SCANNING; + return SANE_STATUS_GOOD; +} + /** */ static SANE_Status u12if_prepare( U12_Device *dev ) @@ -486,7 +525,7 @@ static SANE_Status u12if_prepare( U12_Device *dev ) DBG( _DBG_INFO, "u12if_prepare()\n" ); - u12motor_ToHomePosition( dev ); + u12motor_ToHomePosition( dev, SANE_TRUE ); res = u12hw_WarmupLamp( dev ); if( res != SANE_STATUS_GOOD ) @@ -495,6 +534,8 @@ static SANE_Status u12if_prepare( U12_Device *dev ) res = u12shading_DoCalibration( dev ); if( res != SANE_STATUS_GOOD ) return res; + + u12image_PrepareScaling( dev ); u12motor_ForceToLeaveHomePos( dev ); u12hw_SetupScanningCondition( dev ); @@ -527,44 +568,18 @@ static SANE_Status u12if_readLine( U12_Device *dev, SANE_Byte *line_buffer ) return SANE_STATUS_CANCELLED; } -#if 0 - ps->Scan.dwLinesToRead = count / ps->DataInf.dwAppBytesPerLine; - DBG( DBG_HIGH, "dwLinesToRead = %ld\n", ps->Scan.dwLinesToRead ); + if( dev->scaleBuf != NULL ) { + res = u12image_ReadOneImageLine( dev, dev->scaleBuf ); + if( SANE_STATUS_GOOD != res ) + return res; - if( ps->Scan.dwLinesToRead > ps->DataInf.dwAppLinesPerArea ) - ps->Scan.dwLinesToRead = ps->DataInf.dwAppLinesPerArea; + u12image_ScaleX( dev, dev->scaleBuf, line_buffer ); - ps->DataInf.dwAppLinesPerArea -= ps->Scan.dwLinesToRead; - - if (ps->DataInf.dwScanFlag & SCANDEF_BmpStyle) - buffer += ((ps->Scan.dwLinesToRead - 1) * ps->DataInf.dwAppBytesPerLine); - - if (ps->DataInf.dwVxdFlag & _VF_DATATOUSERBUFFER) - ps->DataInf.pCurrentBuffer = ps->Scan.bp.pMonoBuf; - - while(ps->fScanningStatus && ps->Scan.dwLinesToRead) { -#endif - - res = u12image_ReadOneImageLine( dev, line_buffer ); - if( SANE_STATUS_GOOD != res ) - return res; - -#if 0 - /* - * as we might scan images that exceed the CCD-capabilities - * in x-resolution, we have to enlarge the line data - */ - if( NULL != scaleBuf ) { - ScaleX( ps, ps->Scan.bp.pMonoBuf, scaleBuf ); - copy_to_user( buffer, scaleBuf, ps->DataInf.dwAppPhyBytesPerLine); + } else { + res = u12image_ReadOneImageLine( dev, line_buffer ); + if( SANE_STATUS_GOOD != res ) + return res; } -#endif - -#if 0 - buffer += ps->Scan.lBufferAdjust; - dwLinesRead++; - ps->Scan.dwLinesToRead--; -#endif return SANE_STATUS_GOOD; } diff --git a/backend/u12-image.c b/backend/u12-image.c index ff6564a13..1a8d57c74 100644 --- a/backend/u12-image.c +++ b/backend/u12-image.c @@ -6,6 +6,9 @@ * * History: * - 0.01 - initial version + * - 0.02 - fixed fnColor42() to return 16bit values instead of + * only 12bit (this is the maximum the scanner can) + * - added scaling function u12image_ScaleX() * . *
* This file is part of the SANE package. @@ -122,7 +125,6 @@ static SANE_Bool fnReadToDriver( U12_Device *dev ) */ static SANE_Bool fnReadOutScanner( U12_Device *dev ) { -#if 1 if( dev->scan.bd_rk.wBlueDiscard ) { dev->scan.bd_rk.wBlueDiscard--; @@ -141,18 +143,15 @@ static SANE_Bool fnReadOutScanner( U12_Device *dev ) return SANE_FALSE; } else { -#endif u12io_ReadColorData( dev, dev->bufs.b1.pReadBuf, dev->DataInf.dwAsicBytesPerPlane ); return SANE_TRUE; -#if 1 } -#endif } /** some sampling functions */ -static SANE_Bool fnEveryLines( U12_Device *dev ) +static SANE_Bool fnEveryLine( U12_Device *dev ) { _VAR_NOT_USED( dev ); return SANE_TRUE; @@ -218,7 +217,7 @@ static void fnColor42( U12_Device *dev, void *pb, void *img, u_long len ) { u_short *src; RGBUShortDef *dest; - + register u_long i; _VAR_NOT_USED( len ); @@ -227,9 +226,9 @@ static void fnColor42( U12_Device *dev, void *pb, void *img, u_long len ) for ( i = dev->DataInf.dwAsicPixelsPerPlane; i; i--, src++, dest++) { - dest->Red = *src; - dest->Green = src[dev->DataInf.dwAsicPixelsPerPlane]; - dest->Blue = src[dev->DataInf.dwAsicPixelsPerPlane * 2]; + dest->Red = (*src) << 4; + dest->Green = (src[dev->DataInf.dwAsicPixelsPerPlane]) << 4; + dest->Blue = (src[dev->DataInf.dwAsicPixelsPerPlane * 2]) << 4; } } @@ -424,15 +423,14 @@ static void u12image_GetImageInfo( U12_Device *dev, ImgDef *image ) static int imageSetupScanSettings( U12_Device *dev, ImgDef *img ) { u_short brightness; - u_long xAdjust; DBG( _DBG_INFO, "imageSetupScanSettings()\n" ); - xAdjust = img->crArea.x + img->crArea.cx; - dev->DataInf.dwScanFlag = img->dwFlag; dev->DataInf.crImage = img->crArea; + DBG( _DBG_INFO,"* DataInf.dwScanFlag = 0x%08lx\n",dev->DataInf.dwScanFlag); + dev->DataInf.crImage.x <<= 1; dev->DataInf.xyAppDpi = img->xyDpi; @@ -447,31 +445,18 @@ static int imageSetupScanSettings( U12_Device *dev, ImgDef *img ) dev->DataInf.crImage.x, dev->DataInf.crImage.y, dev->DataInf.crImage.cx, dev->DataInf.crImage.cy ); - /* - * SetBwBrightness - * [NOTE] - * - * 0 _DEF_BW_THRESHOLD 255 - * +-------------------------+--------------------------------+ - * |<------- Black --------->|<----------- White ------------>| - * So, if user wish to make image darker, the threshold value should be - * higher than _defBwThreshold, otherwise it should lower than the - * _DefBwThreshold. - * Darker = _DefBwThreshold + White * Input / 127; - * Input < 0, and White = 255 - _DefBwThreshold, so - * = _DefBwThreshold - (255 - _DefBwThreshold) * Input / 127; - * The brighter is the same idea. - * - * CHECK: it seems that the brightness only works for the binary mode ! + /* + * 0 _DEF_BW_THRESHOLD 255 + * +-------------------------+--------------------------------+ + * |<------- Black --------->|<----------- White ------------>| + * So, if user wish to make image darker, the threshold value should be + * higher than _defBwThreshold, otherwise it should lower than the + * _DefBwThreshold. + * Darker = _DEF_BW_THRESHOLD + White * Input / 127; + * Input < 0, and White = 255 - _DEF_BW_THRESHOLD, so + * = _DEF_BW_THRESHOLD - (255 - _DEF_BW_THRESHOLD) * Input / 127; + * The brighter is the same idea. */ -#if 0 - if( dev->DataInf.wPhyDataType != COLOR_BW ) {/* if not line art */ - dev->wBrightness = pInf->siBrightness; /* use internal tables for */ - dev->wContrast = pInf->siContrast; /* brightness and contrast */ - - pInf->siBrightness = 0; /* don't use asic for threshold */ - } -#endif /* CHECK: We have now two methods for setting the brightness... */ @@ -485,19 +470,7 @@ static int imageSetupScanSettings( U12_Device *dev, ImgDef *img ) } dev->regs.RD_ThresholdControl = brightness; - DBG( _DBG_INFO, "* 1. brightness = %i\n", brightness ); - - if( dev->DataInf.siBrightness >= 0 ) { - brightness = (short)((long)(-(255 - _DEF_BW_THRESHOLD) * - dev->DataInf.siBrightness) / 127 + _DEF_BW_THRESHOLD); - } else { - brightness = (short)((long)(_DEF_BW_THRESHOLD * - dev->DataInf.siBrightness) / 127 + _DEF_BW_THRESHOLD); - } - brightness = (brightness ^ 0xff) & 0xff; - - dev->regs.RD_ThresholdControl = brightness; - DBG( _DBG_INFO, "* 2. brightness = %i\n", brightness ); + DBG( _DBG_INFO, "* RD_ThresholdControl = %i\n", brightness ); return 0; } @@ -593,7 +566,7 @@ static SANE_Status u12image_SetupScanSettings( U12_Device *dev, ImgDef *img ) /* ------- lines to sample or not? ------- */ if( dev->DataInf.xyAppDpi.y == dev->DataInf.xyPhyDpi.y ) { DBG( _DBG_INFO, "* Sample every line\n" ); - dev->scan.DoSample = fnEveryLines; + dev->scan.DoSample = fnEveryLine; } else { if( dev->DataInf.dwScanFlag & _SCANDEF_PREVIEW ) { @@ -744,10 +717,6 @@ static SANE_Bool u12image_DataIsReady( U12_Device *dev, void* buf ) if( dev->scan.DoSample( dev )) { - if( dev->scan.dwLinesToRead == 1 && - !(u12io_GetScanState( dev ) & _SCANSTATE_STOP)) - u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE ); - /* direct is done here without copying...*/ if( fnDataDirect != dev->scan.DataProcess ) { (*dev->scan.DataProcess)(dev, buf, (void*)(dev->scan.BufPut.red.bp), @@ -827,10 +796,111 @@ static SANE_Status u12image_ReadOneImageLine( U12_Device *dev, void* buf ) } while( !u12io_CheckTimer( &timer )); DBG( _DBG_ERROR, "Timeout - Scanner malfunction !!\n" ); - u12motor_ToHomePosition( dev ); + u12motor_ToHomePosition( dev, SANE_TRUE ); /* timed out, scanner malfunction */ return SANE_STATUS_IO_ERROR; } +/** + */ +static void u12image_PrepareScaling( U12_Device *dev ) +{ + int step; + double ratio; + + dev->scaleBuf = NULL; + DBG( _DBG_INFO, "APP-DPIX=%u, MAX-DPIX=%u\n", + dev->DataInf.xyAppDpi.x, dev->dpi_max_x ); + + if( dev->DataInf.xyAppDpi.x > dev->dpi_max_x ) { + + dev->scaleBuf = malloc( dev->DataInf.dwAppBytesPerLine ); + + ratio = (double)dev->DataInf.xyAppDpi.x/(double)dev->dpi_max_x; + dev->scaleIzoom = (int)(1.0/ratio * 1000); + + switch( dev->DataInf.wAppDataType ) { + + case COLOR_BW : step = 0; break; + case COLOR_256GRAY : step = 1; break; + case COLOR_TRUE24 : step = 3; break; + case COLOR_TRUE42 : step = 6; break; + default : step = 99; break; + } + dev->scaleStep = step; + + DBG( _DBG_INFO, "u12image_PrepareScaling: izoom=%i, step=%u\n", + dev->scaleIzoom, step ); + } else { + + DBG( _DBG_INFO, "u12image_PrepareScaling: DISABLED\n" ); + } +} + +/** scaling picture data in x-direction, using a DDA algorithm + * (digital differential analyzer). + */ +static void u12image_ScaleX( U12_Device *dev, SANE_Byte *ib, SANE_Byte *ob ) +{ + SANE_Byte tmp; + int ddax; + u_long i, j, x; + + /* when not supported, only copy the data */ + if( 99 == dev->scaleStep ) { + memcpy( ob, ib, dev->DataInf.dwAppBytesPerLine ); + return; + } + + /* now scale... */ + if( 0 == dev->scaleStep ) { + + /* binary scaling */ + ddax = 0; + x = 0; + memset( ob, 0, dev->DataInf.dwAppBytesPerLine ); + + for( i = 0; i < dev->DataInf.dwPhysBytesPerLine*8; i++ ) { + + ddax -= 1000; + + while( ddax < 0 ) { + + tmp = ib[(i>>3)]; + + if((x>>3) < dev->DataInf.dwAppBytesPerLine ) { + if( 0 != (tmp &= (1 << ((~(i & 0x7))&0x7)))) + ob[x>>3] |= (1 << ((~(x & 0x7))&0x7)); + } + x++; + ddax += dev->scaleIzoom; + } + } + + } else { + + /* color and gray scaling */ + ddax = 0; + x = 0; + for( i = 0; i < dev->DataInf.dwPhysBytesPerLine*dev->scaleStep; + i+=dev->scaleStep ) { + + ddax -= 1000; + + while( ddax < 0 ) { + + for( j = 0; j < (u_long)dev->scaleStep; j++ ) { + + if((x+j) < dev->DataInf.dwAppBytesPerLine ) { + ob[x+j] = ib[i+j]; + } + } + x += dev->scaleStep; + ddax += dev->scaleIzoom; + } + } + } +} + /* END U12_IMAGE.C ..........................................................*/ diff --git a/backend/u12-io.c b/backend/u12-io.c index 5bd6f9a98..157599186 100644 --- a/backend/u12-io.c +++ b/backend/u12-io.c @@ -7,6 +7,8 @@ * * History: * - 0.01 - initial version + * - 0.02 - changed u12io_GetFifoLength() behaviour + * - added delays to reset function * . *
* This file is part of the SANE package. @@ -265,7 +267,7 @@ gl640ReadBulk( int fd, u_char *setup, u_char *data, size_t size, int mod ) setup[4] = (size) & 0xFF; setup[5] = (size >> 8) & 0xFF; setup[6] = mod; - + CHK (gl640WriteControl (fd, GL640_BULK_SETUP, setup, 8)); len_info = NULL; @@ -282,6 +284,7 @@ gl640ReadBulk( int fd, u_char *setup, u_char *data, size_t size, int mod ) status = sanei_usb_read_bulk( fd, data, ¤t ); if( status != SANE_STATUS_GOOD ) { DBG( _DBG_ERROR, "gl640ReadBulk error\n"); + break; } data += current; complete += current; @@ -414,11 +417,19 @@ static SANE_Bool u12io_OpenScanPath( U12_Device *dev ) u12io_SwitchToSPPMode( dev ); outb_data( dev->fd, _ID_TO_PRINTER ); + _DODELAY(20); outb_data( dev->fd, _ID1ST ); + _DODELAY(5); + outb_data( dev->fd, _ID2ND ); + _DODELAY(5); + outb_data( dev->fd, _ID3RD ); - outb_data( dev->fd, _ID4TH ); + _DODELAY(5); + + outb_data( dev->fd, _ID4TH ); + _DODELAY(5); tmp = u12io_DataFromRegister( dev, REG_ASICID ); if( ASIC_ID == tmp ) { @@ -482,7 +493,7 @@ static SANE_Status u12io_DataToRegs( U12_Device *dev, SANE_Byte *buf, int len ) SANE_Status status; if( dev->mode != _PP_MODE_EPP ) { - DBG( _DBG_ERROR, "u12io_DataToRegsr() in wrong mode!\n" ); + DBG( _DBG_ERROR, "u12io_DataToRegs() in wrong mode!\n" ); return SANE_STATUS_IO_ERROR; } @@ -515,8 +526,7 @@ static SANE_Status u12io_MoveDataToScanner( U12_Device *dev, { SANE_Status status; -/* u12io_IORegisterToScanner( dev, REG_INITDATAFIFO ); -*/ +/* u12io_RegisterToScanner( dev, REG_INITDATAFIFO ); */ u12io_RegisterToScanner( dev, REG_WRITEDATAMODE ); bulk_setup_data[1] = 0x01; @@ -531,8 +541,7 @@ static SANE_Status u12io_ReadData( U12_Device *dev, SANE_Byte *buf, int len ) SANE_Status status; u12io_DataToRegister( dev, REG_MODECONTROL, dev->regs.RD_ModeControl ); -/* u12io_RegisterToScanner( dev, REG_INITDATAFIFO ); - */ +/* u12io_RegisterToScanner( dev, REG_INITDATAFIFO ); */ u12io_RegisterToScanner( dev, REG_READDATAMODE ); bulk_setup_data[1] = 0x00; @@ -542,41 +551,78 @@ static SANE_Status u12io_ReadData( U12_Device *dev, SANE_Byte *buf, int len ) return SANE_STATUS_GOOD; } -/** perform a SW reset of ASIC 98003 +/** perform a SW reset of ASIC P98003 */ static void u12io_SoftwareReset( U12_Device *dev ) { - DBG( _DBG_INFO, "Device reset!!!\n" ); + DBG( _DBG_INFO, "Device reset (%i)!!!\n", dev->fd ); u12io_DataToRegister( dev, REG_TESTMODE, _SW_TESTMODE ); -/* u12io_SwitchToSPPMode( dev ); - */ - outb_data( dev->fd, 0 ); + outb_data( dev->fd, _ID_TO_PRINTER ); + _DODELAY(20); outb_data( dev->fd, _RESET1ST ); + _DODELAY(5); outb_data( dev->fd, _RESET2ND ); + _DODELAY(5); outb_data( dev->fd, _RESET3RD ); + _DODELAY(5); outb_data( dev->fd, _RESET4TH ); + _DODELAY(250); } /** */ -static SANE_Bool u12io_IsConnected( int fd ) +static SANE_Bool u12io_IsConnected( U12_Device *dev ) { + int mode; SANE_Byte tmp; + SANE_Byte buf[6]; - tmp = inb_status( fd ); + DBG( _DBG_INFO, "u12io_IsConnected()\n" ); + tmp = inb_status( dev->fd ); + DBG( _DBG_INFO, "* tmp1 = 0x%02x\n", tmp ); - gl640WriteReq( fd, GL640_EPP_ADDR, REG_ASICID ); - gl640ReadReq ( fd, GL640_EPP_DATA_READ, &tmp ); + gl640WriteReq( dev->fd, GL640_EPP_ADDR, REG_ASICID ); + gl640ReadReq ( dev->fd, GL640_EPP_DATA_READ, &tmp ); + DBG( _DBG_INFO, "* REG_ASICID = 0x%02x\n", tmp ); if( tmp != ASIC_ID ) { - DBG( _DBG_INFO, "Scanner NOT connected!\n" ); + + DBG( _DBG_INFO, "* Scanner is NOT connected!\n" ); +/* FIXME: really needed? */ +#if 1 + if( dev->initialized ) { + + tmp = inb_status( dev->fd ); + DBG( _DBG_INFO, "* tmp3 = 0x%02x\n", tmp ); + + gl640WriteReq( dev->fd, GL640_EPP_ADDR, REG_ASICID ); + gl640ReadReq ( dev->fd, GL640_EPP_DATA_READ, &tmp ); + DBG( _DBG_INFO, "* REG_ASICID = 0x%02x\n", tmp ); + + mode = dev->mode; + dev->mode = _PP_MODE_EPP; + u12io_DataToRegister( dev, REG_ADCADDR, 1 ); + u12io_DataToRegister( dev, REG_ADCDATA, 0 ); + u12io_DataToRegister( dev, REG_ADCSERIALOUT, 0 ); + + buf[0] = REG_MODECONTROL; + buf[1] = 0x19; + buf[2] = REG_STEPCONTROL; + buf[3] = 0xff; + buf[4] = REG_MOTOR0CONTROL; + buf[5] = 0; + u12io_DataToRegs( dev, buf, 3 ); + dev->mode = mode; + } +#endif return SANE_FALSE; } - DBG( _DBG_INFO, "Scanner connected!\n" ); + u12io_SwitchToEPPMode( dev ); + DBG( _DBG_INFO, "* Scanner is connected!\n" ); return SANE_TRUE; } @@ -755,7 +801,17 @@ static u_long u12io_GetFifoLength( U12_Device *dev ) len_r = (u_long)data[5] * 256 + (u_long)data[4]; len_g = (u_long)data[8] * 256 + (u_long)data[7]; len_b = (u_long)data[11] * 256 + (u_long)data[10]; - len = len_r /*+ len_g + len_b*/; + + if( dev->DataInf.wPhyDataType < COLOR_TRUE24 ) { + len = len_g; + } else { + + len = len_r; + if( len_g < len ) + len = len_g; + if( len_b < len ) + len = len_b; + } DBG( _DBG_READ, "FIFO-LEN: %lu %lu %lu = %lu\n", len_r, len_g, len_b, len ); return len; diff --git a/backend/u12-map.c b/backend/u12-map.c index 8a4a0234d..25bd11415 100644 --- a/backend/u12-map.c +++ b/backend/u12-map.c @@ -5,6 +5,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - no changes * . *
* This file is part of the SANE package. diff --git a/backend/u12-motor.c b/backend/u12-motor.c index 31782f175..74bac0f72 100644 --- a/backend/u12-motor.c +++ b/backend/u12-motor.c @@ -6,6 +6,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - no changes * . *
* This file is part of the SANE package. @@ -173,7 +174,7 @@ static void u12motor_PositionModuleToHome( U12_Device *dev ) /** function to bring the sensor back home */ -static void u12motor_ToHomePosition( U12_Device *dev ) +static void u12motor_ToHomePosition( U12_Device *dev, SANE_Bool wait ) { TimerDef timer; @@ -181,11 +182,14 @@ static void u12motor_ToHomePosition( U12_Device *dev ) if( !(u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER)) { u12motor_PositionModuleToHome( dev ); - u12io_StartTimer( &timer, _SECOND * 20); - do { - if( u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER) - break; - } while( !u12io_CheckTimer( &timer )); + + if( wait ) { + u12io_StartTimer( &timer, _SECOND * 20); + do { + if( u12io_DataFromRegister( dev, REG_STATUS ) & _FLAG_PAPER) + break; + } while( !u12io_CheckTimer( &timer )); + } } DBG( _DBG_INFO, "- done !\n" ); } diff --git a/backend/u12-scanner.h b/backend/u12-scanner.h index a3e2bec7d..be0c200cb 100644 --- a/backend/u12-scanner.h +++ b/backend/u12-scanner.h @@ -5,6 +5,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - removed useless stuff * . *
* This file is part of the SANE package. @@ -245,7 +246,6 @@ typedef struct u_long negBegin; /* used while scanning in TPA modes */ u_long posBegin; SANE_Byte bDiscardAll; - u_long dwLinesToRead; union { u_short wGreenDiscard; diff --git a/backend/u12-shading.c b/backend/u12-shading.c index cccff7ccb..c1c735678 100644 --- a/backend/u12-shading.c +++ b/backend/u12-shading.c @@ -6,6 +6,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - * . *
* This file is part of the SANE package. @@ -161,7 +162,7 @@ static SANE_Status u12shadingAdjustShadingWaveform( U12_Device *dev ) dev->scan.refreshState = SANE_FALSE; u12io_PutOnAllRegisters( dev ); - _DODELAY( 45 ); +/* _DODELAY( 100 ); */ if( dev->shade.pHilight ) { @@ -592,7 +593,7 @@ static SANE_Status u12shading_AdjustRGBGain( U12_Device *dev ) dev->a_nbNewAdrPointer[1] = 0x77; u12io_PutOnAllRegisters( dev ); - _DODELAY( 45 ); +/* _DODELAY( 100 ); */ /* read one shading line and work on it */ if( u12io_ReadOneShadingLine( dev, @@ -701,7 +702,7 @@ static SANE_Status u12shadingAdjustDark( U12_Device *dev ) dev->a_nbNewAdrPointer[1] = 0x77; u12io_PutOnAllRegisters( dev ); - _DODELAY( 45 ); +/* _DODELAY( 100 ); */ /* read one shading line and work on it */ if( u12io_ReadOneShadingLine(dev, diff --git a/backend/u12-tpa.c b/backend/u12-tpa.c index 72e3b1aa6..a583ce5e7 100644 --- a/backend/u12-tpa.c +++ b/backend/u12-tpa.c @@ -6,6 +6,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - no changes * . *
* This file is part of the SANE package. diff --git a/backend/u12.c b/backend/u12.c index 29a47085a..b2d6be3a8 100644 --- a/backend/u12.c +++ b/backend/u12.c @@ -7,6 +7,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - enabled other scan-modes *. *
* This file is part of the SANE package. @@ -78,14 +79,14 @@ #include "../include/sane/sanei.h" #include "../include/sane/saneopts.h" -#define BACKEND_VERSION "0.01-1" +#define BACKEND_VERSION "0.02-2" #define BACKEND_NAME u12 #include "../include/sane/sanei_backend.h" #include "../include/sane/sanei_config.h" #include "../include/sane/sanei_thread.h" #include "../include/sane/sanei_usb.h" -/*#define ALL_MODES*/ +#define ALL_MODES #include "u12-scanner.h" #include "u12-hwdef.h" @@ -144,7 +145,7 @@ static const SANE_String_Const mode_list[] = SANE_I18N("Binary"), SANE_I18N("Gray"), SANE_I18N("Color"), - SANE_I18N("Color 42/48"), + SANE_I18N("Color 36"), NULL }; @@ -416,13 +417,16 @@ static SANE_Status do_cancel( U12_Scanner *scanner, SANE_Bool closepipe ) #endif } scanner->reader_pid = 0; - DBG( _DBG_PROC,"reader_process killed\n"); + DBG( _DBG_PROC, "reader_process killed\n"); #if 1 - u12io_SoftwareReset( scanner->hw ); - _DODELAY(250); - u12io_CloseScanPath( scanner->hw ); - u12io_OpenScanPath( scanner->hw ); + if( scanner->hw->fd >= 0 ) { + u12io_SoftwareReset( scanner->hw ); +#if 0 + u12io_CloseScanPath( scanner->hw ); + _DODELAY(250); +#endif + } #endif } @@ -1168,6 +1172,9 @@ void sane_close( SANE_Handle handle ) if( NULL != s->hw->shade.pHilight ) free( s->hw->shade.pHilight ); + if( NULL != s->hw->scaleBuf ) + free( s->hw->scaleBuf ); + drvClose( s->hw ); if (prev) @@ -1592,33 +1599,33 @@ SANE_Status sane_start( SANE_Handle handle ) */ ndpi = s->val[OPT_RESOLUTION].w; - /* exchange the values as we can't deal with negative heights and so on...*/ - tmp = s->val[OPT_TL_X].w; - if( tmp > s->val[OPT_BR_X].w ) { + /* exchange the values as we can't deal with negative heights and so on...*/ + tmp = s->val[OPT_TL_X].w; + if( tmp > s->val[OPT_BR_X].w ) { DBG( _DBG_INFO, "exchanging BR-X - TL-X\n" ); - s->val[OPT_TL_X].w = s->val[OPT_BR_X].w; - s->val[OPT_BR_X].w = tmp; - } + s->val[OPT_TL_X].w = s->val[OPT_BR_X].w; + s->val[OPT_BR_X].w = tmp; + } - tmp = s->val[OPT_TL_Y].w; - if( tmp > s->val[OPT_BR_Y].w ) { + tmp = s->val[OPT_TL_Y].w; + if( tmp > s->val[OPT_BR_Y].w ) { DBG( _DBG_INFO, "exchanging BR-Y - TL-Y\n" ); - s->val[OPT_TL_Y].w = s->val[OPT_BR_Y].w; - s->val[OPT_BR_Y].w = tmp; - } + s->val[OPT_TL_Y].w = s->val[OPT_BR_Y].w; + s->val[OPT_BR_Y].w = tmp; + } /* position and extent are always relative to 300 dpi */ dpi_x = (double)dev->dpi_max_x; dpi_y = (double)dev->dpi_max_y; - left = (int)(SANE_UNFIX (s->val[OPT_TL_X].w)* dpi_x/ - (_MM_PER_INCH*(dpi_y/_MEASURE_BASE))); - top = (int)(SANE_UNFIX (s->val[OPT_TL_Y].w)*dpi_y/ - (_MM_PER_INCH*(dpi_y/_MEASURE_BASE))); - width = (int)(SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w) * - dpi_x / (_MM_PER_INCH *(dpi_x/_MEASURE_BASE))); - height = (int)(SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w) * - dpi_y / (_MM_PER_INCH *(dpi_y/_MEASURE_BASE))); + left = (int)(SANE_UNFIX(s->val[OPT_TL_X].w)* dpi_x/ + (_MM_PER_INCH*(dpi_x/_MEASURE_BASE))); + top = (int)(SANE_UNFIX(s->val[OPT_TL_Y].w)*dpi_y/ + (_MM_PER_INCH*(dpi_y/_MEASURE_BASE))); + width = (int)(SANE_UNFIX(s->val[OPT_BR_X].w - s->val[OPT_TL_X].w) * + dpi_x / (_MM_PER_INCH *(dpi_x/_MEASURE_BASE))); + height = (int)(SANE_UNFIX(s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w) * + dpi_y / (_MM_PER_INCH *(dpi_y/_MEASURE_BASE))); if((width == 0) || (height == 0)) { DBG( _DBG_ERROR, "invalid width or height!\n" ); @@ -1656,7 +1663,7 @@ SANE_Status sane_start( SANE_Handle handle ) #endif if( s->val[OPT_PREVIEW].w ) - image.dwFlag &= _SCANDEF_PREVIEW; + image.dwFlag |= _SCANDEF_PREVIEW; /* set adjustments for brightness and contrast */ dev->DataInf.siBrightness = s->val[OPT_BRIGHTNESS].w; @@ -1690,11 +1697,6 @@ SANE_Status sane_start( SANE_Handle handle ) return SANE_STATUS_IO_ERROR; } -#if 0 - DBG( _DBG_SANE_INIT, "dwflag = 0x%lx dwBytesPerLine = %ld \n", - dev->scanning.dwFlag, dev->scanning.dwBytesLine ); -#endif - s->buf = realloc( s->buf, (s->params.lines) * s->params.bytes_per_line ); if( NULL == s->buf ) { DBG( _DBG_ERROR, "realloc failed\n" ); diff --git a/backend/u12.h b/backend/u12.h index 51331244f..a9d13c50c 100644 --- a/backend/u12.h +++ b/backend/u12.h @@ -5,6 +5,7 @@ * * History: * - 0.01 - initial version + * - 0.02 - added scaling variables to struct u12d * . *
* This file is part of the SANE package. @@ -277,10 +278,13 @@ typedef struct u12d RGBByteDef RegDACOffset; RGBByteDef RegDACGain; - ShadowRegs regs; /**< for holding ASIC register values */ - DataInfo DataInf; /**< all static info about the current scan */ - ScanInfo scan; /**< buffer and motor management during scan */ + ShadowRegs regs; /**< for holding ASIC register values */ + DataInfo DataInf; /**< all static info about the current scan */ + ScanInfo scan; /**< buffer and motor management during scan */ BufferDef bufs; + void *scaleBuf; /**< buffer for line scaling */ + int scaleStep; /**< step size for line scaling */ + int scaleIzoom; /**< factor for line scaling */ u_long ModelOriginY; SANE_Byte ModelCtrl;