kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			3241 wiersze
		
	
	
		
			88 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			3241 wiersze
		
	
	
		
			88 KiB
		
	
	
	
		
			C
		
	
	
/* sane - Scanner Access Now Easy.
 | 
						|
 | 
						|
   Copyright (C) 2005 Mustek.
 | 
						|
   Originally maintained by Mustek
 | 
						|
   Author:Jack Roy 2005.5.24
 | 
						|
 | 
						|
   This file is part of the SANE package.
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or
 | 
						|
   modify it under the terms of the GNU General Public License as
 | 
						|
   published by the Free Software Foundation; either version 2 of the
 | 
						|
   License, or (at your option) any later version.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful, but
 | 
						|
   WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
   General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software
 | 
						|
   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 | 
						|
   MA 02111-1307, USA.
 | 
						|
 | 
						|
   As a special exception, the authors of SANE give permission for
 | 
						|
   additional uses of the libraries contained in this release of SANE.
 | 
						|
 | 
						|
   The exception is that, if you link a SANE library with other files
 | 
						|
   to produce an executable, this does not by itself cause the
 | 
						|
   resulting executable to be covered by the GNU General Public
 | 
						|
   License.  Your use of that executable is in no way restricted on
 | 
						|
   account of linking the SANE library code into it.
 | 
						|
 | 
						|
   This exception does not, however, invalidate any other reasons why
 | 
						|
   the executable file might be covered by the GNU General Public
 | 
						|
   License.
 | 
						|
 | 
						|
   If you submit changes to SANE to the maintainers to be included in
 | 
						|
   a subsequent release, you agree by submitting the changes that
 | 
						|
   those changes may be distributed with this exception intact.
 | 
						|
 | 
						|
   If you write modifications of your own for SANE, it is your choice
 | 
						|
   whether to permit this exception to apply to your modifications.
 | 
						|
   If you do not wish that, delete this exception notice.
 | 
						|
 | 
						|
   This file implements a SANE backend for the Mustek BearPaw 2448 TA Pro 
 | 
						|
   and similar USB2 scanners. */
 | 
						|
 | 
						|
#include <pthread.h>		/* HOLD */
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
/* local header files */
 | 
						|
#include "mustek_usb2_asic.c"
 | 
						|
 | 
						|
#include "mustek_usb2_high.h"
 | 
						|
 | 
						|
/* ******************++ spuicall_g.h ****************************/
 | 
						|
 | 
						|
/*global variable HOLD: these should go to scanner structure */
 | 
						|
 | 
						|
/*base type*/
 | 
						|
static SANE_Bool g_bOpened;
 | 
						|
static SANE_Bool g_bPrepared;
 | 
						|
static SANE_Bool g_isCanceled;
 | 
						|
static SANE_Bool g_bSharpen;
 | 
						|
static SANE_Bool g_bFirstReadImage;
 | 
						|
static SANE_Bool g_isScanning;
 | 
						|
static SANE_Bool g_isSelfGamma;
 | 
						|
 | 
						|
static SANE_Byte g_bScanBits;
 | 
						|
static SANE_Byte *g_lpReadImageHead;
 | 
						|
 | 
						|
static unsigned short s_wOpticalYDpi[] = { 1200, 600, 300, 150, 75, 0 };
 | 
						|
static unsigned short s_wOpticalXDpi[] = { 1200, 600, 300, 150, 75, 0 };
 | 
						|
static unsigned short g_X;
 | 
						|
static unsigned short g_Y;
 | 
						|
static unsigned short g_Width;
 | 
						|
static unsigned short g_Height;
 | 
						|
static unsigned short g_XDpi;
 | 
						|
static unsigned short g_YDpi;
 | 
						|
static unsigned short g_SWWidth;
 | 
						|
static unsigned short g_SWHeight;
 | 
						|
static unsigned short g_wPixelDistance;		/*even & odd sensor problem */
 | 
						|
static unsigned short g_wLineDistance;
 | 
						|
static unsigned short g_wScanLinesPerBlock;
 | 
						|
static unsigned short g_wReadedLines;
 | 
						|
static unsigned short g_wReadImageLines;
 | 
						|
static unsigned short g_wReadyShadingLine;
 | 
						|
static unsigned short g_wStartShadingLinePos;
 | 
						|
static unsigned short g_wLineartThreshold;
 | 
						|
 | 
						|
static unsigned int g_wtheReadyLines;
 | 
						|
static unsigned int g_wMaxScanLines;
 | 
						|
static unsigned int g_dwScannedTotalLines;
 | 
						|
static unsigned int g_dwImageBufferSize;
 | 
						|
static unsigned int g_BytesPerRow;
 | 
						|
static unsigned int g_SWBytesPerRow;
 | 
						|
static unsigned int g_dwCalibrationSize;
 | 
						|
static unsigned int g_dwBufferSize;
 | 
						|
 | 
						|
static unsigned int g_dwTotalTotalXferLines;
 | 
						|
 | 
						|
static unsigned short *g_pGammaTable;
 | 
						|
static unsigned char *g_pDeviceFile;
 | 
						|
 | 
						|
static pthread_t g_threadid_readimage;
 | 
						|
 | 
						|
/*user define type*/
 | 
						|
static COLORMODE g_ScanMode;
 | 
						|
static TARGETIMAGE g_tiTarget;
 | 
						|
static SCANTYPE g_ScanType = ST_Reflective;
 | 
						|
static SCANSOURCE g_ssScanSource;
 | 
						|
static PIXELFLAVOR g_PixelFlavor;
 | 
						|
 | 
						|
static SUGGESTSETTING g_ssSuggest;
 | 
						|
static Asic g_chip;
 | 
						|
 | 
						|
static int g_nSecLength, g_nDarkSecLength;
 | 
						|
static int g_nSecNum, g_nDarkSecNum;
 | 
						|
static unsigned short g_wCalWidth;
 | 
						|
static unsigned short g_wDarkCalWidth;
 | 
						|
static int g_nPowerNum;
 | 
						|
static unsigned short g_wStartPosition;
 | 
						|
 | 
						|
static pthread_mutex_t g_scannedLinesMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
						|
static pthread_mutex_t g_readyLinesMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
						|
 | 
						|
/*for modify the last point*/
 | 
						|
static SANE_Byte * g_lpBefLineImageData = NULL;
 | 
						|
static SANE_Bool g_bIsFirstReadBefData = TRUE;
 | 
						|
static unsigned int g_dwAlreadyGetLines = 0;
 | 
						|
 | 
						|
/* forward declarations */
 | 
						|
static SANE_Bool MustScanner_Init (void);
 | 
						|
static SANE_Bool MustScanner_GetScannerState (void);
 | 
						|
static SANE_Bool MustScanner_PowerControl (SANE_Bool isLampOn, SANE_Bool isTALampOn);
 | 
						|
static SANE_Bool MustScanner_BackHome (void);
 | 
						|
static SANE_Bool MustScanner_Prepare (SANE_Byte bScanSource);
 | 
						|
#ifdef SANE_UNUSED
 | 
						|
static SANE_Bool MustScanner_AdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
 | 
						|
				      SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
 | 
						|
				      unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
 | 
						|
				      SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
 | 
						|
				      unsigned short wStdMaxLevel);
 | 
						|
static SANE_Bool MustScanner_SecondAdjustOffset (int nTimes, SANE_Bool * bDirection,
 | 
						|
					    SANE_Byte * bOffset, SANE_Byte * bLastMin,
 | 
						|
					    SANE_Byte * bLastOffset, unsigned short * wMinValue,
 | 
						|
					    SANE_Byte * bOffsetUpperBound,
 | 
						|
					    SANE_Byte * bOffsetLowerBound,
 | 
						|
					    unsigned short wStdMinLevel, unsigned short wStdMaxLevel);
 | 
						|
#endif
 | 
						|
static unsigned short MustScanner_FiltLower (unsigned short * pSort, unsigned short TotalCount, unsigned short LowCount,
 | 
						|
				   unsigned short HighCount);
 | 
						|
static SANE_Bool MustScanner_GetRgb48BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
					 unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetRgb48BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
						unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetRgb24BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
					 unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetRgb24BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
						unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono16BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
					  unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono16BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
						 unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono8BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
					 unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono8BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
						unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono1BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
					 unsigned short * wLinesCount);
 | 
						|
static SANE_Bool MustScanner_GetMono1BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
						unsigned short * wLinesCount);
 | 
						|
static void *MustScanner_ReadDataFromScanner (void * dummy);
 | 
						|
static void MustScanner_PrepareCalculateMaxMin (unsigned short wResolution);
 | 
						|
static void MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * lpMaxValue,
 | 
						|
					 unsigned short * lpMinValue, unsigned short wResolution);
 | 
						|
 | 
						|
static SANE_Byte QBET4 (SANE_Byte A, SANE_Byte B);
 | 
						|
static unsigned int GetScannedLines (void);
 | 
						|
static unsigned int GetReadyLines (void);
 | 
						|
static void AddScannedLines (unsigned short wAddLines);
 | 
						|
static void AddReadyLines (void);
 | 
						|
static void ModifyLinePoint (SANE_Byte * lpImageData,
 | 
						|
			     SANE_Byte * lpImageDataBefore,
 | 
						|
			     unsigned int dwBytesPerLine,
 | 
						|
			     unsigned int dwLinesCount,
 | 
						|
			     unsigned short wPixDistance, unsigned short wModPtCount);
 | 
						|
 | 
						|
#include "mustek_usb2_reflective.c"
 | 
						|
