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;