From 349bce36cab0f470826067e5bb6340ee92e2b598 Mon Sep 17 00:00:00 2001 From: Gerhard Jaeger Date: Mon, 5 Jul 2004 12:59:03 +0000 Subject: [PATCH] Added support for binary scanning for the CanoScan D660U, cleanup work. --- backend/plustek-usb.c | 36 +- backend/plustek-usb.h | 32 +- backend/plustek-usbdevs.c | 5 +- backend/plustek-usbhw.c | 19 +- backend/plustek-usbimg.c | 1327 +++++++++++++++++++------------------ backend/plustek-usbmap.c | 26 +- backend/plustek-usbscan.c | 53 +- 7 files changed, 761 insertions(+), 737 deletions(-) diff --git a/backend/plustek-usb.c b/backend/plustek-usb.c index 912970b91..50ae3f981 100644 --- a/backend/plustek-usb.c +++ b/backend/plustek-usb.c @@ -705,9 +705,7 @@ static int usbDev_getCropInfo( Plustek_Device *dev, pCropInfo ci ) DBG( _DBG_INFO, "usbDev_getCropInfo()\n" ); - _VAR_NOT_USED(dev); - - usb_GetImageInfo( &ci->ImgDef, &size ); + usb_GetImageInfo( dev, &ci->ImgDef, &size ); ci->dwPixelsPerLine = size.dwPixels; ci->dwLinesPerArea = size.dwLines; @@ -726,7 +724,7 @@ static int usbDev_getCropInfo( Plustek_Device *dev, pCropInfo ci ) /** */ static int usbDev_setMap( Plustek_Device *dev, SANE_Word *map, - SANE_Word length, SANE_Word channel ) + SANE_Word length, SANE_Word channel ) { SANE_Word i, idx; @@ -762,10 +760,12 @@ static int usbDev_setMap( Plustek_Device *dev, SANE_Word *map, */ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si ) { + DCapsDef *caps = &dev->usbDev.Caps; + DBG( _DBG_INFO, "usbDev_setScanEnv()\n" ); - /* clear all the stuff */ - memset( &dev->scanning, 0, sizeof(ScanDef)); + /* clear all the stuff */ + memset( &dev->scanning, 0, sizeof(ScanDef)); if((si->ImgDef.dwFlag & SCANDEF_Adf) && (si->ImgDef.dwFlag & SCANDEF_ContinuousScan)) { @@ -781,30 +781,34 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si ) (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((dev->usbDev.vendor == 0x04A9) && (dev->usbDev.product == 0x2208)) { - DBG( _DBG_INFO, "* Gray(GRAY256) from color set (D660U)!\n" ); + 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; } } else if ( si->ImgDef.wDataType == COLOR_GRAY16 ) { - if((dev->usbDev.vendor == 0x04A9) && (dev->usbDev.product == 0x2208)) { - DBG( _DBG_INFO, "* Gray(GRAY16) from color set (D660U)!\n" ); + 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; + } } - usb_SaveImageInfo( dev, &si->ImgDef ); - usb_GetImageInfo ( &si->ImgDef, &dev->scanning.sParam.Size ); + usb_GetImageInfo ( dev, &si->ImgDef, &dev->scanning.sParam.Size ); /* Flags */ dev->scanning.dwFlag = si->ImgDef.dwFlag & - (SCANFLAG_bgr | SCANFLAG_BottomUp | SCANFLAG_Invert | + (SCANFLAG_bgr | SCANFLAG_BottomUp | SCANFLAG_DWORDBoundary | SCANFLAG_RightAlign | SCANFLAG_StillModule | SCANDEF_Adf | SCANDEF_ContinuousScan); @@ -823,14 +827,14 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si ) dev->scanning.dwFlag &= ~SCANFLAG_RightAlign; if( dev->scanning.dwFlag & SCANFLAG_DWORDBoundary ) { - if( dev->scanning.fGrayFromColor ) + if( dev->scanning.fGrayFromColor && dev->scanning.fGrayFromColor < 10) dev->scanning.dwBytesLine = (dev->scanning.sParam.Size.dwBytes / 3 + 3) & 0xfffffffcUL; else dev->scanning.dwBytesLine = (dev->scanning.sParam.Size.dwBytes + 3UL) & 0xfffffffcUL; } else { - if( dev->scanning.fGrayFromColor ) + if( dev->scanning.fGrayFromColor && dev->scanning.fGrayFromColor < 10) dev->scanning.dwBytesLine = dev->scanning.sParam.Size.dwBytes / 3; else dev->scanning.dwBytesLine = dev->scanning.sParam.Size.dwBytes; diff --git a/backend/plustek-usb.h b/backend/plustek-usb.h index d07fd54f5..4b68f813c 100644 --- a/backend/plustek-usb.h +++ b/backend/plustek-usb.h @@ -32,6 +32,7 @@ * - added gamma to struct HWDefault * - 0.48 - added DEVCAPSFLAG_LargeTPA * - added min_ffstep to ClkMotorDef + * - added _WAF_BIN_FROM_COLOR and _WAF_GRAY_FROM_COLOR * . *
* This file is part of the SANE package. @@ -231,7 +232,9 @@ enum _WORKAROUNDS _WAF_BYPASS_CALIBRATION = 0x00000008, /* no calibration,use linear gamma */ _WAF_INV_NEGATIVE_MAP = 0x00000010, /* the backend does the neg. stuff */ _WAF_SKIP_FINE = 0x00000020, /* skip the fine calbration */ - _WAF_SKIP_WHITEFINE = 0x00000040 /* skip the fine white calbration */ + _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 */ }; /** for lamps connected to the misc I/O pins*/ @@ -308,7 +311,6 @@ enum SCANFLAG SCANFLAG_bgr = 0x00004000, SCANFLAG_BottomUp = 0x00008000, - SCANFLAG_Invert = 0x00010000, SCANFLAG_DWORDBoundary = 0x00020000, SCANFLAG_RightAlign = 0x00040000, SCANFLAG_StillModule = 0x00080000, @@ -340,21 +342,21 @@ typedef struct SrcAttr typedef struct DevCaps { - SrcAttrDef Normal; /**< Reflection */ - SrcAttrDef Positive; /**< Positive film */ - SrcAttrDef Negative; /**< Negative film */ - SrcAttrDef Adf; /**< Adf device */ - XY OpticDpi; /**< Maximum DPI */ - u_short wFlags; /**< Flag to indicate what kinds of elements */ + SrcAttrDef Normal; /**< Reflection */ + SrcAttrDef Positive; /**< Positive film */ + SrcAttrDef Negative; /**< Negative film */ + SrcAttrDef Adf; /**< Adf device */ + XY OpticDpi; /**< Maximum DPI */ + u_short wFlags; /**< Flag to indicate what kinds of elements */ /* are available */ - u_char bSensorOrder; /**< CCD color sequences, see _SENSORORDER */ - u_char bSensorDistance;/**< CCD Color distance */ - u_char bButtons; /**< Number of buttons */ - u_char bCCD; /**< CCD ID */ - u_char bPCB; /**< PCB ID */ - u_long workaroundFlag; /**< Flag to allow special work arounds, see */ + u_char bSensorOrder; /**< CCD color sequences, see _SENSORORDER */ + u_char bSensorDistance; /**< CCD Color distance */ + u_char bButtons; /**< Number of buttons */ + u_char bCCD; /**< CCD ID */ + u_char bPCB; /**< PCB ID */ + u_long workaroundFlag; /**< Flag to allow special work arounds, see */ /* _WORKAROUNDS */ - u_long lamp; /**< for lamp: loword: normal, hiword: tpa */ + u_long lamp; /**< for lamp: loword: normal, hiword: tpa */ } DCapsDef, *pDCapsDef; diff --git a/backend/plustek-usbdevs.c b/backend/plustek-usbdevs.c index fc085dbc1..e211b0e57 100644 --- a/backend/plustek-usbdevs.c +++ b/backend/plustek-usbdevs.c @@ -661,7 +661,8 @@ static DCapsDef Cap0x04A9_0x2208 = 1, kNEC8861, /* use default settings during calibration */ 0, - _WAF_MISC_IO_LAMPS, _MIO5 + _TPA(_MIO6) + (_WAF_MISC_IO_LAMPS | _WAF_BIN_FROM_COLOR | _WAF_GRAY_FROM_COLOR), + _MIO5 + _TPA(_MIO6) }; /* Canon N670U/N676U/LiDE20 @@ -2519,7 +2520,7 @@ 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, 0x0100, + { MODEL_CANONCCD1200, 2, 31, 6, 0x0120, /* 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 }, diff --git a/backend/plustek-usbhw.c b/backend/plustek-usbhw.c index b627da71c..eb3bf2447 100644 --- a/backend/plustek-usbhw.c +++ b/backend/plustek-usbhw.c @@ -238,6 +238,7 @@ static SANE_Bool usb_SensorPaper( int handle ) */ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) { + SANE_Bool retval; u_char value; u_short ffs, step; long dwTicks; @@ -251,8 +252,7 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) step = 1; ffs = a_bRegs[0x48] * 256 + a_bRegs[0x49]; - DBG( _DBG_INFO2, "# FSS=%u (0x%04x)\n", ffs, ffs ); - + retval = SANE_FALSE; for(;;) { usleep( 1000 ); @@ -281,13 +281,16 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay ) sanei_lm983x_write(dev->fd, 0x48, &a_bRegs[0x48], 2, SANE_TRUE); } else { - if( !stay ) - return SANE_TRUE; + if( !stay ) { + retval = SANE_TRUE; + break; + } } step++; } - return SANE_FALSE; + DBG( _DBG_INFO2, "# FSS=%u (0x%04x) - %u steps\n", ffs, ffs, step ); + return retval; } /** @@ -599,7 +602,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) * assumptions: MCLK = 6, Lineratemode (CM=1) */ wFastFeedStepSize = (u_short)(dwCrystalFrequency / (mclk_div * 8 * 1 * - hw->dMaxMotorSpeed * 4 * hw->wMotorDpi)); + hw->dMaxMotorSpeed * 4 * hw->wMotorDpi)); a_bRegs[0x48] = (u_char)(wFastFeedStepSize >> 8); a_bRegs[0x49] = (u_char)(wFastFeedStepSize & 0xFF); a_bRegs[0x4a] = 0; @@ -638,7 +641,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) /* 1 channel grayscale, green channel */ if( !usbio_WriteReg(dev->fd, 0x26, 0x8C)) return SANE_FALSE; - + _UIO(sanei_lm983x_write(dev->fd, 0x48, &a_bRegs[0x48], 4, SANE_TRUE)); _UIO(sanei_lm983x_write(dev->fd, 0x56, &a_bRegs[0x56], 3, SANE_TRUE)); @@ -652,7 +655,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait ) if( !usbio_WriteReg(dev->fd, 0x07, 2)) return SANE_FALSE; - + #if 0 if( hw->motorModel == MODEL_Tokyo600) { diff --git a/backend/plustek-usbimg.c b/backend/plustek-usbimg.c index c5b576f6e..783b22638 100644 --- a/backend/plustek-usbimg.c +++ b/backend/plustek-usbimg.c @@ -26,6 +26,7 @@ * - 0.47 - added big-endian/little endian stuff * - 0.48 - fixed usb_ColorDuplicateGray16() and * usb_ColorScaleGray16() + * - added usb_BWScaleFromColor() and usb_BWDuplicateFromColor * - cleanup * . *
@@ -69,7 +70,7 @@ *
*/ -#define _SCALER 1000 +#define _SCALER 1000 static u_char bShift, Shift; static u_char *pbSrce, *pbDest; @@ -81,8 +82,12 @@ static u_short wR, wG, wB; static pHiLoDef pwm; /* - * */ +static u_char BitTable[8] = +{ + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 +}; + static u_char BitsReverseTable[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, @@ -102,13 +107,11 @@ static u_char BitsReverseTable[256] = 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; -#if 0 -inline void ReverseBits(int b, u_charPBYTE &pTar, int &iByte, int &iWeightSum, - int iSrcWeight = 0, int iTarWeight = 0, int cMax = 8); -#endif + +/************************ some helper functions ******************************/ static void ReverseBits( int b, u_char **pTar, int *iByte, int *iWeightSum, - int iSrcWeight, int iTarWeight, int cMax ) + int iSrcWeight, int iTarWeight, int cMax ) { int bit; @@ -145,10 +148,7 @@ static void ReverseBits( int b, u_char **pTar, int *iByte, int *iWeightSum, } } } -#if 0 -void ReverseBitStream(PBYTE pSrc, PBYTE pTar, int iPixels, int iBufSize, - int iSrcWeight = 0, int iTarWeight = 0, int iPadBit = 1); -#endif + static void usb_ReverseBitStream( u_char *pSrc, u_char *pTar, int iPixels, int iBufSize, int iSrcWeight/* = 0*/, int iTarWeight/* = 0*/, int iPadBit/* = 1*/) @@ -210,35 +210,35 @@ static void usb_ReverseBitStream( u_char *pSrc, u_char *pTar, int iPixels, /** */ -static void usb_AverageColorByte( struct Plustek_Device *dev ) +static void usb_AverageColorByte( Plustek_Device *dev ) { u_long dw; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; - if((scanning->sParam.bSource == SOURCE_Negative || - scanning->sParam.bSource == SOURCE_Transparency) && - scanning->sParam.PhyDpi.x > 800) { + if((scan->sParam.bSource == SOURCE_Negative || + scan->sParam.bSource == SOURCE_Transparency) && + scan->sParam.PhyDpi.x > 800) { - for (dw = 0; dw < (scanning->sParam.Size.dwPhyPixels - 1); dw++) + for (dw = 0; dw < (scan->sParam.Size.dwPhyPixels - 1); dw++) { - scanning->Red.pcb[dw].a_bColor[0] = - (u_char)(((u_short)scanning->Red.pcb[dw].a_bColor[0] + - (u_short)scanning->Red.pcb[dw + 1].a_bColor[0]) / 2); + scan->Red.pcb[dw].a_bColor[0] = + (u_char)(((u_short)scan->Red.pcb[dw].a_bColor[0] + + (u_short)scan->Red.pcb[dw + 1].a_bColor[0]) / 2); - scanning->Green.pcb[dw].a_bColor[0] = - (u_char)(((u_short)scanning->Green.pcb[dw].a_bColor[0] + - (u_short)scanning->Green.pcb[dw + 1].a_bColor[0]) / 2); + scan->Green.pcb[dw].a_bColor[0] = + (u_char)(((u_short)scan->Green.pcb[dw].a_bColor[0] + + (u_short)scan->Green.pcb[dw + 1].a_bColor[0]) / 2); - scanning->Blue.pcb[dw].a_bColor[0] = - (u_char)(((u_short)scanning->Blue.pcb[dw].a_bColor[0] + - (u_short)scanning->Blue.pcb[dw + 1].a_bColor[0]) / 2); + scan->Blue.pcb[dw].a_bColor[0] = + (u_char)(((u_short)scan->Blue.pcb[dw].a_bColor[0] + + (u_short)scan->Blue.pcb[dw + 1].a_bColor[0]) / 2); } } } /** */ -static void usb_AverageColorWord( struct Plustek_Device *dev ) +static void usb_AverageColorWord( Plustek_Device *dev ) { u_char ls = 2; u_long dw; @@ -278,46 +278,43 @@ static void usb_AverageColorWord( struct Plustek_Device *dev ) /** */ -static void usb_AverageGrayByte( struct Plustek_Device *dev ) +static void usb_AverageGrayByte( Plustek_Device *dev ) { u_long dw; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; - if((scanning->sParam.bSource == SOURCE_Negative || - scanning->sParam.bSource == SOURCE_Transparency) && - scanning->sParam.PhyDpi.x > 800) + if((scan->sParam.bSource == SOURCE_Negative || + scan->sParam.bSource == SOURCE_Transparency) && + scan->sParam.PhyDpi.x > 800) { - for (dw = 0; dw < (scanning->sParam.Size.dwPhyPixels - 1); dw++) - scanning->Green.pb[dw] = (u_char)(((u_short)scanning->Green.pb[dw]+ - (u_short)scanning->Green.pb[dw+1]) / 2); + for (dw = 0; dw < (scan->sParam.Size.dwPhyPixels - 1); dw++) + scan->Green.pb[dw] = (u_char)(((u_short)scan->Green.pb[dw]+ + (u_short)scan->Green.pb[dw+1]) / 2); } - } /** */ -static void usb_AverageGrayWord( struct Plustek_Device *dev ) +static void usb_AverageGrayWord( Plustek_Device *dev ) { u_long dw; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; - if((scanning->sParam.bSource == SOURCE_Negative || - scanning->sParam.bSource == SOURCE_Transparency) && - scanning->sParam.PhyDpi.x > 800) + if((scan->sParam.bSource == SOURCE_Negative || + scan->sParam.bSource == SOURCE_Transparency) && + scan->sParam.PhyDpi.x > 800) { - scanning->Green.pw[0] = _HILO2WORD(scanning->Green.philo[0]) >> 2; + scan->Green.pw[0] = _HILO2WORD(scan->Green.philo[0]) >> 2; - for (dw = 0; dw < (scanning->sParam.Size.dwPhyPixels - 1); dw++) + for (dw = 0; dw < (scan->sParam.Size.dwPhyPixels - 1); dw++) { - scanning->Green.pw[dw + 1] = _HILO2WORD(scanning->Green.philo[dw+1]) >> 2; - - scanning->Green.pw[dw] = (u_short)(((u_long)scanning->Green.pw[dw]+ - (u_long)scanning->Green.pw[dw+1]) / 2); - - scanning->Green.pw[dw] = _HILO2WORD(scanning->Green.philo[dw]) << 2; + scan->Green.pw[dw + 1] = _HILO2WORD(scan->Green.philo[dw+1]) >> 2; + scan->Green.pw[dw] = (u_short)(((u_long)scan->Green.pw[dw]+ + (u_long)scan->Green.pw[dw+1]) / 2); + scan->Green.pw[dw] = _HILO2WORD(scan->Green.philo[dw]) << 2; } - scanning->Green.pw[dw] = _HILO2WORD(scanning->Green.philo[dw]) << 2; + scan->Green.pw[dw] = _HILO2WORD(scan->Green.philo[dw]) << 2; } } @@ -325,173 +322,554 @@ static void usb_AverageGrayWord( struct Plustek_Device *dev ) * returns the zoom value, used for our scaling algorithm (DDA algo * digital differential analyzer). */ -static int usb_GetScaler( pScanDef scanning ) +static int usb_GetScaler( ScanDef *scan ) { double ratio; - ratio = (double)scanning->sParam.UserDpi.x/ - (double)scanning->sParam.PhyDpi.x; - + ratio = (double)scan->sParam.UserDpi.x/ + (double)scan->sParam.PhyDpi.x; + return (int)(1.0/ratio * _SCALER); } -/** +/******************************* the copy functions **************************/ + +/** do a simple memcopy from scan-buffer to user buffer */ -static void usb_ColorScaleGray( struct Plustek_Device *dev ) +static void usb_ColorDuplicate8( Plustek_Device *dev ) { - int izoom, ddax; u_long dw; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; usb_AverageColorByte( dev ); - - dw = scanning->sParam.Size.dwPixels; - if( scanning->sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; + dwPixels = scan->sParam.Size.dwPixels - 1; } else { iNext = 1; dwPixels = 0; } - - izoom = usb_GetScaler( scanning ); - switch( scanning->fGrayFromColor ) { - - case 1: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { + for( dw = 0; dw < scan->sParam.Size.dwPixels; + dw++, dwPixels = dwPixels + iNext ) { - ddax -= _SCALER; + scan->UserBuf.pb_rgb[dwPixels].Red = scan->Red.pcb[dw].a_bColor[0]; + scan->UserBuf.pb_rgb[dwPixels].Green = scan->Green.pcb[dw].a_bColor[0]; + scan->UserBuf.pb_rgb[dwPixels].Blue = scan->Blue.pcb[dw].a_bColor[0]; + } +} - while((ddax < 0) && (dw > 0)) { +/** reorder from rgb line to rgb pixel (CIS scanner) + */ +static void usb_ColorDuplicate8_2( Plustek_Device *dev ) +{ + u_long dw; + pScanDef scan = &dev->scanning; - scanning->UserBuf.pb[dwPixels] = - scanning->Red.pcb[dwBitsPut].a_bColor[0]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } - break; - - case 2: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { + if( scan->sParam.bSource == SOURCE_ADF ) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } - ddax -= _SCALER; + for( dw = 0; dw < scan->sParam.Size.dwPixels; + dw++, dwPixels = dwPixels + iNext ) { - while((ddax < 0) && (dw > 0)) { - - scanning->UserBuf.pb[dwPixels] = - scanning->Green.pcb[dwBitsPut].a_bColor[0]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } - break; - - case 3: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { - - ddax -= _SCALER; - - while((ddax < 0) && (dw > 0)) { - - scanning->UserBuf.pb[dwPixels] = - scanning->Blue.pcb[dwBitsPut].a_bColor[0]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } - break; + scan->UserBuf.pb_rgb[dwPixels].Red = (u_char)scan->Red.pb[dw]; + scan->UserBuf.pb_rgb[dwPixels].Green = (u_char)scan->Green.pb[dw]; + scan->UserBuf.pb_rgb[dwPixels].Blue = (u_char)scan->Blue.pb[dw]; } } /** - * */ -static void usb_ColorScaleGray_2( struct Plustek_Device *dev ) +static void usb_ColorDuplicate16( Plustek_Device *dev ) { - int izoom, ddax; - u_long dw; - pScanDef scanning = &dev->scanning; + u_char ls; + u_long dw; + pScanDef scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); - usb_AverageColorByte( dev ); + usb_AverageColorWord( dev ); - dw = scanning->sParam.Size.dwPixels; - - if( scanning->sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; + dwPixels = scan->sParam.Size.dwPixels - 1; } else { iNext = 1; dwPixels = 0; } - izoom = usb_GetScaler( scanning ); + if( scan->dwFlag & SCANFLAG_RightAlign ) + ls = Shift; + else + ls = 0; - switch( scanning->fGrayFromColor ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, + dwPixels = dwPixels + iNext) { + if( swap ) { + scan->UserBuf.pw_rgb[dwPixels].Red = + _HILO2WORD(scan->Red.pcw[dw].HiLo[0]) >> ls; + scan->UserBuf.pw_rgb[dwPixels].Green = + _HILO2WORD(scan->Green.pcw[dw].HiLo[0]) >> ls; + scan->UserBuf.pw_rgb[dwPixels].Blue = + _HILO2WORD(scan->Blue.pcw[dw].HiLo[0]) >> ls; + } else { + scan->UserBuf.pw_rgb[dwPixels].Red = scan->Red.pw[dw] >> ls; + scan->UserBuf.pw_rgb[dwPixels].Green= scan->Green.pw[dw] >> ls; + scan->UserBuf.pw_rgb[dwPixels].Blue = scan->Blue.pw[dw] >> ls; + } + } +} + +/** + */ +static void usb_ColorDuplicate16_2( Plustek_Device *dev ) +{ + u_char ls; + HiLoDef tmp; + u_long dw; + pScanDef scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); + + usb_AverageColorWord( dev ); + + if( scan->sParam.bSource == SOURCE_ADF ) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } + + if( scan->dwFlag & SCANFLAG_RightAlign ) + ls = Shift; + else + ls = 0; + + for( dw = 0; dw < scan->sParam.Size.dwPixels; + dw++, dwPixels = dwPixels + iNext) { + + if( swap ) { + tmp = *((pHiLoDef)&scan->Red.pw[dw]); + scan->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> ls; + + tmp = *((pHiLoDef)&scan->Green.pw[dw]); + scan->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> ls; + + tmp = *((pHiLoDef)&scan->Blue.pw[dw]); + scan->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> ls; + + } else { + + scan->UserBuf.pw_rgb[dwPixels].Red = scan->Red.pw[dw] >> ls; + scan->UserBuf.pw_rgb[dwPixels].Green = scan->Green.pw[dw] >> ls; + scan->UserBuf.pw_rgb[dwPixels].Blue = scan->Blue.pw[dw] >> ls; + } + } +} + +/** + */ +static void usb_ColorDuplicatePseudo16( Plustek_Device *dev ) +{ + u_long dw; + pScanDef scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) + { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } + else + { + iNext = 1; + dwPixels = 0; + } + + wR = (u_short)scan->Red.pcb[0].a_bColor[0]; + wG = (u_short)scan->Green.pcb[0].a_bColor[0]; + wB = (u_short)scan->Blue.pcb[0].a_bColor[0]; + + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + { + scan->UserBuf.pw_rgb[dwPixels].Red = + (wR + scan->Red.pcb[dw].a_bColor[0]) << bShift; + scan->UserBuf.pw_rgb[dwPixels].Green = + (wG + scan->Green.pcb[dw].a_bColor[0]) << bShift; + scan->UserBuf.pw_rgb[dwPixels].Blue = + (wB + scan->Blue.pcb[dw].a_bColor[0]) << bShift; + + wR = (u_short)scan->Red.pcb[dw].a_bColor[0]; + wG = (u_short)scan->Green.pcb[dw].a_bColor[0]; + wB = (u_short)scan->Blue.pcb[dw].a_bColor[0]; + } +} + +/** + */ +static void usb_ColorDuplicateGray( Plustek_Device *dev ) +{ + u_long dw; + pScanDef scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } + + switch(scan->fGrayFromColor) { + case 1: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { - - ddax -= _SCALER; - - while((ddax < 0) && (dw > 0)) { - - scanning->UserBuf.pb[dwPixels] = - scanning->Red.pb[dwBitsPut]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Red.pcb[dw].a_bColor[0]; break; - case 2: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { - - ddax -= _SCALER; - - while((ddax < 0) && (dw > 0)) { - - scanning->UserBuf.pb[dwPixels] = - scanning->Green.pb[dwBitsPut]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Green.pcb[dw].a_bColor[0]; break; - case 3: - for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { - - ddax -= _SCALER; - - while((ddax < 0) && (dw > 0)) { - - scanning->UserBuf.pb[dwPixels] = scanning->Blue.pb[dwBitsPut]; - - dwPixels = dwPixels + iNext; - ddax += izoom; - dw--; - } - } + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Blue.pcb[dw].a_bColor[0]; break; } } /** */ -static void usb_ColorScaleGray16( struct Plustek_Device *dev ) +static void usb_ColorDuplicateGray_2( Plustek_Device *dev ) +{ + u_long dw; + pScanDef scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } + + switch(scan->fGrayFromColor) + { + case 1: + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Red.pb[dw]; + break; + case 3: + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Blue.pb[dw]; + break; + default: + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pb[dwPixels] = scan->Green.pb[dw]; + break; + } +} + +/** + */ +static void usb_ColorDuplicateGray16( Plustek_Device *dev ) +{ + u_char ls; + u_long dw; + pScanDef scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); + + usb_AverageColorByte( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 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++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = + _HILO2WORD(scan->Red.pcw[dw].HiLo[0]) >> ls; + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = scan->Red.pw[dw] >> ls; + } + break; + case 2: + if( swap ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = + _HILO2WORD(scan->Green.pcw[dw].HiLo[0]) >> ls; + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = scan->Green.pw[dw] >> ls; + } + break; + case 3: + if( swap ) { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = + _HILO2WORD(scan->Blue.pcw[dw].HiLo[0]) >> ls; + } else { + for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) + scan->UserBuf.pw[dwPixels] = scan->Blue.pw[dw] >> ls; + } + break; + } +} + +/** + */ +static void usb_GrayDuplicate8( Plustek_Device *dev ) +{ + pScanDef scan = &dev->scanning; + + usb_AverageGrayByte( dev ); + + if( scan->sParam.bSource == SOURCE_ADF ) { + + dwPixels = scan->sParam.Size.dwPixels; + pbSrce = scan->Green.pb; + pbDest = scan->UserBuf.pb + dwPixels - 1; + + for(; dwPixels; dwPixels--, pbSrce++, pbDest--) + *pbDest = *pbSrce; + + } else + memcpy( scan->UserBuf.pb, scan->Green.pb, scan->sParam.Size.dwBytes ); +} + +/** + */ +static void usb_GrayDuplicate16( Plustek_Device *dev ) +{ + u_char ls; + pScanDef scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); + + usb_AverageGrayWord( dev ); + + if( scan->sParam.bSource == SOURCE_ADF ) { + iNext = -1; + pwDest = scan->UserBuf.pw + scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + pwDest = scan->UserBuf.pw; + } + + if( scan->dwFlag & SCANFLAG_RightAlign ) + ls = Shift; + else + ls = 0; + + pwm = scan->Green.philo; + for ( dwPixels = scan->sParam.Size.dwPixels; dwPixels--; + pwm++, pwDest = pwDest + iNext) { + if( swap ) + *pwDest = (_PHILO2WORD(pwm)) >> ls; + else + *pwDest = *((u_short*)pwm) >> ls; + } +} + +/** + */ +static void usb_GrayDuplicatePseudo16( Plustek_Device *dev ) +{ + pScanDef scan = &dev->scanning; + + usb_AverageGrayByte( dev ); + + if (scan->sParam.bSource == SOURCE_ADF) + { + iNext = -1; + pwDest = scan->UserBuf.pw + scan->sParam.Size.dwPixels - 1; + } + else + { + iNext = 1; + pwDest = scan->UserBuf.pw; + } + + pbSrce = scan->Green.pb; + wG = (u_short)*pbSrce; + + for( dwPixels = scan->sParam.Size.dwPixels; + dwPixels--; pbSrce++, pwDest = pwDest + iNext ) { + + *pwDest = (wG + *pbSrce) << bShift; + wG = (u_short)*pbSrce; + } +} + +/** copy binary data to the user buffer + */ +static void usb_BWDuplicate( Plustek_Device *dev ) +{ + pScanDef scan = &dev->scanning; + + if(scan->sParam.bSource == SOURCE_ADF) + { + usb_ReverseBitStream( scan->Green.pb, scan->UserBuf.pb, + scan->sParam.Size.dwValidPixels, + scan->dwBytesLine, 0, 0, 1 ); + } else { + memcpy( scan->UserBuf.pb, scan->Green.pb, scan->sParam.Size.dwBytes ); + } +} + +/** generate binary data from one of the three color inputs according to the + * value in fGrayFromColor + */ +static void usb_BWDuplicateFromColor( Plustek_Device *dev ) +{ + u_char d, s; + u_short j; + ColorByteDef *src; + pScanDef scan = &dev->scanning; + + if( scan->sParam.bSource == SOURCE_ADF ) { + pbDest = scan->UserBuf.pb + scan->sParam.Size.dwPixels - 1; + iNext = -1; + } else { + pbDest = scan->UserBuf.pb; + iNext = 1; + } + + switch(scan->fGrayFromColor) { + case 1: src = scan->Red.pcb; break; + case 3: src = scan->Blue.pcb; break; + default: src = scan->Green.pcb; break; + } + + d = j = 0; + for( dwPixels = scan->sParam.Size.dwPixels; dwPixels; dwPixels--, src++ ) { + + s = src->a_bColor[0]; + if( s != 0 ) + d |= BitTable[j]; + j++; + if( j == 8 ) { + *pbDest = d; + pbDest += iNext; + + d = j = 0; + } + } +} + +/************************** the scaling functions ****************************/ + +/** + */ +static void usb_ColorScaleGray( Plustek_Device *dev ) +{ + int izoom, ddax; + u_long dw; + ColorByteDef *src; + pScanDef scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + dw = scan->sParam.Size.dwPixels; + + if( scan->sParam.bSource == SOURCE_ADF ) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } + + switch(scan->fGrayFromColor) { + case 1: src = scan->Red.pcb; break; + case 3: src = scan->Blue.pcb; break; + default: src = scan->Green.pcb; break; + } + + izoom = usb_GetScaler( scan ); + + for( dwBitsPut = 0, ddax = 0; dw; src++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dw > 0)) { + + scan->UserBuf.pb[dwPixels] = src->a_bColor[0]; + + dwPixels = dwPixels + iNext; + ddax += izoom; + dw--; + } + } +} + +/** + */ +static void usb_ColorScaleGray_2( Plustek_Device *dev ) +{ + int izoom, ddax; + u_long dw; + pScanDef scan = &dev->scanning; + + usb_AverageColorByte( dev ); + + dw = scan->sParam.Size.dwPixels; + + if( scan->sParam.bSource == SOURCE_ADF ) { + iNext = -1; + dwPixels = scan->sParam.Size.dwPixels - 1; + } else { + iNext = 1; + dwPixels = 0; + } + + switch(scan->fGrayFromColor) { + case 1: pbSrce = scan->Red.pb; break; + case 3: pbSrce = scan->Blue.pb; break; + default: pbSrce = scan->Green.pb; break; + } + + izoom = usb_GetScaler( scan ); + + for( dwBitsPut = 0, ddax = 0; dw; pbSrce++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dw > 0)) { + + scan->UserBuf.pb[dwPixels] = *pbSrce; + + dwPixels = dwPixels + iNext; + ddax += izoom; + dw--; + } + } +} + +/** + */ +static void usb_ColorScaleGray16( Plustek_Device *dev ) { u_char ls; int izoom, ddax; @@ -584,7 +962,7 @@ static void usb_ColorScaleGray16( struct Plustek_Device *dev ) /** here we copy and scale from scanner world to user world... */ -static void usb_ColorScale8( struct Plustek_Device *dev ) +static void usb_ColorScale8( Plustek_Device *dev ) { int izoom, ddax; u_long dw; @@ -626,23 +1004,23 @@ static void usb_ColorScale8( struct Plustek_Device *dev ) } } -static void usb_ColorScale8_2( struct Plustek_Device *dev ) +static void usb_ColorScale8_2( Plustek_Device *dev ) { int izoom, ddax; u_long dw; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; - dw = scanning->sParam.Size.dwPixels; + dw = scan->sParam.Size.dwPixels; - if( scanning->sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; + dwPixels = scan->sParam.Size.dwPixels - 1; } else { iNext = 1; dwPixels = 0; } - izoom = usb_GetScaler( scanning ); + izoom = usb_GetScaler( scan ); for( dwBitsPut = 0, ddax = 0; dw; dwBitsPut++ ) { @@ -650,26 +1028,20 @@ static void usb_ColorScale8_2( struct Plustek_Device *dev ) while((ddax < 0) && (dw > 0)) { - scanning->UserBuf.pb_rgb[dwPixels].Red = - scanning->Red.pb[dwBitsPut]; - - scanning->UserBuf.pb_rgb[dwPixels].Green = - scanning->Green.pb[dwBitsPut]; - - scanning->UserBuf.pb_rgb[dwPixels].Blue = - scanning->Blue.pb[dwBitsPut]; - + scan->UserBuf.pb_rgb[dwPixels].Red = scan->Red.pb[dwBitsPut]; + scan->UserBuf.pb_rgb[dwPixels].Green = scan->Green.pb[dwBitsPut]; + scan->UserBuf.pb_rgb[dwPixels].Blue = scan->Blue.pb[dwBitsPut]; + dwPixels = dwPixels + iNext; ddax += izoom; dw--; } - } + } } /** - * */ -static void usb_ColorScale16( struct Plustek_Device *dev ) +static void usb_ColorScale16( Plustek_Device *dev ) { u_char ls; int izoom, ddax; @@ -733,9 +1105,8 @@ static void usb_ColorScale16( struct Plustek_Device *dev ) } /** - * */ -static void usb_ColorScale16_2( struct Plustek_Device *dev ) +static void usb_ColorScale16_2( Plustek_Device *dev ) { u_char ls; HiLoDef tmp; @@ -801,7 +1172,7 @@ static void usb_ColorScale16_2( struct Plustek_Device *dev ) /** */ -static void usb_ColorScalePseudo16( struct Plustek_Device *dev ) +static void usb_ColorScalePseudo16( Plustek_Device *dev ) { int izoom, ddax; u_long dw; @@ -851,321 +1222,9 @@ static void usb_ColorScalePseudo16( struct Plustek_Device *dev ) } } -/** do a simple memcopy from "driver-space" to "user-space" - */ -static void usb_ColorDuplicate8( struct Plustek_Device *dev ) -{ - u_long dw; - pScanDef scanning = &dev->scanning; - - usb_AverageColorByte( dev ); - - if( scanning->sParam.bSource == SOURCE_ADF ) { - iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 0; - } - - for( dw = 0; dw < scanning->sParam.Size.dwPixels; - dw++, dwPixels = dwPixels + iNext ) { - - scanning->UserBuf.pb_rgb[dwPixels].Red = - scanning->Red.pcb[dw].a_bColor[0]; - - scanning->UserBuf.pb_rgb[dwPixels].Green = - scanning->Green.pcb[dw].a_bColor[0]; - - scanning->UserBuf.pb_rgb[dwPixels].Blue = - scanning->Blue.pcb[dw].a_bColor[0]; - } -} - -/** reorder from rgb line to rgb pixel (CIS scanner) - */ -static void usb_ColorDuplicate8_2( struct Plustek_Device *dev ) -{ - u_long dw; - pScanDef scanning = &dev->scanning; - - if( scanning->sParam.bSource == SOURCE_ADF ) { - iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 0; - } - - for( dw = 0; dw < scanning->sParam.Size.dwPixels; - dw++, dwPixels = dwPixels + iNext ) { - - scanning->UserBuf.pb_rgb[dwPixels].Red = (u_char)scanning->Red.pb[dw]; - scanning->UserBuf.pb_rgb[dwPixels].Green = (u_char)scanning->Green.pb[dw]; - scanning->UserBuf.pb_rgb[dwPixels].Blue = (u_char)scanning->Blue.pb[dw]; - } -} - /** */ -static void usb_ColorDuplicate16( struct Plustek_Device *dev ) -{ - u_char ls; - u_long dw; - pScanDef scan = &dev->scanning; - SANE_Bool swap = usb_HostSwap(); - - usb_AverageColorWord( dev ); - - if( scan->sParam.bSource == SOURCE_ADF ) { - iNext = -1; - dwPixels = scan->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 0; - } - - if( scan->dwFlag & SCANFLAG_RightAlign ) - ls = Shift; - else - ls = 0; - - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, - dwPixels = dwPixels + iNext) { - - if( swap ) { - scan->UserBuf.pw_rgb[dwPixels].Red = - _HILO2WORD(scan->Red.pcw[dw].HiLo[0]) >> ls; - scan->UserBuf.pw_rgb[dwPixels].Green = - _HILO2WORD(scan->Green.pcw[dw].HiLo[0]) >> ls; - scan->UserBuf.pw_rgb[dwPixels].Blue = - _HILO2WORD(scan->Blue.pcw[dw].HiLo[0]) >> ls; - } else { - scan->UserBuf.pw_rgb[dwPixels].Red = scan->Red.pw[dw] >> ls; - scan->UserBuf.pw_rgb[dwPixels].Green= scan->Green.pw[dw] >> ls; - scan->UserBuf.pw_rgb[dwPixels].Blue = scan->Blue.pw[dw] >> ls; - } - } -} - -/** - */ -static void usb_ColorDuplicate16_2( struct Plustek_Device *dev ) -{ - u_char ls; - HiLoDef tmp; - u_long dw; - pScanDef scan = &dev->scanning; - SANE_Bool swap = usb_HostSwap(); - - usb_AverageColorWord( dev ); - - if( scan->sParam.bSource == SOURCE_ADF ) { - iNext = -1; - dwPixels = scan->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 0; - } - - if( scan->dwFlag & SCANFLAG_RightAlign ) - ls = Shift; - else - ls = 0; - - for( dw = 0; dw < scan->sParam.Size.dwPixels; - dw++, dwPixels = dwPixels + iNext) { - - if( swap ) { - tmp = *((pHiLoDef)&scan->Red.pw[dw]); - scan->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> ls; - - tmp = *((pHiLoDef)&scan->Green.pw[dw]); - scan->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> ls; - - tmp = *((pHiLoDef)&scan->Blue.pw[dw]); - scan->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> ls; - - } else { - - scan->UserBuf.pw_rgb[dwPixels].Red = scan->Red.pw[dw] >> ls; - scan->UserBuf.pw_rgb[dwPixels].Green = scan->Green.pw[dw] >> ls; - scan->UserBuf.pw_rgb[dwPixels].Blue = scan->Blue.pw[dw] >> ls; - } - } -} - -/** - */ -static void usb_ColorDuplicatePseudo16( struct Plustek_Device *dev ) -{ - u_long dw; - pScanDef scanning = &dev->scanning; - - usb_AverageColorByte( dev ); - - if (scanning->sParam.bSource == SOURCE_ADF) - { - iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; - } - else - { - iNext = 1; - dwPixels = 0; - } - - wR = (u_short)scanning->Red.pcb[0].a_bColor[0]; - wG = (u_short)scanning->Green.pcb[0].a_bColor[0]; - wB = (u_short)scanning->Blue.pcb[0].a_bColor[0]; - - for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - { - scanning->UserBuf.pw_rgb[dwPixels].Red = - (wR + scanning->Red.pcb[dw].a_bColor[0]) << bShift; - scanning->UserBuf.pw_rgb[dwPixels].Green = - (wG + scanning->Green.pcb[dw].a_bColor[0]) << bShift; - scanning->UserBuf.pw_rgb[dwPixels].Blue = - (wB + scanning->Blue.pcb[dw].a_bColor[0]) << bShift; - - wR = (u_short)scanning->Red.pcb[dw].a_bColor[0]; - wG = (u_short)scanning->Green.pcb[dw].a_bColor[0]; - wB = (u_short)scanning->Blue.pcb[dw].a_bColor[0]; - } -} - -/** - */ -static void usb_ColorDuplicateGray( struct Plustek_Device *dev ) -{ - u_long dw; - pScanDef scan = &dev->scanning; - - usb_AverageColorByte( dev ); - - if (scan->sParam.bSource == SOURCE_ADF) { - iNext = -1; - dwPixels = scan->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 0; - } - - switch(scan->fGrayFromColor) { - - case 1: - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pb[dwPixels] = scan->Red.pcb[dw].a_bColor[0]; - break; - case 2: - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pb[dwPixels] = scan->Green.pcb[dw].a_bColor[0]; - break; - case 3: - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pb[dwPixels] = scan->Blue.pcb[dw].a_bColor[0]; - break; - } -} - -/** - */ -static void usb_ColorDuplicateGray_2( struct Plustek_Device *dev ) -{ - u_long dw; - pScanDef scanning = &dev->scanning; - - usb_AverageColorByte( dev ); - - if (scanning->sParam.bSource == SOURCE_ADF) - { - iNext = -1; - dwPixels = scanning->sParam.Size.dwPixels - 1; - } - else - { - iNext = 1; - dwPixels = 0; - } - - switch(scanning->fGrayFromColor) - { - case 1: - for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scanning->UserBuf.pb[dwPixels] = scanning->Red.pb[dw]; - break; - case 2: - for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scanning->UserBuf.pb[dwPixels] = scanning->Green.pb[dw]; - break; - case 3: - for (dw = 0; dw < scanning->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scanning->UserBuf.pb[dwPixels] = scanning->Blue.pb[dw]; - break; - } -} - -/** - */ -static void usb_ColorDuplicateGray16( struct Plustek_Device *dev ) -{ - u_char ls; - u_long dw; - pScanDef scan = &dev->scanning; - SANE_Bool swap = usb_HostSwap(); - - usb_AverageColorByte( dev ); - - if (scan->sParam.bSource == SOURCE_ADF) { - iNext = -1; - dwPixels = scan->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - dwPixels = 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++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = - _HILO2WORD(scan->Red.pcw[dw].HiLo[0]) >> ls; - } else { - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = scan->Red.pw[dw] >> ls; - } - break; - case 2: - if( swap ) { - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = - _HILO2WORD(scan->Green.pcw[dw].HiLo[0]) >> ls; - } else { - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = scan->Green.pw[dw] >> ls; - } - break; - case 3: - if( swap ) { - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = - _HILO2WORD(scan->Blue.pcw[dw].HiLo[0]) >> ls; - } else { - for (dw = 0; dw < scan->sParam.Size.dwPixels; dw++, dwPixels = dwPixels + iNext) - scan->UserBuf.pw[dwPixels] = scan->Blue.pw[dw] >> ls; - } - break; - } -} - -/** - */ -static void usb_BWScale( struct Plustek_Device *dev ) +static void usb_BWScale( Plustek_Device *dev ) { u_char tmp; int izoom, ddax; @@ -1176,10 +1235,10 @@ static void usb_BWScale( struct Plustek_Device *dev ) if( scanning->sParam.bSource == SOURCE_ADF ) { int iSum = wSum; usb_ReverseBitStream(scanning->Green.pb, scanning->UserBuf.pb, - scanning->sParam.Size.dwValidPixels, - scanning->dwBytesLine, - scanning->sParam.PhyDpi.x, - scanning->sParam.UserDpi.x, 1 ); + scanning->sParam.Size.dwValidPixels, + scanning->dwBytesLine, + scanning->sParam.PhyDpi.x, + scanning->sParam.UserDpi.x, 1 ); wSum = iSum; return; @@ -1188,11 +1247,11 @@ static void usb_BWScale( struct Plustek_Device *dev ) iNext = 1; } - izoom = usb_GetScaler( scanning ); + izoom = usb_GetScaler( scanning ); memset( pbDest, 0, scanning->dwBytesLine ); ddax = 0; - dw = 0; + dw = 0; for( i = 0; i < scanning->sParam.Size.dwValidPixels; i++ ) { @@ -1201,7 +1260,7 @@ static void usb_BWScale( struct Plustek_Device *dev ) while( ddax < 0 ) { tmp = pbSrce[(i>>3)]; - + if((dw>>3) < scanning->sParam.Size.dwValidPixels ) { if( 0 != (tmp &= (1 << ((~(i & 0x7))&0x7)))) @@ -1215,43 +1274,76 @@ static void usb_BWScale( struct Plustek_Device *dev ) /** */ -static void usb_BWDuplicate( struct Plustek_Device *dev ) +static void usb_BWScaleFromColor( Plustek_Device *dev ) { - pScanDef scanning = &dev->scanning; + u_char d, s; + u_short j; + int izoom, ddax; + ColorByteDef *src; + pScanDef scan = &dev->scanning; - if(scanning->sParam.bSource == SOURCE_ADF) - { - usb_ReverseBitStream( scanning->Green.pb, scanning->UserBuf.pb, - scanning->sParam.Size.dwValidPixels, - scanning->dwBytesLine, 0, 0, 1 ); + if (scan->sParam.bSource == SOURCE_ADF) { + pbDest = scan->UserBuf.pb + scan->sParam.Size.dwPixels - 1; + iNext = -1; } else { - memcpy( scanning->UserBuf.pb, - scanning->Green.pb, scanning->sParam.Size.dwBytes ); - } + pbDest = scan->UserBuf.pb; + iNext = 1; + } + + /* setup the source buffer */ + switch(scan->fGrayFromColor) { + case 1: src = scan->Red.pcb; break; + case 3: src = scan->Blue.pcb; break; + default: src = scan->Green.pcb; break; + } + + izoom = usb_GetScaler( scan ); + ddax = 0; + + d = j = 0; + for( dwPixels = scan->sParam.Size.dwPixels; dwPixels; src++ ) { + + ddax -= _SCALER; + + while((ddax < 0) && (dwPixels > 0)) { + + s = src->a_bColor[0]; + if( s != 0 ) + d |= BitTable[j]; + j++; + if( j == 8 ) { + *pbDest = d; + pbDest = pbDest + iNext; + d = j = 0; + } + ddax += izoom; + dwPixels--; + } + } } /** */ -static void usb_GrayScale8( struct Plustek_Device *dev ) +static void usb_GrayScale8( Plustek_Device *dev ) { int izoom, ddax; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; usb_AverageGrayByte( dev ); - pbSrce = scanning->Green.pb; - if( scanning->sParam.bSource == SOURCE_ADF ) { - pbDest = scanning->UserBuf.pb + scanning->sParam.Size.dwPixels - 1; + pbSrce = scan->Green.pb; + if( scan->sParam.bSource == SOURCE_ADF ) { + pbDest = scan->UserBuf.pb + scan->sParam.Size.dwPixels - 1; iNext = -1; } else { - pbDest = scanning->UserBuf.pb; + pbDest = scan->UserBuf.pb; iNext = 1; } - izoom = usb_GetScaler( scanning ); + izoom = usb_GetScaler( scan ); ddax = 0; - for( dwPixels = scanning->sParam.Size.dwPixels; dwPixels; pbSrce++ ) { + for( dwPixels = scan->sParam.Size.dwPixels; dwPixels; pbSrce++ ) { ddax -= _SCALER; @@ -1261,41 +1353,41 @@ static void usb_GrayScale8( struct Plustek_Device *dev ) pbDest = pbDest + iNext; ddax += izoom; dwPixels--; - } + } } } /** */ -static void usb_GrayScale16( struct Plustek_Device *dev ) +static void usb_GrayScale16( Plustek_Device *dev ) { u_char ls; int izoom, ddax; - pScanDef scanning = &dev->scanning; - SANE_Bool swap = usb_HostSwap(); + pScanDef scan = &dev->scanning; + SANE_Bool swap = usb_HostSwap(); usb_AverageGrayWord( dev); - pwm = scanning->Green.philo; - wSum = scanning->sParam.PhyDpi.x; + pwm = scan->Green.philo; + wSum = scan->sParam.PhyDpi.x; - if( scanning->sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { iNext = -1; - pwDest = scanning->UserBuf.pw + scanning->sParam.Size.dwPixels - 1; + pwDest = scan->UserBuf.pw + scan->sParam.Size.dwPixels - 1; } else { iNext = 1; - pwDest = scanning->UserBuf.pw; + pwDest = scan->UserBuf.pw; } - izoom = usb_GetScaler( scanning ); + izoom = usb_GetScaler( scan ); ddax = 0; - if( scanning->dwFlag & SCANFLAG_RightAlign ) + if( scan->dwFlag & SCANFLAG_RightAlign ) ls = Shift; else ls = 0; - for( dwPixels = scanning->sParam.Size.dwPixels; dwPixels; pwm++ ) { + for( dwPixels = scan->sParam.Size.dwPixels; dwPixels; pwm++ ) { ddax -= _SCALER; @@ -1315,28 +1407,28 @@ static void usb_GrayScale16( struct Plustek_Device *dev ) /** */ -static void usb_GrayScalePseudo16( struct Plustek_Device *dev ) +static void usb_GrayScalePseudo16( Plustek_Device *dev ) { int izoom, ddax; - pScanDef scanning = &dev->scanning; + pScanDef scan = &dev->scanning; usb_AverageGrayByte( dev ); - if( scanning->sParam.bSource == SOURCE_ADF ) { + if( scan->sParam.bSource == SOURCE_ADF ) { iNext = -1; - pwDest = scanning->UserBuf.pw + scanning->sParam.Size.dwPixels - 1; + pwDest = scan->UserBuf.pw + scan->sParam.Size.dwPixels - 1; } else { iNext = 1; - pwDest = scanning->UserBuf.pw; + pwDest = scan->UserBuf.pw; } - pbSrce = scanning->Green.pb; + pbSrce = scan->Green.pb; wG = (u_short)*pbSrce; - izoom = usb_GetScaler( scanning ); + izoom = usb_GetScaler( scan ); ddax = 0; - for( dwPixels = scanning->sParam.Size.dwPixels; dwPixels; pbSrce++ ) { + for( dwPixels = scan->sParam.Size.dwPixels; dwPixels; pbSrce++ ) { ddax -= _SCALER; @@ -1351,95 +1443,10 @@ static void usb_GrayScalePseudo16( struct Plustek_Device *dev ) } } -/** - * - */ -static void usb_GrayDuplicate8( struct Plustek_Device *dev ) -{ - pScanDef scanning = &dev->scanning; - - usb_AverageGrayByte( dev ); - - if( scanning->sParam.bSource == SOURCE_ADF ) { - - dwPixels = scanning->sParam.Size.dwPixels; - pbSrce = scanning->Green.pb; - pbDest = scanning->UserBuf.pb + dwPixels - 1; - - for(; dwPixels; dwPixels--, pbSrce++, pbDest--) - *pbDest = *pbSrce; - - } else - memcpy( scanning->UserBuf.pb, - scanning->Green.pb, scanning->sParam.Size.dwBytes ); -} - -/** - */ -static void usb_GrayDuplicate16( struct Plustek_Device *dev ) -{ - u_char ls; - pScanDef scanning = &dev->scanning; - SANE_Bool swap = usb_HostSwap(); - - usb_AverageGrayWord( dev ); - - if( scanning->sParam.bSource == SOURCE_ADF ) { - iNext = -1; - pwDest = scanning->UserBuf.pw + scanning->sParam.Size.dwPixels - 1; - } else { - iNext = 1; - pwDest = scanning->UserBuf.pw; - } - - if( scanning->dwFlag & SCANFLAG_RightAlign ) - ls = Shift; - else - ls = 0; - - pwm = scanning->Green.philo; - for ( dwPixels = scanning->sParam.Size.dwPixels; dwPixels--; - pwm++, pwDest = pwDest + iNext) { - if( swap ) - *pwDest = (_PHILO2WORD(pwm)) >> ls; - else - *pwDest = *((u_short*)pwm) >> ls; - } -} - -/** - */ -static void usb_GrayDuplicatePseudo16( struct Plustek_Device *dev ) -{ - pScanDef scanning = &dev->scanning; - - usb_AverageGrayByte( dev ); - - if (scanning->sParam.bSource == SOURCE_ADF) - { - iNext = -1; - pwDest = scanning->UserBuf.pw + scanning->sParam.Size.dwPixels - 1; - } - else - { - iNext = 1; - pwDest = scanning->UserBuf.pw; - } - - pbSrce = scanning->Green.pb; - wG = (u_short)*pbSrce; - - for( dwPixels = scanning->sParam.Size.dwPixels; - dwPixels--; pbSrce++, pwDest = pwDest + iNext ) { - - *pwDest = (wG + *pbSrce) << bShift; - wG = (u_short)*pbSrce; - } -} /** function to select the apropriate pixel copy function */ -static void usb_GetImageProc( struct Plustek_Device *dev ) +static void usb_GetImageProc( Plustek_Device *dev ) { pScanDef scanning = &dev->scanning; pDCapsDef sc = &dev->usbDev.Caps; @@ -1455,7 +1462,7 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) case SCANDATATYPE_Color: if (scanning->sParam.bBitDepth > 8) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorScale16_2; DBG( _DBG_INFO, "ImageProc is: ColorScale16_2\n" ); } else { @@ -1466,31 +1473,34 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) scanning->pfnProcess = usb_ColorScaleGray16; DBG( _DBG_INFO, "ImageProc is: ColorScaleGray16\n" ); } - } else if (scanning->dwFlag & SCANFLAG_Pseudo48) { scanning->pfnProcess = usb_ColorScalePseudo16; DBG( _DBG_INFO, "ImageProc is: ColorScalePseudo16\n" ); } else if (scanning->fGrayFromColor) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorScaleGray_2; DBG( _DBG_INFO, "ImageProc is: ColorScaleGray_2\n" ); } else { - scanning->pfnProcess = usb_ColorScaleGray; - DBG( _DBG_INFO, "ImageProc is: ColorScaleGray\n" ); + if (scanning->fGrayFromColor > 7 ) { + scanning->pfnProcess = usb_BWScaleFromColor; + DBG( _DBG_INFO, "ImageProc is: BWScaleFromColor\n" ); + } else { + scanning->pfnProcess = usb_ColorScaleGray; + DBG( _DBG_INFO, "ImageProc is: ColorScaleGray\n" ); + } } - } else { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorScale8_2; DBG( _DBG_INFO, "ImageProc is: ColorScale8_2\n" ); } else { scanning->pfnProcess = usb_ColorScale8; DBG( _DBG_INFO, "ImageProc is: ColorScale8\n" ); } - } + } break; case SCANDATATYPE_Gray: @@ -1505,8 +1515,8 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) } else { scanning->pfnProcess = usb_GrayScale8; DBG( _DBG_INFO, "ImageProc is: GrayScale8\n" ); - } - } + } + } break; default: @@ -1522,7 +1532,7 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) case SCANDATATYPE_Color: if (scanning->sParam.bBitDepth > 8) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorDuplicate16_2; DBG( _DBG_INFO, "ImageProc is: ColorDuplicate16_2\n" ); } else { @@ -1537,22 +1547,27 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) scanning->pfnProcess = usb_ColorDuplicatePseudo16; DBG( _DBG_INFO, "ImageProc is: ColorDuplicatePseudo16\n" ); } else if (scanning->fGrayFromColor) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorDuplicateGray_2; DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray_2\n" ); } else { - scanning->pfnProcess = usb_ColorDuplicateGray; - DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray\n" ); + if (scanning->fGrayFromColor > 7 ) { + scanning->pfnProcess = usb_BWDuplicateFromColor; + DBG( _DBG_INFO, "ImageProc is: BWDuplicateFromColor\n" ); + } else { + scanning->pfnProcess = usb_ColorDuplicateGray; + DBG( _DBG_INFO, "ImageProc is: ColorDuplicateGray\n" ); + } } } else { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( usb_IsCISDevice(dev)){ scanning->pfnProcess = usb_ColorDuplicate8_2; DBG( _DBG_INFO, "ImageProc is: ColorDuplicate8_2\n" ); } else { scanning->pfnProcess = usb_ColorDuplicate8; DBG( _DBG_INFO, "ImageProc is: ColorDuplicate8\n" ); } - } + } break; case SCANDATATYPE_Gray: @@ -1566,8 +1581,8 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) } else { scanning->pfnProcess = usb_GrayDuplicate8; DBG( _DBG_INFO, "ImageProc is: GrayDuplicate8\n" ); - } - } + } + } break; default: @@ -1584,11 +1599,10 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) bShift = 5; } else { - /* - * this should fix the Bearpaw/U12 discrepancy + /* this should fix the Bearpaw/U12 discrepancy * in general the fix is needed, but not for the U12 * why? - no idea! - */ + */ if(_WAF_BSHIFT7_BUG == (_WAF_BSHIFT7_BUG & sc->workaroundFlag)) bShift = 0; /* Holger Bischof 16.12.2001 */ else @@ -1611,7 +1625,7 @@ static void usb_GetImageProc( struct Plustek_Device *dev ) * here we read the image data into our intermediate buffer (in the NT version * the function was implemented as thread) */ -static SANE_Int usb_ReadData( struct Plustek_Device *dev ) +static SANE_Int usb_ReadData( Plustek_Device *dev ) { u_long dw, dwRet, dwBytes, pl; pScanDef scan = &dev->scanning; @@ -1638,10 +1652,9 @@ static SANE_Int usb_ReadData( struct Plustek_Device *dev ) if(!scan->sParam.Size.dwTotalBytes && dw < (pl * 1024)) { if(!(a_bRegs[0x4e] = (u_char)ceil((double)dw / - (4.0 * hw->wDRAMSize)))) { + (4.0 * hw->wDRAMSize)))) { a_bRegs[0x4e] = 1; } - a_bRegs[0x4f] = 0; sanei_lm983x_write( dev->fd, 0x4e, &a_bRegs[0x4e], 2, SANE_TRUE ); diff --git a/backend/plustek-usbmap.c b/backend/plustek-usbmap.c index 652223fad..c8c20ac85 100644 --- a/backend/plustek-usbmap.c +++ b/backend/plustek-usbmap.c @@ -18,7 +18,7 @@ * - 0.45 - no changes * - 0.46 - no changes * - 0.47 - cleanup work - * - 0.48 - no changes + * - 0.48 - added support for binary from color scans * . *
* This file is part of the SANE package. @@ -126,16 +126,16 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType ) /* the maps are have been already set */ - /* do the brightness and contrast adjustment ... */ - if( scanning->sParam.bDataType != SCANDATATYPE_BW ) + /* do the brightness and contrast adjustment ... */ + if( scanning->sParam.bDataType != SCANDATATYPE_BW ) usb_MapAdjust( dev ); if( !usbio_WriteReg( dev->fd, 7, 0)) return SANE_FALSE; /* we download all the time all three color maps, as we run - * into trouble elsewhere on CanoScan models using gray mode - */ + * into trouble elsewhere on CanoScan models using gray mode + */ #if 0 if( bDataType == SCANDATATYPE_Color ) { color = 0; @@ -155,17 +155,18 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType ) /* select color */ value = (color << 2)+2; - + /* set gamma color selector */ usbio_WriteReg( dev->fd, 0x03, value ); usbio_WriteReg( dev->fd, 0x04, 0 ); usbio_WriteReg( dev->fd, 0x05, 0 ); - + /* write the gamma table entry to merlin */ - if( scanning->sParam.bDataType == SCANDATATYPE_BW ) { - + if((scanning->sParam.bDataType == SCANDATATYPE_BW) || + (scanning->fGrayFromColor > 7 )) { + iThreshold = (int)((double)scanning->sParam.siThreshold * - (_MAP_SIZE/200.0)) + (_MAP_SIZE/2); + (_MAP_SIZE/200.0)) + (_MAP_SIZE/2); iThreshold = _MAP_SIZE - iThreshold; if(iThreshold < 0) iThreshold = 0; @@ -192,11 +193,6 @@ static SANE_Bool usb_MapDownload( pPlustek_Device dev, u_char bDataType ) (sc->workaroundFlag &_WAF_INV_NEGATIVE_MAP)) { fInverse ^= 1; } - - if((scanning->dwFlag & SCANFLAG_Invert) && - !(scanning->dwFlag & SCANFLAG_Pseudo48)) { - fInverse ^= 1; - } if( fInverse ) { diff --git a/backend/plustek-usbscan.c b/backend/plustek-usbscan.c index 372569566..4e7247623 100644 --- a/backend/plustek-usbscan.c +++ b/backend/plustek-usbscan.c @@ -89,7 +89,7 @@ static u_long m_dwPauseLimit; static SANE_Bool m_fStart = SANE_FALSE; /* Prototype... */ -static SANE_Bool usb_DownloadShadingData( pPlustek_Device, u_char ); +static SANE_Bool usb_DownloadShadingData( Plustek_Device*, u_char ); /** returns the min of the two values val1 and val2 * @param val1 - first parameter @@ -126,7 +126,7 @@ 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( pPlustek_Device dev, u_short xdpi ) +static u_short usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi ) { u_short res; pScanDef scanning = &dev->scanning; @@ -204,7 +204,7 @@ static u_short usb_SetAsicDpiX( pPlustek_Device dev, u_short xdpi ) * @param ydpi - user specified vertical resolution * @return - */ -static u_short usb_SetAsicDpiY( pPlustek_Device dev, u_short ydpi ) +static u_short usb_SetAsicDpiY( Plustek_Device *dev, u_short ydpi ) { pScanDef scanning = &dev->scanning; pDCapsDef sCaps = &dev->usbDev.Caps; @@ -256,7 +256,7 @@ static u_short usb_SetAsicDpiY( pPlustek_Device dev, u_short ydpi ) * @param pParam - pointer to the current scan parameters * @return - Nothing */ -static void usb_SetColorAndBits( pPlustek_Device dev, pScanParam pParam ) +static void usb_SetColorAndBits( Plustek_Device *dev, pScanParam pParam ) { pHWDef hw = &dev->usbDev.HwSetting; @@ -313,7 +313,7 @@ static void usb_SetColorAndBits( pPlustek_Device dev, pScanParam pParam ) * @param pParam - pointer to the current scan parameters * @return - Nothing */ -static void usb_GetScanRect( pPlustek_Device dev, pScanParam pParam ) +static void usb_GetScanRect( Plustek_Device *dev, pScanParam pParam ) { u_short wDataPixelStart, wLineEnd; @@ -481,7 +481,7 @@ static void usb_GetScanRect( pPlustek_Device dev, pScanParam pParam ) /** preset scan stepsize and fastfeed stepsize */ -static void usb_PresetStepSize( pPlustek_Device dev, pScanParam pParam ) +static void usb_PresetStepSize( Plustek_Device *dev, pScanParam pParam ) { u_short ssize; double mclkdiv = pParam->dMCLK; @@ -500,7 +500,7 @@ static void usb_PresetStepSize( pPlustek_Device dev, pScanParam pParam ) /** calculate default phase difference DPD */ -static void usb_GetDPD( pPlustek_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 */ @@ -550,7 +550,7 @@ static void usb_GetDPD( pPlustek_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( pPlustek_Device dev, pScanParam pParam ) +static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam ) { double dMaxIntegrationTime; double dMaxMCLKDivider; @@ -644,7 +644,7 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam ) /** calculate the step size of each scan step */ -static void usb_GetStepSize( pPlustek_Device dev, pScanParam pParam ) +static void usb_GetStepSize( Plustek_Device *dev, pScanParam pParam ) { pHWDef hw = &dev->usbDev.HwSetting; @@ -672,7 +672,7 @@ static void usb_GetStepSize( pPlustek_Device dev, pScanParam pParam ) /** */ -static void usb_GetLineLength( pPlustek_Device dev ) +static void usb_GetLineLength( Plustek_Device *dev ) { /* [note] * The ITA in this moment is always 0, it will be changed later when we @@ -776,7 +776,7 @@ static void usb_GetLineLength( pPlustek_Device dev ) /** usb_GetMotorParam * registers 0x56, 0x57 */ -static void usb_GetMotorParam( pPlustek_Device dev, pScanParam pParam ) +static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam ) { int idx, i; pClkMotorDef clk; @@ -926,14 +926,14 @@ static void usb_GetMotorParam( pPlustek_Device dev, pScanParam pParam ) /** */ -static void usb_GetPauseLimit( pPlustek_Device dev, pScanParam pParam ) +static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam ) { int coeffsize, scaler; pHWDef hw = &dev->usbDev.HwSetting; scaler = 1; if( hw->bReg_0x26 & _ONE_CH_COLOR ) { - if( pParam->bDataType == SCANDATATYPE_Color ) { + if( pParam->bDataType == SCANDATATYPE_Color ) { scaler = 3; } } @@ -986,19 +986,19 @@ static void usb_GetPauseLimit( pPlustek_Device dev, pScanParam pParam ) /** usb_GetScanLinesAndSize */ -static void usb_GetScanLinesAndSize( pPlustek_Device dev, pScanParam pParam ) +static void usb_GetScanLinesAndSize( Plustek_Device *dev, pScanParam pParam ) { pDCapsDef sCaps = &dev->usbDev.Caps; pHWDef hw = &dev->usbDev.HwSetting; pParam->Size.dwPhyLines = (u_long)ceil((double) pParam->Size.dwLines * - pParam->PhyDpi.y / pParam->UserDpi.y); + pParam->PhyDpi.y / pParam->UserDpi.y); /* Calculate color offset */ if (pParam->bCalibration == PARAM_Scan && pParam->bChannels == 3) { dev->scanning.bLineDistance = sCaps->bSensorDistance * - pParam->PhyDpi.y / sCaps->OpticDpi.x; + pParam->PhyDpi.y / sCaps->OpticDpi.x; pParam->Size.dwPhyLines += (dev->scanning.bLineDistance << 1); } else @@ -1020,7 +1020,7 @@ static void usb_GetScanLinesAndSize( pPlustek_Device dev, pScanParam pParam ) /** function to preset/reset the merlin registers */ -static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam ) +static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam ) { static u_char reg8, reg38[6], reg48[2]; @@ -1180,7 +1180,7 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam ) /** */ -static SANE_Bool usb_ScanBegin( pPlustek_Device dev, SANE_Bool auto_park ) +static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park ) { u_char value; u_short inches; @@ -1260,7 +1260,7 @@ static SANE_Bool usb_ScanBegin( pPlustek_Device dev, SANE_Bool auto_park ) /** usb_ScanEnd * stop all the processing stuff and reposition sensor back home */ -static SANE_Bool usb_ScanEnd( pPlustek_Device dev ) +static SANE_Bool usb_ScanEnd( Plustek_Device *dev ) { u_char value; @@ -1287,7 +1287,7 @@ static SANE_Bool usb_ScanEnd( pPlustek_Device dev ) /** */ -static SANE_Bool usb_IsDataAvailableInDRAM( pPlustek_Device dev ) +static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev ) { /* Compute polling timeout * Height (Inches) / MaxScanSpeed (Inches/Second) = Seconds to move the @@ -1339,7 +1339,7 @@ static SANE_Bool usb_IsDataAvailableInDRAM( pPlustek_Device dev ) /** */ -static SANE_Bool usb_ScanReadImage( pPlustek_Device dev, +static SANE_Bool usb_ScanReadImage( Plustek_Device *dev, void *pBuf, u_long dwSize ) { static u_long dwBytes = 0; @@ -1427,7 +1427,7 @@ static SANE_Bool usb_ScanReadImage( pPlustek_Device dev, /** */ -static void usb_GetImageInfo( pImgDef pInfo, pWinInfo pSize ) +static void usb_GetImageInfo( Plustek_Device *dev, pImgDef pInfo, pWinInfo pSize ) { DBG( _DBG_INFO, "usb_GetImageInfo()\n" ); @@ -1441,7 +1441,12 @@ static void usb_GetImageInfo( pImgDef pInfo, pWinInfo pSize ) break; case COLOR_TRUE24: - pSize->dwBytes = pSize->dwPixels * 3UL; + if( dev->scanning.fGrayFromColor > 7 ){ + pSize->dwBytes = (pSize->dwPixels + 7UL) >> 3; + pSize->dwPixels = pSize->dwBytes * 8; + } else { + pSize->dwBytes = pSize->dwPixels * 3UL; + } break; case COLOR_GRAY16: @@ -1461,7 +1466,7 @@ static void usb_GetImageInfo( pImgDef pInfo, pWinInfo pSize ) /** */ -static void usb_SaveImageInfo( pPlustek_Device dev, pImgDef pInfo ) +static void usb_SaveImageInfo( Plustek_Device *dev, pImgDef pInfo ) { pHWDef hw = &dev->usbDev.HwSetting; pScanParam pParam = &dev->scanning.sParam;