#include "mustek_usb2_transparent.c"
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/13
 | 
						|
	Routine Description: 
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	if initialize the scanner success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_Init ()
 | 
						|
{
 | 
						|
  DBG (DBG_FUNC, "MustScanner_Init: Call in\n");
 | 
						|
 | 
						|
  g_chip.firmwarestate = FS_NULL;
 | 
						|
  if (STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Init: Asic_Open return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_Initialize (&g_chip))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Init: Asic_Initialize return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  g_dwImageBufferSize = 24L * 1024L * 1024L;
 | 
						|
  g_dwBufferSize = 64L * 1024L;
 | 
						|
  g_dwCalibrationSize = 64L * 1024L;
 | 
						|
  g_lpReadImageHead = NULL;
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_bFirstReadImage = TRUE;
 | 
						|
  g_bOpened = FALSE;
 | 
						|
  g_bPrepared = FALSE;
 | 
						|
  g_bSharpen = FALSE;
 | 
						|
 | 
						|
  g_isScanning = FALSE;
 | 
						|
  g_isSelfGamma = FALSE;
 | 
						|
  g_pGammaTable = NULL;
 | 
						|
 | 
						|
  if (NULL != g_pDeviceFile)
 | 
						|
    {
 | 
						|
      free (g_pDeviceFile);
 | 
						|
      g_pDeviceFile = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  g_ssScanSource = SS_Reflective;
 | 
						|
  g_PixelFlavor = PF_BlackIs0;
 | 
						|
 | 
						|
  Asic_Close (&g_chip);
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_Init: leave MustScanner_Init\n");
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/13
 | 
						|
Routine Description: 
 | 
						|
	check the scanner connect status
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	if scanner's status is OK
 | 
						|
	return TRUE
 | 
						|
	else 
 | 
						|
	return FASLE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetScannerState ()
 | 
						|
{
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetScannerState: Asic_Open return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      Asic_Close (&g_chip);
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/13
 | 
						|
Routine Description: 
 | 
						|
	Turn the lamp on or off
 | 
						|
Parameters:
 | 
						|
	isLampOn: turn the lamp on or off
 | 
						|
	isTALampOn: turn the TA lamp on or off
 | 
						|
Return value: 
 | 
						|
	if operation success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_PowerControl (SANE_Bool isLampOn, SANE_Bool isTALampOn)
 | 
						|
{
 | 
						|
  SANE_Bool hasTA;
 | 
						|
  DBG (DBG_FUNC, "MustScanner_PowerControl: Call in\n");
 | 
						|
  if (STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_PowerControl: Asic_Open return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_TurnLamp (&g_chip, isLampOn))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_PowerControl: Asic_TurnLamp return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_IsTAConnected (&g_chip, &hasTA))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_PowerControl: Asic_IsTAConnected return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (hasTA)
 | 
						|
    {
 | 
						|
      if (STATUS_GOOD != Asic_TurnTA (&g_chip, isTALampOn))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_PowerControl: Asic_TurnTA return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  Asic_Close (&g_chip);
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_PowerControl: leave MustScanner_PowerControl\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/13
 | 
						|
Routine Description: 
 | 
						|
	Turn the carriage home
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	if the operation success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_BackHome ()
 | 
						|
{
 | 
						|
  DBG (DBG_FUNC, "MustScanner_BackHome: call in \n");
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_BackHome: Asic_Open return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_CarriageHome (&g_chip, FALSE))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_BackHome: Asic_CarriageHome return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_WaitUnitReady (&g_chip))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_BackHome: Asic_WaitUnitReady return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  Asic_Close (&g_chip);
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_BackHome: leave  MustScanner_BackHome\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/13
 | 
						|
Routine Description: 
 | 
						|
	prepare the scan image
 | 
						|
Parameters:
 | 
						|
	bScanSource: the scan source
 | 
						|
Return value: 
 | 
						|
	if operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_Prepare (SANE_Byte bScanSource)
 | 
						|
{
 | 
						|
  DBG (DBG_FUNC, "MustScanner_Prepare: call in\n");
 | 
						|
 | 
						|
  if (STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
 | 
						|
 | 
						|
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Prepare: Asic_Open return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  if (STATUS_GOOD != Asic_WaitUnitReady (&g_chip))
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_Prepare: Asic_WaitUnitReady return error\n");
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (SS_Reflective == bScanSource)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Reflective\n");
 | 
						|
      if (STATUS_GOOD != Asic_TurnLamp (&g_chip, TRUE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnLamp return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (STATUS_GOOD != Asic_SetSource (&g_chip, LS_REFLECTIVE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_Prepare: Asic_SetSource return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else if (SS_Positive == bScanSource)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Positive\n");
 | 
						|
      if (STATUS_GOOD != Asic_TurnTA (&g_chip, TRUE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnTA return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
      if (STATUS_GOOD != Asic_SetSource (&g_chip, LS_POSITIVE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_Prepare: Asic_SetSource return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else if (SS_Negative == bScanSource)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Negative\n");
 | 
						|
 | 
						|
      if (STATUS_GOOD != Asic_TurnTA (&g_chip, TRUE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnTA return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (STATUS_GOOD != Asic_SetSource (&g_chip, LS_NEGATIVE))
 | 
						|
	{
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_Prepare: Asic_SetSource return error\n");
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
      DBG (DBG_FUNC, "MustScanner_Prepare: Asic_SetSource return good\n");
 | 
						|
    }
 | 
						|
 | 
						|
  Asic_Close (&g_chip);
 | 
						|
  g_bPrepared = TRUE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_Prepare: leave MustScanner_Prepare\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef SANE_UNUSED
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Adjuest the offset
 | 
						|
Parameters:
 | 
						|
	nTimes: Adjuest offset the times
 | 
						|
	bDirection: whether direction
 | 
						|
	bOffset: the data of offset
 | 
						|
	bLastMin: the last min data
 | 
						|
	bLastOffset: the last offset data
 | 
						|
	wMinValue: the min value of offset
 | 
						|
	bOffsetUpperBound: the upper bound of offset
 | 
						|
	bOffsetLowerBound: the lower bound of offset
 | 
						|
	wStdMinLevel: the min level of offset
 | 
						|
	wStdMaxLevel: the max level of offset
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_AdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
 | 
						|
			  SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
 | 
						|
			  unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
 | 
						|
			  SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
 | 
						|
			  unsigned short wStdMaxLevel)
 | 
						|
{
 | 
						|
  if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
 | 
						|
    {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (nTimes == 0)
 | 
						|
    {
 | 
						|
      *bLastMin = LOSANE_Byte (*wMinValue);
 | 
						|
      *bLastOffset = *bOffset;
 | 
						|
 | 
						|
      if (*wMinValue == 255)
 | 
						|
	{
 | 
						|
	  *bOffset = 0;
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  *bOffset = 255;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  if (nTimes == 1)
 | 
						|
    {
 | 
						|
      if (*wMinValue > *bLastMin)
 | 
						|
	{
 | 
						|
	  if (*wMinValue > wStdMaxLevel && *bLastMin > wStdMaxLevel)
 | 
						|
	    {
 | 
						|
	      *bDirection = !(*bDirection);
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (*wMinValue < wStdMinLevel && *bLastMin < wStdMinLevel)
 | 
						|
	    return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (*wMinValue < *bLastMin)
 | 
						|
	{
 | 
						|
	  if (*wMinValue < wStdMinLevel && *bLastMin < wStdMinLevel)
 | 
						|
	    *bDirection = !(*bDirection);
 | 
						|
 | 
						|
	  if (*wMinValue > wStdMaxLevel && *bLastMin > wStdMaxLevel)
 | 
						|
	    return TRUE;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  if (nTimes > 1)
 | 
						|
    {
 | 
						|
      if (*wMinValue > *bLastMin)
 | 
						|
	{
 | 
						|
	  SANE_Byte bTemp;
 | 
						|
 | 
						|
	  bTemp = *bOffset;
 | 
						|
 | 
						|
	  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
 | 
						|
	  if (nTimes > 2)
 | 
						|
	    {
 | 
						|
	      if (*wMinValue > wStdMaxLevel)
 | 
						|
		if (bDirection)
 | 
						|
		  *bOffsetLowerBound = bTemp;
 | 
						|
		else
 | 
						|
		  *bOffsetUpperBound = bTemp;
 | 
						|
 | 
						|
 | 
						|
	      else if (bDirection)
 | 
						|
		*bOffsetUpperBound = bTemp;
 | 
						|
	      else
 | 
						|
		*bOffsetLowerBound = bTemp;
 | 
						|
	    }
 | 
						|
 | 
						|
	  *bLastOffset = bTemp;
 | 
						|
	  *bLastMin = (SANE_Byte) * wMinValue;
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  SANE_Byte bTemp;
 | 
						|
 | 
						|
	  bTemp = *bOffset;
 | 
						|
 | 
						|
	  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
 | 
						|
	  if (nTimes > 2)
 | 
						|
	    {
 | 
						|
	      if (*wMinValue == *bLastMin)
 | 
						|
		{
 | 
						|
		  if (*wMinValue > wStdMaxLevel)
 | 
						|
		    {
 | 
						|
		      if (!bDirection)
 | 
						|
			*bOffsetUpperBound = bTemp;
 | 
						|
		      else
 | 
						|
			*bOffsetLowerBound = bTemp;
 | 
						|
		    }
 | 
						|
		  else
 | 
						|
		    {
 | 
						|
		      if (!bDirection)
 | 
						|
			*bOffsetLowerBound = bTemp;
 | 
						|
		      else
 | 
						|
			*bOffsetUpperBound = bTemp;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  if (*wMinValue > wStdMaxLevel)
 | 
						|
		    {
 | 
						|
		      if (bDirection)
 | 
						|
			*bOffsetUpperBound = bTemp;
 | 
						|
		      else
 | 
						|
			*bOffsetLowerBound = bTemp;
 | 
						|
		    }
 | 
						|
		  else
 | 
						|
		    {
 | 
						|
		      if (bDirection)
 | 
						|
			*bOffsetLowerBound = bTemp;
 | 
						|
		      else
 | 
						|
			*bOffsetUpperBound = bTemp;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
	  *bLastOffset = bTemp;
 | 
						|
	  *bLastMin = (SANE_Byte) * wMinValue;
 | 
						|
 | 
						|
	}
 | 
						|
    }				/* end of if(nTimes > 1) */
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef SANE_UNUSED
 | 
						|
/**********************************************************************
 | 
						|
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Adjuest the offset second times
 | 
						|
Parameters:
 | 
						|
	nTimes: Adjuest offset the times
 | 
						|
	bDirection: whether direction
 | 
						|
	bOffset: the data of offset
 | 
						|
	bLastMin: the last min data
 | 
						|
	bLastOffset: the last offset data
 | 
						|
	wMinValue: the min value of offset
 | 
						|
	bOffsetUpperBound: the upper bound of offset
 | 
						|
	bOffsetLowerBound: the lower bound of offset
 | 
						|
	wStdMinLevel: the min level of offset
 | 
						|
	wStdMaxLevel: the max level of offset
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_SecondAdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
 | 
						|
				SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
 | 
						|
				unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
 | 
						|
				SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
 | 
						|
				unsigned short wStdMaxLevel)
 | 
						|
{
 | 
						|
  if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
 | 
						|
    {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  if (nTimes == 0)
 | 
						|
    {
 | 
						|
      *bLastMin = LOSANE_Byte (*wMinValue);
 | 
						|
      *bLastOffset = *bOffset;
 | 
						|
 | 
						|
      if (*bDirection == 0)
 | 
						|
	{
 | 
						|
	  *bOffsetUpperBound = *bLastOffset;
 | 
						|
	  *bOffsetLowerBound = 0;
 | 
						|
	  *bOffset = 0;
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  *bOffsetUpperBound = 255;
 | 
						|
	  *bOffsetLowerBound = *bLastOffset;
 | 
						|
	  *bOffset = 255;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  if (nTimes >= 1)
 | 
						|
    {
 | 
						|
      if (*wMinValue > wStdMaxLevel)
 | 
						|
	{
 | 
						|
	  if (*wMinValue > *bLastMin)
 | 
						|
	    {
 | 
						|
	      if (*bDirection == 0)
 | 
						|
		{
 | 
						|
		  *bOffsetUpperBound = *bOffset;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  *bOffsetLowerBound = *bOffset;
 | 
						|
		}
 | 
						|
 | 
						|
	      *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      if (*bDirection == 1)
 | 
						|
		{
 | 
						|
		  *bOffsetUpperBound = *bOffset;
 | 
						|
		  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  *bOffsetLowerBound = *bOffset;
 | 
						|
		  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}			/*end of if(*wMinValue > MAX_OFFSET) */
 | 
						|
 | 
						|
 | 
						|
      if (*wMinValue < wStdMinLevel)
 | 
						|
	{
 | 
						|
	  if (*wMinValue > *bLastMin)
 | 
						|
	    {
 | 
						|
	      if (*bDirection == 0)
 | 
						|
		{
 | 
						|
		  *bOffsetLowerBound = *bOffset;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  *bOffsetUpperBound = *bOffset;
 | 
						|
		}
 | 
						|
 | 
						|
	      *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      if (*bDirection == 1)
 | 
						|
		{
 | 
						|
		  *bOffsetUpperBound = *bOffset;
 | 
						|
		  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  *bOffsetLowerBound = *bOffset;
 | 
						|
		  *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}			/*end of if(*wMinValue > MIN_OFFSET) */
 | 
						|
      *bLastMin = (SANE_Byte) * wMinValue;
 | 
						|
    }				/*end of if(nTimes >= 1)     */
 | 
						|
 | 
						|
  /* HOLD: missing return value! Correct? */
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Filter the data
 | 
						|
Parameters:
 | 
						|
	pSort: the sort data
 | 
						|
	TotalCount: the total count 
 | 
						|
	LowCount: the low count
 | 
						|
	HighCount: the upper count
 | 
						|
Return value: 
 | 
						|
	the data of Filter 	
 | 
						|
***********************************************************************/
 | 
						|
static unsigned short
 | 
						|
MustScanner_FiltLower (unsigned short * pSort, unsigned short TotalCount, unsigned short LowCount,
 | 
						|
		       unsigned short HighCount)
 | 
						|
{
 | 
						|
  unsigned short Bound = TotalCount - 1;
 | 
						|
  unsigned short LeftCount = HighCount - LowCount;
 | 
						|
  int Temp = 0;
 | 
						|
  unsigned int Sum = 0;
 | 
						|
  unsigned short i, j;
 | 
						|
 | 
						|
  for (i = 0; i < Bound; i++)
 | 
						|
 | 
						|
    {
 | 
						|
      for (j = 0; j < Bound - i; j++)
 | 
						|
	{
 | 
						|
	  if (pSort[j + 1] > pSort[j])
 | 
						|
	    {
 | 
						|
	      Temp = pSort[j];
 | 
						|
	      pSort[j] = pSort[j + 1];
 | 
						|
	      pSort[j + 1] = Temp;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  for (i = 0; i < LeftCount; i++)
 | 
						|
    Sum += pSort[i + LowCount];
 | 
						|
  return (unsigned short) (Sum / LeftCount);
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when single CCD and color is 48bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetRgb48BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
			     unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned short wRLinePos = 0;
 | 
						|
  unsigned short wGLinePos = 0;
 | 
						|
  unsigned short wBLinePos = 0;
 | 
						|
  unsigned short wRTempData;
 | 
						|
  unsigned short wGTempData;
 | 
						|
  unsigned short wBTempData;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: call in \n");
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
  TotalXferLines = 0;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!isOrderInvert)
 | 
						|
    {
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
	      wGLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
	      wBLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth; i++)
 | 
						|
		{
 | 
						|
		  wRTempData =
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      0);
 | 
						|
		  wRTempData +=
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      1) << 8;
 | 
						|
		  wGTempData =
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      2);
 | 
						|
		  wGTempData +=
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      3) << 8;
 | 
						|
		  wBTempData =
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      4);
 | 
						|
		  wBTempData +=
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      5) << 8;
 | 
						|
		  *(lpLine + i * 6 + 0) = LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		  *(lpLine + i * 6 + 1) = HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		  *(lpLine + i * 6 + 2) =
 | 
						|
		    LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		  *(lpLine + i * 6 + 3) =
 | 
						|
		    HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		  *(lpLine + i * 6 + 4) =
 | 
						|
		    LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		  *(lpLine + i * 6 + 5) =
 | 
						|
		    HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		}
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
 | 
						|
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
	      wGLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
	      wBLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth; i++)
 | 
						|
		{
 | 
						|
		  wRTempData =
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      0);
 | 
						|
		  wRTempData +=
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      1) << 8;
 | 
						|
		  wGTempData =
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      2);
 | 
						|
		  wGTempData +=
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      3) << 8;
 | 
						|
		  wBTempData =
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      4);
 | 
						|
		  wBTempData +=
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
 | 
						|
		      5) << 8;
 | 
						|
		  *(lpLine + i * 6 + 4) = LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		  *(lpLine + i * 6 + 5) = HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		  *(lpLine + i * 6 + 2) =
 | 
						|
		    LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		  *(lpLine + i * 6 + 3) =
 | 
						|
		    HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		  *(lpLine + i * 6 + 0) =
 | 
						|
		    LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		  *(lpLine + i * 6 + 1) =
 | 
						|
		    HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}			/*end for */
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetRgb48BitLine: leave MustScanner_GetRgb48BitLine\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when double CCD and color is 48bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetRgb48BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
				    unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
 | 
						|
  unsigned short wRLinePosOdd = 0;
 | 
						|
  unsigned short wGLinePosOdd = 0;
 | 
						|
  unsigned short wBLinePosOdd = 0;
 | 
						|
  unsigned short wRLinePosEven = 0;
 | 
						|
  unsigned short wGLinePosEven = 0;
 | 
						|
  unsigned short wBLinePosEven = 0;
 | 
						|
  unsigned int wRTempData;
 | 
						|
  unsigned int wGTempData;
 | 
						|
  unsigned int wBTempData;
 | 
						|
  unsigned int wNextTempData;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine1200DPI: call in \n");
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine1200DPI: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!isOrderInvert)
 | 
						|
    {
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      if (ST_Reflective == g_ScanType)
 | 
						|
		{
 | 
						|
		  wRLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  wRLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth;)
 | 
						|
		{
 | 
						|
		  if (i + 1 != g_SWWidth)
 | 
						|
		    {
 | 
						|
		      wRTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 0);
 | 
						|
		      wRTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 1) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 0);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 1) << 8;
 | 
						|
		      wRTempData = (wRTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wGTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 2);
 | 
						|
		      wGTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 3) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 2);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 3) << 8;
 | 
						|
		      wGTempData = (wGTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wBTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 4);
 | 
						|
		      wBTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 5) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 4);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 5) << 8;
 | 
						|
		      wBTempData = (wBTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      *(lpLine + i * 6 + 0) =
 | 
						|
			LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 1) =
 | 
						|
			HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 2) =
 | 
						|
			LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 3) =
 | 
						|
			HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 4) =
 | 
						|
			LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      *(lpLine + i * 6 + 5) =
 | 
						|
			HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      i++;
 | 
						|
		      if (i >= g_SWWidth)
 | 
						|
			{
 | 
						|
			  break;
 | 
						|
			}
 | 
						|
 | 
						|
		      wRTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 0);
 | 
						|
		      wRTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 1) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 0);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 1) << 8;
 | 
						|
		      wRTempData = (wRTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wGTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 2);
 | 
						|
		      wGTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 3) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 2);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 3) << 8;
 | 
						|
		      wGTempData = (wGTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wBTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 4);
 | 
						|
		      wBTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 5) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 4);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 5) << 8;
 | 
						|
		      wBTempData = (wBTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      *(lpLine + i * 6 + 0) =
 | 
						|
			LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 1) =
 | 
						|
			HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 2) =
 | 
						|
			LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 3) =
 | 
						|
			HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 4) =
 | 
						|
			LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      *(lpLine + i * 6 + 5) =
 | 
						|
			HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
 | 
						|
		      i++;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
 | 
						|
	      break;
 | 
						|
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      if (ST_Reflective == g_ScanType)
 | 
						|
		{
 | 
						|
		  wRLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  wRLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth;)
 | 
						|
		{
 | 
						|
		  if ((i + 1) != g_SWWidth)
 | 
						|
		    {
 | 
						|
		      wRTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 0);
 | 
						|
		      wRTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 1) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 0);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 1) << 8;
 | 
						|
		      wRTempData = (wRTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wGTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 2);
 | 
						|
		      wGTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 3) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 2);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 3) << 8;
 | 
						|
		      wGTempData = (wGTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wBTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 4);
 | 
						|
		      wBTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 6 + 5) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 4);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 5) << 8;
 | 
						|
		      wBTempData = (wBTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      *(lpLine + i * 6 + 4) =
 | 
						|
			LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 5) =
 | 
						|
			HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 2) =
 | 
						|
			LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 3) =
 | 
						|
			HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 0) =
 | 
						|
			LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      *(lpLine + i * 6 + 1) =
 | 
						|
			HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      i++;
 | 
						|
		      if (i >= g_SWWidth)
 | 
						|
			{
 | 
						|
			  break;
 | 
						|
			}
 | 
						|
 | 
						|
		      wRTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 0);
 | 
						|
		      wRTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 1) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 0);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 1) << 8;
 | 
						|
		      wRTempData = (wRTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      wGTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 2);
 | 
						|
		      wGTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 3) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 2);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 3) << 8;
 | 
						|
		      wGTempData = (wGTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
 | 
						|
		      wBTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 4);
 | 
						|
		      wBTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 6 + 5) << 8;
 | 
						|
		      wNextTempData =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 4);
 | 
						|
		      wNextTempData +=
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 6 + 5) << 8;
 | 
						|
		      wBTempData = (wBTempData + wNextTempData) >> 1;
 | 
						|
 | 
						|
		      *(lpLine + i * 6 + 4) =
 | 
						|
			LOBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 5) =
 | 
						|
			HIBYTE (g_pGammaTable[wRTempData]);
 | 
						|
		      *(lpLine + i * 6 + 2) =
 | 
						|
			LOBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 3) =
 | 
						|
			HIBYTE (g_pGammaTable[wGTempData + 65536]);
 | 
						|
		      *(lpLine + i * 6 + 0) =
 | 
						|
			LOBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      *(lpLine + i * 6 + 1) =
 | 
						|
			HIBYTE (g_pGammaTable[wBTempData + 131072]);
 | 
						|
		      i++;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetRgb48BitLine1200DPI: leave MustScanner_GetRgb48BitLine1200DPI\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when single CCD and color is 24bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetRgb24BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
			     unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned short wRLinePos = 0;
 | 
						|
  unsigned short wGLinePos = 0;
 | 
						|
  unsigned short wBLinePos = 0;
 | 
						|
  SANE_Byte byRed;
 | 
						|
  SANE_Byte byGreen;
 | 
						|
  SANE_Byte byBlue;
 | 
						|
  SANE_Byte bNextPixel = 0;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  unsigned short tempR, tempG, tempB;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: call in\n");
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetRgb24BitLine: get wWantedTotalLines= %d\n",
 | 
						|
       wWantedTotalLines);
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread create\n");
 | 
						|
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!isOrderInvert)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: !isOrderInvert\n");
 | 
						|
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
	      wGLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
	      wBLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth; i++)
 | 
						|
		{
 | 
						|
		  byRed =
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      0);
 | 
						|
		  bNextPixel =
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow +
 | 
						|
		      (i + 1) * 3 + 0);
 | 
						|
		  byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  byGreen =
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      1);
 | 
						|
		  bNextPixel =
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow +
 | 
						|
		      (i + 1) * 3 + 1);
 | 
						|
		  byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  byBlue =
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      2);
 | 
						|
		  bNextPixel =
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow +
 | 
						|
		      (i + 1) * 3 + 2);
 | 
						|
		  byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		  tempR = (unsigned short) ((byRed << 4) | QBET4 (byBlue, byGreen));
 | 
						|
		  tempG = (unsigned short) ((byGreen << 4) | QBET4 (byRed, byBlue));
 | 
						|
		  tempB = (unsigned short) ((byBlue << 4) | QBET4 (byGreen, byRed));
 | 
						|
 | 
						|
		  *(lpLine + i * 3 + 0) =
 | 
						|
		    (unsigned char) (*(g_pGammaTable + tempR));
 | 
						|
		  *(lpLine + i * 3 + 1) =
 | 
						|
		    (unsigned char) (*(g_pGammaTable + 4096 + tempG));
 | 
						|
		  *(lpLine + i * 3 + 2) =
 | 
						|
		    (unsigned char) (*(g_pGammaTable + 8192 + tempB));
 | 
						|
