2004-07-16 11:39:09 +00:00
|
|
|
/* @file plustek-pp_dac.c
|
2003-09-24 14:08:01 +00:00
|
|
|
* @brief all the shading function formerly found in shading.c.
|
|
|
|
* don't ask me why I called this file dac.c...
|
2003-09-23 07:10:53 +00:00
|
|
|
*
|
|
|
|
* based on sources acquired from Plustek Inc.
|
|
|
|
* Copyright (C) 1998 Plustek Inc.
|
2004-01-09 15:57:55 +00:00
|
|
|
* Copyright (C) 2000-2004 Gerhard Jaeger <gerhard@gjaeger.de>
|
2003-09-23 07:10:53 +00:00
|
|
|
* also based on the work done by Rick Bronson
|
|
|
|
*
|
2003-09-24 14:08:01 +00:00
|
|
|
* History:
|
|
|
|
* - 0.30 - initial version
|
|
|
|
* - 0.31 - no changes
|
|
|
|
* - 0.32 - no changes
|
|
|
|
* - 0.33 - added some comments
|
|
|
|
* - 0.34 - slight changes
|
|
|
|
* - 0.35 - removed SetInitialGainRAM from structure pScanData
|
|
|
|
* - 0.36 - added dacP96001WaitForShading and changed dacP96WaitForShading to
|
|
|
|
* dacP96003WaitForShading
|
|
|
|
* - changes, due to define renaming
|
|
|
|
* - 0.37 - removed dacP98FillShadingDarkToShadingRegister()
|
|
|
|
* - removed // comments
|
|
|
|
* - some code cleanup
|
|
|
|
* - 0.38 - added P12 stuff
|
|
|
|
* - 0.39 - no changes
|
|
|
|
* - 0.40 - disabled the A3I stuff
|
|
|
|
* - 0.41 - no changes
|
|
|
|
* - 0.42 - changed include names
|
2004-07-16 11:39:09 +00:00
|
|
|
* - 0.43 - no changes
|
2003-09-24 14:08:01 +00:00
|
|
|
* .
|
|
|
|
* <hr>
|
|
|
|
* This file is part of the SANE package.
|
2003-09-23 07:10:53 +00:00
|
|
|
*
|
2003-09-24 14:08:01 +00:00
|
|
|
* 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.
|
2003-09-23 07:10:53 +00:00
|
|
|
*
|
2003-09-24 14:08:01 +00:00
|
|
|
* 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.
|
2003-09-23 07:10:53 +00:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2003-09-24 14:08:01 +00:00
|
|
|
* 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.
|
|
|
|
* <hr>
|
2003-09-23 07:10:53 +00:00
|
|
|
*/
|
|
|
|
#include "plustek-pp_scan.h"
|
|
|
|
|
|
|
|
/************************** local definitions ********************************/
|
|
|
|
|
|
|
|
/***************************** global vars ***********************************/
|
|
|
|
|
|
|
|
static const Byte a_bCorrectTimesTable[4] = {0, 1, 2, 4};
|
|
|
|
|
|
|
|
static ULong dwADCPipeLine = 4 * 4;
|
|
|
|
static ULong dwReadyLen;
|
|
|
|
|
|
|
|
/*************************** local functions *********************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98AdjustGainAverage( pScanData ps )
|
|
|
|
{
|
|
|
|
pUChar pDest, pSrce;
|
|
|
|
ULong dw, dw1;
|
|
|
|
UShort wSum;
|
|
|
|
|
|
|
|
pDest = pSrce = ps->pScanBuffer1;
|
|
|
|
|
|
|
|
for (dw1 = 0; dw1 < (2560 * 3) / 16; dw1++, pDest++) {
|
|
|
|
for (dw = 0, wSum = 0; dw < 16; dw++, pSrce++)
|
|
|
|
wSum += *pSrce;
|
|
|
|
|
|
|
|
*pDest = wSum / 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98FillDarkDAC( pScanData ps )
|
|
|
|
{
|
|
|
|
IODataRegisterToDAC( ps, 0x20, ps->bRedDAC );
|
|
|
|
IODataRegisterToDAC( ps, 0x21, ps->bGreenDAC );
|
|
|
|
IODataRegisterToDAC( ps, 0x22, ps->bBlueDAC );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98SetReadFBKRegister( pScanData ps )
|
|
|
|
{
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE + _SCAN_1ST_AVERAGE;
|
|
|
|
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Motor0Control = _MotorOn;
|
|
|
|
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
|
|
|
ps->AsicReg.RD_Origin = 4;
|
|
|
|
ps->AsicReg.RD_Pixels = 512;
|
|
|
|
ps->AsicReg.RD_Motor1Control = 0;
|
|
|
|
ps->AsicReg.RD_Motor0Control = 0;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_CONTROL + _LED_ACTIVITY;
|
|
|
|
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_ModelControl += _ModelDpi300;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ps->AsicReg.RD_Dpi = 600;
|
|
|
|
ps->AsicReg.RD_ModelControl += _ModelDpi600;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static UShort dacP98CalDarkOff( pScanData ps, UShort wChDarkOff,
|
|
|
|
UShort wDACCompareHigh, UShort wDACOffset )
|
|
|
|
{
|
|
|
|
UShort wTemp;
|
|
|
|
|
|
|
|
if ((_CCD_518 == ps->Device.bCCDID) || (_CCD_535 == ps->Device.bCCDID)) {
|
|
|
|
wTemp = wChDarkOff + wDACOffset;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (_CCD_3797 == ps->Device.bCCDID) {
|
|
|
|
if (wChDarkOff > wDACOffset) {
|
|
|
|
wTemp = wChDarkOff - wDACOffset;
|
|
|
|
} else {
|
|
|
|
wTemp = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (wChDarkOff > wDACCompareHigh) {
|
|
|
|
wTemp = wChDarkOff - wDACCompareHigh;
|
|
|
|
} else {
|
|
|
|
wTemp = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return wTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP98AdjustDAC( UShort DarkOff, UShort wHigh,
|
|
|
|
UShort wLow, pUChar pbReg, Bool *fDACStopFlag )
|
|
|
|
{
|
|
|
|
if (DarkOff > wHigh) {
|
|
|
|
if ((DarkOff - wHigh) > 10) {
|
|
|
|
if ((DarkOff - wHigh) > 2550)
|
|
|
|
*pbReg += ((DarkOff - wHigh) / 20);
|
|
|
|
else
|
|
|
|
*pbReg += ((DarkOff - wHigh) / 10);
|
|
|
|
} else
|
|
|
|
*pbReg += 1;
|
|
|
|
|
|
|
|
if (!(*pbReg))
|
|
|
|
*pbReg = 0xff;
|
|
|
|
|
|
|
|
*fDACStopFlag = _FALSE;
|
|
|
|
return _FALSE;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (DarkOff < wLow) {
|
|
|
|
if (DarkOff > 0)
|
|
|
|
*pbReg -= 2;
|
|
|
|
else
|
|
|
|
*pbReg -= 10;
|
|
|
|
|
|
|
|
*fDACStopFlag = _FALSE;
|
|
|
|
return _FALSE;
|
|
|
|
} else
|
|
|
|
return _TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP98CheckChannelDarkLevel( pScanData ps )
|
|
|
|
{
|
|
|
|
Bool fDACStopFlag = _TRUE;
|
|
|
|
|
|
|
|
dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Red,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Red,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpLo.Colors.Red,
|
|
|
|
&ps->bRedDAC, &fDACStopFlag );
|
|
|
|
dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Green,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Green,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpLo.Colors.Green,
|
|
|
|
&ps->bGreenDAC, &fDACStopFlag );
|
|
|
|
dacP98AdjustDAC( ps->Shade.DarkOffset.Colors.Blue,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue,
|
|
|
|
&ps->bBlueDAC, &fDACStopFlag );
|
|
|
|
|
|
|
|
return fDACStopFlag;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Average left offset 30, 16 pixels as each color's dark level
|
|
|
|
*/
|
|
|
|
static void dacP98FillChannelDarkLevelControl( pScanData ps )
|
|
|
|
{
|
|
|
|
DataPointer p;
|
|
|
|
ULong dwPos, dw, dwSum;
|
|
|
|
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
|
|
|
|
dwPos = 0x10 * 3;
|
|
|
|
} else {
|
|
|
|
dwPos = 0x20 * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos), dwSum = 0, dw = 16;
|
|
|
|
dw; dw--, p.pw++) {
|
|
|
|
dwSum += (ULong)(*p.pw);
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Red = (UShort)(dwSum / 16);
|
|
|
|
|
|
|
|
for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos + 1024), dwSum = 0, dw = 16;
|
|
|
|
dw; dw--, p.pw++) {
|
|
|
|
dwSum += (ULong)(*p.pw);
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Green = (UShort)(dwSum / 16);
|
|
|
|
|
|
|
|
for (p.pw = (pUShort)(ps->pScanBuffer1 + dwPos + 1024 * 2), dwSum = 0, dw = 16;
|
|
|
|
dw; dw--, p.pw++) {
|
|
|
|
dwSum += (ULong)(*p.pw);
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Blue = (UShort)(dwSum / 16);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98AdjustGain( pScanData ps )
|
|
|
|
{
|
|
|
|
DataPointer p;
|
|
|
|
ULong dw;
|
|
|
|
UShort w;
|
|
|
|
Byte b[3];
|
|
|
|
pUChar pbReg[3];
|
|
|
|
|
|
|
|
dacP98AdjustGainAverage( ps );
|
|
|
|
|
|
|
|
pbReg[0] = &ps->bRedGainIndex;
|
|
|
|
pbReg[1] = &ps->bGreenGainIndex;
|
|
|
|
pbReg[2] = &ps->bBlueGainIndex;
|
|
|
|
|
|
|
|
for (w = 0, p.pb = ps->pScanBuffer1; w < 3; w++) {
|
|
|
|
|
|
|
|
for (dw = 2560 / 16, b [w] = 0; dw; dw--, p.pb++) {
|
|
|
|
if (b [w] < *p.pb)
|
|
|
|
b [w] = *p.pb;
|
|
|
|
}
|
|
|
|
if (b[w] < _GAIN_LOW) {
|
|
|
|
if ((_GAIN_P98_HIGH - b[w]) < b[w])
|
|
|
|
*(pbReg[w]) += 1;
|
|
|
|
else
|
|
|
|
*(pbReg[w]) += 4;
|
|
|
|
} else {
|
|
|
|
if (b[w] > _GAIN_P98_HIGH)
|
|
|
|
*(pbReg[w]) -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98CheckLastGain( pScanData ps )
|
|
|
|
{
|
|
|
|
DataPointer p;
|
|
|
|
ULong dw;
|
|
|
|
UShort w;
|
|
|
|
Byte b[3];
|
|
|
|
pUChar pbReg[3];
|
|
|
|
|
|
|
|
dacP98AdjustGainAverage( ps );
|
|
|
|
|
|
|
|
pbReg[0] = &ps->bRedGainIndex;
|
|
|
|
pbReg[1] = &ps->bGreenGainIndex;
|
|
|
|
pbReg[2] = &ps->bBlueGainIndex;
|
|
|
|
|
|
|
|
for (w = 0, p.pb = ps->pScanBuffer1; w < 3; w++) {
|
|
|
|
for (dw = 2560 / 16, b [w] = 0; dw; dw--, p.pb++) {
|
|
|
|
if (b[w] < *p.pb)
|
|
|
|
b[w] = *p.pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (b[w] > _GAIN_P98_HIGH) {
|
|
|
|
*(pbReg [w]) -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98FillGainInitialRestRegister( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegThresholdGapControl, ps->AsicReg.RD_ThresholdGapCtrl );
|
|
|
|
IODataToRegister( ps, ps->RegModelControl, ps->AsicReg.RD_ModelControl );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98SetInitialGainRegister( pScanData ps )
|
|
|
|
{
|
|
|
|
DacP98FillGainOutDirectPort( ps ); /* R/G/B GainOut to scanner */
|
|
|
|
dacP98FillGainInitialRestRegister( ps );/* Model Control2, LED, Correct.*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Find the the most ideal intensity for each color (RGB)
|
|
|
|
*/
|
|
|
|
static void dacP98SetRGBGainRegister( pScanData ps )
|
|
|
|
{
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
|
|
|
|
dacP98SetInitialGainRegister( ps );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
|
|
|
ps->AsicReg.RD_Motor0Control = _MotorOn + _MotorDirForward + _MotorHEightStep;
|
|
|
|
ps->AsicReg.RD_XStepTime = ps->bSpeed4;
|
|
|
|
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi300;
|
|
|
|
ps->AsicReg.RD_Origin = 32 + 60 + 4;
|
|
|
|
} else {
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi600;
|
|
|
|
ps->AsicReg.RD_Origin = 64 + 120 + 4;
|
|
|
|
}
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Pixels = 2560;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98FillRGBMap( pUChar pBuffer )
|
|
|
|
{
|
|
|
|
ULong dw, dw1;
|
|
|
|
pULong pdw = (pULong)(pBuffer);
|
|
|
|
|
|
|
|
for( dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101 ) {
|
|
|
|
*pdw++ = dw1;
|
|
|
|
*pdw++ = dw1;
|
|
|
|
*pdw++ = dw1;
|
|
|
|
*pdw++ = dw1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** here we download the current mapping table
|
|
|
|
*/
|
|
|
|
static void dacP98DownloadMapTable( pScanData ps, pUChar pBuffer )
|
|
|
|
{
|
|
|
|
Byte bAddr;
|
|
|
|
ULong i;
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegScanControl,
|
|
|
|
(Byte)((ps->AsicReg.RD_ScanControl & 0xfc) | _SCAN_BYTEMODE));
|
|
|
|
|
|
|
|
for( i = 3, bAddr = _MAP_ADDR_RED; i--; bAddr += _MAP_ADDR_SIZE ) {
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeMappingMem );
|
|
|
|
IODataToRegister( ps, ps->RegMemoryLow, 0);
|
|
|
|
IODataToRegister( ps, ps->RegMemoryHigh, bAddr );
|
|
|
|
|
|
|
|
IOMoveDataToScanner( ps, pBuffer, 4096 );
|
|
|
|
pBuffer += 4096;
|
|
|
|
}
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98DownloadShadingTable( pScanData ps,
|
|
|
|
pUChar pBuffer, ULong size )
|
|
|
|
{
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeShadingMem );
|
|
|
|
IODataToRegister( ps, ps->RegMemoryLow, 0 );
|
|
|
|
IODataToRegister( ps, ps->RegMemoryHigh, 0 );
|
|
|
|
|
|
|
|
/* set 12 bits output color */
|
|
|
|
IODataToRegister( ps, ps->RegScanControl,
|
|
|
|
(Byte)(ps->AsicReg.RD_ScanControl | _SCAN_12BITMODE));
|
|
|
|
|
|
|
|
/* MoveDataToShadingRam() */
|
|
|
|
IOMoveDataToScanner( ps ,pBuffer, size );
|
|
|
|
|
|
|
|
if( _ASIC_IS_98003 == ps->sCaps.AsicID )
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeScan );
|
|
|
|
else
|
|
|
|
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
|
|
|
|
|
|
|
DacP98FillShadingDarkToShadingRegister( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Build a linear map for asic (this model is 12-bit scanner, there are 4096
|
|
|
|
* map entries but just generate 256 level output, so the content must be 0 to
|
|
|
|
* 255), then fill the shading buffer (the first 3k), and map table (the last
|
|
|
|
* 1k) to asic for R & G & B channels.
|
|
|
|
*
|
|
|
|
* I need pScanBuffer2 size = 5400 * 2 * 3
|
|
|
|
* pScanBuffer1 size = 256 * 16 * 2
|
|
|
|
*/
|
|
|
|
static void dacP98SetInitialGainRAM( pScanData ps )
|
|
|
|
{
|
|
|
|
memset( ps->pScanBuffer2, 0xff, (5400 * 2 * 3));
|
|
|
|
|
|
|
|
dacP98DownloadShadingTable( ps, ps->pScanBuffer2, (5400 * 2 * 3));
|
|
|
|
|
|
|
|
dacP98FillRGBMap( ps->pScanBuffer1 ); /* Fill 12 Bits R Map */
|
|
|
|
dacP98FillRGBMap( ps->pScanBuffer1 + 4096 ); /* Fill 12 Bits G Map */
|
|
|
|
dacP98FillRGBMap( ps->pScanBuffer1 + 8192 ); /* Fill 12 Bits B Map */
|
|
|
|
|
|
|
|
dacP98DownloadMapTable( ps, ps->pScanBuffer1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Find the the most ideal intensity for each color (RGB)
|
|
|
|
*/
|
|
|
|
static void dacP98AdjustRGBGain( pScanData ps )
|
|
|
|
{
|
|
|
|
int bCorrectTimes;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98AdjustRGBGain()\n" );
|
|
|
|
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
dacP98SetInitialGainRAM( ps ); /* set shading ram and read out data to */
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
ps->bRedGainIndex = 0x02;
|
|
|
|
ps->bGreenGainIndex = 0x02;
|
|
|
|
ps->bBlueGainIndex = 0x02;
|
|
|
|
|
|
|
|
for (bCorrectTimes = 10; bCorrectTimes; bCorrectTimes-- ) {
|
|
|
|
|
|
|
|
dacP98SetRGBGainRegister( ps ); /* shading the most brightness &*/
|
|
|
|
ps->PauseColorMotorRunStates( ps ); /* stop scan states */
|
|
|
|
IOReadOneShadingLine( ps, ps->pScanBuffer1, 2560UL );
|
|
|
|
dacP98AdjustGain( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
dacP98SetRGBGainRegister( ps ); /* shading the most brightness & */
|
|
|
|
ps->PauseColorMotorRunStates( ps ); /* stop scan states */
|
|
|
|
|
|
|
|
IOReadOneShadingLine( ps, ps->pScanBuffer1, 2560UL );
|
|
|
|
|
|
|
|
dacP98CheckLastGain( ps );
|
|
|
|
DacP98FillGainOutDirectPort( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98SetAdjustShadingRegister( pScanData ps )
|
|
|
|
{
|
|
|
|
DBG( DBG_LOW, "dacP98SetAdjustShadingRegister()\n" );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE + _SCAN_1ST_AVERAGE;
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegScanControl,
|
|
|
|
ps->AsicReg.RD_ScanControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_Motor0Control = _MotorOn + _MotorHEightStep + _MotorDirForward;
|
|
|
|
ps->AsicReg.RD_XStepTime = ps->bSpeed1;
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_ACTIVITY + _LED_CONTROL;
|
|
|
|
|
|
|
|
if (ps->bSetScanModeFlag & _ScanMode_AverageOut) {
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Pixels = 2700;
|
|
|
|
ps->AsicReg.RD_ModelControl += _ModelDpi300;
|
|
|
|
} else {
|
|
|
|
ps->AsicReg.RD_Dpi = 600;
|
|
|
|
ps->AsicReg.RD_Pixels = 5400;
|
|
|
|
ps->AsicReg.RD_ModelControl += _ModelDpi600;
|
|
|
|
}
|
|
|
|
ps->AsicReg.RD_Origin = 4;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98ReadShadingScanLine( pScanData ps )
|
|
|
|
{
|
|
|
|
TimerDef timer;
|
|
|
|
|
|
|
|
MiscStartTimer( &timer, _SECOND );
|
|
|
|
|
|
|
|
ps->Scan.bFifoSelect = ps->RegGFifoOffset;
|
|
|
|
|
|
|
|
while((IOReadFifoLength( ps ) < dwReadyLen) &&
|
|
|
|
!MiscCheckTimer(&timer)) {
|
|
|
|
_DO_UDELAY( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
IOReadColorData( ps, ps->pScanBuffer2, ps->dwShadingLen );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98GainResize( pUShort pValue, UShort wResize)
|
|
|
|
{
|
|
|
|
DataType Data;
|
|
|
|
Byte bTemp;
|
|
|
|
|
|
|
|
Data.dwValue = ((ULong) *pValue) * (ULong) wResize / 100;
|
|
|
|
|
|
|
|
if (0x1000 <= Data.dwValue)
|
|
|
|
Data.wValue = 0xfff;
|
|
|
|
|
|
|
|
Data.wValue *= 16;
|
|
|
|
|
|
|
|
bTemp = Data.wOverlap.b1st;
|
|
|
|
Data.wOverlap.b1st = Data.wOverlap.b2nd;
|
|
|
|
Data.wOverlap.b2nd = bTemp;
|
|
|
|
|
|
|
|
*pValue = Data.wValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98SortHilightShadow( pScanData ps, pUShort pwData,
|
|
|
|
ULong dwHilightOff, ULong dwShadowOff )
|
|
|
|
{
|
|
|
|
ULong dwLines, dwPixels;
|
|
|
|
UShort wVCmp, wTmp;
|
|
|
|
pUShort pw;
|
|
|
|
|
|
|
|
for (dwPixels = 0; dwPixels < (ps->dwShadingPixels - 4); dwPixels++) {
|
|
|
|
|
|
|
|
pw = (pUShort)ps->Shade.pHilight + dwHilightOff + dwPixels;
|
|
|
|
wVCmp = pwData[dwPixels] & 0xfffU;
|
|
|
|
|
|
|
|
for (dwLines = _DEF_BRIGHTEST_SKIP; dwLines--; pw += 5400UL) {
|
|
|
|
if (wVCmp > *pw) {
|
|
|
|
wTmp = wVCmp;
|
|
|
|
wVCmp = *pw;
|
|
|
|
*pw = wTmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (dwPixels = 0; dwPixels < (ps->dwShadingPixels - 4); dwPixels++) {
|
|
|
|
|
|
|
|
pw = ps->pwShadow + dwShadowOff + dwPixels;
|
|
|
|
wVCmp = pwData [dwPixels] & 0xfffU;
|
|
|
|
|
|
|
|
for (dwLines = _DEF_DARKEST_SKIP; dwLines--; pw += 5400UL) {
|
|
|
|
|
|
|
|
if (wVCmp < *pw) {
|
|
|
|
wTmp = wVCmp;
|
|
|
|
wVCmp = *pw;
|
|
|
|
*pw = wTmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98WriteBackToShadingRAM( pScanData ps )
|
|
|
|
{
|
|
|
|
ULong dw;
|
|
|
|
|
|
|
|
pUShort pBuffer = (pUShort)ps->pScanBuffer2;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98WriteBackToShadingRAM()\n" );
|
|
|
|
|
|
|
|
if (ps->DataInf.wPhyDataType >= COLOR_TRUE24) {
|
|
|
|
|
|
|
|
for (dw = 0; dw < 5400; dw++) {
|
|
|
|
|
|
|
|
*pBuffer = ((pUShort)ps->pScanBuffer1)[dw] -
|
|
|
|
ps->Shade.DarkOffset.Colors.Red;
|
|
|
|
dacP98GainResize( pBuffer,
|
|
|
|
ps->Shade.pCcdDac->GainResize.Colors.Red );
|
|
|
|
pBuffer ++;
|
|
|
|
|
|
|
|
*pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400] -
|
|
|
|
ps->Shade.DarkOffset.Colors.Green;
|
|
|
|
dacP98GainResize( pBuffer,
|
|
|
|
ps->Shade.pCcdDac->GainResize.Colors.Green );
|
|
|
|
pBuffer ++;
|
|
|
|
|
|
|
|
*pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400 * 2] -
|
|
|
|
ps->Shade.DarkOffset.Colors.Blue;
|
|
|
|
dacP98GainResize( pBuffer,
|
|
|
|
ps->Shade.pCcdDac->GainResize.Colors.Blue );
|
|
|
|
pBuffer ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
for (dw = 0; dw < 5400; dw++) {
|
|
|
|
|
|
|
|
DataType Data;
|
|
|
|
Byte bTemp;
|
|
|
|
|
|
|
|
*pBuffer = ((pUShort)ps->pScanBuffer1)[dw + 5400] -
|
|
|
|
ps->Shade.DarkOffset.Colors.Green;
|
|
|
|
|
|
|
|
Data.wValue = (*pBuffer) * 16;
|
|
|
|
bTemp = Data.wOverlap.b1st;
|
|
|
|
Data.wOverlap.b1st = Data.wOverlap.b2nd;
|
|
|
|
Data.wOverlap.b2nd = bTemp;
|
|
|
|
*pBuffer = Data.wValue;
|
|
|
|
pBuffer++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
dacP98DownloadShadingTable( ps, ps->pScanBuffer2, (5400 * 2 * 3));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98ShadingRunLoop( pScanData ps )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
DataPointer p;
|
|
|
|
|
|
|
|
p.pb = ps->a_nbNewAdrPointer;
|
|
|
|
|
|
|
|
switch( ps->IO.portMode ) {
|
|
|
|
case _PORT_SPP:
|
|
|
|
case _PORT_BIDI:
|
|
|
|
*p.pw++ = 0;
|
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
*p.pdw++ = 0x00800700;
|
|
|
|
*p.pw = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
*p.pb++ = 0;
|
|
|
|
for (i = 0; i < 15; i++)
|
|
|
|
*p.pw++ = 0xf888;
|
|
|
|
*p.pb = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IOSetToMotorRegister( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98Adjust12BitShading( pScanData ps )
|
|
|
|
{
|
|
|
|
DataPointer pd, pt;
|
|
|
|
ULong dw, dw1, dwLoop;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98Adjust12BitShading()\n" );
|
|
|
|
|
|
|
|
memset( ps->pScanBuffer1, 0, (5400 * 4 * 3));
|
|
|
|
|
|
|
|
if( ps->Shade.pHilight && (_Shading_32Times == ps->bShadingTimeFlag)) {
|
|
|
|
|
|
|
|
memset( ps->Shade.pHilight, 0, (ps->dwHilight * 2UL));
|
|
|
|
|
|
|
|
for (dw = 0; dw < ps->dwShadow; dw++)
|
|
|
|
ps->pwShadow[dw] = 0xfff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* in the original code this function does not exist !
|
|
|
|
* (of course the code behind the function does ;-)
|
|
|
|
*/
|
|
|
|
dacP98SetAdjustShadingRegister( ps );
|
|
|
|
|
|
|
|
dacP98ShadingRunLoop( ps );
|
|
|
|
_DODELAY( 24 );
|
|
|
|
|
|
|
|
if ((ps->DataInf.dwScanFlag & SCANDEF_TPA ) ||
|
|
|
|
(_Shading_32Times == ps->bShadingTimeFlag)) {
|
|
|
|
dwLoop = 32;
|
|
|
|
} else {
|
|
|
|
if (_Shading_16Times == ps->bShadingTimeFlag) {
|
|
|
|
dwLoop = 16;
|
|
|
|
} else {
|
|
|
|
dwLoop = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (dw1 = 0; dw1 < dwLoop; dw1++) {
|
|
|
|
|
|
|
|
ps->Scan.bFifoSelect = ps->RegGFifoOffset;
|
|
|
|
|
|
|
|
dacP98ReadShadingScanLine( ps );
|
|
|
|
|
|
|
|
if((_Shading_32Times == ps->bShadingTimeFlag) && ps->Shade.pHilight ) {
|
|
|
|
|
|
|
|
dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2, 0, 0 );
|
|
|
|
dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2 +
|
|
|
|
ps->dwShadingPixels,
|
|
|
|
ps->dwHilightCh, ps->dwShadowCh );
|
|
|
|
|
|
|
|
dacP98SortHilightShadow( ps, (pUShort)ps->pScanBuffer2 +
|
|
|
|
ps->dwShadingPixels * 2,
|
|
|
|
ps->dwHilightCh * 2, ps->dwShadowCh * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SumAdd12BitShadingR */
|
|
|
|
pd.pw = (pUShort)ps->pScanBuffer2;
|
|
|
|
pt.pdw = (pULong)(ps->pScanBuffer1 + dwADCPipeLine);
|
|
|
|
|
|
|
|
for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
|
|
|
|
*pt.pdw += (ULong)(*pd.pw & 0x0fff);
|
|
|
|
|
|
|
|
/* SumAdd10BitShadingG */
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut )
|
|
|
|
pd.pw = (pUShort)(ps->pScanBuffer2 + 2700 * 2);
|
|
|
|
else
|
|
|
|
pd.pw = (pUShort)(ps->pScanBuffer2 + 5400 * 2);
|
|
|
|
|
|
|
|
pt.pdw = (pULong)(ps->pScanBuffer1 + 5400 * 4 + dwADCPipeLine);
|
|
|
|
|
|
|
|
for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
|
|
|
|
*pt.pdw += (ULong)(*pd.pw & 0x0fff);
|
|
|
|
|
|
|
|
/* SumAdd12BitShadingB */
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut )
|
|
|
|
pd.pw = (pUShort)(ps->pScanBuffer2 + 2700 * 4);
|
|
|
|
else
|
|
|
|
pd.pw = (pUShort)(ps->pScanBuffer2 + 5400 * 4);
|
|
|
|
|
|
|
|
pt.pdw = (pULong)(ps->pScanBuffer1 + 5400 * 8 + dwADCPipeLine);
|
|
|
|
|
|
|
|
for (dw = 5400 - 4; dw; dw--, pd.pw++, pt.pdw++)
|
|
|
|
*pt.pdw += (ULong)(*pd.pw * 94 / 100 & 0x0fff);
|
|
|
|
|
|
|
|
/* one line */
|
|
|
|
if (IOReadFifoLength( ps ) <= 2500)
|
|
|
|
IORegisterDirectToScanner( ps, ps->RegRefreshScanState );
|
|
|
|
}
|
|
|
|
|
|
|
|
TPAP98001AverageShadingData( ps );
|
|
|
|
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
dacP98WriteBackToShadingRAM( ps );
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP98WaitForShading( pScanData ps )
|
|
|
|
{
|
|
|
|
Byte oldLineControl;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98WaitForShading()\n" );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* before getting the shading data, (re)init the ASIC
|
|
|
|
*/
|
|
|
|
ps->InitialSetCurrentSpeed( ps );
|
|
|
|
ps->ReInitAsic( ps, _TRUE );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegLineControl,
|
|
|
|
ps->AsicReg.RD_LineControl );
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Red = 0;
|
|
|
|
ps->Shade.DarkOffset.Colors.Green = 0;
|
|
|
|
ps->Shade.DarkOffset.Colors.Blue = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* according to the scan mode, switch on the lamp
|
|
|
|
*/
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
|
|
|
|
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi300;
|
|
|
|
} else {
|
|
|
|
ps->AsicReg.RD_ModelControl = _LED_CONTROL + _ModelDpi600;
|
|
|
|
}
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegModelControl,
|
|
|
|
ps->AsicReg.RD_ModelControl );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegModeControl, _ModeScan);
|
|
|
|
|
|
|
|
oldLineControl = ps->AsicReg.RD_LineControl;
|
|
|
|
IOSetXStepLineScanTime( ps, _DEFAULT_LINESCANTIME );
|
|
|
|
|
|
|
|
/* set line control */
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegLineControl,
|
|
|
|
ps->AsicReg.RD_LineControl );
|
|
|
|
|
|
|
|
/* Wait for Sensor to position */
|
|
|
|
if( !ps->GotoShadingPosition( ps ))
|
|
|
|
return _FALSE;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_LineControl = oldLineControl;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegLineControl,
|
|
|
|
ps->AsicReg.RD_LineControl );
|
|
|
|
|
|
|
|
dwADCPipeLine = 4 * 4;
|
|
|
|
|
|
|
|
if( ps->bSetScanModeFlag & _ScanMode_AverageOut ) {
|
|
|
|
dwReadyLen = 2500;
|
|
|
|
ps->dwShadingLen = 2700 * 2;
|
|
|
|
ps->dwShadingPixels = 2700;
|
|
|
|
} else {
|
|
|
|
dwReadyLen = 5000;
|
|
|
|
ps->dwShadingLen = 5400 * 2;
|
|
|
|
ps->dwShadingPixels = 5400;
|
|
|
|
}
|
|
|
|
|
|
|
|
dacP98AdjustRGBGain ( ps );
|
|
|
|
DacP98AdjustDark ( ps );
|
|
|
|
dacP98Adjust12BitShading( ps );
|
|
|
|
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
DacP98FillShadingDarkToShadingRegister( ps );
|
|
|
|
|
|
|
|
if ( COLOR_BW != ps->DataInf.wPhyDataType )
|
|
|
|
dacP98DownloadMapTable( ps, ps->a_bMapTable );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
return _TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set RAM bank and size, then write the data to it
|
|
|
|
*/
|
|
|
|
static void dacP96FillWhole4kRAM( pScanData ps, pUChar pBuf )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegMemAccessControl,
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeProgram;
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
|
|
|
|
|
|
|
|
IOMoveDataToScanner( ps, pBuf, ps->ShadingBankSize );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96FillChannelDarkOffset( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegRedChDarkOffset,
|
|
|
|
ps->Asic96Reg.RD_RedChDarkOff );
|
|
|
|
IODataToRegister( ps, ps->RegGreenChDarkOffset,
|
|
|
|
ps->Asic96Reg.RD_GreenChDarkOff );
|
|
|
|
IODataToRegister( ps, ps->RegBlueChDarkOffset,
|
|
|
|
ps->Asic96Reg.RD_BlueChDarkOff );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96FillEvenOddControl( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegRedChEvenOffset,
|
|
|
|
ps->Asic96Reg.RD_RedChEvenOff );
|
|
|
|
IODataToRegister( ps, ps->RegGreenChEvenOffset,
|
|
|
|
ps->Asic96Reg.RD_GreenChEvenOff );
|
|
|
|
IODataToRegister( ps, ps->RegBlueChEvenOffset,
|
|
|
|
ps->Asic96Reg.RD_BlueChEvenOff );
|
|
|
|
IODataToRegister( ps, ps->RegRedChOddOffset,
|
|
|
|
ps->Asic96Reg.RD_RedChOddOff );
|
|
|
|
IODataToRegister( ps, ps->RegGreenChOddOffset,
|
|
|
|
ps->Asic96Reg.RD_GreenChOddOff );
|
|
|
|
IODataToRegister( ps, ps->RegBlueChOddOffset,
|
|
|
|
ps->Asic96Reg.RD_BlueChOddOff );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Used for capture data to pScanData->pPrescan16.
|
|
|
|
* Used to replace:
|
|
|
|
* 1) ReadFBKScanLine (3 * 1024, 5)
|
|
|
|
* 2) ReadOneScanLine (3 * 2560, 11)
|
|
|
|
* 4) ReadShadingScanLine (3 * 1280, 6)
|
|
|
|
*/
|
|
|
|
static void dacP96ReadDataWithinOneSecond( pScanData ps,
|
|
|
|
ULong dwLen, Byte bBlks )
|
|
|
|
{
|
|
|
|
TimerDef timer;
|
|
|
|
|
|
|
|
MiscStartTimer( &timer, _SECOND );
|
|
|
|
|
|
|
|
while((IODataRegisterFromScanner( ps, ps->RegFifoOffset) < bBlks) &&
|
|
|
|
!MiscCheckTimer(&timer));
|
|
|
|
|
|
|
|
IOReadScannerImageData( ps, ps->pPrescan16, dwLen );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96GetEvenOddOffset( pUChar pb, pWordVal pwv )
|
|
|
|
{
|
|
|
|
ULong dw;
|
|
|
|
UShort we, wo;
|
|
|
|
|
|
|
|
for (dw = 8, we = wo = 0; dw; dw-- ) {
|
|
|
|
we += *pb++;
|
|
|
|
wo += *pb++;
|
|
|
|
}
|
|
|
|
|
|
|
|
pwv->b1st = (Byte)(we >> 3);
|
|
|
|
pwv->b2nd = (Byte)(wo >> 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96SumAverageShading( pScanData ps, pUChar pDest, pUChar pSrce )
|
|
|
|
{
|
|
|
|
ULong dw;
|
|
|
|
UShort wLeft[6];
|
|
|
|
UShort wSumL, wSumR;
|
|
|
|
|
|
|
|
pSrce += ps->Offset70 + ps->Device.DataOriginX;
|
|
|
|
pDest += ps->Offset70 + ps->Device.DataOriginX;
|
|
|
|
|
|
|
|
wLeft[0] = wLeft[1] = wLeft[2] =
|
|
|
|
wLeft[3] = wLeft[4] = wLeft[5] = (UShort)*pSrce;
|
|
|
|
|
|
|
|
wSumL = wLeft[0] * 6;
|
|
|
|
wSumR = (UShort)pSrce[1] + pSrce[2] + pSrce[3] + pSrce[4] +
|
|
|
|
pSrce[5] + pSrce[6];
|
|
|
|
|
|
|
|
/* for (dw = 2772; dw; dw--, pSrce++, pDest++) */
|
|
|
|
for (dw = ps->BufferSizePerModel - 6; dw; dw--, pSrce++, pDest++) {
|
|
|
|
|
|
|
|
*pDest = (Byte)(((UShort)*pSrce * 4 + wSumL + wSumR) / 16);
|
|
|
|
wSumL = wSumL - wLeft [0] + (UShort)*pSrce;
|
|
|
|
|
|
|
|
wLeft[0] = wLeft[1];
|
|
|
|
wLeft[1] = wLeft[2];
|
|
|
|
wLeft[2] = wLeft[3];
|
|
|
|
wLeft[3] = wLeft[4];
|
|
|
|
wLeft[4] = wLeft[5];
|
|
|
|
wLeft[5] = (UShort)*pSrce;
|
|
|
|
wSumR = wSumR - (UShort) *(pSrce + 1) + (UShort) *(pSrce + 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96WriteLinearGamma( pScanData ps,
|
|
|
|
pUChar pBuf, ULong dwEntries, Byte bBank )
|
|
|
|
{
|
|
|
|
ULong dw;
|
|
|
|
pULong pdw = (pULong)(pBuf + ps->ShadingBufferSize);
|
|
|
|
|
|
|
|
for (dw = 0; dwEntries; pdw++, dwEntries--, dw += 0x01010101)
|
|
|
|
*pdw = dw;
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = bBank;
|
|
|
|
|
|
|
|
dacP96FillWhole4kRAM( ps, pBuf );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96FillChannelShadingOffset( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegRedChShadingOffset,
|
|
|
|
ps->Asic96Reg.u28.RD_RedChShadingOff);
|
|
|
|
IODataToRegister( ps, ps->RegGreenChShadingOffset,
|
|
|
|
ps->Asic96Reg.u29.RD_GreenChShadingOff);
|
|
|
|
IODataToRegister( ps, ps->RegBlueChShadingOffset,
|
|
|
|
ps->Asic96Reg.RD_BlueChShadingOff);
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96GetHilightShadow( pScanData ps,
|
|
|
|
pUChar pBuf, pUChar pChOff, pUChar pHigh )
|
|
|
|
{
|
|
|
|
ULong dw;
|
|
|
|
|
|
|
|
/* GetShadingImageExtent (ps) */
|
|
|
|
if (ps->DataInf.wAppDataType < COLOR_256GRAY)
|
|
|
|
dw = (ULong)(ps->DataInf.crImage.cx & 0xfff8);
|
|
|
|
else
|
|
|
|
dw = (ULong)ps->DataInf.crImage.cx;
|
|
|
|
|
|
|
|
for( pBuf += ps->DataInf.crImage.x, *pChOff = 0xff, *pHigh = 0;
|
|
|
|
dw; dw--, pBuf++ ) {
|
|
|
|
|
|
|
|
if (*pChOff < *pBuf) {
|
|
|
|
if (*pHigh < *pBuf)
|
|
|
|
*pHigh = *pBuf; /* brightest */
|
|
|
|
} else
|
|
|
|
*pChOff = *pBuf; /* darkest */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96ReadColorShadingLine( pScanData ps )
|
|
|
|
{
|
|
|
|
Byte b2ndDiscard, b3rdDiscard, b1stReadLines, b2ndReadLines;
|
|
|
|
Byte b3rdReadLines;
|
|
|
|
ULong dw;
|
|
|
|
DataType Data;
|
|
|
|
|
|
|
|
/* ClearScanBuffer1 (ps) */
|
|
|
|
/* buffer to keep sum of data */
|
|
|
|
memset( ps->pScanBuffer1, 0, ps->BufferForDataRead1 );
|
|
|
|
|
|
|
|
b2ndDiscard = ps->b2ndLinesOffset;
|
|
|
|
b3rdDiscard = ps->b1stLinesOffset;
|
|
|
|
b1stReadLines = b2ndReadLines = b3rdReadLines = 8;
|
|
|
|
|
|
|
|
while( _TRUE ) {
|
|
|
|
|
|
|
|
/* ReadShadingScanLine(ps) */
|
|
|
|
dacP96ReadDataWithinOneSecond( ps, ps->ShadingScanLineLen,
|
|
|
|
ps->ShadingScanLineBlks );
|
|
|
|
|
|
|
|
if (b1stReadLines) {
|
|
|
|
|
|
|
|
b1stReadLines--;
|
|
|
|
|
|
|
|
/* SumAdd10BitShadingR */
|
|
|
|
for (dw = 0; dw < ps->BufferSizeBase; dw++)
|
|
|
|
((pUShort)ps->pScanBuffer1)[dw] += (UShort)ps->pPrescan16 [dw];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!b2ndDiscard) {
|
|
|
|
if (b2ndReadLines) {
|
|
|
|
b2ndReadLines--;
|
|
|
|
/* SumAdd10BitShadingG */
|
|
|
|
for (dw = ps->BufferSizeBase;dw < (ULong)ps->BufferSizeBase * 2;dw++) {
|
|
|
|
((pUShort)ps->pScanBuffer1)[dw] +=
|
|
|
|
(UShort)ps->pPrescan16[dw];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
b2ndDiscard--;
|
|
|
|
|
|
|
|
if (!b3rdDiscard) {
|
|
|
|
if (b3rdReadLines) {
|
|
|
|
b3rdReadLines--;
|
|
|
|
/* SumAdd10BitShadingB */
|
|
|
|
for (dw = ps->BufferSizeBase * 2;
|
|
|
|
dw < (ULong)ps->BufferSizeBase * 3; dw++) {
|
|
|
|
((pUShort)ps->pScanBuffer1)[dw] +=
|
|
|
|
(UShort)ps->pPrescan16[dw];
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
b3rdDiscard--;
|
|
|
|
|
|
|
|
IORegisterDirectToScanner( ps, ps->RegRefreshScanState );
|
|
|
|
}
|
|
|
|
|
|
|
|
for (dw = 0; dw < (ULong)ps->BufferSizeBase * 3; dw++) {
|
|
|
|
|
|
|
|
Data.wOverlap.b1st =
|
|
|
|
Data.wOverlap.b2nd = (Byte)(((pUShort)ps->pScanBuffer1)[dw] / 8);
|
|
|
|
((pUShort)ps->pPrescan16)[dw] = Data.wValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96SetShadingGainProc( pScanData ps, Byte bHigh, ULong dwCh )
|
|
|
|
{
|
|
|
|
Byte bDark, bGain, bGainX2, bGainX4, bMask;
|
|
|
|
pUChar pbChDark, pbSrce, pbDest;
|
|
|
|
ULong dw;
|
|
|
|
|
|
|
|
pbChDark = NULL, pbSrce = NULL, pbDest = NULL;
|
|
|
|
bDark = 0, bGain = 0, bGainX2 = 0, bGainX4 = 0, bMask = 0;
|
|
|
|
|
|
|
|
switch( dwCh ) {
|
|
|
|
|
|
|
|
case 0: /* red */
|
|
|
|
pbChDark = &ps->Asic96Reg.u28.RD_RedChShadingOff;
|
|
|
|
pbSrce = ps->pPrescan16;
|
|
|
|
pbDest = ps->pScanBuffer1 + ps->Offset70 + ps->Device.DataOriginX;
|
|
|
|
bGainX2 = 1;
|
|
|
|
bGainX4 = 3;
|
|
|
|
bMask = 0x3c;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* green */
|
|
|
|
pbChDark = &ps->Asic96Reg.u29.RD_GreenChShadingOff;
|
|
|
|
pbSrce = ps->pPrescan16 + ps->BufferSizePerModel;
|
|
|
|
pbDest = ps->pScanBuffer1 + ps->Offset70 + ps->ShadingBankSize +
|
|
|
|
ps->Device.DataOriginX;
|
|
|
|
bGainX2 = 4;
|
|
|
|
bGainX4 = 0x0c;
|
|
|
|
bMask = 0x33;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
pbChDark = &ps->Asic96Reg.RD_BlueChShadingOff;
|
|
|
|
pbSrce = ps->pPrescan16 + ps->BufferSizePerModel * 2;
|
|
|
|
pbDest = ps->pScanBuffer1 + ps->Offset70 + ps->ShadingBankSize * 2 +
|
|
|
|
ps->Device.DataOriginX;
|
|
|
|
bGainX2 = 0x10;
|
|
|
|
bGainX4 = 0x30;
|
|
|
|
bMask = 0x0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
bDark = *pbChDark;
|
|
|
|
if ((bHigh -= bDark) > 60U) {
|
|
|
|
/* Hilight - Shadow > 60, Quality not so good */
|
|
|
|
bGain = bGainX2; /* Gain x 2 */
|
|
|
|
if (bHigh > 120U)
|
|
|
|
bGain = bGainX4; /* Poor quality, Gain x 4 */
|
|
|
|
} else
|
|
|
|
bGain = 0;
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl &= bMask;
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl |= bGain;
|
|
|
|
|
|
|
|
if (!bGain) {
|
|
|
|
/* GammaGain1 (ps) */
|
|
|
|
for (dw = ps->BufferSizePerModel; dw; dw--, pbSrce++, pbDest++)
|
|
|
|
if (*pbSrce > bDark)
|
|
|
|
*pbDest = (*pbSrce - bDark) * 4;
|
|
|
|
else
|
|
|
|
*pbDest = 0;
|
|
|
|
} else
|
|
|
|
if (bGain == bGainX2) {
|
|
|
|
/* GammaGain2 */
|
|
|
|
for (dw = ps->BufferSizePerModel; dw; dw--, pbSrce++, pbDest++)
|
|
|
|
if (*pbSrce > bDark)
|
|
|
|
*pbDest = (*pbSrce - bDark) * 2;
|
|
|
|
else
|
|
|
|
*pbDest = 0;
|
|
|
|
} else {
|
|
|
|
/* GammaGain4 (ps) */
|
|
|
|
memcpy( pbDest, pbSrce, ps->BufferSizePerModel );
|
|
|
|
*pbChDark = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96FillShadingAndGammaTable( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankRed; /* R */
|
|
|
|
dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankGreen; /* G */
|
|
|
|
dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = ps->ShadingBankBlue; /* B */
|
|
|
|
dacP96FillWhole4kRAM( ps, ps->pPrescan16 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96SetInitialGainRAM( pScanData ps )
|
|
|
|
{
|
|
|
|
ULong dw, dw1;
|
|
|
|
pULong pdw = (pULong)(ps->pPrescan16 + ps->ShadingBufferSize);
|
|
|
|
|
|
|
|
memset( ps->pPrescan16, 0xff, ps->ShadingBufferSize );
|
|
|
|
|
|
|
|
for (dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101, pdw++)
|
|
|
|
*pdw = dw1;
|
|
|
|
|
|
|
|
dacP96FillShadingAndGammaTable( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96Adjust10BitShading( pScanData ps )
|
|
|
|
{
|
|
|
|
pULong pdw;
|
|
|
|
ULong dw;
|
|
|
|
Byte bRedHigh, bGreenHigh, bBlueHigh;
|
|
|
|
|
|
|
|
/* ShadingMotorRunLoop(ps)
|
|
|
|
* set scan states as:
|
|
|
|
* 40h, 00, 00, 00, 40h, 01, 03, 02, ... (repeat)
|
|
|
|
* so, read a R/G/B line every 2 steps
|
|
|
|
*/
|
|
|
|
pdw = (pULong)ps->a_nbNewAdrPointer;
|
|
|
|
for (dw = 0; dw < 4; dw++) {
|
|
|
|
*pdw++ = 0x40;
|
|
|
|
*pdw++ = 0x02030140;
|
|
|
|
}
|
|
|
|
|
|
|
|
dacP96SetInitialGainRAM( ps); /* initiates the shading buffers and maps */
|
|
|
|
|
|
|
|
/* SetAdjustShadingRegister(ps) */
|
|
|
|
/* Prepare Physical/2 dpi, 8.5" scanning condition for reading the shading area */
|
|
|
|
ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->IgnorePF | ps->MotorOn |
|
|
|
|
_MotorDirForward;
|
|
|
|
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
|
|
|
|
ps->AsicReg.RD_Dpi = ps->PhysicalDpi / 2;
|
|
|
|
ps->AsicReg.RD_Origin = (UShort)(ps->Offset70 +
|
|
|
|
ps->Device.DataOriginX);
|
|
|
|
ps->AsicReg.RD_Pixels = ps->BufferSizeBase;
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl = _ShadingRCorrectX4|_ShadingGCorrectX4|
|
|
|
|
_ShadingBCorrectX4;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegShadingCorrectCtrl,
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl );
|
|
|
|
|
|
|
|
/* Read shaded data and do average */
|
|
|
|
dacP96ReadColorShadingLine( ps );
|
|
|
|
|
|
|
|
/* ExpandAndAverage (ps) ------------------------------------------------*/
|
|
|
|
/*
|
|
|
|
for (dw = 0; dw < 1280 * 3; dw++)
|
|
|
|
{
|
|
|
|
Data.wOverlap.b1st =
|
|
|
|
Data.wOverlap.b2nd = (Byte)(((pUShort) ps->pScanBuffer1)[dw] / 8);
|
|
|
|
((pULong) ps->pPrescan16)[dw] = Data.wValue;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/* CalculateShadingOffset (ps); */
|
|
|
|
dacP96GetHilightShadow( ps, ps->pPrescan16,
|
|
|
|
&ps->Asic96Reg.u28.RD_RedChShadingOff, &bRedHigh );
|
|
|
|
|
|
|
|
dacP96GetHilightShadow( ps, ps->pPrescan16 + ps->BufferSizePerModel,
|
|
|
|
&ps->Asic96Reg.u29.RD_GreenChShadingOff, &bGreenHigh );
|
|
|
|
|
|
|
|
dacP96GetHilightShadow( ps, ps->pPrescan16 + ps->BufferSizePerModel * 2,
|
|
|
|
&ps->Asic96Reg.RD_BlueChShadingOff, &bBlueHigh );
|
|
|
|
|
|
|
|
/* SubTheImageDataBase (ps) */
|
|
|
|
dacP96SetShadingGainProc( ps, bRedHigh, 0 ); /* red */
|
|
|
|
dacP96SetShadingGainProc( ps, bGreenHigh, 1 ); /* green */
|
|
|
|
dacP96SetShadingGainProc( ps, bBlueHigh, 2 ); /* blue */
|
|
|
|
dacP96FillChannelShadingOffset( ps );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegShadingCorrectCtrl,
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl );
|
|
|
|
|
|
|
|
dacP96SumAverageShading( ps, ps->pPrescan16, ps->pScanBuffer1 );
|
|
|
|
dacP96SumAverageShading( ps, ps->pPrescan16 + ps->ShadingBankSize,
|
|
|
|
ps->pScanBuffer1 + ps->ShadingBankSize );
|
|
|
|
dacP96SumAverageShading( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
|
|
|
|
ps->pScanBuffer1 + ps->ShadingBankSize * 2 );
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/* PrewriteBackToGammaShadingRAM( ps) */
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16, 256, ps->ShadingBankRed );
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize, 256,
|
|
|
|
ps->ShadingBankGreen );
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
|
|
|
|
256, ps->ShadingBankBlue );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP96003WaitForShading( pScanData ps )
|
|
|
|
{
|
|
|
|
int bCorrectTimes;
|
|
|
|
DataPointer p;
|
|
|
|
ULong dw;
|
|
|
|
UShort w;
|
|
|
|
WordVal wv;
|
|
|
|
pUChar pbReg[3];
|
|
|
|
Byte b[3];
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP96003WaitForShading()\n" );
|
|
|
|
|
|
|
|
/* TurnOnLamp () */
|
|
|
|
ps->AsicReg.RD_ScanControl |= ps->bLampOn;
|
|
|
|
IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_LedControl = _LedActControl | _LedMotorActEnable;
|
|
|
|
IOCmdRegisterToScanner(ps, ps->RegLedControl, ps->Asic96Reg.RD_LedControl);
|
|
|
|
|
|
|
|
if ( ps->GotoShadingPosition( ps )) {
|
|
|
|
|
|
|
|
/* AdjustRGBGain () =================================================*/
|
|
|
|
ps->Asic96Reg.RD_RedGainOut = ps->Asic96Reg.RD_GreenGainOut =
|
|
|
|
ps->Asic96Reg.RD_BlueGainOut = 8;
|
|
|
|
ps->Asic96Reg.u26.RD_ModelControl2 = _Model2DirectOutPort;
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner(ps, ps->RegModelControl2, _Model2DirectOutPort);
|
|
|
|
|
|
|
|
for ( bCorrectTimes = 4; bCorrectTimes >= 1; bCorrectTimes-- ) {
|
|
|
|
|
|
|
|
ps->PauseColorMotorRunStates( ps );
|
|
|
|
|
|
|
|
/* SetRGBGainRegister () ----------------------------------------*/
|
|
|
|
ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
|
|
|
|
dacP96SetInitialGainRAM( ps );
|
|
|
|
|
|
|
|
/* SetInitialGainRegister () ++++++++++++++++++++++++++++++++++++*/
|
|
|
|
ps->Asic96Reg.u28.RD_RedChShadingOff =
|
|
|
|
ps->Asic96Reg.u29.RD_GreenChShadingOff =
|
|
|
|
ps->Asic96Reg.RD_BlueChShadingOff =
|
|
|
|
ps->Asic96Reg.RD_RedChDarkOff =
|
|
|
|
ps->Asic96Reg.RD_GreenChDarkOff =
|
|
|
|
ps->Asic96Reg.RD_BlueChDarkOff =
|
|
|
|
ps->Asic96Reg.RD_RedChEvenOff =
|
|
|
|
ps->Asic96Reg.RD_GreenChEvenOff =
|
|
|
|
ps->Asic96Reg.RD_BlueChEvenOff =
|
|
|
|
ps->Asic96Reg.RD_RedChOddOff =
|
|
|
|
ps->Asic96Reg.RD_GreenChOddOff =
|
|
|
|
ps->Asic96Reg.RD_BlueChOddOff = 0;
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl = _ShadingRCorrectX4 |
|
|
|
|
_ShadingGCorrectX4 |
|
|
|
|
_ShadingBCorrectX4;
|
|
|
|
|
|
|
|
dacP96FillChannelShadingOffset( ps );
|
|
|
|
dacP96FillChannelDarkOffset( ps );
|
|
|
|
dacP96FillEvenOddControl( ps );
|
|
|
|
|
|
|
|
/* FillGainOutDirectPort (); */
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
IODataToRegister( ps, ps->RegRedGainOutDirect,
|
|
|
|
ps->Asic96Reg.RD_RedGainOut );
|
|
|
|
IODataToRegister( ps, ps->RegGreenGainOutDirect,
|
|
|
|
ps->Asic96Reg.RD_GreenGainOut );
|
|
|
|
IODataToRegister( ps, ps->RegBlueGainOutDirect,
|
|
|
|
ps->Asic96Reg.RD_BlueGainOut );
|
|
|
|
|
|
|
|
/* FillGainInitialRestRegister (); */
|
|
|
|
IODataToRegister( ps, ps->RegModelControl2,
|
|
|
|
ps->Asic96Reg.u26.RD_ModelControl2 );
|
|
|
|
IODataToRegister( ps, ps->RegThresholdGapControl,
|
|
|
|
ps->AsicReg.RD_ThresholdGapCtrl );
|
|
|
|
IODataToRegister( ps, ps->RegLedControl,
|
|
|
|
ps->Asic96Reg.RD_LedControl );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegShadingCorrectCtrl,
|
|
|
|
ps->Asic96Reg.RD_ShadingCorrectCtrl );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MotorControl = 0;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
|
|
|
|
ps->Asic96Reg.RD_MotorControl = (ps->IgnorePF |
|
|
|
|
ps->MotorOn | _MotorDirForward);
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Origin = 142;
|
|
|
|
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
|
|
|
|
ps->AsicReg.RD_Dpi = ps->PhysicalDpi;
|
|
|
|
ps->AsicReg.RD_Pixels = ps->BufferSizePerModel;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* ReadOneScanLine (); */
|
|
|
|
dacP96ReadDataWithinOneSecond( ps, ps->OneScanLineLen, 11 );
|
|
|
|
|
|
|
|
/* AdjustGain () */
|
|
|
|
/* FindTheMaxGain (), AdjustGainOutData (); */
|
|
|
|
|
|
|
|
pbReg[0] = &ps->Asic96Reg.RD_RedGainOut;
|
|
|
|
pbReg[1] = &ps->Asic96Reg.RD_GreenGainOut;
|
|
|
|
pbReg[2] = &ps->Asic96Reg.RD_BlueGainOut;
|
|
|
|
|
|
|
|
for (w = 0, p.pb = ps->pPrescan16; w < 3; w++) {
|
|
|
|
/* CHANGE: org was: for (dw = 2560, b[w] = 0; dw; dw--, p.pb++) { */
|
|
|
|
for (dw = (ps->OneScanLineLen/3), b[w] = 0; dw; dw--, p.pb++) {
|
|
|
|
|
|
|
|
if (b[w] < *p.pb)
|
|
|
|
b[w] = *p.pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (b[w] < _GAIN_LOW)
|
|
|
|
*(pbReg[w]) += a_bCorrectTimesTable[bCorrectTimes - 1];
|
|
|
|
else
|
|
|
|
if (b[w] > _GAIN_P96_HIGH)
|
|
|
|
*(pbReg[w]) -= a_bCorrectTimesTable[bCorrectTimes - 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===================================================================*/
|
|
|
|
|
|
|
|
/* SonyFBK ()/ToshibaFBK ()====================================*/
|
|
|
|
/*FillRGBDarkLevel0Table (); */
|
|
|
|
memset( ps->pPrescan16, 0xff, ps->ShadingBankSize );
|
|
|
|
|
|
|
|
for( dw = 0, p.pb = ps->pPrescan16 + ps->ShadingBufferSize;
|
|
|
|
dw <=255; dw++, p.pb++ ) {
|
|
|
|
*p.pb = (Byte) dw;
|
|
|
|
}
|
|
|
|
|
|
|
|
dacP96FillShadingAndGammaTable( ps );
|
|
|
|
|
|
|
|
ps->PauseColorMotorRunStates( ps );
|
|
|
|
|
|
|
|
/* SetReadFBKRegister () */
|
|
|
|
ps->Asic96Reg.RD_MotorControl = 0;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->IgnorePF | ps->MotorOn |
|
|
|
|
_MotorDirForward;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Origin = 22;
|
|
|
|
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
|
|
|
|
ps->AsicReg.RD_Dpi = ps->PhysicalDpi;
|
|
|
|
ps->AsicReg.RD_Pixels = ps->FBKScanLineLenBase;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
/* ReadFBKScanLine () */
|
|
|
|
dacP96ReadDataWithinOneSecond( ps, ps->FBKScanLineLen,
|
|
|
|
ps->FBKScanLineBlks );
|
|
|
|
|
|
|
|
/*===================================================================*/
|
|
|
|
if ( ps->fSonyCCD ) {
|
|
|
|
|
|
|
|
/* FillChannelDarkLevelControl (); */
|
|
|
|
for ( p.pb = ps->pPrescan16 + 32, w = 0, dw = 16;
|
|
|
|
dw; dw--, p.pb++) {
|
|
|
|
w += (UShort) *p.pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_RedChDarkOff = (Byte)(w / 16);
|
|
|
|
|
|
|
|
for ( p.pb = ps->pPrescan16 + 32 + ps->FBKScanLineLenBase, w = 0, dw = 16;
|
|
|
|
dw; dw--, p.pb++ ) {
|
|
|
|
w += (UShort)*p.pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_GreenChDarkOff = (Byte)(w / 16);
|
|
|
|
|
|
|
|
for ( p.pb = ps->pPrescan16 + 32 + ps->FBKScanLineLenBase * 2, w = 0, dw = 16;
|
|
|
|
dw; dw--, p.pb++) {
|
|
|
|
w += (UShort)*p.pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_BlueChDarkOff = (Byte)(w / 16);
|
|
|
|
|
|
|
|
dacP96FillChannelDarkOffset( ps );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* FillToshibaDarkLevelControl (); */
|
|
|
|
dacP96GetEvenOddOffset( ps->pPrescan16 + 32, &wv );
|
|
|
|
ps->Asic96Reg.RD_RedChEvenOff = wv.b1st;
|
|
|
|
ps->Asic96Reg.RD_RedChOddOff = wv.b2nd;
|
|
|
|
|
|
|
|
dacP96GetEvenOddOffset( ps->pPrescan16 + 32 + ps->FBKScanLineLenBase, &wv );
|
|
|
|
ps->Asic96Reg.RD_GreenChEvenOff = wv.b1st;
|
|
|
|
ps->Asic96Reg.RD_GreenChOddOff = wv.b2nd;
|
|
|
|
|
|
|
|
dacP96GetEvenOddOffset( ps->pPrescan16 + 32 + ps->FBKScanLineLenBase * 2, &wv );
|
|
|
|
ps->Asic96Reg.RD_BlueChEvenOff = wv.b1st;
|
|
|
|
ps->Asic96Reg.RD_BlueChOddOff = wv.b2nd;
|
|
|
|
|
|
|
|
dacP96FillEvenOddControl( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SetInitialGainRAM (); */
|
|
|
|
dacP96Adjust10BitShading( ps );
|
|
|
|
|
|
|
|
return _TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96001ToSetShadingAddress( pScanData ps, pUChar pData )
|
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegMemAccessControl,
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl);
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeProgram;
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeProgram );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
|
|
|
|
IODataToRegister( ps, ps->RegMotorControl, ps->Asic96Reg.RD_MotorControl);
|
|
|
|
|
|
|
|
memset( ps->pScanBuffer1, 0, (64 + 8 + ps->Offset70));
|
|
|
|
memcpy( ps->pScanBuffer1 + 64 + 8 + ps->Offset70, pData,
|
|
|
|
_BUF_SIZE_BASE_CONST * 2 );
|
|
|
|
|
|
|
|
IOMoveDataToScanner( ps, ps->pScanBuffer1,
|
|
|
|
_BUF_SIZE_BASE_CONST * 2 + 64 + 8 + ps->Offset70 );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeScan );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96001WriteBackToColorShadingRam( pScanData ps )
|
|
|
|
{
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3a);
|
|
|
|
dacP96001ToSetShadingAddress( ps, ps->pPrescan16 );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3e);
|
|
|
|
dacP96001ToSetShadingAddress( ps, ps->pPrescan16 + _BUF_SIZE_BASE_CONST*2);
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MemAccessControl = (_MemBankSize4k96001 | 0x3c);
|
|
|
|
dacP96001ToSetShadingAddress( ps, ps->pPrescan16 + _BUF_SIZE_BASE_CONST*4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP96001ModifyShadingColor( pByte pData, Byte bMul )
|
|
|
|
{
|
|
|
|
UShort w;
|
|
|
|
ULong dw;
|
|
|
|
|
|
|
|
for ( dw = 0; dw < _BUF_SIZE_BASE_CONST * 2; dw++ ) {
|
|
|
|
|
|
|
|
w = (UShort)(Byte)(~pData[dw]) * bMul / 100U;
|
|
|
|
|
|
|
|
if (w >= 255U)
|
|
|
|
pData[dw] = 0;
|
|
|
|
else
|
|
|
|
pData[dw] = (Byte)~w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Byte dacP96001FBKReading( pScanData ps, Byte bValue,
|
|
|
|
Byte bReg, pByte pbSave, Bool bFBKModify )
|
|
|
|
{
|
|
|
|
TimerDef timer;
|
|
|
|
UShort w, wSum;
|
|
|
|
Byte addrSeq[8] = { 0x40, 0x20, 0x10, 0x08, 4, 2, 1, 0 };
|
|
|
|
Byte bTemp, bFBKTemp, bFBKIndex;
|
|
|
|
|
|
|
|
if( bFBKModify ) {
|
|
|
|
bFBKIndex = 3;
|
|
|
|
bFBKTemp = *pbSave;
|
|
|
|
} else {
|
|
|
|
bFBKTemp = 0x80;
|
|
|
|
bFBKIndex = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while( _TRUE ) {
|
|
|
|
|
|
|
|
*pbSave = bFBKTemp;
|
|
|
|
IOCmdRegisterToScanner( ps, bReg, bFBKTemp );
|
|
|
|
|
|
|
|
/* SetColorRunTable (BYTE) */
|
|
|
|
memset( ps->a_nbNewAdrPointer, bValue, _SCANSTATE_BYTES );
|
|
|
|
MotorSetConstantMove( ps, 0 );
|
|
|
|
|
|
|
|
/* SetReadFBK (pScanData) */
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
ps->Asic96Reg.RD_MotorControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE | ps->bLampOn;
|
|
|
|
ps->AsicReg.RD_ModelControl =
|
|
|
|
(_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0 );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Origin = 22;
|
|
|
|
ps->AsicReg.RD_Pixels = 1024;
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MotorControl =
|
|
|
|
(ps->FullStep | ps->MotorOn | _MotorDirForward);
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
ps->Asic96Reg.RD_MotorControl );
|
|
|
|
|
|
|
|
MiscStartTimer( &timer, _SECOND );
|
|
|
|
while((IODataRegisterFromScanner( ps, ps->RegFifoOffset) < 1) &&
|
|
|
|
!MiscCheckTimer( &timer ));
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
|
|
|
|
IOReadScannerImageData( ps, ps->pScanBuffer1, 64 );
|
|
|
|
|
|
|
|
for( w = 26, wSum = 0; w < 42; w++)
|
|
|
|
wSum += ps->pScanBuffer1[w];
|
|
|
|
|
|
|
|
wSum >>= 4;
|
|
|
|
bTemp = addrSeq[bFBKIndex++];
|
|
|
|
|
|
|
|
if( bTemp ) {
|
|
|
|
if( wSum < 0xfe )
|
|
|
|
bFBKTemp += bTemp;
|
|
|
|
else
|
|
|
|
bFBKTemp -= bTemp;
|
|
|
|
} else {
|
|
|
|
return bFBKTemp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP96001WaitForShading( pScanData ps )
|
|
|
|
{
|
|
|
|
Bool bFBKModify;
|
|
|
|
Byte bRSave;
|
|
|
|
Byte bGSave;
|
|
|
|
Byte bBSave;
|
|
|
|
ULong dw;
|
|
|
|
pULong pdw;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP96001WaitForShading()\n" );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl |= ps->bLampOn;
|
|
|
|
IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
|
|
|
|
|
|
|
|
if ( ps->GotoShadingPosition( ps )) {
|
|
|
|
|
|
|
|
_DODELAY( 250 );
|
|
|
|
|
|
|
|
/* AdjustMostWideOffset70 (pScanData) -------------------------------*/
|
|
|
|
/* FillABitGray (pScanData)*/
|
|
|
|
memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
|
|
|
|
ps->a_nbNewAdrPointer[8] =
|
|
|
|
ps->a_nbNewAdrPointer[24] = 0x30;
|
|
|
|
|
|
|
|
MotorSetConstantMove( ps, 32 );
|
|
|
|
|
|
|
|
/* SetMaxWideRegister (pScanData) */
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE | ps->bLampOn;
|
|
|
|
|
|
|
|
ps->Asic96Reg.RD_MotorControl =
|
|
|
|
(ps->MotorOn | ps->IgnorePF | _MotorDirForward);
|
|
|
|
ps->AsicReg.RD_ModelControl =
|
|
|
|
(_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0);
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Origin = 64 + 8;
|
|
|
|
ps->AsicReg.RD_Pixels = 2700;
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
ps->Asic96Reg.RD_MotorControl );
|
|
|
|
|
|
|
|
/* ReadMaxWideLine */
|
|
|
|
dacP96ReadDataWithinOneSecond( ps, 2700, 5 );
|
|
|
|
|
|
|
|
/* AdjustOffset70Proc (pScanData)------------------------------------*/
|
|
|
|
{
|
|
|
|
ULong dwSum, dw, dwLeft, dwCenter;
|
|
|
|
|
|
|
|
/* AverageWideBank (pScanData) */
|
|
|
|
for( dwSum = 0, dw = 0; dw < 2700; dw++ )
|
|
|
|
dwSum += (ULong)ps->pPrescan16[dw];
|
|
|
|
|
|
|
|
dwSum /= 2700UL;
|
|
|
|
|
|
|
|
if( dwSum <= 0x80 ) {
|
|
|
|
|
|
|
|
memcpy( ps->pScanBuffer1, ps->pPrescan16, 140 );
|
|
|
|
memcpy( ps->pScanBuffer1 + 140,
|
|
|
|
ps->pPrescan16 + _BUF_SIZE_BASE_CONST * 2, 140);
|
|
|
|
|
|
|
|
/* BlackOffsetCheck (pScanData) */
|
|
|
|
for( dw = dwLeft = 0; dw < 140; dw++ ) {
|
|
|
|
if( ps->pScanBuffer1[dw] >= 0xe0 )
|
|
|
|
dwLeft++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* WhiteOffsetCheck (pScanData) */
|
|
|
|
for( dw = 140, dwCenter = 0; dw < 280; dw++ ) {
|
|
|
|
if( ps->pScanBuffer1[dw] < 0xe0 )
|
|
|
|
dwCenter++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dwLeft) {
|
|
|
|
ps->Offset70 = (dwLeft + dwCenter) / 2 + 14;
|
|
|
|
} else {
|
|
|
|
if (dwCenter == 140)
|
|
|
|
ps->Offset70 = 70;
|
|
|
|
else
|
|
|
|
ps->Offset70 = dwCenter / 2 + 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
memset( ps->pPrescan16, 0, ps->BufferSizePerModel * 3 );
|
|
|
|
dacP96001WriteBackToColorShadingRam( ps );
|
|
|
|
|
|
|
|
/* SetFBK */
|
|
|
|
if((IODataRegisterFromScanner(ps, ps->RegReadIOBufBus) & 0x0f) == 0x0f)
|
|
|
|
bFBKModify = 0;
|
|
|
|
else
|
|
|
|
bFBKModify = 1;
|
|
|
|
|
|
|
|
dacP96001FBKReading(ps, 0x10, ps->RegRedDCAdjust, &bRSave,bFBKModify);
|
|
|
|
dacP96001FBKReading(ps, 0x30, ps->RegGreenDCAdjust,&bGSave,bFBKModify);
|
|
|
|
dacP96001FBKReading(ps, 0x20, ps->RegBlueDCAdjust, &bBSave,bFBKModify);
|
|
|
|
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
IODataToRegister( ps, ps->RegRedDCAdjust, (Byte)(bRSave + 2));
|
|
|
|
IODataToRegister( ps, ps->RegGreenDCAdjust, (Byte)(bGSave + 2));
|
|
|
|
IODataToRegister( ps, ps->RegBlueDCAdjust, bBSave);
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
/* Turn off and then turn on motor */
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
(Byte)(ps->Asic96Reg.RD_MotorControl & ~ps->MotorOn));
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
ps->Asic96Reg.RD_MotorControl );
|
|
|
|
|
|
|
|
/* FillABitColor (pScanData) */
|
|
|
|
pdw = (pULong)ps->a_nbNewAdrPointer;
|
|
|
|
for( dw = 0; dw < 4; dw++) {
|
|
|
|
*pdw++ = 0x40;
|
|
|
|
*pdw++ = 0x2030140;
|
|
|
|
}
|
|
|
|
|
|
|
|
IOSetToMotorRegister( ps );
|
|
|
|
|
|
|
|
/* SetShadingRegister (pScanData) */
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
ps->Asic96Reg.RD_MotorControl );
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_LineControl = ps->TimePerLine;
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE | ps->bLampOn;
|
|
|
|
ps->Asic96Reg.RD_MotorControl = ps->FullStep | _MotorDirForward;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModelControl =
|
|
|
|
(_ModelMemSize32k96001 | _ModelDpi300 | _ModelWhiteIs0);
|
|
|
|
ps->AsicReg.RD_Dpi = 150;
|
|
|
|
ps->AsicReg.RD_Origin = (UShort)(64 + 8 + ps->Offset70);
|
|
|
|
ps->AsicReg.RD_Pixels = ps->BufferSizeBase;
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
IOCmdRegisterToScanner( ps, ps->RegMotorControl,
|
|
|
|
(Byte)(ps->MotorOn | ps->IgnorePF | _MotorDirForward));
|
|
|
|
|
|
|
|
dacP96ReadColorShadingLine( ps );
|
|
|
|
|
|
|
|
/* ModifyShadingColor (pScanData) */
|
|
|
|
dacP96001ModifyShadingColor( ps->pPrescan16, 103 );
|
|
|
|
dacP96001ModifyShadingColor( ps->pPrescan16 +
|
|
|
|
_BUF_SIZE_BASE_CONST * 2 * 2, 97);
|
|
|
|
dacP96001WriteBackToColorShadingRam( ps );
|
|
|
|
return _TRUE;
|
|
|
|
}
|
|
|
|
return _FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98003GainOffsetToDAC( pScanData ps, Byte ch, Byte reg, Byte d )
|
|
|
|
{
|
|
|
|
if( ps->Device.bDACType == _DA_SAMSUNG8531 ) {
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegADCAddress, 0 );
|
|
|
|
IODataToRegister( ps, ps->RegADCData, ch );
|
|
|
|
IODataToRegister( ps, ps->RegADCSerialOutStr, ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegADCAddress, reg );
|
|
|
|
IODataToRegister( ps, ps->RegADCData, d );
|
|
|
|
IODataToRegister( ps, ps->RegADCSerialOutStr, d );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98003AdjustRGBGain( pScanData ps )
|
|
|
|
{
|
|
|
|
ULong i;
|
|
|
|
Byte bHi[3];
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98003AdjustRGBGain()\n" );
|
|
|
|
|
|
|
|
ps->Shade.Gain.Colors.Red =
|
|
|
|
ps->Shade.Gain.Colors.Green =
|
|
|
|
ps->Shade.Gain.Colors.Blue = ps->Shade.bUniGain;
|
|
|
|
|
|
|
|
ps->Shade.Hilight.Colors.Red =
|
|
|
|
ps->Shade.Hilight.Colors.Green =
|
|
|
|
ps->Shade.Hilight.Colors.Blue = 0;
|
|
|
|
|
|
|
|
ps->Shade.bGainHigh = _GAIN_P98003_HIGH;
|
|
|
|
ps->Shade.bGainLow = _GAIN_P98003_LOW;
|
|
|
|
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
|
|
|
|
for( i = 10; i-- && !ps->Shade.fStop; ) {
|
|
|
|
|
|
|
|
ps->Shade.fStop = _TRUE;
|
|
|
|
|
|
|
|
/* SetRGBGainRegister () */
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
|
|
|
|
|
|
|
DacP98003FillToDAC( ps, &ps->Device.RegDACGain, &ps->Shade.Gain );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
|
|
|
ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
|
|
|
|
|
|
|
|
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
|
|
|
ps->AsicReg.RD_Origin = (UShort)ps->Device.DataOriginX >> 1;
|
|
|
|
else
|
|
|
|
ps->AsicReg.RD_Origin = (UShort)ps->Device.DataOriginX;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Pixels = 2560;
|
|
|
|
|
|
|
|
/* PauseColorMotorRunStates () */
|
|
|
|
memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
|
|
|
|
ps->a_nbNewAdrPointer[1] = 0x77;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
_DODELAY( 70 );
|
|
|
|
|
|
|
|
/* read one shading line and work on it */
|
|
|
|
if( IOReadOneShadingLine( ps, (pUChar)ps->Bufs.b1.pShadingRam, 2560)) {
|
|
|
|
|
|
|
|
if ( ps->DataInf.wPhyDataType <= COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
bHi[1] = DacP98003SumGains(
|
|
|
|
(pUChar)ps->Bufs.b1.pShadingRam + 2560, 2560);
|
|
|
|
if( bHi[1] )
|
|
|
|
DacP98003AdjustGain( ps, _CHANNEL_GREEN, bHi[1] );
|
|
|
|
else {
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bHi[0] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam, 2560);
|
|
|
|
bHi[1] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam + 2560, 2560);
|
|
|
|
bHi[2] = DacP98003SumGains((pUChar)ps->Bufs.b1.pShadingRam + 5120, 2560);
|
|
|
|
|
|
|
|
if (!bHi[0] || !bHi[1] || !bHi[2] ) {
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
} else {
|
|
|
|
DacP98003AdjustGain( ps, _CHANNEL_RED, bHi[0] );
|
|
|
|
DacP98003AdjustGain( ps, _CHANNEL_GREEN, bHi[1] );
|
|
|
|
DacP98003AdjustGain( ps, _CHANNEL_BLUE, bHi[2] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if( !ps->Shade.fStop )
|
|
|
|
DBG( DBG_LOW, "dacP98003AdjustRGBGain() - all loops done!!!\n" );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DacP98003FillToDAC( ps, &ps->Device.RegDACGain, &ps->Shade.Gain );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static UShort dacP98003SumDarks( pScanData ps, pUShort data )
|
|
|
|
{
|
|
|
|
UShort i, loop;
|
|
|
|
|
|
|
|
if( ps->Device.bCCDID == _CCD_3799 ) {
|
|
|
|
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
|
|
|
data += 0x18;
|
|
|
|
else
|
|
|
|
data += 0x30;
|
|
|
|
} else {
|
|
|
|
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
|
|
|
data += 0x18;
|
|
|
|
else
|
|
|
|
data += 0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0, loop = 16; loop--; data++ )
|
|
|
|
i += *data;
|
|
|
|
i >>= 4;
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98003AdjustShadingWaveform( pScanData ps )
|
|
|
|
{
|
|
|
|
Byte b;
|
|
|
|
UShort count, wR, wG, wB, tmp;
|
|
|
|
DataType var;
|
|
|
|
DataPointer pvar, psum;
|
|
|
|
RBGPtrDef cp;
|
|
|
|
pRGBUShortDef pRGB, pwsum;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98003AdjustShadingWaveForm()\n" );
|
|
|
|
|
|
|
|
memset( ps->Bufs.b2.pSumBuf, 0, (5400 * 3 * 2));
|
|
|
|
|
|
|
|
/* SetAdjustShadingRegister () */
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_LineControl = _LOBYTE(ps->Shade.wExposure);
|
|
|
|
ps->AsicReg.RD_ExtLineControl = _HIBYTE(ps->Shade.wExposure);
|
|
|
|
IODataToRegister( ps, ps->RegExtendedLineControl,
|
|
|
|
ps->AsicReg.RD_ExtLineControl );
|
|
|
|
IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_XStepTime = _LOBYTE(ps->Shade.wExposure);
|
|
|
|
ps->AsicReg.RD_ExtXStepTime = _HIBYTE(ps->Shade.wExposure);
|
|
|
|
IODataToRegister( ps, ps->RegExtendedXStep, ps->AsicReg.RD_ExtXStepTime );
|
|
|
|
IODataToRegister( ps, ps->RegXStepTime, ps->AsicReg.RD_XStepTime );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ModeControl = _ModeScan;
|
|
|
|
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
|
|
|
ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
|
|
|
|
|
|
|
|
if( ps->Shade.bIntermediate & _ScanMode_AverageOut ) {
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
ps->AsicReg.RD_Pixels = 2700;
|
|
|
|
ps->Shade.shadingBytes = 2700 * 2;
|
|
|
|
} else {
|
|
|
|
ps->AsicReg.RD_Dpi = 600;
|
|
|
|
ps->AsicReg.RD_Pixels = 5400;
|
|
|
|
ps->Shade.shadingBytes = 5400 * 2;
|
|
|
|
}
|
|
|
|
ps->AsicReg.RD_Origin = _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( pvar.pdw = (pULong)ps->a_nbNewAdrPointer,
|
|
|
|
var.dwValue = _SCANSTATE_BYTES >> 2; var.dwValue--; pvar.pdw++) {
|
|
|
|
*pvar.pdw = 0x00f00080;
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Scan.fRefreshState = _FALSE;
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
_DODELAY( 55 );
|
|
|
|
|
|
|
|
/* SetupHilightShadow () */
|
|
|
|
if( ps->Shade.pHilight ) {
|
|
|
|
|
|
|
|
memset( ps->Shade.pHilight, 0,
|
|
|
|
ps->Shade.shadingBytes * ps->Shade.skipHilight * 3 );
|
|
|
|
|
|
|
|
memset((pUChar)ps->Shade.pHilight +
|
|
|
|
ps->Shade.shadingBytes * ps->Shade.skipHilight * 3, 0xff,
|
|
|
|
ps->Shade.shadingBytes * ps->Shade.skipShadow * 3 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for( count = 32; count--;) {
|
|
|
|
|
|
|
|
IOReadOneShadingLine( ps,
|
|
|
|
((pUChar)ps->Bufs.b1.pShadingRam)+_SHADING_BEGINX,
|
|
|
|
ps->Shade.shadingBytes );
|
|
|
|
|
|
|
|
/* SaveHilightShadow() */
|
|
|
|
if( ps->Shade.pHilight ) {
|
|
|
|
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
cp.red.usp = ps->Bufs.b1.pShadingRam + _SHADING_BEGINX;
|
|
|
|
cp.green.usp = cp.red.usp + ps->AsicReg.RD_Pixels;
|
|
|
|
cp.blue.usp = cp.green.usp + ps->AsicReg.RD_Pixels;
|
|
|
|
pvar.pusrgb = (pRGBUShortDef)ps->Shade.pHilight +
|
|
|
|
_SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
pRGB = pvar.pusrgb++;
|
|
|
|
wR = *cp.red.usp;
|
|
|
|
wG = *cp.green.usp;
|
|
|
|
wB = *cp.blue.usp;
|
|
|
|
|
|
|
|
for( b = ps->Shade.skipHilight; b--;
|
|
|
|
pRGB += ps->AsicReg.RD_Pixels) {
|
|
|
|
|
|
|
|
if( wR > pRGB->Red ) {
|
|
|
|
tmp = wR;
|
|
|
|
wR = pRGB->Red;
|
|
|
|
pRGB->Red = tmp;
|
|
|
|
}
|
|
|
|
if( wG > pRGB->Green ) {
|
|
|
|
tmp = wG;
|
|
|
|
wG = pRGB->Green;
|
|
|
|
pRGB->Green = tmp;
|
|
|
|
}
|
|
|
|
if( wB > pRGB->Blue ) {
|
|
|
|
tmp = wB;
|
|
|
|
wB = pRGB->Blue;
|
|
|
|
pRGB->Blue = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wR = *cp.red.usp++;
|
|
|
|
wG = *cp.green.usp++;
|
|
|
|
wB = *cp.blue.usp++;
|
|
|
|
for(b = ps->Shade.skipShadow; b--;
|
|
|
|
pRGB += ps->AsicReg.RD_Pixels) {
|
|
|
|
|
|
|
|
if (wR < pRGB->Red) {
|
|
|
|
tmp = wR;
|
|
|
|
wR = pRGB->Red;
|
|
|
|
pRGB->Red = tmp;
|
|
|
|
}
|
|
|
|
if (wG < pRGB->Green) {
|
|
|
|
tmp = wG;
|
|
|
|
wG = pRGB->Green;
|
|
|
|
pRGB->Green = tmp;
|
|
|
|
}
|
|
|
|
if (wB < pRGB->Blue) {
|
|
|
|
tmp = wB;
|
|
|
|
wB = pRGB->Blue;
|
|
|
|
pRGB->Blue = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
cp.green.usp = ps->Bufs.b1.pShadingRam +
|
|
|
|
ps->AsicReg.RD_Pixels + _SHADING_BEGINX;
|
|
|
|
cp.blue.usp = (pUShort) ps->Shade.pHilight + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
cp.red.usp = cp.blue.usp++;
|
|
|
|
wG = *cp.green.usp;
|
|
|
|
for( b = ps->Shade.skipHilight; b--;
|
|
|
|
cp.red.usp += ps->AsicReg.RD_Pixels) {
|
|
|
|
if( wG > *cp.red.usp ) {
|
|
|
|
tmp = wG;
|
|
|
|
wG = *cp.red.usp;
|
|
|
|
*cp.red.usp = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wG = *cp.green.usp++;
|
|
|
|
for (b = ps->Shade.skipShadow; b--;
|
|
|
|
cp.red.usp += ps->AsicReg.RD_Pixels) {
|
|
|
|
if( wG < *cp.red.usp ) {
|
|
|
|
tmp = wG;
|
|
|
|
wG = *cp.red.usp;
|
|
|
|
*cp.red.usp = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* AddToSumBuffer() */
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
cp.red.usp = ps->Bufs.b1.pShadingRam + _SHADING_BEGINX;
|
|
|
|
cp.green.usp = cp.red.usp + ps->AsicReg.RD_Pixels;
|
|
|
|
cp.blue.usp = cp.green.usp + ps->AsicReg.RD_Pixels;
|
|
|
|
|
|
|
|
pvar.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = (ULong)ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;
|
|
|
|
pvar.pulrgb++, cp.red.usp++, cp.green.usp++, cp.blue.usp++) {
|
|
|
|
pvar.pulrgb->Red += (ULong)*cp.red.usp;
|
|
|
|
pvar.pulrgb->Green += (ULong)*cp.green.usp;
|
|
|
|
pvar.pulrgb->Blue += (ULong)*cp.blue.usp;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
cp.green.usp = ps->Bufs.b1.pShadingRam + ps->AsicReg.RD_Pixels +
|
|
|
|
_SHADING_BEGINX;
|
|
|
|
pvar.pdw = (pULong)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
for(var.dwValue = (ULong)ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--; pvar.pdw++, cp.green.usp++) {
|
|
|
|
*pvar.pdw += (ULong)*cp.green.usp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( IOReadFifoLength( ps ) < ps->AsicReg.RD_Pixels )
|
|
|
|
IORegisterToScanner( ps, ps->RegRefreshScanState );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* AverageAfterSubHilightShadow() */
|
|
|
|
if( ps->Shade.pHilight ) {
|
|
|
|
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
psum.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
pwsum = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
pvar.pusrgb = (pRGBUShortDef)ps->Shade.pHilight + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
pRGB = pvar.pusrgb++;
|
|
|
|
|
|
|
|
for( b = ps->Shade.skipHilight + ps->Shade.skipShadow;
|
|
|
|
b--; pRGB += ps->AsicReg.RD_Pixels ) {
|
|
|
|
|
|
|
|
psum.pulrgb->Red -= (ULong)pRGB->Red;
|
|
|
|
psum.pulrgb->Green -= (ULong)pRGB->Green;
|
|
|
|
psum.pulrgb->Blue -= (ULong)pRGB->Blue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pwsum->Red = (UShort)(psum.pulrgb->Red / ps->Shade.dwDiv);
|
|
|
|
pwsum->Green = (UShort)(psum.pulrgb->Green / ps->Shade.dwDiv);
|
|
|
|
pwsum->Blue = (UShort)(psum.pulrgb->Blue / ps->Shade.dwDiv);
|
|
|
|
psum.pulrgb++;
|
|
|
|
pwsum++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cp.green.ulp = (pULong)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
cp.blue.usp = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
pvar.pw = (pUShort)ps->Shade.pHilight + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
cp.red.usp = pvar.pw++;
|
|
|
|
|
|
|
|
for( b = ps->Shade.skipHilight + ps->Shade.skipShadow;
|
|
|
|
b--; cp.red.usp += ps->AsicReg.RD_Pixels )
|
|
|
|
*cp.green.ulp -= *cp.red.usp;
|
|
|
|
|
|
|
|
*cp.blue.usp = (UShort)(*cp.green.ulp / ps->Shade.dwDiv);
|
|
|
|
cp.blue.usp++;
|
|
|
|
cp.green.ulp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
psum.pulrgb = (pRGBULongDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
pwsum = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
pwsum->Red = (UShort)(psum.pulrgb->Red >> 5);
|
|
|
|
pwsum->Green = (UShort)(psum.pulrgb->Green >> 5);
|
|
|
|
pwsum->Blue = (UShort)(psum.pulrgb->Blue >> 5);
|
|
|
|
psum.pulrgb++;
|
|
|
|
pwsum++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cp.green.ulp = (pULong)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
cp.blue.usp = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for (var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
*cp.blue.usp = (UShort)(*cp.green.ulp >> 5);
|
|
|
|
cp.blue.usp++;
|
|
|
|
cp.green.ulp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Process negative & transparency here */
|
|
|
|
if( ps->DataInf.dwScanFlag & SCANDEF_TPA )
|
|
|
|
TPAP98003FindCenterPointer( ps );
|
|
|
|
|
|
|
|
if( ps->DataInf.dwScanFlag & SCANDEF_Negative )
|
|
|
|
TPAP98003Reshading( ps );
|
|
|
|
|
|
|
|
pRGB = (pRGBUShortDef)&ps->Shade.pCcdDac->GainResize;
|
|
|
|
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
pwsum = (pRGBUShortDef)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
|
|
|
|
if ((short)(pwsum->Red -= ps->Shade.DarkOffset.Colors.Red) > 0) {
|
|
|
|
pwsum->Red = pwsum->Red * pRGB->Red / 100U;
|
|
|
|
if( pwsum->Red > 0xfff )
|
|
|
|
pwsum->Red = 0xfff;
|
|
|
|
} else
|
|
|
|
pwsum->Red = 0;
|
|
|
|
|
|
|
|
if((short)(pwsum->Green -= ps->Shade.DarkOffset.Colors.Green) > 0) {
|
|
|
|
pwsum->Green = pwsum->Green * pRGB->Green / 100U;
|
|
|
|
if( pwsum->Green > 0xfff )
|
|
|
|
pwsum->Green = 0xfff;
|
|
|
|
} else
|
|
|
|
pwsum->Green = 0;
|
|
|
|
|
|
|
|
if ((short)(pwsum->Blue -= ps->Shade.DarkOffset.Colors.Blue) > 0) {
|
|
|
|
pwsum->Blue = pwsum->Blue * pRGB->Blue / 100U;
|
|
|
|
if( pwsum->Blue > 0xfff )
|
|
|
|
pwsum->Blue = 0xfff;
|
|
|
|
} else
|
|
|
|
pwsum->Blue = 0;
|
|
|
|
|
|
|
|
wR = (UShort)(pwsum->Red >> 4);
|
|
|
|
pwsum->Red <<= 12;
|
|
|
|
pwsum->Red |= wR;
|
|
|
|
wR = (UShort)(pwsum->Green >> 4);
|
|
|
|
pwsum->Green <<= 12;
|
|
|
|
pwsum->Green |= wR;
|
|
|
|
wR = (UShort)(pwsum->Blue>> 4);
|
|
|
|
pwsum->Blue <<= 12;
|
|
|
|
pwsum->Blue |= wR;
|
|
|
|
pwsum++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
cp.green.usp = (pUShort)ps->Bufs.b2.pSumBuf + _SHADING_BEGINX;
|
|
|
|
|
|
|
|
for( var.dwValue = ps->AsicReg.RD_Pixels - _SHADING_BEGINX;
|
|
|
|
var.dwValue--;) {
|
|
|
|
|
|
|
|
if((short)(*cp.green.usp -= ps->Shade.DarkOffset.Colors.Green) > 0) {
|
|
|
|
|
|
|
|
*cp.green.usp = *cp.green.usp * pRGB->Green / 100U;
|
|
|
|
if( *cp.green.usp > 0xfff )
|
|
|
|
*cp.green.usp = 0xfff;
|
|
|
|
} else
|
|
|
|
*cp.green.usp = 0;
|
|
|
|
|
|
|
|
wR = (UShort)(*cp.green.usp >> 4);
|
|
|
|
*cp.green.usp <<= 12;
|
|
|
|
*cp.green.usp |= wR;
|
|
|
|
|
|
|
|
cp.green.usp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DownloadShadingAndSetDark() */
|
|
|
|
dacP98DownloadShadingTable( ps, ps->Bufs.b2.pSumBuf, (5400 * 3 * 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static void dacP98003AdjustDark( pScanData ps )
|
|
|
|
{
|
|
|
|
ULong i;
|
|
|
|
UShort wDarks[3];
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98003AdjustDark()\n" );
|
|
|
|
|
|
|
|
ps->Shade.DarkDAC.Colors = ps->Shade.pCcdDac->DarkDAC.Colors;
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
|
|
|
|
for( i = 16; i-- && !ps->Shade.fStop;) {
|
|
|
|
|
|
|
|
ps->Shade.fStop = _TRUE;
|
|
|
|
|
|
|
|
/* FillDarkToDAC() */
|
|
|
|
DacP98003FillToDAC( ps, &ps->Device.RegDACOffset, &ps->Shade.DarkDAC );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegModeControl, _ModeIdle );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = (_SCAN_12BITMODE + _SCAN_1ST_AVERAGE);
|
|
|
|
IOSelectLampSource( ps );
|
|
|
|
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
|
|
|
ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
|
|
|
|
|
|
|
|
ps->AsicReg.RD_Origin = _SHADING_BEGINX;
|
|
|
|
ps->AsicReg.RD_Pixels = 512;
|
|
|
|
|
|
|
|
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
|
|
|
ps->AsicReg.RD_Dpi = 300;
|
|
|
|
else
|
|
|
|
ps->AsicReg.RD_Dpi = 600;
|
|
|
|
|
|
|
|
|
|
|
|
/* PauseColorMotorRunStates () */
|
|
|
|
memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
|
|
|
|
ps->a_nbNewAdrPointer[1] = 0x77;
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
_DODELAY( 70 );
|
|
|
|
|
|
|
|
/* read one shading line and work on it */
|
|
|
|
if( IOReadOneShadingLine(ps, (pUChar)ps->Bufs.b1.pShadingRam, 512*2)) {
|
|
|
|
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
wDarks[0] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam );
|
|
|
|
wDarks[1] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
|
|
|
|
ps->AsicReg.RD_Pixels );
|
|
|
|
wDarks[2] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
|
|
|
|
ps->AsicReg.RD_Pixels * 2UL);
|
|
|
|
|
|
|
|
if( !wDarks[0] || !wDarks[1] || !wDarks[2] ) {
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
} else {
|
|
|
|
ps->Shade.DarkOffset.wColors[0] = wDarks[0];
|
|
|
|
ps->Shade.DarkOffset.wColors[1] = wDarks[1];
|
|
|
|
ps->Shade.DarkOffset.wColors[2] = wDarks[2];
|
|
|
|
(*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
|
|
|
|
_CHANNEL_RED, wDarks[0] );
|
|
|
|
(*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
|
|
|
|
_CHANNEL_GREEN, wDarks[1] );
|
|
|
|
(*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
|
|
|
|
_CHANNEL_BLUE, wDarks[2] );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
wDarks[1] = dacP98003SumDarks( ps, ps->Bufs.b1.pShadingRam +
|
|
|
|
ps->AsicReg.RD_Pixels );
|
|
|
|
if (!wDarks[1] )
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
else {
|
|
|
|
ps->Shade.DarkOffset.wColors[1] = wDarks[1];
|
|
|
|
(*(ps->Device).fnDACDark)( ps, ps->Shade.pCcdDac,
|
|
|
|
_CHANNEL_GREEN, wDarks[1] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CalculateDarkDependOnCCD() */
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_RED );
|
|
|
|
(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_GREEN );
|
|
|
|
(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_BLUE );
|
|
|
|
} else
|
|
|
|
(*(ps->Device).fnDarkOffset)( ps, ps->Shade.pCcdDac, _CHANNEL_GREEN );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static Bool dacP98003WaitForShading( pScanData ps )
|
|
|
|
{
|
|
|
|
ULong i, tmp;
|
|
|
|
Byte bScanControl;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "dacP98003WaitForShading()\n" );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* before getting the shading data, (re)init the ASIC
|
|
|
|
*/
|
|
|
|
ps->ReInitAsic( ps, _TRUE );
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Red = 0;
|
|
|
|
ps->Shade.DarkOffset.Colors.Green = 0;
|
|
|
|
ps->Shade.DarkOffset.Colors.Blue = 0;
|
|
|
|
|
|
|
|
IORegisterToScanner( ps, ps->RegResetMTSC );
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegModelControl, ps->AsicReg.RD_ModelControl);
|
|
|
|
IODataToRegister( ps, ps->RegMotorDriverType,
|
|
|
|
ps->AsicReg.RD_MotorDriverType );
|
|
|
|
IODataToRegister( ps, ps->RegScanControl1,
|
|
|
|
(_SCANSTOPONBUFFULL| _MFRC_BY_XSTEP));
|
|
|
|
ps->GotoShadingPosition( ps );
|
|
|
|
|
|
|
|
bScanControl = ps->AsicReg.RD_ScanControl;
|
|
|
|
|
|
|
|
/* SetShadingMapForGainDark */
|
|
|
|
memset( ps->Bufs.b2.pSumBuf, 0xff, (5400 * 3 * 2));
|
|
|
|
|
|
|
|
/* DownloadShadingAndSetDark() */
|
|
|
|
dacP98DownloadShadingTable( ps, ps->Bufs.b2.pSumBuf, (5400 * 3 * 2));
|
|
|
|
|
|
|
|
for( i = 0, tmp = 0; i < 1024; tmp += 0x01010101, i += 4 ) {
|
|
|
|
ps->Bufs.b1.Buf.pdw[i] =
|
|
|
|
ps->Bufs.b1.Buf.pdw[i+1] =
|
|
|
|
ps->Bufs.b1.Buf.pdw[i+2] =
|
|
|
|
ps->Bufs.b1.Buf.pdw[i+3] = tmp;
|
|
|
|
}
|
|
|
|
|
2004-01-09 15:57:55 +00:00
|
|
|
memcpy( ps->Bufs.b1.pShadingMap + 4096, ps->Bufs.b1.pShadingMap, 4096 );
|
|
|
|
memcpy( ps->Bufs.b1.pShadingMap + 8192, ps->Bufs.b1.pShadingMap, 4096 );
|
2003-09-23 07:10:53 +00:00
|
|
|
dacP98DownloadMapTable( ps, ps->Bufs.b1.pShadingMap );
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "wExposure = %u\n", ps->Shade.wExposure);
|
|
|
|
DBG( DBG_LOW, "wXStep = %u\n", ps->Shade.wXStep);
|
|
|
|
|
|
|
|
ps->AsicReg.RD_LineControl = (_LOBYTE(ps->Shade.wExposure));
|
|
|
|
ps->AsicReg.RD_ExtLineControl = (_HIBYTE(ps->Shade.wExposure));
|
|
|
|
IODataToRegister(ps, ps->RegExtendedLineControl,
|
|
|
|
ps->AsicReg.RD_ExtLineControl );
|
|
|
|
IODataToRegister(ps, ps->RegLineControl, ps->AsicReg.RD_LineControl );
|
|
|
|
|
|
|
|
dacP98003AdjustRGBGain( ps );
|
|
|
|
dacP98003AdjustDark( ps );
|
|
|
|
dacP98003AdjustShadingWaveform( ps );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_ScanControl = bScanControl;
|
|
|
|
|
|
|
|
/* here we have to download the table in any case...*/
|
|
|
|
dacP98DownloadMapTable( ps, ps->a_bMapTable );
|
|
|
|
|
|
|
|
MotorP98003BackToHomeSensor( ps );
|
|
|
|
|
|
|
|
return _TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************ exported functions *********************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC int DacInitialize( pScanData ps )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
DBG( DBG_HIGH, "DacInitialize()\n" );
|
|
|
|
|
|
|
|
if( NULL == ps )
|
|
|
|
return _E_NULLPTR;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* depending on the asic, we set some functions
|
|
|
|
*/
|
|
|
|
if( _ASIC_IS_98003 == ps->sCaps.AsicID ) {
|
|
|
|
|
|
|
|
ps->WaitForShading = dacP98003WaitForShading;
|
|
|
|
|
|
|
|
} else if( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
|
|
|
|
|
|
|
|
ps->WaitForShading = dacP98WaitForShading;
|
|
|
|
|
|
|
|
} else if( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
|
|
|
|
|
|
|
|
ps->WaitForShading = dacP96003WaitForShading;
|
|
|
|
|
|
|
|
} else if( _ASIC_IS_96001 == ps->sCaps.AsicID ) {
|
|
|
|
|
|
|
|
ps->WaitForShading = dacP96001WaitForShading;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
DBG( DBG_HIGH , "NOT SUPPORTED ASIC !!!\n" );
|
|
|
|
return _E_NOSUPP;
|
|
|
|
}
|
|
|
|
return _OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Fill out the R/G/B GainOut value
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP98FillGainOutDirectPort( pScanData ps )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
|
|
|
|
IODataRegisterToDAC( ps, 0x28, ps->bRedGainIndex );
|
|
|
|
IODataRegisterToDAC( ps, 0x29, ps->bGreenGainIndex );
|
|
|
|
IODataRegisterToDAC( ps, 0x2a, ps->bBlueGainIndex );
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP98FillShadingDarkToShadingRegister( pScanData ps )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
pUChar pValue;
|
|
|
|
Byte bReg;
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "DacP98FillShadingDarkToShadingRegister()\n" );
|
|
|
|
|
|
|
|
ps->AsicReg.RD_RedDarkOff = ps->Shade.DarkOffset.Colors.Red;
|
|
|
|
ps->AsicReg.RD_GreenDarkOff = ps->Shade.DarkOffset.Colors.Green;
|
|
|
|
ps->AsicReg.RD_BlueDarkOff = ps->Shade.DarkOffset.Colors.Blue;
|
|
|
|
|
|
|
|
pValue = (pUChar)&ps->AsicReg.RD_RedDarkOff;
|
|
|
|
for (bReg = ps->RegRedChDarkOffsetLow; bReg <= ps->RegBlueChDarkOffsetHigh;
|
|
|
|
bReg++, pValue++) {
|
|
|
|
|
|
|
|
IODataToRegister( ps, bReg, *pValue );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP98AdjustDark( pScanData ps )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
Byte bCorrectTimes; /* used to be a global var !*/
|
|
|
|
|
|
|
|
DBG( DBG_LOW, "DacP98AdjustDark()\n" );
|
|
|
|
|
|
|
|
ps->Shade.pCcdDac->DarkDAC.Colors.Red = ps->bsPreRedDAC;
|
|
|
|
ps->Shade.pCcdDac->DarkDAC.Colors.Green = ps->bsPreGreenDAC;
|
|
|
|
ps->Shade.pCcdDac->DarkDAC.Colors.Blue = ps->bsPreBlueDAC;
|
|
|
|
|
|
|
|
if( ps->DataInf.dwScanFlag & SCANDEF_Negative ) {
|
|
|
|
bCorrectTimes = 6;
|
|
|
|
} else {
|
|
|
|
bCorrectTimes = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CHANGE
|
|
|
|
** original code seems to be buggy : for (bCorrectTimes ; bCorrectTimes--;) {
|
|
|
|
*/
|
|
|
|
for (;bCorrectTimes ; bCorrectTimes-- ) {
|
|
|
|
|
|
|
|
ps->OpenScanPath( ps );
|
|
|
|
dacP98FillDarkDAC( ps );
|
|
|
|
dacP98SetReadFBKRegister( ps );
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
IOPutOnAllRegisters( ps );
|
|
|
|
|
|
|
|
ps->PauseColorMotorRunStates( ps ); /* stop scan states */
|
|
|
|
|
|
|
|
IOReadOneShadingLine( ps, ps->pScanBuffer1, 512*2 );
|
|
|
|
|
|
|
|
dacP98FillChannelDarkLevelControl( ps );
|
|
|
|
|
|
|
|
if(dacP98CheckChannelDarkLevel( ps ))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Red=
|
|
|
|
dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Red,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Red,
|
|
|
|
ps->Shade.pCcdDac->DarkOffSub.Colors.Red );
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Green =
|
|
|
|
dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Green,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Green,
|
|
|
|
ps->Shade.pCcdDac->DarkOffSub.Colors.Green );
|
|
|
|
|
|
|
|
ps->Shade.DarkOffset.Colors.Blue =
|
|
|
|
dacP98CalDarkOff( ps, ps->Shade.DarkOffset.Colors.Blue,
|
|
|
|
ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue,
|
|
|
|
ps->Shade.pCcdDac->DarkOffSub.Colors.Blue );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP96WriteBackToGammaShadingRAM( pScanData ps )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
/* ModifyGammaShadingOffset(ps) */
|
|
|
|
ps->OpenScanPath( ps);
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegRedChShadingOffset,
|
|
|
|
ps->Asic96Reg.u28.RD_RedChShadingOff );
|
|
|
|
IODataToRegister( ps, ps->RegGreenChShadingOffset,
|
|
|
|
(Byte)((ULong)ps->Asic96Reg.u29.RD_GreenChShadingOff * 96UL/100UL));
|
|
|
|
|
|
|
|
IODataToRegister( ps, ps->RegBlueChShadingOffset,
|
|
|
|
(Byte)((ULong)ps->Asic96Reg.RD_BlueChShadingOff * 91UL/100UL));
|
|
|
|
|
|
|
|
ps->CloseScanPath( ps );
|
|
|
|
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16, 256, ps->ShadingBankRed);
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize,
|
|
|
|
256, ps->ShadingBankGreen);
|
|
|
|
dacP96WriteLinearGamma( ps, ps->pPrescan16 + ps->ShadingBankSize * 2,
|
|
|
|
256, ps->ShadingBankBlue);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP98003FillToDAC( pScanData ps, pRGBByteDef regs, pColorByte data )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
if ( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
|
|
|
|
|
|
|
dacP98003GainOffsetToDAC( ps, _DAC_RED, regs->Red, data->Colors.Red );
|
|
|
|
dacP98003GainOffsetToDAC( ps, _DAC_GREENCOLOR,
|
|
|
|
regs->Green, data->Colors.Green );
|
|
|
|
dacP98003GainOffsetToDAC( ps, _DAC_BLUE,
|
|
|
|
regs->Blue, data->Colors.Blue );
|
|
|
|
} else {
|
|
|
|
dacP98003GainOffsetToDAC( ps, _DAC_GREENMONO, regs->Green,
|
|
|
|
data->Colors.Green );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC void DacP98003AdjustGain( pScanData ps, ULong color, Byte hilight )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
if( hilight < ps->Shade.bGainLow ) {
|
|
|
|
|
|
|
|
if( ps->Shade.Hilight.bColors[color] < ps->Shade.bGainHigh ) {
|
|
|
|
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
ps->Shade.Hilight.bColors[color] = hilight;
|
|
|
|
|
|
|
|
if( hilight <= (Byte)(ps->Shade.bGainLow - hilight))
|
|
|
|
ps->Shade.Gain.bColors[color] += ps->Shade.bGainDouble;
|
|
|
|
else
|
|
|
|
ps->Shade.Gain.bColors[color]++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if( hilight > ps->Shade.bGainHigh ) {
|
|
|
|
ps->Shade.fStop = _FALSE;
|
|
|
|
ps->Shade.Hilight.bColors[color] = hilight;
|
|
|
|
ps->Shade.Gain.bColors[color]--;
|
|
|
|
} else
|
|
|
|
ps->Shade.Hilight.bColors[color] = hilight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ps->Shade.Gain.bColors[color] > ps->Shade.bMaxGain ) {
|
|
|
|
ps->Shade.Gain.bColors[color] = ps->Shade.bMaxGain;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
2003-09-24 14:08:01 +00:00
|
|
|
_LOC Byte DacP98003SumGains( pUChar pb, ULong pixelsLine )
|
2003-09-23 07:10:53 +00:00
|
|
|
{
|
|
|
|
Byte bHilight, tmp;
|
|
|
|
ULong dwPixels, dwAve;
|
|
|
|
UShort sum;
|
|
|
|
|
|
|
|
for( bHilight = 0, dwPixels = pixelsLine >> 4; dwPixels--; ) {
|
|
|
|
|
|
|
|
for( sum = 0, dwAve = 16; dwAve--; pb++)
|
|
|
|
sum += (UShort)*pb;
|
|
|
|
|
|
|
|
sum >>= 4;
|
|
|
|
tmp = (Byte)sum;
|
|
|
|
|
|
|
|
if( tmp > bHilight )
|
|
|
|
bHilight = tmp;
|
|
|
|
}
|
|
|
|
return bHilight;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* END PLUSTEK-PP_DAC.C .....................................................*/
|