sane-project-backends/backend/mustek_usb2_high.c

3241 wiersze
86 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 BOOL g_bOpened;
static BOOL g_bPrepared;
static BOOL g_isCanceled;
static BOOL g_bSharpen;
static BOOL g_bFirstReadImage;
static BOOL g_isScanning;
static BOOL g_isSelfGamma;
static BYTE g_bScanBits;
static BYTE *g_lpReadImageHead;
static WORD s_wOpticalYDpi[] = { 1200, 600, 300, 150, 75, 0 };
static WORD s_wOpticalXDpi[] = { 1200, 600, 300, 150, 75, 0 };
static WORD g_X;
static WORD g_Y;
static WORD g_Width;
static WORD g_Height;
static WORD g_XDpi;
static WORD g_YDpi;
static WORD g_SWWidth;
static WORD g_SWHeight;
static WORD g_wPixelDistance; /*even & odd sensor problem */
static WORD g_wLineDistance;
static WORD g_wScanLinesPerBlock;
static WORD g_wReadedLines;
static WORD g_wReadImageLines;
static WORD g_wReadyShadingLine;
static WORD g_wStartShadingLinePos;
static WORD g_wLineartThreshold;
static DWORD g_wtheReadyLines;
static DWORD g_wMaxScanLines;
static DWORD g_dwScannedTotalLines;
static DWORD g_dwImageBufferSize;
static DWORD g_BytesPerRow;
static DWORD g_SWBytesPerRow;
static DWORD g_dwCalibrationSize;
static DWORD g_dwBufferSize;
static DWORD 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 WORD g_wCalWidth;
static WORD g_wDarkCalWidth;
static int g_nPowerNum;
static WORD 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 LPBYTE g_lpBefLineImageData = NULL;
static BOOL g_bIsFirstReadBefData = TRUE;
static DWORD g_dwAlreadyGetLines = 0;
/* forward declarations */
static BOOL MustScanner_Init (void);
static BOOL MustScanner_GetScannerState (void);
static BOOL MustScanner_PowerControl (BOOL isLampOn, BOOL isTALampOn);
static BOOL MustScanner_BackHome (void);
static BOOL MustScanner_Prepare (BYTE bScanSource);
#ifdef SANE_UNUSED
static BOOL MustScanner_AdjustOffset (int nTimes, BOOL * bDirection, BYTE * bOffset,
BYTE * bLastMin, BYTE * bLastOffset,
WORD * wMinValue, BYTE * bOffsetUpperBound,
BYTE * bOffsetLowerBound, WORD wStdMinLevel,
WORD wStdMaxLevel);
static BOOL MustScanner_SecondAdjustOffset (int nTimes, BOOL * bDirection,
BYTE * bOffset, BYTE * bLastMin,
BYTE * bLastOffset, WORD * wMinValue,
BYTE * bOffsetUpperBound,
BYTE * bOffsetLowerBound,
WORD wStdMinLevel, WORD wStdMaxLevel);
#endif
static WORD MustScanner_FiltLower (WORD * pSort, WORD TotalCount, WORD LowCount,
WORD HighCount);
static BOOL MustScanner_GetRgb48BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetRgb48BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetRgb24BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetRgb24BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono16BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono16BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono8BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono8BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono1BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static BOOL MustScanner_GetMono1BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount);
static void *MustScanner_ReadDataFromScanner (void * dummy);
static void MustScanner_PrepareCalculateMaxMin (WORD wResolution);
static void MustScanner_CalculateMaxMin (LPBYTE pBuffer, LPWORD lpMaxValue,
LPWORD lpMinValue, WORD wResolution);
static BYTE QBET4 (BYTE A, BYTE B);
static DWORD GetScannedLines (void);
static DWORD GetReadyLines (void);
static void AddScannedLines (WORD wAddLines);
static void AddReadyLines (void);
static void ModifyLinePoint (LPBYTE lpImageData,
LPBYTE lpImageDataBefore,
DWORD dwBytesPerLine,
DWORD dwLinesCount,
WORD wPixDistance, WORD 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 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 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 BOOL
MustScanner_PowerControl (BOOL isLampOn, BOOL isTALampOn)
{
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 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 BOOL
MustScanner_Prepare (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 BOOL
MustScanner_AdjustOffset (int nTimes, BOOL * bDirection, BYTE * bOffset,
BYTE * bLastMin, BYTE * bLastOffset,
WORD * wMinValue, BYTE * bOffsetUpperBound,
BYTE * bOffsetLowerBound, WORD wStdMinLevel,
WORD wStdMaxLevel)
{
if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
{
return TRUE;
}
if (nTimes == 0)
{
*bLastMin = LOBYTE (*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)
{
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 = (BYTE) * wMinValue;
}
else
{
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 = (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 BOOL
MustScanner_SecondAdjustOffset (int nTimes, BOOL * bDirection, BYTE * bOffset,
BYTE * bLastMin, BYTE * bLastOffset,
WORD * wMinValue, BYTE * bOffsetUpperBound,
BYTE * bOffsetLowerBound, WORD wStdMinLevel,
WORD wStdMaxLevel)
{
if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
{
return TRUE;
}
if (nTimes == 0)
{
*bLastMin = LOBYTE (*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 = (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 WORD
MustScanner_FiltLower (WORD * pSort, WORD TotalCount, WORD LowCount,
WORD HighCount)
{
WORD Bound = TotalCount - 1;
WORD LeftCount = HighCount - LowCount;
int Temp = 0;
DWORD Sum = 0;
WORD 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 (WORD) (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 BOOL
MustScanner_GetRgb48BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wRLinePos = 0;
WORD wGLinePos = 0;
WORD wBLinePos = 0;
WORD wRTempData;
WORD wGTempData;
WORD wBTempData;
WORD 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 BOOL
MustScanner_GetRgb48BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wRLinePosOdd = 0;
WORD wGLinePosOdd = 0;
WORD wBLinePosOdd = 0;
WORD wRLinePosEven = 0;
WORD wGLinePosEven = 0;
WORD wBLinePosEven = 0;
DWORD wRTempData;
DWORD wGTempData;
DWORD wBTempData;
DWORD wNextTempData;
WORD 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 BOOL
MustScanner_GetRgb24BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wRLinePos = 0;
WORD wGLinePos = 0;
WORD wBLinePos = 0;
BYTE byRed;
BYTE byGreen;
BYTE byBlue;
BYTE bNextPixel = 0;
WORD i;
WORD 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 = (WORD) ((byRed << 4) | QBET4 (byBlue, byGreen));
tempG = (WORD) ((byGreen << 4) | QBET4 (byRed, byBlue));
tempB = (WORD) ((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 +
(WORD) ((byRed << 4) |
QBET4 (byBlue, byGreen))));
*(lpLine + i * 3 + 1) =
(unsigned
char) (*(g_pGammaTable + 4096 +
(WORD) ((byGreen << 4) |
QBET4 (byRed, byBlue))));
*(lpLine + i * 3 + 0) =
(unsigned
char) (*(g_pGammaTable + 8192 +
(WORD) ((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 BOOL
MustScanner_GetRgb24BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
BYTE *lpTemp;
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wRLinePosOdd = 0;
WORD wGLinePosOdd = 0;
WORD wBLinePosOdd = 0;
WORD wRLinePosEven = 0;
WORD wGLinePosEven = 0;
WORD wBLinePosEven = 0;
BYTE byRed;
BYTE byGreen;
BYTE byBlue;
BYTE bNextPixel = 0;
WORD 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 +
(WORD) ((byRed << 4) |
QBET4 (byBlue, byGreen))));
*(lpLine + i * 3 + 1) =
(unsigned
char) (*(g_pGammaTable + 4096 +
(WORD) ((byGreen << 4) |
QBET4 (byRed, byBlue))));
*(lpLine + i * 3 + 2) =
(unsigned
char) (*(g_pGammaTable + 8192 +
(WORD) ((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 +
(WORD) ((byRed << 4) |
QBET4 (byBlue, byGreen))));
*(lpLine + i * 3 + 1) =
(unsigned
char) (*(g_pGammaTable + 4096 +
(WORD) ((byGreen << 4) |
QBET4 (byRed, byBlue))));
*(lpLine + i * 3 + 2) =
(unsigned
char) (*(g_pGammaTable + 8192 +
(WORD) ((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 +
(WORD) ((byRed << 4) |
QBET4 (byBlue, byGreen))));
*(lpLine + i * 3 + 1) =
(unsigned
char) (*(g_pGammaTable + 4096 +
(WORD) ((byGreen << 4) |
QBET4 (byRed, byBlue))));
*(lpLine + i * 3 + 0) =
(unsigned
char) (*(g_pGammaTable + 8192 +
(WORD) ((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 +
(WORD) ((byRed << 4) |
QBET4 (byBlue, byGreen))));
*(lpLine + i * 3 + 1) =
(unsigned
char) (*(g_pGammaTable + 4096 +
(WORD) ((byGreen << 4) |
QBET4 (byRed, byBlue))));
*(lpLine + i * 3 + 0) =
(unsigned
char) (*(g_pGammaTable + 8192 +
(WORD) ((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 BOOL
MustScanner_GetMono16BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
DWORD wTempData;
WORD wLinePos = 0;
WORD 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 BOOL
MustScanner_GetMono16BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
DWORD dwTempData;
WORD wLinePosOdd = 0;
WORD wLinePosEven = 0;
WORD i;
LPBYTE 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 =
(DWORD) (*
(g_lpReadImageHead +
wLinePosOdd * g_BytesPerRow + i * 2 + 0));
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosOdd * g_BytesPerRow + i * 2 + 1) << 8);
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
0));
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
1) << 8);
dwTempData = g_pGammaTable[dwTempData >> 1];
*(lpLine + i * 2 + 0) = LOBYTE ((WORD) dwTempData);
*(lpLine + i * 2 + 1) = HIBYTE ((WORD) dwTempData);
i++;
if (i >= g_SWWidth)
{
break;
}
dwTempData =
(DWORD) (*
(g_lpReadImageHead +
wLinePosEven * g_BytesPerRow + i * 2 + 0));
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosEven * g_BytesPerRow + i * 2 + 1) << 8);
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosOdd * g_BytesPerRow + (i + 1) * 2 + 0));
dwTempData +=
(DWORD) (*
(g_lpReadImageHead +
wLinePosOdd * g_BytesPerRow + (i + 1) * 2 +
1) << 8);
dwTempData = g_pGammaTable[dwTempData >> 1];
*(lpLine + i * 2 + 0) = LOBYTE ((WORD) dwTempData);
*(lpLine + i * 2 + 1) = HIBYTE ((WORD) 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 = (LPBYTE) 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 BOOL
MustScanner_GetMono8BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD i;
WORD 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) =
(BYTE) * (g_pGammaTable +
(WORD) ((*
(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 BOOL
MustScanner_GetMono8BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
BYTE *lpTemp;
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wLinePosOdd = 0;
WORD wLinePosEven = 0;
BYTE byGray;
WORD i;
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) =
(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) =
(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 = (LPBYTE) 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 BOOL
MustScanner_GetMono1BitLine (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD wLinePos;
WORD 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 BOOL
MustScanner_GetMono1BitLine1200DPI (BYTE * lpLine, BOOL isOrderInvert,
WORD * wLinesCount)
{
WORD wWantedTotalLines;
WORD TotalXferLines;
WORD i;
WORD wLinePosOdd;
WORD 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 (WORD 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 (LPBYTE pBuffer, LPWORD lpMaxValue,
LPWORD lpMinValue, WORD wResolution)
{
WORD *wSecData = NULL, *wDarkSecData = NULL;
int i, j;
wResolution = wResolution;
wSecData = (WORD *) malloc (sizeof (WORD) * g_nSecNum);
if (wSecData == NULL)
{
return;
}
else
{
memset (wSecData, 0, g_nSecNum * sizeof (WORD));
}
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 = (WORD *) malloc (sizeof (WORD) * g_nDarkSecNum);
if (wDarkSecData == NULL)
{
return;
}
else
{
memset (wDarkSecData, 0, g_nDarkSecNum * sizeof (WORD));
}
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)
{
WORD wTotalReadImageLines = 0;
WORD wWantedLines = g_Height;
LPBYTE lpReadImage = g_lpReadImageHead;
BOOL isWaitImageLineDiff = FALSE;
DWORD wMaxScanLines = g_wMaxScanLines;
WORD wReadImageLines = 0;
WORD wScanLinesThisBlock;
WORD 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 DWORD
GetScannedLines ()
{
DWORD 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 DWORD
GetReadyLines ()
{
DWORD 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 (WORD 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 (LPBYTE lpImageData,
LPBYTE lpImageDataBefore,
DWORD dwBytesPerLine,
DWORD dwLinesCount, WORD wPixDistance, WORD wModPtCount)
{
WORD i = 0;
WORD j = 0;
WORD wLines = 0;
DWORD 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++)
{
DWORD dwBytesBefor = (wLines - 1) * dwBytesPerLine;
DWORD 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 BYTE
QBET4 (BYTE A, BYTE B)
{
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 */