#else
 | 
						|
		  *(lpLine + i * 3 + 0) = (unsigned char) byRed;
 | 
						|
		  *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		  *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine: g_dwTotalTotalXferLines=%d,g_SWHeight=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines, g_SWHeight);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine: g_SWBytesPerRow=%d\n",
 | 
						|
		   g_SWBytesPerRow);
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: isOrderInvert is TRUE\n");
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
	      wGLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
	      wBLinePos =
 | 
						|
		(g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth; i++)
 | 
						|
		{
 | 
						|
		  DBG (DBG_FUNC,
 | 
						|
		       "MustScanner_GetRgb24BitLine: before byRed\n");
 | 
						|
		  byRed =
 | 
						|
		    *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      0);
 | 
						|
		  bNextPixel = *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + (i + 1) * 3 + 0);	/*R-channel */
 | 
						|
		  byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  DBG (DBG_FUNC,
 | 
						|
		       "MustScanner_GetRgb24BitLine: before byGreen\n");
 | 
						|
 | 
						|
		  byGreen =
 | 
						|
		    *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      1);
 | 
						|
		  bNextPixel = *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + (i + 1) * 3 + 1);	/*G-channel */
 | 
						|
		  byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  DBG (DBG_FUNC,
 | 
						|
		       "MustScanner_GetRgb24BitLine: before byBlue\n");
 | 
						|
 | 
						|
		  byBlue =
 | 
						|
		    *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 3 +
 | 
						|
		      2);
 | 
						|
		  bNextPixel = *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + (i + 1) * 3 + 2);	/*B-channel */
 | 
						|
		  byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
 | 
						|
 | 
						|
		  DBG (DBG_FUNC,
 | 
						|
		       "MustScanner_GetRgb24BitLine: before set lpLine\n");
 | 
						|
		  DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: i=%d\n", i);
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		  *(lpLine + i * 3 + 2) =
 | 
						|
		    (unsigned
 | 
						|
		     char) (*(g_pGammaTable +
 | 
						|
			      (unsigned short) ((byRed << 4) |
 | 
						|
				      QBET4 (byBlue, byGreen))));
 | 
						|
		  *(lpLine + i * 3 + 1) =
 | 
						|
		    (unsigned
 | 
						|
		     char) (*(g_pGammaTable + 4096 +
 | 
						|
			      (unsigned short) ((byGreen << 4) |
 | 
						|
				      QBET4 (byRed, byBlue))));
 | 
						|
		  *(lpLine + i * 3 + 0) =
 | 
						|
		    (unsigned
 | 
						|
		     char) (*(g_pGammaTable + 8192 +
 | 
						|
			      (unsigned short) ((byBlue << 4) |
 | 
						|
				      QBET4 (byGreen, byRed))));
 | 
						|
