1141cc406Sopenharmony_ci/* @file u12-shading.c - 2141cc406Sopenharmony_ci * @brief all the shading functions 3141cc406Sopenharmony_ci * 4141cc406Sopenharmony_ci * based on sources acquired from Plustek Inc. 5141cc406Sopenharmony_ci * Copyright (C) 2003-2004 Gerhard Jaeger <gerhard@gjaeger.de> 6141cc406Sopenharmony_ci * 7141cc406Sopenharmony_ci * History: 8141cc406Sopenharmony_ci * - 0.01 - initial version 9141cc406Sopenharmony_ci * - 0.02 - 10141cc406Sopenharmony_ci * . 11141cc406Sopenharmony_ci * <hr> 12141cc406Sopenharmony_ci * This file is part of the SANE package. 13141cc406Sopenharmony_ci * 14141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or 15141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as 16141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 17141cc406Sopenharmony_ci * License, or (at your option) any later version. 18141cc406Sopenharmony_ci * 19141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 20141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 21141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22141cc406Sopenharmony_ci * General Public License for more details. 23141cc406Sopenharmony_ci * 24141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License 25141cc406Sopenharmony_ci * along with this program. If not, see <https://www.gnu.org/licenses/>. 26141cc406Sopenharmony_ci * 27141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for 28141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE. 29141cc406Sopenharmony_ci * 30141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files 31141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the 32141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public 33141cc406Sopenharmony_ci * License. Your use of that executable is in no way restricted on 34141cc406Sopenharmony_ci * account of linking the SANE library code into it. 35141cc406Sopenharmony_ci * 36141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why 37141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public 38141cc406Sopenharmony_ci * License. 39141cc406Sopenharmony_ci * 40141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in 41141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that 42141cc406Sopenharmony_ci * those changes may be distributed with this exception intact. 43141cc406Sopenharmony_ci * 44141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice 45141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications. 46141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice. 47141cc406Sopenharmony_ci * <hr> 48141cc406Sopenharmony_ci */ 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#define _GAIN_HIGH 240 /* Volt. max. value */ 51141cc406Sopenharmony_ci#define _GAIN_LOW 220 /* Volt. min. value */ 52141cc406Sopenharmony_ci 53141cc406Sopenharmony_ci#define _CHANNEL_RED 0 54141cc406Sopenharmony_ci#define _CHANNEL_GREEN 1 55141cc406Sopenharmony_ci#define _CHANNEL_BLUE 2 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ci/* for DAC programming */ 58141cc406Sopenharmony_ci#define _VALUE_CONFIG 0x51 59141cc406Sopenharmony_ci#define _DAC_RED (SANE_Byte)(_VALUE_CONFIG | 0x00) 60141cc406Sopenharmony_ci#define _DAC_GREENCOLOR (SANE_Byte)(_VALUE_CONFIG | 0x04) 61141cc406Sopenharmony_ci#define _DAC_GREENMONO (SANE_Byte)(_VALUE_CONFIG | 0x06) 62141cc406Sopenharmony_ci#define _DAC_BLUE (SANE_Byte)(_VALUE_CONFIG | 0x08) 63141cc406Sopenharmony_ci 64141cc406Sopenharmony_ci 65141cc406Sopenharmony_ci/* forward declarations ... */ 66141cc406Sopenharmony_cistatic void u12tpa_Reshading( U12_Device * ); 67141cc406Sopenharmony_cistatic void u12tpa_FindCenterPointer( U12_Device * ); 68141cc406Sopenharmony_ci 69141cc406Sopenharmony_ci/** 70141cc406Sopenharmony_ci */ 71141cc406Sopenharmony_cistatic void 72141cc406Sopenharmony_ciu12shading_DownloadShadingTable( U12_Device *dev, SANE_Byte *buf, u_long len ) 73141cc406Sopenharmony_ci{ 74141cc406Sopenharmony_ci SANE_Byte *val, *rb; 75141cc406Sopenharmony_ci SANE_Byte reg, regs[20]; 76141cc406Sopenharmony_ci int c; 77141cc406Sopenharmony_ci 78141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_DownloadShadingTable()\n" ); 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MODECONTROL, _ModeShadingMem ); 81141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MEMORYLO, 0 ); 82141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MEMORYHI, 0 ); 83141cc406Sopenharmony_ci 84141cc406Sopenharmony_ci /* set 12 bits output color */ 85141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_SCANCONTROL, 86141cc406Sopenharmony_ci (SANE_Byte)(dev->regs.RD_ScanControl | _SCAN_12BITMODE)); 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci u12io_MoveDataToScanner( dev, buf, len ); 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci regs[0] = REG_MODECONTROL; 91141cc406Sopenharmony_ci regs[1] = _ModeScan; 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci /* FillShadingDarkToShadingRegister() */ 94141cc406Sopenharmony_ci dev->regs.RD_RedDarkOff = dev->shade.DarkOffset.Colors.Red; 95141cc406Sopenharmony_ci dev->regs.RD_GreenDarkOff = dev->shade.DarkOffset.Colors.Green; 96141cc406Sopenharmony_ci dev->regs.RD_BlueDarkOff = dev->shade.DarkOffset.Colors.Blue; 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci val = (SANE_Byte*)&dev->regs.RD_RedDarkOff; 99141cc406Sopenharmony_ci rb = ®s[2]; 100141cc406Sopenharmony_ci c = 1; 101141cc406Sopenharmony_ci for( reg = REG_REDCHDARKOFFSETLO; 102141cc406Sopenharmony_ci reg <= REG_BLUECHDARKOFFSETHI; reg++, val++) { 103141cc406Sopenharmony_ci 104141cc406Sopenharmony_ci *(rb++) = reg; 105141cc406Sopenharmony_ci *(rb++) = *val; 106141cc406Sopenharmony_ci c++; 107141cc406Sopenharmony_ci } 108141cc406Sopenharmony_ci u12io_DataToRegs( dev, regs, c ); 109141cc406Sopenharmony_ci} 110141cc406Sopenharmony_ci 111141cc406Sopenharmony_ci/** 112141cc406Sopenharmony_ci */ 113141cc406Sopenharmony_cistatic SANE_Status u12shadingAdjustShadingWaveform( U12_Device *dev ) 114141cc406Sopenharmony_ci{ 115141cc406Sopenharmony_ci SANE_Byte b; 116141cc406Sopenharmony_ci u_short count, wR, wG, wB, tmp; 117141cc406Sopenharmony_ci DataType var; 118141cc406Sopenharmony_ci DataPointer pvar, psum; 119141cc406Sopenharmony_ci RBGPtrDef cp; 120141cc406Sopenharmony_ci RGBUShortDef *pRGB, *pwsum; 121141cc406Sopenharmony_ci u_long shadingBytes; 122141cc406Sopenharmony_ci 123141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_AdjustShadingWaveForm()\n" ); 124141cc406Sopenharmony_ci 125141cc406Sopenharmony_ci memset( &cp, 0, sizeof(RBGPtrDef)); 126141cc406Sopenharmony_ci memset( dev->bufs.b2.pSumBuf, 0, (5400 * 3 * 2)); 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MODECONTROL, _ModeIdle ); 129141cc406Sopenharmony_ci 130141cc406Sopenharmony_ci dev->regs.RD_LineControl = _LOBYTE(dev->shade.wExposure); 131141cc406Sopenharmony_ci dev->regs.RD_ExtLineControl = _HIBYTE(dev->shade.wExposure); 132141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_EXTENDEDLINECONTROL, 133141cc406Sopenharmony_ci dev->regs.RD_ExtLineControl ); 134141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_LINECONTROL, dev->regs.RD_LineControl ); 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci dev->regs.RD_XStepTime = _LOBYTE(dev->shade.wExposure); 137141cc406Sopenharmony_ci dev->regs.RD_ExtXStepTime = _HIBYTE(dev->shade.wExposure); 138141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_EXTENDEDXSTEP, dev->regs.RD_ExtXStepTime ); 139141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_XSTEPTIME, dev->regs.RD_XStepTime ); 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeScan; 142141cc406Sopenharmony_ci dev->regs.RD_StepControl = _MOTOR0_SCANSTATE; 143141cc406Sopenharmony_ci dev->regs.RD_Motor0Control = _FORWARD_MOTOR; 144141cc406Sopenharmony_ci 145141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) { 146141cc406Sopenharmony_ci 147141cc406Sopenharmony_ci dev->regs.RD_Dpi = 300; 148141cc406Sopenharmony_ci dev->regs.RD_Pixels = 2700; 149141cc406Sopenharmony_ci shadingBytes = 2700 * 2; 150141cc406Sopenharmony_ci } else { 151141cc406Sopenharmony_ci dev->regs.RD_Dpi = 600; 152141cc406Sopenharmony_ci dev->regs.RD_Pixels = 5400; 153141cc406Sopenharmony_ci shadingBytes = 5400 * 2; 154141cc406Sopenharmony_ci } 155141cc406Sopenharmony_ci dev->regs.RD_Origin = _SHADING_BEGINX; 156141cc406Sopenharmony_ci 157141cc406Sopenharmony_ci for( pvar.pdw = (u_long*)dev->scanStates, 158141cc406Sopenharmony_ci var.dwValue = _SCANSTATE_BYTES >> 2; var.dwValue--; pvar.pdw++) { 159141cc406Sopenharmony_ci *pvar.pdw = 0x00f00080; 160141cc406Sopenharmony_ci } 161141cc406Sopenharmony_ci 162141cc406Sopenharmony_ci dev->scan.refreshState = SANE_FALSE; 163141cc406Sopenharmony_ci u12io_PutOnAllRegisters( dev ); 164141cc406Sopenharmony_ci/* _DODELAY( 100 ); */ 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ci if( dev->shade.pHilight ) { 167141cc406Sopenharmony_ci 168141cc406Sopenharmony_ci memset( dev->shade.pHilight, 0, 169141cc406Sopenharmony_ci shadingBytes * dev->shade.skipHilight * 3 ); 170141cc406Sopenharmony_ci 171141cc406Sopenharmony_ci memset((SANE_Byte*)dev->shade.pHilight + 172141cc406Sopenharmony_ci shadingBytes * dev->shade.skipHilight * 3, 0xff, 173141cc406Sopenharmony_ci shadingBytes * dev->shade.skipShadow * 3 ); 174141cc406Sopenharmony_ci } 175141cc406Sopenharmony_ci 176141cc406Sopenharmony_ci for( count = 32; count--; ) { 177141cc406Sopenharmony_ci 178141cc406Sopenharmony_ci if( u12io_IsEscPressed()) { 179141cc406Sopenharmony_ci DBG( _DBG_INFO, "* CANCEL detected!\n" ); 180141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 181141cc406Sopenharmony_ci } 182141cc406Sopenharmony_ci 183141cc406Sopenharmony_ci u12io_ReadOneShadingLine( dev, ((SANE_Byte*)dev->bufs.b1.pShadingRam)+ 184141cc406Sopenharmony_ci _SHADING_BEGINX, shadingBytes ); 185141cc406Sopenharmony_ci 186141cc406Sopenharmony_ci if( dev->shade.pHilight ) { 187141cc406Sopenharmony_ci 188141cc406Sopenharmony_ci if ( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_ci cp.red.usp = dev->bufs.b1.pShadingRam + _SHADING_BEGINX; 191141cc406Sopenharmony_ci cp.green.usp = cp.red.usp + dev->regs.RD_Pixels; 192141cc406Sopenharmony_ci cp.blue.usp = cp.green.usp + dev->regs.RD_Pixels; 193141cc406Sopenharmony_ci pvar.pusrgb = (RGBUShortDef*)dev->shade.pHilight + 194141cc406Sopenharmony_ci _SHADING_BEGINX; 195141cc406Sopenharmony_ci 196141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 197141cc406Sopenharmony_ci var.dwValue--;) { 198141cc406Sopenharmony_ci pRGB = pvar.pusrgb++; 199141cc406Sopenharmony_ci wR = *cp.red.usp; 200141cc406Sopenharmony_ci wG = *cp.green.usp; 201141cc406Sopenharmony_ci wB = *cp.blue.usp; 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci for( b = dev->shade.skipHilight; b--; 204141cc406Sopenharmony_ci pRGB += dev->regs.RD_Pixels ) { 205141cc406Sopenharmony_ci if( wR > pRGB->Red ) { 206141cc406Sopenharmony_ci tmp = wR; 207141cc406Sopenharmony_ci wR = pRGB->Red; 208141cc406Sopenharmony_ci pRGB->Red = tmp; 209141cc406Sopenharmony_ci } 210141cc406Sopenharmony_ci if( wG > pRGB->Green ) { 211141cc406Sopenharmony_ci tmp = wG; 212141cc406Sopenharmony_ci wG = pRGB->Green; 213141cc406Sopenharmony_ci pRGB->Green = tmp; 214141cc406Sopenharmony_ci } 215141cc406Sopenharmony_ci if( wB > pRGB->Blue ) { 216141cc406Sopenharmony_ci tmp = wB; 217141cc406Sopenharmony_ci wB = pRGB->Blue; 218141cc406Sopenharmony_ci pRGB->Blue = tmp; 219141cc406Sopenharmony_ci } 220141cc406Sopenharmony_ci } 221141cc406Sopenharmony_ci 222141cc406Sopenharmony_ci wR = *cp.red.usp++; 223141cc406Sopenharmony_ci wG = *cp.green.usp++; 224141cc406Sopenharmony_ci wB = *cp.blue.usp++; 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci for( b = dev->shade.skipShadow; b--; 227141cc406Sopenharmony_ci pRGB += dev->regs.RD_Pixels ) { 228141cc406Sopenharmony_ci if( wR < pRGB->Red ) { 229141cc406Sopenharmony_ci tmp = wR; 230141cc406Sopenharmony_ci wR = pRGB->Red; 231141cc406Sopenharmony_ci pRGB->Red = tmp; 232141cc406Sopenharmony_ci } 233141cc406Sopenharmony_ci if( wG < pRGB->Green ) { 234141cc406Sopenharmony_ci tmp = wG; 235141cc406Sopenharmony_ci wG = pRGB->Green; 236141cc406Sopenharmony_ci pRGB->Green = tmp; 237141cc406Sopenharmony_ci } 238141cc406Sopenharmony_ci if( wB < pRGB->Blue ) { 239141cc406Sopenharmony_ci tmp = wB; 240141cc406Sopenharmony_ci wB = pRGB->Blue; 241141cc406Sopenharmony_ci pRGB->Blue = tmp; 242141cc406Sopenharmony_ci } 243141cc406Sopenharmony_ci } 244141cc406Sopenharmony_ci } 245141cc406Sopenharmony_ci } else { 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_ci cp.green.usp = dev->bufs.b1.pShadingRam + 248141cc406Sopenharmony_ci dev->regs.RD_Pixels + _SHADING_BEGINX; 249141cc406Sopenharmony_ci cp.blue.usp = (u_short*)dev->shade.pHilight + _SHADING_BEGINX; 250141cc406Sopenharmony_ci 251141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 252141cc406Sopenharmony_ci var.dwValue--;) { 253141cc406Sopenharmony_ci cp.red.usp = cp.blue.usp++; 254141cc406Sopenharmony_ci wG = *cp.green.usp; 255141cc406Sopenharmony_ci for( b = dev->shade.skipHilight; b--; 256141cc406Sopenharmony_ci cp.red.usp += dev->regs.RD_Pixels) { 257141cc406Sopenharmony_ci if( wG > *cp.red.usp ) { 258141cc406Sopenharmony_ci tmp = wG; 259141cc406Sopenharmony_ci wG = *cp.red.usp; 260141cc406Sopenharmony_ci *cp.red.usp = tmp; 261141cc406Sopenharmony_ci } 262141cc406Sopenharmony_ci } 263141cc406Sopenharmony_ci wG = *cp.green.usp++; 264141cc406Sopenharmony_ci for( b = dev->shade.skipShadow; b--; 265141cc406Sopenharmony_ci cp.red.usp += dev->regs.RD_Pixels ) { 266141cc406Sopenharmony_ci if( wG < *cp.red.usp ) { 267141cc406Sopenharmony_ci tmp = wG; 268141cc406Sopenharmony_ci wG = *cp.red.usp; 269141cc406Sopenharmony_ci *cp.red.usp = tmp; 270141cc406Sopenharmony_ci } 271141cc406Sopenharmony_ci } 272141cc406Sopenharmony_ci } 273141cc406Sopenharmony_ci } 274141cc406Sopenharmony_ci } 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ci /* AddToSumBuffer() */ 277141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 278141cc406Sopenharmony_ci 279141cc406Sopenharmony_ci cp.red.usp = dev->bufs.b1.pShadingRam + _SHADING_BEGINX; 280141cc406Sopenharmony_ci cp.green.usp = cp.red.usp + dev->regs.RD_Pixels; 281141cc406Sopenharmony_ci cp.blue.usp = cp.green.usp + dev->regs.RD_Pixels; 282141cc406Sopenharmony_ci 283141cc406Sopenharmony_ci pvar.pulrgb = (RGBULongDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 284141cc406Sopenharmony_ci 285141cc406Sopenharmony_ci for( var.dwValue = (u_long)dev->regs.RD_Pixels - _SHADING_BEGINX; 286141cc406Sopenharmony_ci var.dwValue--; 287141cc406Sopenharmony_ci pvar.pulrgb++, cp.red.usp++, cp.green.usp++, cp.blue.usp++) { 288141cc406Sopenharmony_ci pvar.pulrgb->Red += (u_long)*cp.red.usp; 289141cc406Sopenharmony_ci pvar.pulrgb->Green += (u_long)*cp.green.usp; 290141cc406Sopenharmony_ci pvar.pulrgb->Blue += (u_long)*cp.blue.usp; 291141cc406Sopenharmony_ci } 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci } else { 294141cc406Sopenharmony_ci 295141cc406Sopenharmony_ci cp.green.usp = dev->bufs.b1.pShadingRam + 296141cc406Sopenharmony_ci dev->regs.RD_Pixels + _SHADING_BEGINX; 297141cc406Sopenharmony_ci pvar.pdw = (u_long*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 298141cc406Sopenharmony_ci for( var.dwValue = (u_long)dev->regs.RD_Pixels - _SHADING_BEGINX; 299141cc406Sopenharmony_ci var.dwValue--; pvar.pdw++, cp.green.usp++) { 300141cc406Sopenharmony_ci *pvar.pdw += (u_long)*cp.green.usp; 301141cc406Sopenharmony_ci } 302141cc406Sopenharmony_ci } 303141cc406Sopenharmony_ci 304141cc406Sopenharmony_ci u12io_ResetFifoLen(); 305141cc406Sopenharmony_ci if( u12io_GetFifoLength( dev ) < dev->regs.RD_Pixels ) 306141cc406Sopenharmony_ci u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE ); 307141cc406Sopenharmony_ci } 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci /* AverageAfterSubHilightShadow() */ 310141cc406Sopenharmony_ci if( dev->shade.pHilight ) { 311141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 312141cc406Sopenharmony_ci 313141cc406Sopenharmony_ci psum.pulrgb = (RGBULongDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 314141cc406Sopenharmony_ci pwsum = (RGBUShortDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 315141cc406Sopenharmony_ci pvar.pusrgb = (RGBUShortDef*)dev->shade.pHilight + _SHADING_BEGINX; 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 318141cc406Sopenharmony_ci var.dwValue--;) { 319141cc406Sopenharmony_ci pRGB = pvar.pusrgb++; 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_ci for( b = dev->shade.skipHilight + dev->shade.skipShadow; 322141cc406Sopenharmony_ci b--; pRGB += dev->regs.RD_Pixels ) { 323141cc406Sopenharmony_ci 324141cc406Sopenharmony_ci psum.pulrgb->Red -= (u_long)pRGB->Red; 325141cc406Sopenharmony_ci psum.pulrgb->Green -= (u_long)pRGB->Green; 326141cc406Sopenharmony_ci psum.pulrgb->Blue -= (u_long)pRGB->Blue; 327141cc406Sopenharmony_ci } 328141cc406Sopenharmony_ci 329141cc406Sopenharmony_ci pwsum->Red = (u_short)(psum.pulrgb->Red / dev->shade.dwDiv); 330141cc406Sopenharmony_ci pwsum->Green = (u_short)(psum.pulrgb->Green / dev->shade.dwDiv); 331141cc406Sopenharmony_ci pwsum->Blue = (u_short)(psum.pulrgb->Blue / dev->shade.dwDiv); 332141cc406Sopenharmony_ci psum.pulrgb++; 333141cc406Sopenharmony_ci pwsum++; 334141cc406Sopenharmony_ci } 335141cc406Sopenharmony_ci } else { 336141cc406Sopenharmony_ci cp.green.ulp = (u_long*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 337141cc406Sopenharmony_ci cp.blue.usp = (u_short*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 338141cc406Sopenharmony_ci pvar.pw = (u_short*)dev->shade.pHilight + _SHADING_BEGINX; 339141cc406Sopenharmony_ci 340141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 341141cc406Sopenharmony_ci var.dwValue--;) { 342141cc406Sopenharmony_ci cp.red.usp = pvar.pw++; 343141cc406Sopenharmony_ci 344141cc406Sopenharmony_ci for( b = dev->shade.skipHilight + dev->shade.skipShadow; 345141cc406Sopenharmony_ci b--; cp.red.usp += dev->regs.RD_Pixels ) 346141cc406Sopenharmony_ci *cp.green.ulp -= *cp.red.usp; 347141cc406Sopenharmony_ci 348141cc406Sopenharmony_ci *cp.blue.usp = (u_short)(*cp.green.ulp / dev->shade.dwDiv); 349141cc406Sopenharmony_ci cp.blue.usp++; 350141cc406Sopenharmony_ci cp.green.ulp++; 351141cc406Sopenharmony_ci } 352141cc406Sopenharmony_ci } 353141cc406Sopenharmony_ci } else { 354141cc406Sopenharmony_ci 355141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci psum.pulrgb = (RGBULongDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 358141cc406Sopenharmony_ci pwsum = (RGBUShortDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 361141cc406Sopenharmony_ci var.dwValue--;) { 362141cc406Sopenharmony_ci pwsum->Red = (u_short)(psum.pulrgb->Red >> 5); 363141cc406Sopenharmony_ci pwsum->Green = (u_short)(psum.pulrgb->Green >> 5); 364141cc406Sopenharmony_ci pwsum->Blue = (u_short)(psum.pulrgb->Blue >> 5); 365141cc406Sopenharmony_ci psum.pulrgb++; 366141cc406Sopenharmony_ci pwsum++; 367141cc406Sopenharmony_ci } 368141cc406Sopenharmony_ci } else { 369141cc406Sopenharmony_ci cp.green.ulp = (u_long*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 370141cc406Sopenharmony_ci cp.blue.usp = (u_short*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 373141cc406Sopenharmony_ci var.dwValue--;) { 374141cc406Sopenharmony_ci *cp.blue.usp = (u_short)(*cp.green.ulp >> 5); 375141cc406Sopenharmony_ci cp.blue.usp++; 376141cc406Sopenharmony_ci cp.green.ulp++; 377141cc406Sopenharmony_ci } 378141cc406Sopenharmony_ci } 379141cc406Sopenharmony_ci } 380141cc406Sopenharmony_ci 381141cc406Sopenharmony_ci /* Process negative & transparency here */ 382141cc406Sopenharmony_ci if( dev->DataInf.dwScanFlag & _SCANDEF_TPA ) 383141cc406Sopenharmony_ci u12tpa_FindCenterPointer( dev ); 384141cc406Sopenharmony_ci 385141cc406Sopenharmony_ci if( dev->DataInf.dwScanFlag & _SCANDEF_Negative ) 386141cc406Sopenharmony_ci u12tpa_Reshading( dev ); 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci pRGB = (RGBUShortDef*)&dev->shade.pCcdDac->GainResize; 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci if ( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 391141cc406Sopenharmony_ci 392141cc406Sopenharmony_ci pwsum = (RGBUShortDef*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 393141cc406Sopenharmony_ci 394141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 395141cc406Sopenharmony_ci var.dwValue--;) { 396141cc406Sopenharmony_ci 397141cc406Sopenharmony_ci if ((short)(pwsum->Red -= dev->shade.DarkOffset.Colors.Red) > 0) { 398141cc406Sopenharmony_ci pwsum->Red = pwsum->Red * pRGB->Red / 100U; 399141cc406Sopenharmony_ci if( pwsum->Red > 0xfff ) 400141cc406Sopenharmony_ci pwsum->Red = 0xfff; 401141cc406Sopenharmony_ci } else 402141cc406Sopenharmony_ci pwsum->Red = 0; 403141cc406Sopenharmony_ci 404141cc406Sopenharmony_ci if((short)(pwsum->Green -= dev->shade.DarkOffset.Colors.Green) > 0) { 405141cc406Sopenharmony_ci pwsum->Green = pwsum->Green * pRGB->Green / 100U; 406141cc406Sopenharmony_ci if( pwsum->Green > 0xfff ) 407141cc406Sopenharmony_ci pwsum->Green = 0xfff; 408141cc406Sopenharmony_ci } else 409141cc406Sopenharmony_ci pwsum->Green = 0; 410141cc406Sopenharmony_ci 411141cc406Sopenharmony_ci if ((short)(pwsum->Blue -= dev->shade.DarkOffset.Colors.Blue) > 0) { 412141cc406Sopenharmony_ci pwsum->Blue = pwsum->Blue * pRGB->Blue / 100U; 413141cc406Sopenharmony_ci if( pwsum->Blue > 0xfff ) 414141cc406Sopenharmony_ci pwsum->Blue = 0xfff; 415141cc406Sopenharmony_ci } else 416141cc406Sopenharmony_ci pwsum->Blue = 0; 417141cc406Sopenharmony_ci 418141cc406Sopenharmony_ci wR = (u_short)(pwsum->Red >> 4); 419141cc406Sopenharmony_ci pwsum->Red <<= 12; 420141cc406Sopenharmony_ci pwsum->Red |= wR; 421141cc406Sopenharmony_ci wR = (u_short)(pwsum->Green >> 4); 422141cc406Sopenharmony_ci pwsum->Green <<= 12; 423141cc406Sopenharmony_ci pwsum->Green |= wR; 424141cc406Sopenharmony_ci wR = (u_short)(pwsum->Blue>> 4); 425141cc406Sopenharmony_ci pwsum->Blue <<= 12; 426141cc406Sopenharmony_ci pwsum->Blue |= wR; 427141cc406Sopenharmony_ci pwsum++; 428141cc406Sopenharmony_ci } 429141cc406Sopenharmony_ci } else { 430141cc406Sopenharmony_ci 431141cc406Sopenharmony_ci cp.green.usp = (u_short*)dev->bufs.b2.pSumBuf + _SHADING_BEGINX; 432141cc406Sopenharmony_ci 433141cc406Sopenharmony_ci for( var.dwValue = dev->regs.RD_Pixels - _SHADING_BEGINX; 434141cc406Sopenharmony_ci var.dwValue--;) { 435141cc406Sopenharmony_ci 436141cc406Sopenharmony_ci if((short)(*cp.green.usp -= dev->shade.DarkOffset.Colors.Green) > 0) { 437141cc406Sopenharmony_ci 438141cc406Sopenharmony_ci *cp.green.usp = *cp.green.usp * pRGB->Green / 100U; 439141cc406Sopenharmony_ci if( *cp.green.usp > 0xfff ) 440141cc406Sopenharmony_ci *cp.green.usp = 0xfff; 441141cc406Sopenharmony_ci } else 442141cc406Sopenharmony_ci *cp.green.usp = 0; 443141cc406Sopenharmony_ci 444141cc406Sopenharmony_ci wR = (u_short)(*cp.green.usp >> 4); 445141cc406Sopenharmony_ci *cp.green.usp <<= 12; 446141cc406Sopenharmony_ci *cp.green.usp |= wR; 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci cp.green.usp++; 449141cc406Sopenharmony_ci } 450141cc406Sopenharmony_ci } 451141cc406Sopenharmony_ci 452141cc406Sopenharmony_ci u12shading_DownloadShadingTable(dev, dev->bufs.b2.pSumBuf, (5400 * 3 * 2)); 453141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 454141cc406Sopenharmony_ci} 455141cc406Sopenharmony_ci 456141cc406Sopenharmony_ci/** 457141cc406Sopenharmony_ci */ 458141cc406Sopenharmony_cistatic void u12shading_GainOffsetToDAC( U12_Device *dev, SANE_Byte ch, 459141cc406Sopenharmony_ci SANE_Byte reg, SANE_Byte d ) 460141cc406Sopenharmony_ci{ 461141cc406Sopenharmony_ci if( dev->DACType == _DA_SAMSUNG8531 ) { 462141cc406Sopenharmony_ci u12io_DataRegisterToDAC( dev, 0, ch ); 463141cc406Sopenharmony_ci } 464141cc406Sopenharmony_ci u12io_DataRegisterToDAC( dev, reg, d ); 465141cc406Sopenharmony_ci} 466141cc406Sopenharmony_ci 467141cc406Sopenharmony_ci/** 468141cc406Sopenharmony_ci */ 469141cc406Sopenharmony_cistatic void u12shading_FillToDAC( U12_Device *dev, 470141cc406Sopenharmony_ci RGBByteDef *regs, ColorByte *data ) 471141cc406Sopenharmony_ci{ 472141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 473141cc406Sopenharmony_ci 474141cc406Sopenharmony_ci u12shading_GainOffsetToDAC(dev, _DAC_RED, regs->Red, data->Colors.Red); 475141cc406Sopenharmony_ci u12shading_GainOffsetToDAC(dev, _DAC_GREENCOLOR, 476141cc406Sopenharmony_ci regs->Green, data->Colors.Green); 477141cc406Sopenharmony_ci u12shading_GainOffsetToDAC(dev, _DAC_BLUE, 478141cc406Sopenharmony_ci regs->Blue, data->Colors.Blue); 479141cc406Sopenharmony_ci } else { 480141cc406Sopenharmony_ci u12shading_GainOffsetToDAC(dev, _DAC_GREENMONO, regs->Green, 481141cc406Sopenharmony_ci data->Colors.Green); 482141cc406Sopenharmony_ci } 483141cc406Sopenharmony_ci} 484141cc406Sopenharmony_ci 485141cc406Sopenharmony_ci/** 486141cc406Sopenharmony_ci */ 487141cc406Sopenharmony_cistatic SANE_Byte u12shading_SumGains( SANE_Byte *pb, u_long pixelsLine ) 488141cc406Sopenharmony_ci{ 489141cc406Sopenharmony_ci SANE_Byte hilight, tmp; 490141cc406Sopenharmony_ci u_long dwPixels, dwAve; 491141cc406Sopenharmony_ci u_short sum; 492141cc406Sopenharmony_ci 493141cc406Sopenharmony_ci hilight = 0; 494141cc406Sopenharmony_ci for( dwPixels = pixelsLine >> 4; dwPixels--; ) { 495141cc406Sopenharmony_ci 496141cc406Sopenharmony_ci for( sum = 0, dwAve = 16; dwAve--; pb++ ) 497141cc406Sopenharmony_ci sum += (u_short)*pb; 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci sum >>= 4; 500141cc406Sopenharmony_ci tmp = (SANE_Byte)sum; 501141cc406Sopenharmony_ci 502141cc406Sopenharmony_ci if( tmp > hilight ) 503141cc406Sopenharmony_ci hilight = tmp; 504141cc406Sopenharmony_ci } 505141cc406Sopenharmony_ci return hilight; 506141cc406Sopenharmony_ci} 507141cc406Sopenharmony_ci 508141cc406Sopenharmony_ci/** 509141cc406Sopenharmony_ci */ 510141cc406Sopenharmony_cistatic void 511141cc406Sopenharmony_ciu12shading_AdjustGain( U12_Device *dev, u_long color, SANE_Byte hilight ) 512141cc406Sopenharmony_ci{ 513141cc406Sopenharmony_ci if( hilight < dev->shade.bGainLow ) { 514141cc406Sopenharmony_ci 515141cc406Sopenharmony_ci if( dev->shade.Hilight.bColors[color] < dev->shade.bGainHigh ) { 516141cc406Sopenharmony_ci 517141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 518141cc406Sopenharmony_ci dev->shade.Hilight.bColors[color] = hilight; 519141cc406Sopenharmony_ci 520141cc406Sopenharmony_ci if( hilight <= (SANE_Byte)(dev->shade.bGainLow - hilight)) 521141cc406Sopenharmony_ci dev->shade.Gain.bColors[color] += dev->shade.bGainDouble; 522141cc406Sopenharmony_ci else 523141cc406Sopenharmony_ci dev->shade.Gain.bColors[color]++; 524141cc406Sopenharmony_ci } 525141cc406Sopenharmony_ci } else { 526141cc406Sopenharmony_ci if( hilight > dev->shade.bGainHigh ) { 527141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 528141cc406Sopenharmony_ci dev->shade.Hilight.bColors[color] = hilight; 529141cc406Sopenharmony_ci dev->shade.Gain.bColors[color]--; 530141cc406Sopenharmony_ci } else { 531141cc406Sopenharmony_ci dev->shade.Hilight.bColors[color] = hilight; 532141cc406Sopenharmony_ci } 533141cc406Sopenharmony_ci } 534141cc406Sopenharmony_ci 535141cc406Sopenharmony_ci if( dev->shade.Gain.bColors[color] > dev->shade.bMaxGain ) { 536141cc406Sopenharmony_ci dev->shade.Gain.bColors[color] = dev->shade.bMaxGain; 537141cc406Sopenharmony_ci } 538141cc406Sopenharmony_ci} 539141cc406Sopenharmony_ci 540141cc406Sopenharmony_ci/** 541141cc406Sopenharmony_ci */ 542141cc406Sopenharmony_cistatic SANE_Status u12shading_AdjustRGBGain( U12_Device *dev ) 543141cc406Sopenharmony_ci{ 544141cc406Sopenharmony_ci int i; 545141cc406Sopenharmony_ci SANE_Byte hi[3]; 546141cc406Sopenharmony_ci 547141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_AdjustRGBGain()\n" ); 548141cc406Sopenharmony_ci 549141cc406Sopenharmony_ci dev->shade.Gain.Colors.Red = 550141cc406Sopenharmony_ci dev->shade.Gain.Colors.Green = 551141cc406Sopenharmony_ci dev->shade.Gain.Colors.Blue = dev->shade.bUniGain; 552141cc406Sopenharmony_ci 553141cc406Sopenharmony_ci dev->shade.Hilight.Colors.Red = 554141cc406Sopenharmony_ci dev->shade.Hilight.Colors.Green = 555141cc406Sopenharmony_ci dev->shade.Hilight.Colors.Blue = 0; 556141cc406Sopenharmony_ci 557141cc406Sopenharmony_ci dev->shade.bGainHigh = _GAIN_HIGH; 558141cc406Sopenharmony_ci dev->shade.bGainLow = _GAIN_LOW; 559141cc406Sopenharmony_ci 560141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 561141cc406Sopenharmony_ci 562141cc406Sopenharmony_ci for( i = 10; i-- && !dev->shade.fStop; ) { 563141cc406Sopenharmony_ci 564141cc406Sopenharmony_ci if( u12io_IsEscPressed()) { 565141cc406Sopenharmony_ci DBG( _DBG_INFO, "* CANCEL detected!\n" ); 566141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 567141cc406Sopenharmony_ci } 568141cc406Sopenharmony_ci 569141cc406Sopenharmony_ci dev->shade.fStop = SANE_TRUE; 570141cc406Sopenharmony_ci 571141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MODECONTROL, _ModeIdle ); 572141cc406Sopenharmony_ci 573141cc406Sopenharmony_ci dev->regs.RD_ScanControl = _SCAN_BYTEMODE; 574141cc406Sopenharmony_ci u12hw_SelectLampSource( dev ); 575141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_SCANCONTROL, dev->regs.RD_ScanControl ); 576141cc406Sopenharmony_ci 577141cc406Sopenharmony_ci u12shading_FillToDAC( dev, &dev->RegDACGain, &dev->shade.Gain ); 578141cc406Sopenharmony_ci 579141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeScan; 580141cc406Sopenharmony_ci dev->regs.RD_StepControl = _MOTOR0_SCANSTATE; 581141cc406Sopenharmony_ci dev->regs.RD_Motor0Control = _FORWARD_MOTOR; 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) 584141cc406Sopenharmony_ci dev->regs.RD_Origin = (u_short)_DATA_ORIGIN_X >> 1; 585141cc406Sopenharmony_ci else 586141cc406Sopenharmony_ci dev->regs.RD_Origin = (u_short)_DATA_ORIGIN_X; 587141cc406Sopenharmony_ci 588141cc406Sopenharmony_ci dev->regs.RD_Dpi = 300; 589141cc406Sopenharmony_ci dev->regs.RD_Pixels = 2560; 590141cc406Sopenharmony_ci 591141cc406Sopenharmony_ci memset( dev->scanStates, 0, _SCANSTATE_BYTES ); 592141cc406Sopenharmony_ci dev->scanStates[1] = 0x77; 593141cc406Sopenharmony_ci 594141cc406Sopenharmony_ci u12io_PutOnAllRegisters( dev ); 595141cc406Sopenharmony_ci/* _DODELAY( 100 ); */ 596141cc406Sopenharmony_ci 597141cc406Sopenharmony_ci /* read one shading line and work on it */ 598141cc406Sopenharmony_ci if( u12io_ReadOneShadingLine( dev, 599141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam, 2560)) { 600141cc406Sopenharmony_ci 601141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType <= COLOR_256GRAY ) { 602141cc406Sopenharmony_ci 603141cc406Sopenharmony_ci hi[1] = u12shading_SumGains( 604141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam + 2560, 2560); 605141cc406Sopenharmony_ci if( hi[1] ) { 606141cc406Sopenharmony_ci u12shading_AdjustGain( dev, _CHANNEL_GREEN, hi[1] ); 607141cc406Sopenharmony_ci } else { 608141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 609141cc406Sopenharmony_ci } 610141cc406Sopenharmony_ci } else { 611141cc406Sopenharmony_ci hi[0] = u12shading_SumGains( 612141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam, 2560); 613141cc406Sopenharmony_ci hi[1] = u12shading_SumGains( 614141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam + 2560, 2560); 615141cc406Sopenharmony_ci hi[2] = u12shading_SumGains( 616141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam + 5120, 2560); 617141cc406Sopenharmony_ci 618141cc406Sopenharmony_ci if (!hi[0] || !hi[1] || !hi[2] ) { 619141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 620141cc406Sopenharmony_ci } else { 621141cc406Sopenharmony_ci u12shading_AdjustGain( dev, _CHANNEL_RED, hi[0] ); 622141cc406Sopenharmony_ci u12shading_AdjustGain( dev, _CHANNEL_GREEN, hi[1] ); 623141cc406Sopenharmony_ci u12shading_AdjustGain( dev, _CHANNEL_BLUE, hi[2] ); 624141cc406Sopenharmony_ci } 625141cc406Sopenharmony_ci } 626141cc406Sopenharmony_ci } else 627141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 628141cc406Sopenharmony_ci } 629141cc406Sopenharmony_ci 630141cc406Sopenharmony_ci if( !dev->shade.fStop ) 631141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_AdjustRGBGain() - all loops done!!!\n" ); 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_ci u12shading_FillToDAC( dev, &dev->RegDACGain, &dev->shade.Gain ); 634141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 635141cc406Sopenharmony_ci} 636141cc406Sopenharmony_ci 637141cc406Sopenharmony_ci/** 638141cc406Sopenharmony_ci */ 639141cc406Sopenharmony_cistatic u_short u12shading_SumDarks( U12_Device *dev, u_short *data ) 640141cc406Sopenharmony_ci{ 641141cc406Sopenharmony_ci u_short i, loop; 642141cc406Sopenharmony_ci 643141cc406Sopenharmony_ci if( dev->CCDID == _CCD_3799 ) { 644141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) 645141cc406Sopenharmony_ci data += 0x18; 646141cc406Sopenharmony_ci else 647141cc406Sopenharmony_ci data += 0x30; 648141cc406Sopenharmony_ci } else { 649141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) 650141cc406Sopenharmony_ci data += 0x18; 651141cc406Sopenharmony_ci else 652141cc406Sopenharmony_ci data += 0x20; 653141cc406Sopenharmony_ci } 654141cc406Sopenharmony_ci 655141cc406Sopenharmony_ci for( i = 0, loop = 16; loop--; data++ ) 656141cc406Sopenharmony_ci i += *data; 657141cc406Sopenharmony_ci i >>= 4; 658141cc406Sopenharmony_ci 659141cc406Sopenharmony_ci return i; 660141cc406Sopenharmony_ci} 661141cc406Sopenharmony_ci 662141cc406Sopenharmony_ci/** 663141cc406Sopenharmony_ci */ 664141cc406Sopenharmony_cistatic SANE_Status u12shadingAdjustDark( U12_Device *dev ) 665141cc406Sopenharmony_ci{ 666141cc406Sopenharmony_ci u_long i; 667141cc406Sopenharmony_ci u_short wDarks[3]; 668141cc406Sopenharmony_ci 669141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shadingAdjustDark()\n" ); 670141cc406Sopenharmony_ci dev->shade.DarkDAC.Colors = dev->shade.pCcdDac->DarkDAC.Colors; 671141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 672141cc406Sopenharmony_ci 673141cc406Sopenharmony_ci for( i = 16; i-- && !dev->shade.fStop;) { 674141cc406Sopenharmony_ci 675141cc406Sopenharmony_ci if( u12io_IsEscPressed()) { 676141cc406Sopenharmony_ci DBG( _DBG_INFO, "* CANCEL detected!\n" ); 677141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 678141cc406Sopenharmony_ci } 679141cc406Sopenharmony_ci 680141cc406Sopenharmony_ci dev->shade.fStop = SANE_TRUE; 681141cc406Sopenharmony_ci 682141cc406Sopenharmony_ci u12shading_FillToDAC( dev, &dev->RegDACOffset, &dev->shade.DarkDAC ); 683141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_MODECONTROL, _ModeIdle ); 684141cc406Sopenharmony_ci 685141cc406Sopenharmony_ci dev->regs.RD_ScanControl = (_SCAN_12BITMODE + _SCAN_1ST_AVERAGE); 686141cc406Sopenharmony_ci u12hw_SelectLampSource( dev ); 687141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_SCANCONTROL, dev->regs.RD_ScanControl ); 688141cc406Sopenharmony_ci 689141cc406Sopenharmony_ci dev->regs.RD_StepControl = _MOTOR0_SCANSTATE; 690141cc406Sopenharmony_ci dev->regs.RD_Motor0Control = _FORWARD_MOTOR; 691141cc406Sopenharmony_ci 692141cc406Sopenharmony_ci dev->regs.RD_Origin = _SHADING_BEGINX; 693141cc406Sopenharmony_ci dev->regs.RD_Pixels = 512; 694141cc406Sopenharmony_ci 695141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) 696141cc406Sopenharmony_ci dev->regs.RD_Dpi = 300; 697141cc406Sopenharmony_ci else 698141cc406Sopenharmony_ci dev->regs.RD_Dpi = 600; 699141cc406Sopenharmony_ci 700141cc406Sopenharmony_ci memset( dev->scanStates, 0, _SCANSTATE_BYTES ); 701141cc406Sopenharmony_ci dev->scanStates[1] = 0x77; 702141cc406Sopenharmony_ci 703141cc406Sopenharmony_ci u12io_PutOnAllRegisters( dev ); 704141cc406Sopenharmony_ci/* _DODELAY( 100 ); */ 705141cc406Sopenharmony_ci 706141cc406Sopenharmony_ci /* read one shading line and work on it */ 707141cc406Sopenharmony_ci if( u12io_ReadOneShadingLine(dev, 708141cc406Sopenharmony_ci (SANE_Byte*)dev->bufs.b1.pShadingRam, 512*2)) { 709141cc406Sopenharmony_ci 710141cc406Sopenharmony_ci if ( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 711141cc406Sopenharmony_ci 712141cc406Sopenharmony_ci wDarks[0] = u12shading_SumDarks(dev, dev->bufs.b1.pShadingRam); 713141cc406Sopenharmony_ci wDarks[1] = u12shading_SumDarks(dev, dev->bufs.b1.pShadingRam + 714141cc406Sopenharmony_ci dev->regs.RD_Pixels ); 715141cc406Sopenharmony_ci wDarks[2] = u12shading_SumDarks(dev, dev->bufs.b1.pShadingRam + 716141cc406Sopenharmony_ci dev->regs.RD_Pixels * 2UL); 717141cc406Sopenharmony_ci 718141cc406Sopenharmony_ci if( !wDarks[0] || !wDarks[1] || !wDarks[2] ) { 719141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 720141cc406Sopenharmony_ci } else { 721141cc406Sopenharmony_ci dev->shade.DarkOffset.wColors[0] = wDarks[0]; 722141cc406Sopenharmony_ci dev->shade.DarkOffset.wColors[1] = wDarks[1]; 723141cc406Sopenharmony_ci dev->shade.DarkOffset.wColors[2] = wDarks[2]; 724141cc406Sopenharmony_ci (*dev->fnDACDark)( dev,dev->shade.pCcdDac, 725141cc406Sopenharmony_ci _CHANNEL_RED, wDarks[0] ); 726141cc406Sopenharmony_ci (*dev->fnDACDark)( dev, dev->shade.pCcdDac, 727141cc406Sopenharmony_ci _CHANNEL_GREEN, wDarks[1] ); 728141cc406Sopenharmony_ci (*dev->fnDACDark)( dev, dev->shade.pCcdDac, 729141cc406Sopenharmony_ci _CHANNEL_BLUE, wDarks[2] ); 730141cc406Sopenharmony_ci } 731141cc406Sopenharmony_ci } else { 732141cc406Sopenharmony_ci wDarks[1] = u12shading_SumDarks(dev, dev->bufs.b1.pShadingRam + 733141cc406Sopenharmony_ci dev->regs.RD_Pixels ); 734141cc406Sopenharmony_ci if(!wDarks[1] ) { 735141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 736141cc406Sopenharmony_ci } else { 737141cc406Sopenharmony_ci dev->shade.DarkOffset.wColors[1] = wDarks[1]; 738141cc406Sopenharmony_ci (*dev->fnDACDark)( dev, dev->shade.pCcdDac, 739141cc406Sopenharmony_ci _CHANNEL_GREEN, wDarks[1] ); 740141cc406Sopenharmony_ci } 741141cc406Sopenharmony_ci } 742141cc406Sopenharmony_ci } else { 743141cc406Sopenharmony_ci dev->shade.fStop = SANE_FALSE; 744141cc406Sopenharmony_ci } 745141cc406Sopenharmony_ci } 746141cc406Sopenharmony_ci 747141cc406Sopenharmony_ci /* CalculateDarkDependOnCCD() */ 748141cc406Sopenharmony_ci if ( dev->DataInf.wPhyDataType > COLOR_256GRAY ) { 749141cc406Sopenharmony_ci (*dev->fnDarkOffset)( dev, dev->shade.pCcdDac, _CHANNEL_RED ); 750141cc406Sopenharmony_ci (*dev->fnDarkOffset)( dev, dev->shade.pCcdDac, _CHANNEL_GREEN ); 751141cc406Sopenharmony_ci (*dev->fnDarkOffset)( dev, dev->shade.pCcdDac, _CHANNEL_BLUE ); 752141cc406Sopenharmony_ci } else { 753141cc406Sopenharmony_ci (*dev->fnDarkOffset)( dev, dev->shade.pCcdDac, _CHANNEL_GREEN ); 754141cc406Sopenharmony_ci } 755141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 756141cc406Sopenharmony_ci} 757141cc406Sopenharmony_ci 758141cc406Sopenharmony_ci/** here we download the current mapping table 759141cc406Sopenharmony_ci */ 760141cc406Sopenharmony_cistatic void u12shading_DownloadMapTable( U12_Device *dev, SANE_Byte *buf ) 761141cc406Sopenharmony_ci{ 762141cc406Sopenharmony_ci SANE_Byte addr, regs[6]; 763141cc406Sopenharmony_ci int i; 764141cc406Sopenharmony_ci 765141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_SCANCONTROL, 766141cc406Sopenharmony_ci (SANE_Byte)((dev->regs.RD_ScanControl & 0xfc) | _SCAN_BYTEMODE)); 767141cc406Sopenharmony_ci 768141cc406Sopenharmony_ci /* prepare register settings... */ 769141cc406Sopenharmony_ci regs[0] = REG_MODECONTROL; 770141cc406Sopenharmony_ci regs[1] = _ModeMappingMem; 771141cc406Sopenharmony_ci regs[2] = REG_MEMORYLO; 772141cc406Sopenharmony_ci regs[3] = 0; 773141cc406Sopenharmony_ci regs[4] = REG_MEMORYHI; 774141cc406Sopenharmony_ci 775141cc406Sopenharmony_ci for( i = 3, addr = _MAP_ADDR_RED; i--; addr += _MAP_ADDR_SIZE ) { 776141cc406Sopenharmony_ci 777141cc406Sopenharmony_ci regs[5] = addr; 778141cc406Sopenharmony_ci u12io_DataToRegs( dev, regs, 3 ); 779141cc406Sopenharmony_ci 780141cc406Sopenharmony_ci u12io_MoveDataToScanner( dev, buf, 4096 ); 781141cc406Sopenharmony_ci buf += 4096; 782141cc406Sopenharmony_ci } 783141cc406Sopenharmony_ci 784141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_SCANCONTROL, dev->regs.RD_ScanControl ); 785141cc406Sopenharmony_ci} 786141cc406Sopenharmony_ci 787141cc406Sopenharmony_ci/** 788141cc406Sopenharmony_ci */ 789141cc406Sopenharmony_cistatic SANE_Status u12shading_DoCalibration( U12_Device *dev ) 790141cc406Sopenharmony_ci{ 791141cc406Sopenharmony_ci SANE_Byte tb[4096*3]; 792141cc406Sopenharmony_ci u_long i, tmp; 793141cc406Sopenharmony_ci SANE_Byte bScanControl, rb[20]; 794141cc406Sopenharmony_ci SANE_Status res; 795141cc406Sopenharmony_ci int c; 796141cc406Sopenharmony_ci 797141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_DoCalibration()\n" ); 798141cc406Sopenharmony_ci 799141cc406Sopenharmony_ci /** before getting the shading data, (re)init the ASIC 800141cc406Sopenharmony_ci */ 801141cc406Sopenharmony_ci u12hw_InitAsic( dev, SANE_TRUE ); 802141cc406Sopenharmony_ci 803141cc406Sopenharmony_ci dev->shade.DarkOffset.Colors.Red = 0; 804141cc406Sopenharmony_ci dev->shade.DarkOffset.Colors.Green = 0; 805141cc406Sopenharmony_ci dev->shade.DarkOffset.Colors.Blue = 0; 806141cc406Sopenharmony_ci 807141cc406Sopenharmony_ci c = 0; 808141cc406Sopenharmony_ci _SET_REG( rb, c, REG_RESETMTSC, 0 ); 809141cc406Sopenharmony_ci _SET_REG( rb, c, REG_MODELCONTROL, dev->regs.RD_ModelControl); 810141cc406Sopenharmony_ci _SET_REG( rb, c, REG_MOTORDRVTYPE, dev->regs.RD_MotorDriverType ); 811141cc406Sopenharmony_ci _SET_REG( rb, c, REG_SCANCONTROL1, (_SCANSTOPONBUFFULL| _MFRC_BY_XSTEP)); 812141cc406Sopenharmony_ci 813141cc406Sopenharmony_ci u12io_DataToRegs( dev, rb, c ); 814141cc406Sopenharmony_ci 815141cc406Sopenharmony_ci res = u12motor_GotoShadingPosition( dev ); 816141cc406Sopenharmony_ci if( SANE_STATUS_GOOD != res ) 817141cc406Sopenharmony_ci return res; 818141cc406Sopenharmony_ci 819141cc406Sopenharmony_ci bScanControl = dev->regs.RD_ScanControl; 820141cc406Sopenharmony_ci 821141cc406Sopenharmony_ci /* SetShadingMapForGainDark */ 822141cc406Sopenharmony_ci memset( dev->bufs.b2.pSumBuf, 0xff, (5400 * 3 * 2)); 823141cc406Sopenharmony_ci u12shading_DownloadShadingTable( dev, dev->bufs.b2.pSumBuf, (5400*3*2)); 824141cc406Sopenharmony_ci 825141cc406Sopenharmony_ci for( i = 0, tmp = 0; i < 1024; tmp += 0x01010101, i += 4 ) { 826141cc406Sopenharmony_ci dev->bufs.b1.Buf.pdw[i] = 827141cc406Sopenharmony_ci dev->bufs.b1.Buf.pdw[i+1] = 828141cc406Sopenharmony_ci dev->bufs.b1.Buf.pdw[i+2] = 829141cc406Sopenharmony_ci dev->bufs.b1.Buf.pdw[i+3] = tmp; 830141cc406Sopenharmony_ci } 831141cc406Sopenharmony_ci 832141cc406Sopenharmony_ci memcpy( dev->bufs.b1.pShadingMap + 4096, dev->bufs.b1.pShadingMap, 4096 ); 833141cc406Sopenharmony_ci memcpy( dev->bufs.b1.pShadingMap + 8192, dev->bufs.b1.pShadingMap, 4096 ); 834141cc406Sopenharmony_ci u12shading_DownloadMapTable( dev, dev->bufs.b1.pShadingMap ); 835141cc406Sopenharmony_ci 836141cc406Sopenharmony_ci DBG( _DBG_INFO, "* wExposure = %u\n", dev->shade.wExposure); 837141cc406Sopenharmony_ci DBG( _DBG_INFO, "* wXStep = %u\n", dev->shade.wXStep); 838141cc406Sopenharmony_ci 839141cc406Sopenharmony_ci dev->regs.RD_LineControl = (_LOBYTE(dev->shade.wExposure)); 840141cc406Sopenharmony_ci dev->regs.RD_ExtLineControl = (_HIBYTE(dev->shade.wExposure)); 841141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_EXTENDEDLINECONTROL, 842141cc406Sopenharmony_ci dev->regs.RD_ExtLineControl ); 843141cc406Sopenharmony_ci u12io_DataToRegister( dev, REG_LINECONTROL, dev->regs.RD_LineControl ); 844141cc406Sopenharmony_ci 845141cc406Sopenharmony_ci res = u12shading_AdjustRGBGain( dev ); 846141cc406Sopenharmony_ci if( SANE_STATUS_GOOD != res ) 847141cc406Sopenharmony_ci return res; 848141cc406Sopenharmony_ci 849141cc406Sopenharmony_ci res = u12shadingAdjustDark( dev ); 850141cc406Sopenharmony_ci if( SANE_STATUS_GOOD != res ) 851141cc406Sopenharmony_ci return res; 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci res = u12shadingAdjustShadingWaveform( dev ); 854141cc406Sopenharmony_ci if( SANE_STATUS_GOOD != res ) 855141cc406Sopenharmony_ci return res; 856141cc406Sopenharmony_ci 857141cc406Sopenharmony_ci dev->regs.RD_ScanControl = bScanControl; 858141cc406Sopenharmony_ci 859141cc406Sopenharmony_ci /* here we have to prepare and download the table in any case...*/ 860141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType <= COLOR_256GRAY ) { 861141cc406Sopenharmony_ci u12map_Adjust( dev, _MAP_MASTER, tb ); 862141cc406Sopenharmony_ci } else { 863141cc406Sopenharmony_ci u12map_Adjust( dev, _MAP_RED, tb ); 864141cc406Sopenharmony_ci u12map_Adjust( dev, _MAP_GREEN, tb ); 865141cc406Sopenharmony_ci u12map_Adjust( dev, _MAP_BLUE, tb ); 866141cc406Sopenharmony_ci } 867141cc406Sopenharmony_ci 868141cc406Sopenharmony_ci u12shading_DownloadMapTable( dev, tb ); 869141cc406Sopenharmony_ci 870141cc406Sopenharmony_ci u12motor_BackToHomeSensor( dev ); 871141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12shading_DoCalibration() - done.\n" ); 872141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 873141cc406Sopenharmony_ci} 874141cc406Sopenharmony_ci 875141cc406Sopenharmony_ci/* END U12-SHADING ..........................................................*/ 876