#else
 | 
						|
		  *(lpLine + i * 3 + 2) = (unsigned char) byRed;
 | 
						|
		  *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		  *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine: g_dwTotalTotalXferLines=%d,g_SWHeight=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines, g_SWHeight);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine: g_SWBytesPerRow=%d\n",
 | 
						|
		   g_SWBytesPerRow);
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}			/*end for */
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetRgb24BitLine: leave MustScanner_GetRgb24BitLine\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when double CCD and color is 24bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetRgb24BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
				    unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  SANE_Byte *lpTemp;
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned short wRLinePosOdd = 0;
 | 
						|
  unsigned short wGLinePosOdd = 0;
 | 
						|
  unsigned short wBLinePosOdd = 0;
 | 
						|
  unsigned short wRLinePosEven = 0;
 | 
						|
  unsigned short wGLinePosEven = 0;
 | 
						|
  unsigned short wBLinePosEven = 0;
 | 
						|
  SANE_Byte byRed;
 | 
						|
  SANE_Byte byGreen;
 | 
						|
  SANE_Byte byBlue;
 | 
						|
  SANE_Byte bNextPixel = 0;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine1200DPI: call in\n");
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  TotalXferLines = 0;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
  lpTemp = lpLine;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine1200DPI: thread create\n");
 | 
						|
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  if (!isOrderInvert)
 | 
						|
    {
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
 | 
						|
		   g_Height);
 | 
						|
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      if (ST_Reflective == g_ScanType)
 | 
						|
		{
 | 
						|
		  wRLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  wRLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth;)
 | 
						|
		{
 | 
						|
		  if ((i + 1) != g_SWWidth)
 | 
						|
		    {
 | 
						|
		      byRed =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 0);
 | 
						|
		      bNextPixel = *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow + (i + 1) * 3 + 0);	/*R-channel */
 | 
						|
		      byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byGreen =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 1);
 | 
						|
		      bNextPixel = *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow + (i + 1) * 3 + 1);	/*G-channel */
 | 
						|
		      byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byBlue =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 2);
 | 
						|
		      bNextPixel = *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow + (i + 1) * 3 + 2);	/*B-channel */
 | 
						|
		      byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		      *(lpLine + i * 3 + 0) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable +
 | 
						|
				  (unsigned short) ((byRed << 4) |
 | 
						|
					  QBET4 (byBlue, byGreen))));
 | 
						|
		      *(lpLine + i * 3 + 1) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 4096 +
 | 
						|
				  (unsigned short) ((byGreen << 4) |
 | 
						|
					  QBET4 (byRed, byBlue))));
 | 
						|
		      *(lpLine + i * 3 + 2) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 8192 +
 | 
						|
				  (unsigned short) ((byBlue << 4) |
 | 
						|
					  QBET4 (byGreen, byRed))));
 | 
						|
#else
 | 
						|
		      *(lpLine + i * 3 + 0) = (unsigned char) byRed;
 | 
						|
		      *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		      *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
 | 
						|
		      i++;
 | 
						|
		      if (i >= g_SWWidth)
 | 
						|
			{
 | 
						|
			  break;
 | 
						|
			}
 | 
						|
 | 
						|
		      byRed =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 0);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 0);
 | 
						|
		      byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byGreen =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 1);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 1);
 | 
						|
		      byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byBlue =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 2);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 2);
 | 
						|
		      byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		      *(lpLine + i * 3 + 0) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable +
 | 
						|
				  (unsigned short) ((byRed << 4) |
 | 
						|
					  QBET4 (byBlue, byGreen))));
 | 
						|
		      *(lpLine + i * 3 + 1) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 4096 +
 | 
						|
				  (unsigned short) ((byGreen << 4) |
 | 
						|
					  QBET4 (byRed, byBlue))));
 | 
						|
		      *(lpLine + i * 3 + 2) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 8192 +
 | 
						|
				  (unsigned short) ((byBlue << 4) |
 | 
						|
					  QBET4 (byGreen, byRed))));
 | 
						|
#else
 | 
						|
		      *(lpLine + i * 3 + 0) = (unsigned char) byRed;
 | 
						|
		      *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		      *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
		      i++;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
 | 
						|
		   g_Height);
 | 
						|
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
 | 
						|
      for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
	{
 | 
						|
	  if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	    {
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
 | 
						|
		   g_Height);
 | 
						|
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	      *wLinesCount = TotalXferLines;
 | 
						|
	      g_isScanning = FALSE;
 | 
						|
	      return TRUE;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	    {
 | 
						|
	      if (ST_Reflective == g_ScanType)
 | 
						|
		{
 | 
						|
		  wRLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
	      else
 | 
						|
		{
 | 
						|
		  wRLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wGLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosEven =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance * 2 -
 | 
						|
		     g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
		  wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
		  wGLinePosOdd =
 | 
						|
		    (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
 | 
						|
		  wBLinePosOdd =
 | 
						|
		    (g_wtheReadyLines -
 | 
						|
		     g_wLineDistance * 2) % g_wMaxScanLines;
 | 
						|
		}
 | 
						|
 | 
						|
	      for (i = 0; i < g_SWWidth;)
 | 
						|
		{
 | 
						|
		  if ((i + 1) != g_SWWidth)
 | 
						|
		    {
 | 
						|
		      byRed =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 0);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 0);
 | 
						|
		      byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byGreen =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 1);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 1);
 | 
						|
		      byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byBlue =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  i * 3 + 2);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 2);
 | 
						|
		      byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		      *(lpLine + i * 3 + 2) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable +
 | 
						|
				  (unsigned short) ((byRed << 4) |
 | 
						|
					  QBET4 (byBlue, byGreen))));
 | 
						|
		      *(lpLine + i * 3 + 1) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 4096 +
 | 
						|
				  (unsigned short) ((byGreen << 4) |
 | 
						|
					  QBET4 (byRed, byBlue))));
 | 
						|
		      *(lpLine + i * 3 + 0) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 8192 +
 | 
						|
				  (unsigned short) ((byBlue << 4) |
 | 
						|
					  QBET4 (byGreen, byRed))));
 | 
						|
#else
 | 
						|
		      *(lpLine + i * 3 + 2) = (unsigned char) byRed;
 | 
						|
		      *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		      *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
		      i++;
 | 
						|
		      if (i >= g_SWWidth)
 | 
						|
			{
 | 
						|
			  break;
 | 
						|
			}
 | 
						|
 | 
						|
		      byRed =
 | 
						|
			*(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 0);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 0);
 | 
						|
		      byRed = (byRed + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byGreen =
 | 
						|
			*(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 1);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 1);
 | 
						|
		      byGreen = (byGreen + bNextPixel) >> 1;
 | 
						|
 | 
						|
		      byBlue =
 | 
						|
			*(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
 | 
						|
			  i * 3 + 2);
 | 
						|
		      bNextPixel =
 | 
						|
			*(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
 | 
						|
			  (i + 1) * 3 + 2);
 | 
						|
		      byBlue = (byBlue + bNextPixel) >> 1;
 | 
						|
#ifdef ENABLE_GAMMA
 | 
						|
		      *(lpLine + i * 3 + 2) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable +
 | 
						|
				  (unsigned short) ((byRed << 4) |
 | 
						|
					  QBET4 (byBlue, byGreen))));
 | 
						|
		      *(lpLine + i * 3 + 1) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 4096 +
 | 
						|
				  (unsigned short) ((byGreen << 4) |
 | 
						|
					  QBET4 (byRed, byBlue))));
 | 
						|
		      *(lpLine + i * 3 + 0) =
 | 
						|
			(unsigned
 | 
						|
			 char) (*(g_pGammaTable + 8192 +
 | 
						|
				  (unsigned short) ((byBlue << 4) |
 | 
						|
					  QBET4 (byGreen, byRed))));
 | 
						|
#else
 | 
						|
		      *(lpLine + i * 3 + 2) = (unsigned char) byRed;
 | 
						|
		      *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
 | 
						|
		      *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
 | 
						|
#endif
 | 
						|
		      i++;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
 | 
						|
	      TotalXferLines++;
 | 
						|
	      g_dwTotalTotalXferLines++;
 | 
						|
	      lpLine += g_SWBytesPerRow;
 | 
						|
	      AddReadyLines ();
 | 
						|
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
 | 
						|
		   g_dwTotalTotalXferLines);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
 | 
						|
		   g_Height);
 | 
						|
 | 
						|
	    }
 | 
						|
	  if (g_isCanceled)
 | 
						|
	    {
 | 
						|
	      pthread_cancel (g_threadid_readimage);
 | 
						|
	      pthread_join (g_threadid_readimage, NULL);
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
 | 
						|
	      break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetRgb24BitLine1200DPI: leave MustScanner_GetRgb24BitLine1200DPI\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when single CCD and color is 16bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono16BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
			      unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned int wTempData;
 | 
						|
 | 
						|
  unsigned short wLinePos = 0;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: call in\n");
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
    {
 | 
						|
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  wLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth; i++)
 | 
						|
	    {
 | 
						|
	      wTempData =
 | 
						|
		*(g_lpReadImageHead + wLinePos * g_BytesPerRow + i * 2 + 0);
 | 
						|
	      wTempData +=
 | 
						|
		*(g_lpReadImageHead + wLinePos * g_BytesPerRow + i * 2 +
 | 
						|
		  1) << 8;
 | 
						|
	      *(lpLine + i * 2 + 0) = LOBYTE (g_pGammaTable[wTempData]);
 | 
						|
	      *(lpLine + i * 2 + 1) = HIBYTE (g_pGammaTable[wTempData]);
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
 | 
						|
	  lpLine += g_SWBytesPerRow;
 | 
						|
	  AddReadyLines ();
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono16BitLine: leave MustScanner_GetMono16BitLine\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when double CCD and color is 16bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono16BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
				     unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned int dwTempData;
 | 
						|
  unsigned short wLinePosOdd = 0;
 | 
						|
  unsigned short wLinePosEven = 0;
 | 
						|
  unsigned short i;
 | 
						|
  SANE_Byte * lpTemp = lpLine;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono16BitLine1200DPI: call in\n");
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono16BitLine1200DPI: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
    {
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_GetMono16BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  if (ST_Reflective == g_ScanType)
 | 
						|
	    {
 | 
						|
	      wLinePosOdd =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	      wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      wLinePosEven =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	      wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth;)
 | 
						|
	    {
 | 
						|
	      if ((i + 1) != g_SWWidth)
 | 
						|
		{
 | 
						|
		  dwTempData =
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosOdd * g_BytesPerRow + i * 2 + 0));
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosOdd * g_BytesPerRow + i * 2 + 1) << 8);
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
 | 
						|
			      0));
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
 | 
						|
			      1) << 8);
 | 
						|
		  dwTempData = g_pGammaTable[dwTempData >> 1];
 | 
						|
		  *(lpLine + i * 2 + 0) = LOBYTE ((unsigned short) dwTempData);
 | 
						|
		  *(lpLine + i * 2 + 1) = HIBYTE ((unsigned short) dwTempData);
 | 
						|
		  i++;
 | 
						|
		  if (i >= g_SWWidth)
 | 
						|
		    {
 | 
						|
		      break;
 | 
						|
		    }
 | 
						|
 | 
						|
		  dwTempData =
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosEven * g_BytesPerRow + i * 2 + 0));
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosEven * g_BytesPerRow + i * 2 + 1) << 8);
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosOdd * g_BytesPerRow + (i + 1) * 2 + 0));
 | 
						|
		  dwTempData +=
 | 
						|
		    (unsigned int) (*
 | 
						|
			     (g_lpReadImageHead +
 | 
						|
			      wLinePosOdd * g_BytesPerRow + (i + 1) * 2 +
 | 
						|
			      1) << 8);
 | 
						|
		  dwTempData = g_pGammaTable[dwTempData >> 1];
 | 
						|
		  *(lpLine + i * 2 + 0) = LOBYTE ((unsigned short) dwTempData);
 | 
						|
		  *(lpLine + i * 2 + 1) = HIBYTE ((unsigned short) dwTempData);
 | 
						|
		  i++;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
	  lpLine += g_SWBytesPerRow;
 | 
						|
	  AddReadyLines ();
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_GetMono16BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  /*for modify the last point */
 | 
						|
  if (g_bIsFirstReadBefData)
 | 
						|
    {
 | 
						|
      g_lpBefLineImageData = (SANE_Byte *) malloc (g_SWBytesPerRow);
 | 
						|
      if (NULL == g_lpBefLineImageData)
 | 
						|
	{
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
      memset (g_lpBefLineImageData, 0, g_SWBytesPerRow);
 | 
						|
      memcpy (g_lpBefLineImageData, lpTemp, g_SWBytesPerRow);
 | 
						|
      g_bIsFirstReadBefData = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  ModifyLinePoint (lpTemp, g_lpBefLineImageData, g_SWBytesPerRow,
 | 
						|
		   wWantedTotalLines, 2, 4);
 | 
						|
 | 
						|
  memcpy (g_lpBefLineImageData,
 | 
						|
	  lpTemp + (wWantedTotalLines - 1) * g_SWBytesPerRow,
 | 
						|
	  g_SWBytesPerRow);
 | 
						|
  g_dwAlreadyGetLines += wWantedTotalLines;
 | 
						|
  if (g_dwAlreadyGetLines >= g_SWHeight)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_GetMono16BitLine1200DPI: free before line data!\n");
 | 
						|
      free (g_lpBefLineImageData);
 | 
						|
      g_lpBefLineImageData = NULL;
 | 
						|
      g_dwAlreadyGetLines = 0;
 | 
						|
      g_bIsFirstReadBefData = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono16BitLine1200DPI: leave MustScanner_GetMono16BitLine1200DPI\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when single CCD and color is 8bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono8BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
			     unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
 | 
						|
  unsigned short i;
 | 
						|
  unsigned short wLinePos = 0;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: call in\n");
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
    {
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  wLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth; i++)
 | 
						|
	    {
 | 
						|
	      *(lpLine + i) =
 | 
						|
		(SANE_Byte) * (g_pGammaTable +
 | 
						|
			  (unsigned short) ((*
 | 
						|
				   (g_lpReadImageHead +
 | 
						|
				    wLinePos * g_BytesPerRow +
 | 
						|
				    i) << 4) | (rand () & 0x0f)));
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
	  lpLine += g_SWBytesPerRow;
 | 
						|
	  AddReadyLines ();
 | 
						|
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono8BitLine: leave MustScanner_GetMono8BitLine\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when double CCD and color is 8bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono8BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
				    unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  SANE_Byte *lpTemp;
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
 | 
						|
  unsigned short wLinePosOdd = 0;
 | 
						|
  unsigned short wLinePosEven = 0;
 | 
						|
  SANE_Byte byGray;
 | 
						|
  unsigned short i;
 | 
						|
  SANE_Byte bNextPixel = 0;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: call in\n");
 | 
						|
 | 
						|
  TotalXferLines = 0;
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
  lpTemp = lpLine;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  for (; TotalXferLines < wWantedTotalLines;)
 | 
						|
    {
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  if (ST_Reflective == g_ScanType)
 | 
						|
 | 
						|
	    {
 | 
						|
	      wLinePosOdd =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	      wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      wLinePosEven =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	      wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth;)
 | 
						|
	    {
 | 
						|
	      if ((i + 1) != g_SWWidth)
 | 
						|
		{
 | 
						|
		  byGray =
 | 
						|
		    *(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow + i);
 | 
						|
		  bNextPixel =
 | 
						|
		    *(g_lpReadImageHead + wLinePosEven * g_BytesPerRow +
 | 
						|
		      (i + 1));
 | 
						|
		  byGray = (byGray + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  *(lpLine + i) =
 | 
						|
		    (SANE_Byte) * (g_pGammaTable +
 | 
						|
			      (byGray << 4 | (rand () & 0x0f)));
 | 
						|
		  i++;
 | 
						|
		  if (i >= g_SWWidth)
 | 
						|
		    {
 | 
						|
		      break;
 | 
						|
		    }
 | 
						|
 | 
						|
		  byGray =
 | 
						|
		    *(g_lpReadImageHead + wLinePosEven * g_BytesPerRow + i);
 | 
						|
		  bNextPixel =
 | 
						|
		    *(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow +
 | 
						|
		      (i + 1));
 | 
						|
		  byGray = (byGray + bNextPixel) >> 1;
 | 
						|
 | 
						|
		  *(lpLine + i) =
 | 
						|
		    (SANE_Byte) * (g_pGammaTable +
 | 
						|
			      (byGray << 4 | (rand () & 0x0f)));
 | 
						|
		  i++;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
	  lpLine += g_SWBytesPerRow;
 | 
						|
	  AddReadyLines ();
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  /*for modify the last point */
 | 
						|
  if (g_bIsFirstReadBefData)
 | 
						|
    {
 | 
						|
      g_lpBefLineImageData = (SANE_Byte *) malloc (g_SWBytesPerRow);
 | 
						|
      if (NULL == g_lpBefLineImageData)
 | 
						|
	{
 | 
						|
	  return FALSE;
 | 
						|
	}
 | 
						|
      memset (g_lpBefLineImageData, 0, g_SWBytesPerRow);
 | 
						|
      memcpy (g_lpBefLineImageData, lpTemp, g_SWBytesPerRow);
 | 
						|
      g_bIsFirstReadBefData = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  ModifyLinePoint (lpTemp, g_lpBefLineImageData, g_SWBytesPerRow,
 | 
						|
		   wWantedTotalLines, 1, 4);
 | 
						|
 | 
						|
  memcpy (g_lpBefLineImageData,
 | 
						|
	  lpTemp + (wWantedTotalLines - 1) * g_SWBytesPerRow,
 | 
						|
	  g_SWBytesPerRow);
 | 
						|
  g_dwAlreadyGetLines += wWantedTotalLines;
 | 
						|
  if (g_dwAlreadyGetLines >= g_SWHeight)
 | 
						|
    {
 | 
						|
      DBG (DBG_FUNC,
 | 
						|
	   "MustScanner_GetMono8BitLine1200DPI: free the before line data!\n");
 | 
						|
      free (g_lpBefLineImageData);
 | 
						|
      g_lpBefLineImageData = NULL;
 | 
						|
      g_dwAlreadyGetLines = 0;
 | 
						|
      g_bIsFirstReadBefData = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono8BitLine1200DPI: leave MustScanner_GetMono8BitLine1200DPI\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when single CCD and color is 1bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono1BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
			     unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned short wLinePos;
 | 
						|
  unsigned short i;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: call in\n");
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  memset (lpLine, 0, wWantedTotalLines * g_SWWidth / 8);
 | 
						|
 | 
						|
  for (TotalXferLines = 0; TotalXferLines < wWantedTotalLines;)
 | 
						|
 | 
						|
    {
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  wLinePos = g_wtheReadyLines % g_wMaxScanLines;
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth; i++)
 | 
						|
	    {
 | 
						|
	      if (*(g_lpReadImageHead + wLinePos * g_BytesPerRow + i) >
 | 
						|
		  g_wLineartThreshold)
 | 
						|
		{
 | 
						|
		  *(lpLine + i / 8) += (0x80 >> (i % 8));
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
	  lpLine += (g_SWBytesPerRow / 8);
 | 
						|
	  AddReadyLines ();
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono1BitLine: leave MustScanner_GetMono1BitLine\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Repair line when double CCD and color is 1bit
 | 
						|
Parameters:
 | 
						|
	lpLine: point to image be repaired
 | 
						|
	isOrderInvert: RGB or BGR
 | 
						|
	wLinesCount: how many line be repaired
 | 
						|
Return value: 
 | 
						|
	if the operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Bool
 | 
						|
MustScanner_GetMono1BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
 | 
						|
				    unsigned short * wLinesCount)
 | 
						|
{
 | 
						|
  unsigned short wWantedTotalLines;
 | 
						|
  unsigned short TotalXferLines;
 | 
						|
  unsigned short i;
 | 
						|
  unsigned short wLinePosOdd;
 | 
						|
  unsigned short wLinePosEven;
 | 
						|
 | 
						|
  isOrderInvert = isOrderInvert;
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: call in\n");
 | 
						|
 | 
						|
  g_isCanceled = FALSE;
 | 
						|
  g_isScanning = TRUE;
 | 
						|
  wWantedTotalLines = *wLinesCount;
 | 
						|
 | 
						|
  if (g_bFirstReadImage)
 | 
						|
    {
 | 
						|
      pthread_create (&g_threadid_readimage, NULL,
 | 
						|
		      MustScanner_ReadDataFromScanner, NULL);
 | 
						|
      DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread create\n");
 | 
						|
      g_bFirstReadImage = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
  memset (lpLine, 0, wWantedTotalLines * g_SWWidth / 8);
 | 
						|
 | 
						|
  for (TotalXferLines = 0; TotalXferLines < wWantedTotalLines;)
 | 
						|
    {
 | 
						|
      if (g_dwTotalTotalXferLines >= g_SWHeight)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  *wLinesCount = TotalXferLines;
 | 
						|
	  g_isScanning = FALSE;
 | 
						|
	  return TRUE;
 | 
						|
	}
 | 
						|
 | 
						|
      if (GetScannedLines () > g_wtheReadyLines)
 | 
						|
	{
 | 
						|
	  if (ST_Reflective == g_ScanType)
 | 
						|
	    {
 | 
						|
	      wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	      wLinePosOdd =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
 | 
						|
	      wLinePosEven =
 | 
						|
		(g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
 | 
						|
	    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	  for (i = 0; i < g_SWWidth;)
 | 
						|
	    {
 | 
						|
	      if ((i + 1) != g_SWWidth)
 | 
						|
		{
 | 
						|
		  if (*(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow + i) >
 | 
						|
		      g_wLineartThreshold)
 | 
						|
		    *(lpLine + i / 8) += (0x80 >> (i % 8));
 | 
						|
		  i++;
 | 
						|
		  if (i >= g_SWWidth)
 | 
						|
		    {
 | 
						|
		      break;
 | 
						|
		    }
 | 
						|
 | 
						|
		  if (*(g_lpReadImageHead + wLinePosEven * g_BytesPerRow + i)
 | 
						|
		      > g_wLineartThreshold)
 | 
						|
		    *(lpLine + i / 8) += (0x80 >> (i % 8));
 | 
						|
		  i++;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
	  TotalXferLines++;
 | 
						|
	  g_dwTotalTotalXferLines++;
 | 
						|
	  lpLine += g_SWBytesPerRow / 8;
 | 
						|
	  AddReadyLines ();
 | 
						|
 | 
						|
 | 
						|
	}
 | 
						|
      if (g_isCanceled)
 | 
						|
	{
 | 
						|
	  pthread_cancel (g_threadid_readimage);
 | 
						|
	  pthread_join (g_threadid_readimage, NULL);
 | 
						|
	  DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread exit\n");
 | 
						|
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }				/*end for */
 | 
						|
 | 
						|
  *wLinesCount = TotalXferLines;
 | 
						|
  g_isScanning = FALSE;
 | 
						|
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_GetMono1BitLine1200DPI: leave MustScanner_GetMono1BitLine1200DPI\n");
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/21
 | 
						|
Routine Description: 
 | 
						|
	prepare calculate Max and Min value	
 | 
						|
Parameters:
 | 
						|
	wResolution: the scan resolution
 | 
						|
Return value:
 | 
						|
	none 
 | 
						|
***********************************************************************/
 | 
						|
static void
 | 
						|
MustScanner_PrepareCalculateMaxMin (unsigned short wResolution)
 | 
						|
{
 | 
						|
  g_wDarkCalWidth = 52;
 | 
						|
  if (wResolution <= 600)
 | 
						|
    {
 | 
						|
      g_wCalWidth = ((5120 * wResolution / 600 + 511) >> 9) << 9;
 | 
						|
      g_wDarkCalWidth = g_wDarkCalWidth / (1200 / wResolution);
 | 
						|
 | 
						|
      if (wResolution < 200)
 | 
						|
	{
 | 
						|
	  g_nPowerNum = 3;
 | 
						|
	  g_nSecLength = 8;	/* 2^nPowerNum */
 | 
						|
	  g_nDarkSecLength = g_wDarkCalWidth / 2;	/* Dark has at least 2 sections */
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  g_nPowerNum = 6;
 | 
						|
	  g_nSecLength = 64;	/* 2^nPowerNum */
 | 
						|
	  g_nDarkSecLength = g_wDarkCalWidth / 3;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_nPowerNum = 6;
 | 
						|
      g_nSecLength = 64;	/*2^nPowerNum */
 | 
						|
      g_wCalWidth = 10240;
 | 
						|
      g_nDarkSecLength = g_wDarkCalWidth / 5;
 | 
						|
    }
 | 
						|
 | 
						|
  if (g_nDarkSecLength <= 0)
 | 
						|
    {
 | 
						|
      g_nDarkSecLength = 1;
 | 
						|
    }
 | 
						|
 | 
						|
  g_wStartPosition = 13 * wResolution / 1200;
 | 
						|
  g_wCalWidth -= g_wStartPosition;
 | 
						|
 | 
						|
 | 
						|
  /* start of find Max value */
 | 
						|
  g_nSecNum = (int) (g_wCalWidth / g_nSecLength);
 | 
						|
 | 
						|
  /* start of fin min value */
 | 
						|
  g_nDarkSecNum = (int) (g_wDarkCalWidth / g_nDarkSecLength);
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/21
 | 
						|
Routine Description: 
 | 
						|
	calculate the Max and Min value
 | 
						|
Parameters:
 | 
						|
	pBuffer: the image data
 | 
						|
	lpMaxValue: the max value
 | 
						|
	lpMinValue: the min value
 | 
						|
	wResolution: the scan resolution
 | 
						|
Return value:
 | 
						|
	none 
 | 
						|
***********************************************************************/
 | 
						|
static void
 | 
						|
MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * lpMaxValue,
 | 
						|
			     unsigned short * lpMinValue, unsigned short wResolution)
 | 
						|
{
 | 
						|
  unsigned short *wSecData = NULL, *wDarkSecData = NULL;
 | 
						|
  int i, j;
 | 
						|
 | 
						|
  wResolution = wResolution;
 | 
						|
 | 
						|
  wSecData = (unsigned short *) malloc (sizeof (unsigned short) * g_nSecNum);
 | 
						|
  if (wSecData == NULL)
 | 
						|
    {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      memset (wSecData, 0, g_nSecNum * sizeof (unsigned short));
 | 
						|
    }
 | 
						|
 | 
						|
  for (i = 0; i < g_nSecNum; i++)
 | 
						|
    {
 | 
						|
 | 
						|
      for (j = 0; j < g_nSecLength; j++)
 | 
						|
	wSecData[i] += *(pBuffer + g_wStartPosition + i * g_nSecLength + j);
 | 
						|
      wSecData[i] >>= g_nPowerNum;
 | 
						|
    }
 | 
						|
 | 
						|
  *lpMaxValue = wSecData[0];
 | 
						|
  for (i = 0; i < g_nSecNum; i++)
 | 
						|
    {
 | 
						|
      if (*lpMaxValue < wSecData[i])
 | 
						|
	*lpMaxValue = wSecData[i];
 | 
						|
    }
 | 
						|
 | 
						|
  free (wSecData);
 | 
						|
 | 
						|
  wDarkSecData = (unsigned short *) malloc (sizeof (unsigned short) * g_nDarkSecNum);
 | 
						|
  if (wDarkSecData == NULL)
 | 
						|
    {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      memset (wDarkSecData, 0, g_nDarkSecNum * sizeof (unsigned short));
 | 
						|
    }
 | 
						|
 | 
						|
  for (i = 0; i < g_nDarkSecNum; i++)
 | 
						|
    {
 | 
						|
      for (j = 0; j < g_nDarkSecLength; j++)
 | 
						|
	wDarkSecData[i] +=
 | 
						|
	  *(pBuffer + g_wStartPosition + i * g_nDarkSecLength + j);
 | 
						|
 | 
						|
      wDarkSecData[i] /= g_nDarkSecLength;
 | 
						|
    }
 | 
						|
 | 
						|
  *lpMinValue = wDarkSecData[0];
 | 
						|
  for (i = 0; i < g_nDarkSecNum; i++)
 | 
						|
    {
 | 
						|
      if (*lpMinValue > wDarkSecData[i])
 | 
						|
	*lpMinValue = wDarkSecData[i];
 | 
						|
    }
 | 
						|
  free (wDarkSecData);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Read the data from scanner
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	if operation is success
 | 
						|
	return TRUE
 | 
						|
	else
 | 
						|
	return FALSE
 | 
						|
***********************************************************************/
 | 
						|
static void *
 | 
						|
MustScanner_ReadDataFromScanner (void * dummy)
 | 
						|
{
 | 
						|
  unsigned short wTotalReadImageLines = 0;
 | 
						|
  unsigned short wWantedLines = g_Height;
 | 
						|
  SANE_Byte * lpReadImage = g_lpReadImageHead;
 | 
						|
  SANE_Bool isWaitImageLineDiff = FALSE;
 | 
						|
  unsigned int wMaxScanLines = g_wMaxScanLines;
 | 
						|
  unsigned short wReadImageLines = 0;
 | 
						|
  unsigned short wScanLinesThisBlock;
 | 
						|
  unsigned short wBufferLines = g_wLineDistance * 2 + g_wPixelDistance;
 | 
						|
 | 
						|
  dummy = dummy;
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_ReadDataFromScanner: call in, and in new thread\n");
 | 
						|
 | 
						|
  while (wTotalReadImageLines < wWantedLines && g_lpReadImageHead)
 | 
						|
    {
 | 
						|
      if (!isWaitImageLineDiff)
 | 
						|
	{
 | 
						|
	  wScanLinesThisBlock =
 | 
						|
	    (wWantedLines - wTotalReadImageLines) <
 | 
						|
	    g_wScanLinesPerBlock ? (wWantedLines -
 | 
						|
				    wTotalReadImageLines) :
 | 
						|
	    g_wScanLinesPerBlock;
 | 
						|
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_ReadDataFromScanner: wWantedLines=%d\n",
 | 
						|
	       wWantedLines);
 | 
						|
 | 
						|
	  DBG (DBG_FUNC,
 | 
						|
	       "MustScanner_ReadDataFromScanner: wScanLinesThisBlock=%d\n",
 | 
						|
	       wScanLinesThisBlock);
 | 
						|
 | 
						|
	  if (STATUS_GOOD !=
 | 
						|
	      Asic_ReadImage (&g_chip, lpReadImage, wScanLinesThisBlock))
 | 
						|
	    {
 | 
						|
	      DBG (DBG_FUNC,
 | 
						|
		   "MustScanner_ReadDataFromScanner:Asic_ReadImage return error\n");
 | 
						|
	      DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner:thread exit\n");
 | 
						|
	      return NULL;
 | 
						|
	    }
 | 
						|
 | 
						|
	  /*has read in memroy Buffer */
 | 
						|
	  wReadImageLines += wScanLinesThisBlock;
 | 
						|
 | 
						|
	  AddScannedLines (wScanLinesThisBlock);
 | 
						|
 | 
						|
	  wTotalReadImageLines += wScanLinesThisBlock;
 | 
						|
 | 
						|
	  lpReadImage += wScanLinesThisBlock * g_BytesPerRow;
 | 
						|
 | 
						|
	  /*Buffer is full */
 | 
						|
	  if (wReadImageLines >= wMaxScanLines)
 | 
						|
	    {
 | 
						|
	      lpReadImage = g_lpReadImageHead;
 | 
						|
	      wReadImageLines = 0;
 | 
						|
	    }
 | 
						|
 | 
						|
	  if ((g_dwScannedTotalLines - GetReadyLines ())
 | 
						|
	      >= (wMaxScanLines - (wBufferLines + g_wScanLinesPerBlock))
 | 
						|
	      && g_dwScannedTotalLines > GetReadyLines ())
 | 
						|
	    {
 | 
						|
	      isWaitImageLineDiff = TRUE;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
      else if (g_dwScannedTotalLines <=
 | 
						|
	       GetReadyLines () + wBufferLines + g_wScanLinesPerBlock)
 | 
						|
	{
 | 
						|
	  isWaitImageLineDiff = FALSE;
 | 
						|
	}
 | 
						|
 | 
						|
      pthread_testcancel ();
 | 
						|
    }
 | 
						|
 | 
						|
  DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner: Read image ok\n");
 | 
						|
  DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner: thread exit\n");
 | 
						|
  DBG (DBG_FUNC,
 | 
						|
       "MustScanner_ReadDataFromScanner: leave MustScanner_ReadDataFromScanner\n");
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/26
 | 
						|
Routine Description: 
 | 
						|
	get the lines of scanned
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	the lines of scanned
 | 
						|
***********************************************************************/
 | 
						|
static unsigned int
 | 
						|
GetScannedLines ()
 | 
						|
{
 | 
						|
  unsigned int dwScannedLines = 0;
 | 
						|
 | 
						|
  pthread_mutex_lock (&g_scannedLinesMutex);
 | 
						|
  dwScannedLines = g_dwScannedTotalLines;
 | 
						|
  pthread_mutex_unlock (&g_scannedLinesMutex);
 | 
						|
 | 
						|
  return dwScannedLines;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/26
 | 
						|
 | 
						|
Routine Description: 
 | 
						|
	get lines which pass to superstratum
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value:
 | 
						|
	the lines which pass to superstratum
 | 
						|
***********************************************************************/
 | 
						|
static unsigned int
 | 
						|
GetReadyLines ()
 | 
						|
{
 | 
						|
  unsigned int dwReadyLines = 0;
 | 
						|
 | 
						|
  pthread_mutex_lock (&g_readyLinesMutex);
 | 
						|
  dwReadyLines = g_wtheReadyLines;
 | 
						|
  pthread_mutex_unlock (&g_readyLinesMutex);
 | 
						|
 | 
						|
  return dwReadyLines;
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/26
 | 
						|
Routine Description: 
 | 
						|
	add the scanned total lines
 | 
						|
Parameters:
 | 
						|
	wAddLines: add the lines
 | 
						|
Return value: 
 | 
						|
	none
 | 
						|
***********************************************************************/
 | 
						|
static void
 | 
						|
AddScannedLines (unsigned short wAddLines)
 | 
						|
{
 | 
						|
  pthread_mutex_lock (&g_scannedLinesMutex);
 | 
						|
 | 
						|
  g_dwScannedTotalLines += wAddLines;
 | 
						|
 | 
						|
  pthread_mutex_unlock (&g_scannedLinesMutex);
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/26
 | 
						|
Routine Description: 
 | 
						|
	add the ready lines
 | 
						|
Parameters:
 | 
						|
	none
 | 
						|
Return value: 
 | 
						|
	none
 | 
						|
***********************************************************************/
 | 
						|
static void
 | 
						|
AddReadyLines ()
 | 
						|
{
 | 
						|
  pthread_mutex_lock (&g_readyLinesMutex);
 | 
						|
  g_wtheReadyLines++;
 | 
						|
  pthread_mutex_unlock (&g_readyLinesMutex);
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack            Date: 2005/05/26
 | 
						|
Routine Description:
 | 
						|
	modify the point
 | 
						|
Parameters:
 | 
						|
	lpImageData: the data of image
 | 
						|
  lpImageDataBefore: the data of before line image
 | 
						|
  dwBytesPerLine: the bytes of per line
 | 
						|
  dwLinesCount: the line count
 | 
						|
  wPixDistance: the pixel distance
 | 
						|
  wModPtCount: the modify point count
 | 
						|
Return value:
 | 
						|
	none
 | 
						|
***********************************************************************/
 | 
						|
static void
 | 
						|
ModifyLinePoint (SANE_Byte * lpImageData,
 | 
						|
		 SANE_Byte * lpImageDataBefore,
 | 
						|
		 unsigned int dwBytesPerLine,
 | 
						|
		 unsigned int dwLinesCount, unsigned short wPixDistance, unsigned short wModPtCount)
 | 
						|
{
 | 
						|
  unsigned short i = 0;
 | 
						|
  unsigned short j = 0;
 | 
						|
  unsigned short wLines = 0;
 | 
						|
  unsigned int dwWidth = dwBytesPerLine / wPixDistance;
 | 
						|
  for (i = wModPtCount; i > 0; i--)
 | 
						|
    {
 | 
						|
      for (j = 0; j < wPixDistance; j++)
 | 
						|
	{
 | 
						|
	  /*modify the first line */
 | 
						|
	  *(lpImageData + (dwWidth - i) * wPixDistance + j) =
 | 
						|
	    (*(lpImageData + (dwWidth - i - 1) * wPixDistance + j) +
 | 
						|
	     *(lpImageDataBefore + (dwWidth - i) * wPixDistance + j)) / 2;
 | 
						|
	  /*modify other lines */
 | 
						|
	  for (wLines = 1; wLines < dwLinesCount; wLines++)
 | 
						|
	    {
 | 
						|
	      unsigned int dwBytesBefor = (wLines - 1) * dwBytesPerLine;
 | 
						|
	      unsigned int dwBytes = wLines * dwBytesPerLine;
 | 
						|
	      *(lpImageData + dwBytes + (dwWidth - i) * wPixDistance + j) =
 | 
						|
		(*
 | 
						|
		 (lpImageData + dwBytes + (dwWidth - i - 1) * wPixDistance +
 | 
						|
		  j) + *(lpImageData + dwBytesBefor + (dwWidth -
 | 
						|
						       i) * wPixDistance +
 | 
						|
			 j)) / 2;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**********************************************************************
 | 
						|
Author: Jack             Date: 2005/05/15
 | 
						|
Routine Description: 
 | 
						|
	Modifiy the image data	
 | 
						|
Parameters:
 | 
						|
	A: the input the image data
 | 
						|
	B: the input the iamge data
 | 
						|
Return value:
 | 
						|
	the modified data
 | 
						|
***********************************************************************/
 | 
						|
static SANE_Byte
 | 
						|
QBET4 (SANE_Byte A, SANE_Byte B)
 | 
						|
{
 | 
						|
  SANE_Byte bQBET[16][16] = {
 | 
						|
    {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
 | 
						|
    {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
 | 
						|
    {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
 | 
						|
    {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
 | 
						|
    {1, 1, 1, 1, 3, 3, 3, 3, 6, 6, 6, 6, 10, 10, 11, 11},
 | 
						|
    {1, 1, 1, 1, 3, 3, 3, 3, 6, 6, 6, 6, 10, 10, 11, 11},
 | 
						|
    {2, 2, 2, 2, 3, 3, 3, 3, 7, 7, 7, 7, 10, 10, 11, 11},
 | 
						|
    {2, 2, 2, 2, 3, 3, 3, 3, 7, 7, 7, 7, 10, 10, 11, 11},
 | 
						|
    {4, 4, 4, 4, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
 | 
						|
    {4, 4, 4, 4, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
 | 
						|
    {5, 5, 5, 5, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
 | 
						|
    {5, 5, 5, 5, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
 | 
						|
    {8, 8, 8, 8, 10, 10, 10, 10, 13, 13, 13, 13, 15, 15, 15, 15},
 | 
						|
    {8, 8, 8, 8, 10, 10, 10, 10, 13, 13, 13, 13, 15, 15, 15, 15},
 | 
						|
    {9, 9, 9, 9, 11, 11, 11, 11, 14, 14, 14, 14, 15, 15, 15, 15},
 | 
						|
    {9, 9, 9, 9, 11, 11, 11, 11, 14, 14, 14, 14, 15, 15, 15, 15}
 | 
						|
  };
 | 
						|
 | 
						|
  A = A & 0x0f;
 | 
						|
  B = B & 0x0f;
 | 
						|
  return bQBET[A][B];
 | 
						|
}				/* end of the file MustScanner.c */
 |