1141cc406Sopenharmony_ci/* @file u12_image.c 2141cc406Sopenharmony_ci * @brief functions to convert scanner data into image data 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 - fixed fnColor42() to return 16bit values instead of 10141cc406Sopenharmony_ci * only 12bit (this is the maximum the scanner can) 11141cc406Sopenharmony_ci * - added scaling function u12image_ScaleX() 12141cc406Sopenharmony_ci * . 13141cc406Sopenharmony_ci * <hr> 14141cc406Sopenharmony_ci * This file is part of the SANE package. 15141cc406Sopenharmony_ci * 16141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or 17141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as 18141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 19141cc406Sopenharmony_ci * License, or (at your option) any later version. 20141cc406Sopenharmony_ci * 21141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 22141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 23141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24141cc406Sopenharmony_ci * General Public License for more details. 25141cc406Sopenharmony_ci * 26141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License 27141cc406Sopenharmony_ci * along with this program. If not, see <https://www.gnu.org/licenses/>. 28141cc406Sopenharmony_ci * 29141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for 30141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE. 31141cc406Sopenharmony_ci * 32141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files 33141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the 34141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public 35141cc406Sopenharmony_ci * License. Your use of that executable is in no way restricted on 36141cc406Sopenharmony_ci * account of linking the SANE library code into it. 37141cc406Sopenharmony_ci * 38141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why 39141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public 40141cc406Sopenharmony_ci * License. 41141cc406Sopenharmony_ci * 42141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in 43141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that 44141cc406Sopenharmony_ci * those changes may be distributed with this exception intact. 45141cc406Sopenharmony_ci * 46141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice 47141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications. 48141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice. 49141cc406Sopenharmony_ci * <hr> 50141cc406Sopenharmony_ci */ 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_ci/*************************** local vars **************************************/ 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_cistatic u_short wPreviewScanned = 0; 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_cistatic ExpXStepDef negScan[5] = { 57141cc406Sopenharmony_ci {128, 8}, {96, 12}, {96, 24}, {96, 48}, {96, 96} 58141cc406Sopenharmony_ci}; 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_cistatic ExpXStepDef posScan[5] = { 61141cc406Sopenharmony_ci {128, 8}, {96, 12}, {96, 24}, {96, 48}, {96, 96} 62141cc406Sopenharmony_ci}; 63141cc406Sopenharmony_ci 64141cc406Sopenharmony_cistatic ExpXStepDef nmlScan[5] = { 65141cc406Sopenharmony_ci {160, 10}, {96, 12}, {96, 24}, {96, 48}, {96, 96}, 66141cc406Sopenharmony_ci}; 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_ci/*************************** local functions *********************************/ 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci/** 71141cc406Sopenharmony_ci */ 72141cc406Sopenharmony_cistatic SANE_Bool fnReadToDriver( U12_Device *dev ) 73141cc406Sopenharmony_ci{ 74141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoBSel; 75141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->scan.BufPut.blue.bp, 76141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 77141cc406Sopenharmony_ci 78141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoGSel; 79141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->scan.BufPut.green.bp, 80141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 81141cc406Sopenharmony_ci 82141cc406Sopenharmony_ci if( dev->scan.gd_gk.wGreenKeep ) 83141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenKeep--; 84141cc406Sopenharmony_ci else { 85141cc406Sopenharmony_ci dev->scan.BufPut.green.bp += dev->DataInf.dwAsicBytesPerPlane; 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_ci if( dev->scan.BufPut.green.bp >= dev->scan.BufEnd.green.bp ) 88141cc406Sopenharmony_ci dev->scan.BufPut.green.bp = dev->scan.BufBegin.green.bp; 89141cc406Sopenharmony_ci } 90141cc406Sopenharmony_ci 91141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoRSel; 92141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->scan.BufPut.red.bp, 93141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_ci dev->scan.BufPut.red.bp += dev->DataInf.dwAsicBytesPerPlane; 96141cc406Sopenharmony_ci if( dev->scan.BufPut.red.bp >= dev->scan.BufEnd.red.bp ) 97141cc406Sopenharmony_ci dev->scan.BufPut.red.bp = dev->scan.BufBegin.red.bp; 98141cc406Sopenharmony_ci 99141cc406Sopenharmony_ci if( dev->scan.bd_rk.wRedKeep ) { 100141cc406Sopenharmony_ci dev->scan.bd_rk.wRedKeep--; 101141cc406Sopenharmony_ci return SANE_FALSE; 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci } else { 104141cc406Sopenharmony_ci 105141cc406Sopenharmony_ci dev->scan.BufData.green.bp = dev->scan.BufGet.green.bp; 106141cc406Sopenharmony_ci dev->scan.BufData.red.bp = dev->scan.BufGet.red.bp; 107141cc406Sopenharmony_ci dev->scan.BufData.blue.bp = dev->scan.BufGet.blue.bp; 108141cc406Sopenharmony_ci 109141cc406Sopenharmony_ci dev->scan.BufGet.red.bp += dev->DataInf.dwAsicBytesPerPlane; 110141cc406Sopenharmony_ci dev->scan.BufGet.green.bp += dev->DataInf.dwAsicBytesPerPlane; 111141cc406Sopenharmony_ci 112141cc406Sopenharmony_ci if( dev->scan.BufGet.red.bp >= dev->scan.BufEnd.red.bp ) 113141cc406Sopenharmony_ci dev->scan.BufGet.red.bp = dev->scan.BufBegin.red.bp; 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_ci if( dev->scan.BufGet.green.bp >= dev->scan.BufEnd.green.bp ) 116141cc406Sopenharmony_ci dev->scan.BufGet.green.bp = dev->scan.BufBegin.green.bp; 117141cc406Sopenharmony_ci 118141cc406Sopenharmony_ci return SANE_TRUE; 119141cc406Sopenharmony_ci } 120141cc406Sopenharmony_ci} 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci/** 123141cc406Sopenharmony_ci */ 124141cc406Sopenharmony_cistatic SANE_Bool fnReadOutScanner( U12_Device *dev ) 125141cc406Sopenharmony_ci{ 126141cc406Sopenharmony_ci if( dev->scan.bd_rk.wBlueDiscard ) { 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_ci dev->scan.bd_rk.wBlueDiscard--; 129141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoBSel; 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->bufs.b1.pReadBuf, 132141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 133141cc406Sopenharmony_ci 134141cc406Sopenharmony_ci if( dev->scan.gd_gk.wGreenDiscard ) { 135141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenDiscard--; 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoGSel; 138141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->bufs.b1.pReadBuf, 139141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 140141cc406Sopenharmony_ci } 141141cc406Sopenharmony_ci return SANE_FALSE; 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci } else { 144141cc406Sopenharmony_ci u12io_ReadColorData( dev, dev->bufs.b1.pReadBuf, 145141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 146141cc406Sopenharmony_ci return SANE_TRUE; 147141cc406Sopenharmony_ci } 148141cc406Sopenharmony_ci} 149141cc406Sopenharmony_ci 150141cc406Sopenharmony_ci/** some sampling functions 151141cc406Sopenharmony_ci */ 152141cc406Sopenharmony_cistatic SANE_Bool fnEveryLine( U12_Device *dev ) 153141cc406Sopenharmony_ci{ 154141cc406Sopenharmony_ci _VAR_NOT_USED( dev ); 155141cc406Sopenharmony_ci return SANE_TRUE; 156141cc406Sopenharmony_ci} 157141cc406Sopenharmony_ci 158141cc406Sopenharmony_cistatic SANE_Bool fnSampleLines( U12_Device *dev ) 159141cc406Sopenharmony_ci{ 160141cc406Sopenharmony_ci dev->DataInf.wYSum += dev->DataInf.xyAppDpi.y; 161141cc406Sopenharmony_ci 162141cc406Sopenharmony_ci if( dev->DataInf.wYSum >= dev->DataInf.xyPhyDpi.y ) { 163141cc406Sopenharmony_ci dev->DataInf.wYSum -= dev->DataInf.xyPhyDpi.y; 164141cc406Sopenharmony_ci return SANE_TRUE; 165141cc406Sopenharmony_ci } 166141cc406Sopenharmony_ci return SANE_FALSE; 167141cc406Sopenharmony_ci} 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_cistatic SANE_Bool fnSamplePreview( U12_Device *dev ) 170141cc406Sopenharmony_ci{ 171141cc406Sopenharmony_ci dev->DataInf.wYSum += wPreviewScanned; 172141cc406Sopenharmony_ci if( dev->DataInf.wYSum >= 150 ) { 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_ci dev->DataInf.wYSum -= 150; 175141cc406Sopenharmony_ci return SANE_TRUE; 176141cc406Sopenharmony_ci } 177141cc406Sopenharmony_ci 178141cc406Sopenharmony_ci return SANE_FALSE; 179141cc406Sopenharmony_ci} 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci/** this function is used when 182141cc406Sopenharmony_ci * - the data type is B/W or GrayScale. 183141cc406Sopenharmony_ci * - the required horizontal resolution doesn't exceed the optic spec. 184141cc406Sopenharmony_ci * - the required vertical resolution exceeds the optic spec. 185141cc406Sopenharmony_ci */ 186141cc406Sopenharmony_cistatic void fnDataDirect( U12_Device *dev, void *src, void *dest, u_long len ) 187141cc406Sopenharmony_ci{ 188141cc406Sopenharmony_ci _VAR_NOT_USED( dev ); 189141cc406Sopenharmony_ci memcpy( dest, src, len ); 190141cc406Sopenharmony_ci} 191141cc406Sopenharmony_ci 192141cc406Sopenharmony_ci/** merges the color planes to pixels style without enlarge operation. 193141cc406Sopenharmony_ci */ 194141cc406Sopenharmony_cistatic void fnColorDirect( U12_Device *dev, void *pb, void *img, u_long len ) 195141cc406Sopenharmony_ci{ 196141cc406Sopenharmony_ci SANE_Byte *src; 197141cc406Sopenharmony_ci RGBByteDef *dest; 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci src = (SANE_Byte*)img; 200141cc406Sopenharmony_ci dest = (RGBByteDef*)pb; 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_ci for ( len = dev->DataInf.dwAsicPixelsPerPlane; len; len--, src++, dest++) { 203141cc406Sopenharmony_ci 204141cc406Sopenharmony_ci dest->Red = *src; 205141cc406Sopenharmony_ci dest->Green = src[dev->DataInf.dwAsicPixelsPerPlane]; 206141cc406Sopenharmony_ci dest->Blue = src[dev->DataInf.dwAsicPixelsPerPlane*2]; 207141cc406Sopenharmony_ci } 208141cc406Sopenharmony_ci} 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci/** merges the color planes to pixels style without enlarge operation. 211141cc406Sopenharmony_ci * The scanner returns the pixel data in Motorola-Format, so we have to swap 212141cc406Sopenharmony_ci * (at least on x86) 213141cc406Sopenharmony_ci */ 214141cc406Sopenharmony_cistatic void fnColor42( U12_Device *dev, void *pb, void *img, u_long len ) 215141cc406Sopenharmony_ci{ 216141cc406Sopenharmony_ci u_short *src; 217141cc406Sopenharmony_ci RGBUShortDef *dest; 218141cc406Sopenharmony_ci 219141cc406Sopenharmony_ci register u_long i; 220141cc406Sopenharmony_ci 221141cc406Sopenharmony_ci _VAR_NOT_USED( len ); 222141cc406Sopenharmony_ci src = (u_short*)img; 223141cc406Sopenharmony_ci dest = (RGBUShortDef*)pb; 224141cc406Sopenharmony_ci 225141cc406Sopenharmony_ci for ( i = dev->DataInf.dwAsicPixelsPerPlane; i; i--, src++, dest++) { 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci dest->Red = (*src) << 4; 228141cc406Sopenharmony_ci dest->Green = (src[dev->DataInf.dwAsicPixelsPerPlane]) << 4; 229141cc406Sopenharmony_ci dest->Blue = (src[dev->DataInf.dwAsicPixelsPerPlane * 2]) << 4; 230141cc406Sopenharmony_ci } 231141cc406Sopenharmony_ci} 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci/** 234141cc406Sopenharmony_ci */ 235141cc406Sopenharmony_cistatic void u12image_SetupScanStateVariables( U12_Device *dev, u_long index ) 236141cc406Sopenharmony_ci{ 237141cc406Sopenharmony_ci DataType var; 238141cc406Sopenharmony_ci 239141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12image_SetupScanStateVariables(%lu)\n", index ); 240141cc406Sopenharmony_ci dev->scan.dpiIdx = index; 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci if(!(dev->DataInf.dwScanFlag & _SCANDEF_TPA)) { 243141cc406Sopenharmony_ci 244141cc406Sopenharmony_ci dev->shade.wExposure = nmlScan[index].exposureTime; 245141cc406Sopenharmony_ci dev->shade.wXStep = nmlScan[index].xStepTime; 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_ci if( dev->shade.intermediate & _ScanMode_AverageOut ) { 248141cc406Sopenharmony_ci dev->shade.wExposure >>= 1; 249141cc406Sopenharmony_ci dev->shade.wXStep >>= 1; 250141cc406Sopenharmony_ci } 251141cc406Sopenharmony_ci } else { 252141cc406Sopenharmony_ci if( dev->DataInf.dwScanFlag & _SCANDEF_Transparency ) { 253141cc406Sopenharmony_ci dev->shade.wExposure = posScan[index].exposureTime; 254141cc406Sopenharmony_ci dev->shade.wXStep = posScan[index].xStepTime; 255141cc406Sopenharmony_ci } else { 256141cc406Sopenharmony_ci dev->shade.wExposure = dev->scan.negScan[index].exposureTime; 257141cc406Sopenharmony_ci dev->shade.wXStep = dev->scan.negScan[index].xStepTime; 258141cc406Sopenharmony_ci } 259141cc406Sopenharmony_ci } 260141cc406Sopenharmony_ci dev->scan.dwInterval = 1; 261141cc406Sopenharmony_ci 262141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType == COLOR_BW ) 263141cc406Sopenharmony_ci var.dwValue = 0; 264141cc406Sopenharmony_ci else { 265141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType == COLOR_256GRAY ) 266141cc406Sopenharmony_ci var.dwValue = 2500; 267141cc406Sopenharmony_ci else 268141cc406Sopenharmony_ci var.dwValue = 3200; 269141cc406Sopenharmony_ci } 270141cc406Sopenharmony_ci 271141cc406Sopenharmony_ci /* for small size/descreen */ 272141cc406Sopenharmony_ci if((dev->DataInf.xyAppDpi.y >= 300) && var.dwValue && 273141cc406Sopenharmony_ci (dev->DataInf.dwAsicBytesPerPlane <= var.dwValue)) { 274141cc406Sopenharmony_ci dev->scan.dwInterval <<= 1; 275141cc406Sopenharmony_ci } 276141cc406Sopenharmony_ci 277141cc406Sopenharmony_ci if( var.dwValue && dev->DataInf.dwAsicBytesPerPlane > var.dwValue ) { 278141cc406Sopenharmony_ci if((var.dwValue << 1) > dev->DataInf.dwAsicBytesPerPlane) 279141cc406Sopenharmony_ci dev->scan.dwInterval <<= 1; 280141cc406Sopenharmony_ci else 281141cc406Sopenharmony_ci if((var.dwValue << 2) > dev->DataInf.dwAsicBytesPerPlane) 282141cc406Sopenharmony_ci dev->scan.dwInterval <<= 2; 283141cc406Sopenharmony_ci else 284141cc406Sopenharmony_ci dev->scan.dwInterval <<= 3; 285141cc406Sopenharmony_ci } 286141cc406Sopenharmony_ci 287141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType >= COLOR_TRUE24 ) { 288141cc406Sopenharmony_ci 289141cc406Sopenharmony_ci if( dev->DataInf.xyPhyDpi.y > 75U ) { 290141cc406Sopenharmony_ci if( dev->f0_8_16 ) { 291141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenDiscard = dev->DataInf.xyPhyDpi.y / 75U; 292141cc406Sopenharmony_ci } else { 293141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenDiscard = dev->DataInf.xyPhyDpi.y / 150U; 294141cc406Sopenharmony_ci } 295141cc406Sopenharmony_ci } else { 296141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenDiscard = 1; 297141cc406Sopenharmony_ci } 298141cc406Sopenharmony_ci 299141cc406Sopenharmony_ci dev->scan.bd_rk.wBlueDiscard = dev->scan.gd_gk.wGreenDiscard << 1; 300141cc406Sopenharmony_ci } else { 301141cc406Sopenharmony_ci dev->scan.bd_rk.wBlueDiscard = dev->scan.gd_gk.wGreenDiscard = 0; 302141cc406Sopenharmony_ci } 303141cc406Sopenharmony_ci} 304141cc406Sopenharmony_ci 305141cc406Sopenharmony_ci/** limit the resolution 306141cc406Sopenharmony_ci */ 307141cc406Sopenharmony_cistatic u_short 308141cc406Sopenharmony_ciu12image_GetPhysDPI( U12_Device *dev, ImgDef *img, SANE_Bool fDpiX ) 309141cc406Sopenharmony_ci{ 310141cc406Sopenharmony_ci if( fDpiX ) { 311141cc406Sopenharmony_ci 312141cc406Sopenharmony_ci if( img->xyDpi.x > dev->dpi_max_x ) 313141cc406Sopenharmony_ci return dev->dpi_max_x; 314141cc406Sopenharmony_ci else 315141cc406Sopenharmony_ci return img->xyDpi.x; 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci } else { 318141cc406Sopenharmony_ci 319141cc406Sopenharmony_ci if( img->xyDpi.y > dev->dpi_max_y ) 320141cc406Sopenharmony_ci return dev->dpi_max_y; 321141cc406Sopenharmony_ci else 322141cc406Sopenharmony_ci return img->xyDpi.y; 323141cc406Sopenharmony_ci } 324141cc406Sopenharmony_ci} 325141cc406Sopenharmony_ci 326141cc406Sopenharmony_ci/** calculate the image properties according to the scanmode 327141cc406Sopenharmony_ci * set all internally needed information 328141cc406Sopenharmony_ci */ 329141cc406Sopenharmony_cistatic void u12image_GetImageInfo( U12_Device *dev, ImgDef *image ) 330141cc406Sopenharmony_ci{ 331141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12image_GetImageInfo()\n" ); 332141cc406Sopenharmony_ci 333141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.x = u12image_GetPhysDPI(dev, image, SANE_TRUE ); 334141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = u12image_GetPhysDPI(dev, image, SANE_FALSE); 335141cc406Sopenharmony_ci 336141cc406Sopenharmony_ci DBG( _DBG_INFO, "* xyPhyDpi.x = %u, xyPhyDpi.y = %u\n", 337141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.x, dev->DataInf.xyPhyDpi.y ); 338141cc406Sopenharmony_ci 339141cc406Sopenharmony_ci DBG( _DBG_INFO, "* crArea.x = %u, crArea.y = %u\n", 340141cc406Sopenharmony_ci image->crArea.x, image->crArea.y ); 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci DBG( _DBG_INFO, "* crArea.cx = %u, crArea.cy = %u\n", 343141cc406Sopenharmony_ci image->crArea.cx, image->crArea.cy ); 344141cc406Sopenharmony_ci 345141cc406Sopenharmony_ci dev->DataInf.xyRatio = (double)dev->DataInf.xyPhyDpi.y/ 346141cc406Sopenharmony_ci (double)dev->DataInf.xyPhyDpi.x; 347141cc406Sopenharmony_ci 348141cc406Sopenharmony_ci dev->DataInf.dwAppLinesPerArea = (u_long)image->crArea.cy * 349141cc406Sopenharmony_ci image->xyDpi.y / _MEASURE_BASE; 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_ci dev->DataInf.dwAppPixelsPerLine = (u_long)image->crArea.cx * 352141cc406Sopenharmony_ci image->xyDpi.x / _MEASURE_BASE; 353141cc406Sopenharmony_ci 354141cc406Sopenharmony_ci dev->DataInf.dwPhysBytesPerLine = (u_long)image->crArea.cx * 355141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.x / _MEASURE_BASE; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci if( image->wDataType <= COLOR_BW ) { 358141cc406Sopenharmony_ci dev->DataInf.dwAsicPixelsPerPlane = 359141cc406Sopenharmony_ci (dev->DataInf.dwAppPixelsPerLine+7UL) & 0xfffffff8UL; 360141cc406Sopenharmony_ci dev->DataInf.dwAppPhyBytesPerLine = 361141cc406Sopenharmony_ci dev->DataInf.dwAppBytesPerLine = 362141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine = 363141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane = dev->DataInf.dwAsicPixelsPerPlane>>3; 364141cc406Sopenharmony_ci } else { 365141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane = 366141cc406Sopenharmony_ci dev->DataInf.dwAsicPixelsPerPlane = dev->DataInf.dwAppPixelsPerLine; 367141cc406Sopenharmony_ci } 368141cc406Sopenharmony_ci 369141cc406Sopenharmony_ci if( COLOR_TRUE42 == image->wDataType ) { 370141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane *= 2; 371141cc406Sopenharmony_ci } 372141cc406Sopenharmony_ci 373141cc406Sopenharmony_ci switch( image->wDataType ) { 374141cc406Sopenharmony_ci 375141cc406Sopenharmony_ci case COLOR_BW: 376141cc406Sopenharmony_ci dev->scan.DataProcess = fnDataDirect; 377141cc406Sopenharmony_ci dev->DataInf.wPhyDataType = COLOR_BW; 378141cc406Sopenharmony_ci dev->shade.intermediate = _ScanMode_Mono; 379141cc406Sopenharmony_ci break; 380141cc406Sopenharmony_ci 381141cc406Sopenharmony_ci case COLOR_256GRAY: 382141cc406Sopenharmony_ci dev->scan.DataProcess = fnDataDirect; 383141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine = 384141cc406Sopenharmony_ci dev->DataInf.dwAppPhyBytesPerLine = dev->DataInf.dwAppPixelsPerLine; 385141cc406Sopenharmony_ci dev->DataInf.wPhyDataType = COLOR_256GRAY; 386141cc406Sopenharmony_ci dev->shade.intermediate = _ScanMode_Mono; 387141cc406Sopenharmony_ci break; 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci case COLOR_TRUE24: 390141cc406Sopenharmony_ci dev->scan.DataProcess = fnColorDirect; 391141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine = 392141cc406Sopenharmony_ci dev->DataInf.dwAppPhyBytesPerLine = dev->DataInf.dwAppPixelsPerLine * 3; 393141cc406Sopenharmony_ci dev->DataInf.wPhyDataType = COLOR_TRUE24; 394141cc406Sopenharmony_ci dev->shade.intermediate = _ScanMode_Color; 395141cc406Sopenharmony_ci break; 396141cc406Sopenharmony_ci 397141cc406Sopenharmony_ci case COLOR_TRUE42: 398141cc406Sopenharmony_ci dev->scan.DataProcess = fnColor42; 399141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine = 400141cc406Sopenharmony_ci dev->DataInf.dwAppPhyBytesPerLine = dev->DataInf.dwAppPixelsPerLine * 6; 401141cc406Sopenharmony_ci dev->DataInf.wPhyDataType = COLOR_TRUE42; 402141cc406Sopenharmony_ci dev->shade.intermediate = _ScanMode_Color; 403141cc406Sopenharmony_ci break; 404141cc406Sopenharmony_ci } 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_ci /* raus mit einem von beiden!!!!*/ 407141cc406Sopenharmony_ci dev->DataInf.dwAppBytesPerLine = dev->DataInf.dwAppPhyBytesPerLine; 408141cc406Sopenharmony_ci 409141cc406Sopenharmony_ci DBG( _DBG_INFO, "AppLinesPerArea = %lu\n", dev->DataInf.dwAppLinesPerArea ); 410141cc406Sopenharmony_ci DBG( _DBG_INFO, "AppPixelsPerLine = %lu\n", dev->DataInf.dwAppPixelsPerLine ); 411141cc406Sopenharmony_ci DBG( _DBG_INFO, "AppPhyBytesPerLine = %lu\n", dev->DataInf.dwAppPhyBytesPerLine ); 412141cc406Sopenharmony_ci DBG( _DBG_INFO, "AppBytesPerLine = %lu\n", dev->DataInf.dwAppBytesPerLine ); 413141cc406Sopenharmony_ci DBG( _DBG_INFO, "AsicPixelsPerPlane = %lu\n", dev->DataInf.dwAsicPixelsPerPlane ); 414141cc406Sopenharmony_ci DBG( _DBG_INFO, "AsicBytesPerPlane = %lu\n", dev->DataInf.dwAsicBytesPerPlane ); 415141cc406Sopenharmony_ci DBG( _DBG_INFO, "AsicBytesPerLine = %lu\n", dev->DataInf.dwAsicBytesPerLine ); 416141cc406Sopenharmony_ci DBG( _DBG_INFO, "Physical Bytes = %lu\n", dev->DataInf.dwPhysBytesPerLine ); 417141cc406Sopenharmony_ci} 418141cc406Sopenharmony_ci 419141cc406Sopenharmony_ci/** 420141cc406Sopenharmony_ci */ 421141cc406Sopenharmony_cistatic int imageSetupScanSettings( U12_Device *dev, ImgDef *img ) 422141cc406Sopenharmony_ci{ 423141cc406Sopenharmony_ci u_short brightness; 424141cc406Sopenharmony_ci 425141cc406Sopenharmony_ci DBG( _DBG_INFO, "imageSetupScanSettings()\n" ); 426141cc406Sopenharmony_ci 427141cc406Sopenharmony_ci dev->DataInf.dwScanFlag = img->dwFlag; 428141cc406Sopenharmony_ci dev->DataInf.crImage = img->crArea; 429141cc406Sopenharmony_ci 430141cc406Sopenharmony_ci DBG( _DBG_INFO,"* DataInf.dwScanFlag = 0x%08lx\n",dev->DataInf.dwScanFlag); 431141cc406Sopenharmony_ci 432141cc406Sopenharmony_ci dev->DataInf.crImage.x <<= 1; 433141cc406Sopenharmony_ci 434141cc406Sopenharmony_ci dev->DataInf.xyAppDpi = img->xyDpi; 435141cc406Sopenharmony_ci dev->DataInf.wAppDataType = img->wDataType; 436141cc406Sopenharmony_ci 437141cc406Sopenharmony_ci u12image_GetImageInfo( dev, img ); 438141cc406Sopenharmony_ci 439141cc406Sopenharmony_ci dev->scan.lBufferAdjust = (long)dev->DataInf.dwAppBytesPerLine; 440141cc406Sopenharmony_ci 441141cc406Sopenharmony_ci DBG( _DBG_INFO, "* Scan settings:\n" ); 442141cc406Sopenharmony_ci DBG( _DBG_INFO, "* ImageInfo: (x=%u,y=%u,dx=%u,dy=%u)\n", 443141cc406Sopenharmony_ci dev->DataInf.crImage.x, dev->DataInf.crImage.y, 444141cc406Sopenharmony_ci dev->DataInf.crImage.cx, dev->DataInf.crImage.cy ); 445141cc406Sopenharmony_ci 446141cc406Sopenharmony_ci /* 447141cc406Sopenharmony_ci * 0 _DEF_BW_THRESHOLD 255 448141cc406Sopenharmony_ci * +-------------------------+--------------------------------+ 449141cc406Sopenharmony_ci * |<------- Black --------->|<----------- White ------------>| 450141cc406Sopenharmony_ci * So, if user wish to make image darker, the threshold value should be 451141cc406Sopenharmony_ci * higher than _defBwThreshold, otherwise it should lower than the 452141cc406Sopenharmony_ci * _DefBwThreshold. 453141cc406Sopenharmony_ci * Darker = _DEF_BW_THRESHOLD + White * Input / 127; 454141cc406Sopenharmony_ci * Input < 0, and White = 255 - _DEF_BW_THRESHOLD, so 455141cc406Sopenharmony_ci * = _DEF_BW_THRESHOLD - (255 - _DEF_BW_THRESHOLD) * Input / 127; 456141cc406Sopenharmony_ci * The brighter is the same idea. 457141cc406Sopenharmony_ci */ 458141cc406Sopenharmony_ci 459141cc406Sopenharmony_ci/* CHECK: We have now two methods for setting the brightness... 460141cc406Sopenharmony_ci*/ 461141cc406Sopenharmony_ci DBG( _DBG_INFO, "* brightness = %i\n", dev->DataInf.siBrightness ); 462141cc406Sopenharmony_ci if ( dev->DataInf.siBrightness < 0) { 463141cc406Sopenharmony_ci brightness = (u_short)(_DEF_BW_THRESHOLD - 464141cc406Sopenharmony_ci (255 - _DEF_BW_THRESHOLD) * dev->DataInf.siBrightness /127); 465141cc406Sopenharmony_ci } else { 466141cc406Sopenharmony_ci brightness = (u_short)(_DEF_BW_THRESHOLD - 467141cc406Sopenharmony_ci _DEF_BW_THRESHOLD * dev->DataInf.siBrightness /127); 468141cc406Sopenharmony_ci } 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci dev->regs.RD_ThresholdControl = brightness; 471141cc406Sopenharmony_ci DBG( _DBG_INFO, "* RD_ThresholdControl = %i\n", brightness ); 472141cc406Sopenharmony_ci return 0; 473141cc406Sopenharmony_ci} 474141cc406Sopenharmony_ci 475141cc406Sopenharmony_ci/** PrepareScanningVariables() !!! 476141cc406Sopenharmony_ci */ 477141cc406Sopenharmony_cistatic SANE_Status u12image_SetupScanSettings( U12_Device *dev, ImgDef *img ) 478141cc406Sopenharmony_ci{ 479141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12image_SetupScanSettings()\n" ); 480141cc406Sopenharmony_ci 481141cc406Sopenharmony_ci wPreviewScanned = 0; 482141cc406Sopenharmony_ci dev->scan.dpiIdx = 0; 483141cc406Sopenharmony_ci dev->scan.negScan = negScan; 484141cc406Sopenharmony_ci 485141cc406Sopenharmony_ci imageSetupScanSettings( dev, img ); 486141cc406Sopenharmony_ci 487141cc406Sopenharmony_ci if( !(dev->DataInf.dwScanFlag & _SCANDEF_TPA )) { 488141cc406Sopenharmony_ci 489141cc406Sopenharmony_ci dev->scan.dwScanOrigin = dev->adj.upNormal * 4 + _RFT_SCANNING_ORG; 490141cc406Sopenharmony_ci 491141cc406Sopenharmony_ci } else if( dev->DataInf.dwScanFlag & _SCANDEF_Transparency) { 492141cc406Sopenharmony_ci 493141cc406Sopenharmony_ci dev->scan.dwScanOrigin = dev->adj.upPositive * 4 + _POS_SCANNING_ORG; 494141cc406Sopenharmony_ci } else { 495141cc406Sopenharmony_ci dev->scan.dwScanOrigin = dev->adj.upNegative * 4 + _NEG_SCANNING_ORG; 496141cc406Sopenharmony_ci } 497141cc406Sopenharmony_ci dev->scan.dwScanOrigin += 64 /*dev->dwModelOriginY*/; 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.y <= 75 ) { 500141cc406Sopenharmony_ci 501141cc406Sopenharmony_ci if( dev->DataInf.dwScanFlag & _SCANDEF_PREVIEW ) { 502141cc406Sopenharmony_ci 503141cc406Sopenharmony_ci dev->scan.bDiscardAll = 0; 504141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 150; 505141cc406Sopenharmony_ci dev->shade.intermediate |= _ScanMode_AverageOut; 506141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 1 ); 507141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenDiscard = 0; 508141cc406Sopenharmony_ci 509141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.y >= 38 ) 510141cc406Sopenharmony_ci dev->scan.bd_rk.wBlueDiscard = 1; 511141cc406Sopenharmony_ci else 512141cc406Sopenharmony_ci dev->scan.bd_rk.wBlueDiscard = 0; 513141cc406Sopenharmony_ci 514141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType >= COLOR_256GRAY ) { 515141cc406Sopenharmony_ci dev->shade.wXStep = 6; 516141cc406Sopenharmony_ci dev->shade.wExposure = 8 * dev->shade.wXStep; 517141cc406Sopenharmony_ci } 518141cc406Sopenharmony_ci } else { 519141cc406Sopenharmony_ci if(!(dev->DataInf.dwScanFlag & _SCANDEF_TPA) && 520141cc406Sopenharmony_ci (dev->DataInf.xyAppDpi.y <= 50) && 521141cc406Sopenharmony_ci (dev->DataInf.wPhyDataType >= COLOR_TRUE24)) { 522141cc406Sopenharmony_ci dev->shade.intermediate |= _ScanMode_AverageOut; 523141cc406Sopenharmony_ci } 524141cc406Sopenharmony_ci 525141cc406Sopenharmony_ci if((dev->DataInf.wPhyDataType<COLOR_TRUE24) || dev->f0_8_16 || 526141cc406Sopenharmony_ci (dev->shade.intermediate & _ScanMode_AverageOut)) { 527141cc406Sopenharmony_ci 528141cc406Sopenharmony_ci dev->scan.bDiscardAll = 1; 529141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 75; 530141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 0 ); 531141cc406Sopenharmony_ci } else { 532141cc406Sopenharmony_ci dev->scan.bDiscardAll = 2; 533141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 150; 534141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 1 ); 535141cc406Sopenharmony_ci } 536141cc406Sopenharmony_ci } 537141cc406Sopenharmony_ci } else { 538141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.y <= 150 ) { 539141cc406Sopenharmony_ci 540141cc406Sopenharmony_ci dev->scan.bDiscardAll = 2; 541141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 150; 542141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 1 ); 543141cc406Sopenharmony_ci 544141cc406Sopenharmony_ci } else if( dev->DataInf.xyAppDpi.y <= 300 ) { 545141cc406Sopenharmony_ci 546141cc406Sopenharmony_ci dev->scan.bDiscardAll = 4; 547141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 300; 548141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 2 ); 549141cc406Sopenharmony_ci 550141cc406Sopenharmony_ci } else if( dev->DataInf.xyAppDpi.y <= 600 ) { 551141cc406Sopenharmony_ci 552141cc406Sopenharmony_ci dev->scan.bDiscardAll = 8; 553141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 600; 554141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 3 ); 555141cc406Sopenharmony_ci 556141cc406Sopenharmony_ci } else { 557141cc406Sopenharmony_ci 558141cc406Sopenharmony_ci dev->scan.bDiscardAll = 16; 559141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y = 1200; 560141cc406Sopenharmony_ci u12image_SetupScanStateVariables( dev, 4 ); 561141cc406Sopenharmony_ci } 562141cc406Sopenharmony_ci } 563141cc406Sopenharmony_ci 564141cc406Sopenharmony_ci /* ------- lines to sample or not? ------- */ 565141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.y == dev->DataInf.xyPhyDpi.y ) { 566141cc406Sopenharmony_ci DBG( _DBG_INFO, "* Sample every line\n" ); 567141cc406Sopenharmony_ci dev->scan.DoSample = fnEveryLine; 568141cc406Sopenharmony_ci } else { 569141cc406Sopenharmony_ci if( dev->DataInf.dwScanFlag & _SCANDEF_PREVIEW ) { 570141cc406Sopenharmony_ci 571141cc406Sopenharmony_ci DBG( _DBG_INFO, "* Sample preview\n" ); 572141cc406Sopenharmony_ci dev->scan.DoSample = fnSamplePreview; 573141cc406Sopenharmony_ci dev->DataInf.wYSum = 150; 574141cc406Sopenharmony_ci 575141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.y >= 38 ) 576141cc406Sopenharmony_ci wPreviewScanned = dev->DataInf.xyAppDpi.y * 2; 577141cc406Sopenharmony_ci else if( dev->DataInf.xyAppDpi.y >= 19 ) 578141cc406Sopenharmony_ci wPreviewScanned = dev->DataInf.xyAppDpi.y * 4; 579141cc406Sopenharmony_ci else 580141cc406Sopenharmony_ci wPreviewScanned = dev->DataInf.xyAppDpi.y * 8; 581141cc406Sopenharmony_ci } else { 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci DBG( _DBG_INFO, "* Sample lines (%u - %u)...\n", 584141cc406Sopenharmony_ci dev->DataInf.xyPhyDpi.y, dev->DataInf.xyAppDpi.y ); 585141cc406Sopenharmony_ci dev->scan.DoSample = fnSampleLines; 586141cc406Sopenharmony_ci dev->DataInf.wYSum = dev->DataInf.xyPhyDpi.y - dev->DataInf.xyAppDpi.y; 587141cc406Sopenharmony_ci } 588141cc406Sopenharmony_ci } 589141cc406Sopenharmony_ci 590141cc406Sopenharmony_ci /* now assign the buffer pointers for image acquisition 591141cc406Sopenharmony_ci */ 592141cc406Sopenharmony_ci dev->scan.p48BitBuf.pb = NULL; 593141cc406Sopenharmony_ci 594141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType >= COLOR_TRUE24 ) { 595141cc406Sopenharmony_ci 596141cc406Sopenharmony_ci u_long r, g, b; 597141cc406Sopenharmony_ci 598141cc406Sopenharmony_ci r = (u_long)_SIZE_REDFIFO / 599141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane - dev->scan.bd_rk.wRedKeep; 600141cc406Sopenharmony_ci g = (u_long)_SIZE_GREENFIFO / 601141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane - dev->scan.gd_gk.wGreenKeep; 602141cc406Sopenharmony_ci 603141cc406Sopenharmony_ci if((int)r < 16 || (int)g < 16) { 604141cc406Sopenharmony_ci 605141cc406Sopenharmony_ci b = (u_long)(dev->scan.bd_rk.wRedKeep + 606141cc406Sopenharmony_ci dev->scan.gd_gk.wGreenKeep + 2U) * 607141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane; 608141cc406Sopenharmony_ci 609141cc406Sopenharmony_ci DBG( _DBG_INFO, "48Bit buffer request: " 610141cc406Sopenharmony_ci "len=%lu bytes, available=%lu\n", b, _SIZE_TOTAL_BUF_TPA ); 611141cc406Sopenharmony_ci 612141cc406Sopenharmony_ci if( b > _SIZE_TOTAL_BUF_TPA ) { 613141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Not that much FIFO memory available!\n" ); 614141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 615141cc406Sopenharmony_ci } 616141cc406Sopenharmony_ci 617141cc406Sopenharmony_ci dev->scan.p48BitBuf.pb = dev->bufs.b1.pReadBuf; 618141cc406Sopenharmony_ci } 619141cc406Sopenharmony_ci } 620141cc406Sopenharmony_ci 621141cc406Sopenharmony_ci if( dev->scan.p48BitBuf.pb ){ 622141cc406Sopenharmony_ci dev->scan.DataRead = fnReadToDriver; 623141cc406Sopenharmony_ci dev->scan.BufGet.red.bp = 624141cc406Sopenharmony_ci dev->scan.BufPut.red.bp = 625141cc406Sopenharmony_ci dev->scan.BufBegin.red.bp = dev->scan.p48BitBuf.pb; 626141cc406Sopenharmony_ci dev->scan.BufEnd.red.bp = 627141cc406Sopenharmony_ci dev->scan.BufBegin.green.bp = 628141cc406Sopenharmony_ci dev->scan.BufGet.green.bp = 629141cc406Sopenharmony_ci dev->scan.BufPut.green.bp = dev->scan.p48BitBuf.pb + 630141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine * 631141cc406Sopenharmony_ci (dev->scan.bd_rk.wRedKeep + 1U); 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_ci dev->scan.BufEnd.green.bp = dev->scan.BufBegin.green.bp + 634141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine * 635141cc406Sopenharmony_ci (dev->scan.gd_gk.wGreenKeep + 1U); 636141cc406Sopenharmony_ci dev->scan.BufPut.blue.bp = 637141cc406Sopenharmony_ci dev->scan.BufGet.blue.bp = dev->bufs.b1.pReadBuf + 638141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine * 2; 639141cc406Sopenharmony_ci } else { 640141cc406Sopenharmony_ci dev->scan.DataRead = fnReadOutScanner; 641141cc406Sopenharmony_ci dev->scan.BufPut.red.bp = dev->bufs.b1.pReadBuf; 642141cc406Sopenharmony_ci dev->scan.BufData.green.bp = 643141cc406Sopenharmony_ci dev->scan.BufPut.green.bp = dev->scan.BufPut.red.bp + 644141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine; 645141cc406Sopenharmony_ci dev->scan.BufPut.blue.bp = dev->scan.BufPut.green.bp + 646141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerLine; 647141cc406Sopenharmony_ci 648141cc406Sopenharmony_ci dev->scan.BufData.red.bp = dev->scan.BufPut.red.bp; 649141cc406Sopenharmony_ci dev->scan.BufData.blue.bp = dev->scan.BufPut.blue.bp; 650141cc406Sopenharmony_ci } 651141cc406Sopenharmony_ci 652141cc406Sopenharmony_ci/* CHECK: maybe remove this stuff */ 653141cc406Sopenharmony_ci#if 0 654141cc406Sopenharmony_ci if( ps->DataInf.dwScanFlag & _SCANDEF_Transparency) { 655141cc406Sopenharmony_ci posScan[1].exposureTime = 96; 656141cc406Sopenharmony_ci posScan[1].xStepTime = 12; 657141cc406Sopenharmony_ci posScan[2].exposureTime = 96; 658141cc406Sopenharmony_ci posScan[2].xStepTime = 24; 659141cc406Sopenharmony_ci posScan[3].exposureTime = 96; 660141cc406Sopenharmony_ci posScan[3].xStepTime = 48; 661141cc406Sopenharmony_ci posScan[4].exposureTime = 96; 662141cc406Sopenharmony_ci posScan[4].xStepTime = 96; 663141cc406Sopenharmony_ci 664141cc406Sopenharmony_ci /* Reset shading Exposure Time & xStep Time */ 665141cc406Sopenharmony_ci ps->Shade.wExposure = posScan[ps->Scan.dpiIdx].exposureTime; 666141cc406Sopenharmony_ci ps->Shade.wXStep = posScan[ps->Scan.dpiIdx].xStepTime; 667141cc406Sopenharmony_ci } 668141cc406Sopenharmony_ci else if( ps->DataInf.dwScanFlag & _SCANDEF_Negative) { 669141cc406Sopenharmony_ci ps->Scan.negScan[1].exposureTime = 96; 670141cc406Sopenharmony_ci ps->Scan.negScan[1].xStepTime = 12; 671141cc406Sopenharmony_ci ps->Scan.negScan[2].exposureTime = 96; 672141cc406Sopenharmony_ci ps->Scan.negScan[2].xStepTime = 24; 673141cc406Sopenharmony_ci ps->Scan.negScan[3].exposureTime = 96; 674141cc406Sopenharmony_ci ps->Scan.negScan[3].xStepTime = 48; 675141cc406Sopenharmony_ci ps->Scan.negScan[4].exposureTime = 96; 676141cc406Sopenharmony_ci ps->Scan.negScan[4].xStepTime = 96; 677141cc406Sopenharmony_ci 678141cc406Sopenharmony_ci /* Reset shading Exposure Time & xStep Time */ 679141cc406Sopenharmony_ci ps->Shade.wExposure = ps->Scan.negScan[ps->Scan.dpiIdx].exposureTime; 680141cc406Sopenharmony_ci ps->Shade.wXStep = ps->Scan.negScan[ps->Scan.dpiIdx].xStepTime; 681141cc406Sopenharmony_ci } 682141cc406Sopenharmony_ci#endif 683141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 684141cc406Sopenharmony_ci} 685141cc406Sopenharmony_ci 686141cc406Sopenharmony_ci/** 687141cc406Sopenharmony_ci */ 688141cc406Sopenharmony_cistatic SANE_Bool u12image_DataIsReady( U12_Device *dev, void* buf ) 689141cc406Sopenharmony_ci{ 690141cc406Sopenharmony_ci DBG( _DBG_READ, "* DataIsReady()\n" ); 691141cc406Sopenharmony_ci 692141cc406Sopenharmony_ci if( dev->scan.bDiscardAll ) { 693141cc406Sopenharmony_ci dev->scan.bDiscardAll--; 694141cc406Sopenharmony_ci 695141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType <= COLOR_256GRAY ) { 696141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoGSel; 697141cc406Sopenharmony_ci u12io_ReadMonoData( dev, dev->bufs.b1.pReadBuf, 698141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 699141cc406Sopenharmony_ci } else { 700141cc406Sopenharmony_ci u12io_ReadColorData( dev, dev->bufs.b1.pReadBuf, 701141cc406Sopenharmony_ci dev->DataInf.dwAsicBytesPerPlane ); 702141cc406Sopenharmony_ci } 703141cc406Sopenharmony_ci return SANE_FALSE; 704141cc406Sopenharmony_ci } 705141cc406Sopenharmony_ci 706141cc406Sopenharmony_ci if( dev->DataInf.wPhyDataType <= COLOR_256GRAY ) { 707141cc406Sopenharmony_ci 708141cc406Sopenharmony_ci dev->regs.RD_ModeControl = _ModeFifoGSel; 709141cc406Sopenharmony_ci u12io_ReadMonoData( dev, buf, dev->DataInf.dwAsicBytesPerPlane ); 710141cc406Sopenharmony_ci 711141cc406Sopenharmony_ci } else { 712141cc406Sopenharmony_ci 713141cc406Sopenharmony_ci if( !dev->scan.DataRead( dev )) { 714141cc406Sopenharmony_ci return SANE_FALSE; 715141cc406Sopenharmony_ci } 716141cc406Sopenharmony_ci } 717141cc406Sopenharmony_ci 718141cc406Sopenharmony_ci if( dev->scan.DoSample( dev )) { 719141cc406Sopenharmony_ci 720141cc406Sopenharmony_ci /* direct is done here without copying...*/ 721141cc406Sopenharmony_ci if( fnDataDirect != dev->scan.DataProcess ) { 722141cc406Sopenharmony_ci (*dev->scan.DataProcess)(dev, buf, (void*)(dev->scan.BufPut.red.bp), 723141cc406Sopenharmony_ci dev->DataInf.dwAppPhyBytesPerLine); 724141cc406Sopenharmony_ci } 725141cc406Sopenharmony_ci return SANE_TRUE; 726141cc406Sopenharmony_ci } 727141cc406Sopenharmony_ci return SANE_FALSE; 728141cc406Sopenharmony_ci} 729141cc406Sopenharmony_ci 730141cc406Sopenharmony_ci/** 731141cc406Sopenharmony_ci */ 732141cc406Sopenharmony_cistatic SANE_Status u12image_ReadOneImageLine( U12_Device *dev, void* buf ) 733141cc406Sopenharmony_ci{ 734141cc406Sopenharmony_ci SANE_Byte b, state; 735141cc406Sopenharmony_ci TimerDef timer, t2; 736141cc406Sopenharmony_ci 737141cc406Sopenharmony_ci DBG( _DBG_READ, "u12image_ReadOneImageLine()\n" ); 738141cc406Sopenharmony_ci 739141cc406Sopenharmony_ci u12io_StartTimer( &timer, _LINE_TIMEOUT ); 740141cc406Sopenharmony_ci u12io_StartTimer( &t2, _SECOND*2 ); 741141cc406Sopenharmony_ci do { 742141cc406Sopenharmony_ci 743141cc406Sopenharmony_ci state = u12io_GetScanState( dev ); 744141cc406Sopenharmony_ci dev->scan.bNowScanState = (state & _SCANSTATE_MASK); 745141cc406Sopenharmony_ci 746141cc406Sopenharmony_ci if( state & _SCANSTATE_STOP ) { 747141cc406Sopenharmony_ci 748141cc406Sopenharmony_ci DBG( _DBG_READ, "* SCANSTATE_STOP\n" ); 749141cc406Sopenharmony_ci u12motor_ModuleForwardBackward( dev ); 750141cc406Sopenharmony_ci 751141cc406Sopenharmony_ci if( u12io_GetFifoLength( dev ) >= dev->scan.dwMinReadFifo ) 752141cc406Sopenharmony_ci if( u12image_DataIsReady( dev, buf )) 753141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 754141cc406Sopenharmony_ci 755141cc406Sopenharmony_ci } else { 756141cc406Sopenharmony_ci 757141cc406Sopenharmony_ci dev->scan.bModuleState = _MotorInNormalState; 758141cc406Sopenharmony_ci b = dev->scan.bNowScanState - dev->scan.oldScanState; 759141cc406Sopenharmony_ci 760141cc406Sopenharmony_ci if((char) b < 0) 761141cc406Sopenharmony_ci b += _NUMBER_OF_SCANSTEPS; 762141cc406Sopenharmony_ci 763141cc406Sopenharmony_ci if( b >= dev->scan.bRefresh ) { 764141cc406Sopenharmony_ci 765141cc406Sopenharmony_ci u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE ); 766141cc406Sopenharmony_ci dev->scan.oldScanState = u12io_GetScanState( dev ); 767141cc406Sopenharmony_ci dev->scan.oldScanState &= _SCANSTATE_MASK; 768141cc406Sopenharmony_ci } 769141cc406Sopenharmony_ci 770141cc406Sopenharmony_ci if( u12io_GetFifoLength( dev ) >= dev->scan.dwMaxReadFifo ) { 771141cc406Sopenharmony_ci 772141cc406Sopenharmony_ci if( u12image_DataIsReady( dev, buf )) 773141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 774141cc406Sopenharmony_ci } 775141cc406Sopenharmony_ci else { 776141cc406Sopenharmony_ci 777141cc406Sopenharmony_ci b = dev->scan.bNowScanState - dev->scan.oldScanState; 778141cc406Sopenharmony_ci 779141cc406Sopenharmony_ci if((char) b < 0) 780141cc406Sopenharmony_ci b += _NUMBER_OF_SCANSTEPS; 781141cc406Sopenharmony_ci 782141cc406Sopenharmony_ci if( b >= dev->scan.bRefresh ) { 783141cc406Sopenharmony_ci 784141cc406Sopenharmony_ci u12io_RegisterToScanner( dev, REG_REFRESHSCANSTATE ); 785141cc406Sopenharmony_ci dev->scan.oldScanState = u12io_GetScanState( dev ); 786141cc406Sopenharmony_ci dev->scan.oldScanState &= _SCANSTATE_MASK; 787141cc406Sopenharmony_ci } 788141cc406Sopenharmony_ci 789141cc406Sopenharmony_ci if( u12io_GetFifoLength( dev ) >= dev->scan.dwMinReadFifo ) { 790141cc406Sopenharmony_ci if( u12image_DataIsReady( dev, buf )) 791141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 792141cc406Sopenharmony_ci } 793141cc406Sopenharmony_ci } 794141cc406Sopenharmony_ci } 795141cc406Sopenharmony_ci 796141cc406Sopenharmony_ci } while( !u12io_CheckTimer( &timer )); 797141cc406Sopenharmony_ci 798141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Timeout - Scanner malfunction !!\n" ); 799141cc406Sopenharmony_ci u12motor_ToHomePosition( dev, SANE_TRUE ); 800141cc406Sopenharmony_ci 801141cc406Sopenharmony_ci /* timed out, scanner malfunction */ 802141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 803141cc406Sopenharmony_ci} 804141cc406Sopenharmony_ci 805141cc406Sopenharmony_ci/** 806141cc406Sopenharmony_ci */ 807141cc406Sopenharmony_cistatic void u12image_PrepareScaling( U12_Device *dev ) 808141cc406Sopenharmony_ci{ 809141cc406Sopenharmony_ci int step; 810141cc406Sopenharmony_ci double ratio; 811141cc406Sopenharmony_ci 812141cc406Sopenharmony_ci dev->scaleBuf = NULL; 813141cc406Sopenharmony_ci DBG( _DBG_INFO, "APP-DPIX=%u, MAX-DPIX=%u\n", 814141cc406Sopenharmony_ci dev->DataInf.xyAppDpi.x, dev->dpi_max_x ); 815141cc406Sopenharmony_ci 816141cc406Sopenharmony_ci if( dev->DataInf.xyAppDpi.x > dev->dpi_max_x ) { 817141cc406Sopenharmony_ci 818141cc406Sopenharmony_ci dev->scaleBuf = malloc( dev->DataInf.dwAppBytesPerLine ); 819141cc406Sopenharmony_ci 820141cc406Sopenharmony_ci ratio = (double)dev->DataInf.xyAppDpi.x/(double)dev->dpi_max_x; 821141cc406Sopenharmony_ci dev->scaleIzoom = (int)(1.0/ratio * 1000); 822141cc406Sopenharmony_ci 823141cc406Sopenharmony_ci switch( dev->DataInf.wAppDataType ) { 824141cc406Sopenharmony_ci 825141cc406Sopenharmony_ci case COLOR_BW : step = 0; break; 826141cc406Sopenharmony_ci case COLOR_256GRAY : step = 1; break; 827141cc406Sopenharmony_ci case COLOR_TRUE24 : step = 3; break; 828141cc406Sopenharmony_ci case COLOR_TRUE42 : step = 6; break; 829141cc406Sopenharmony_ci default : step = 99; break; 830141cc406Sopenharmony_ci } 831141cc406Sopenharmony_ci dev->scaleStep = step; 832141cc406Sopenharmony_ci 833141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12image_PrepareScaling: izoom=%i, step=%u\n", 834141cc406Sopenharmony_ci dev->scaleIzoom, step ); 835141cc406Sopenharmony_ci } else { 836141cc406Sopenharmony_ci 837141cc406Sopenharmony_ci DBG( _DBG_INFO, "u12image_PrepareScaling: DISABLED\n" ); 838141cc406Sopenharmony_ci } 839141cc406Sopenharmony_ci} 840141cc406Sopenharmony_ci 841141cc406Sopenharmony_ci/** scaling picture data in x-direction, using a DDA algorithm 842141cc406Sopenharmony_ci * (digital differential analyzer). 843141cc406Sopenharmony_ci */ 844141cc406Sopenharmony_cistatic void u12image_ScaleX( U12_Device *dev, SANE_Byte *ib, SANE_Byte *ob ) 845141cc406Sopenharmony_ci{ 846141cc406Sopenharmony_ci SANE_Byte tmp; 847141cc406Sopenharmony_ci int ddax; 848141cc406Sopenharmony_ci u_long i, j, x; 849141cc406Sopenharmony_ci 850141cc406Sopenharmony_ci /* when not supported, only copy the data */ 851141cc406Sopenharmony_ci if( 99 == dev->scaleStep ) { 852141cc406Sopenharmony_ci memcpy( ob, ib, dev->DataInf.dwAppBytesPerLine ); 853141cc406Sopenharmony_ci return; 854141cc406Sopenharmony_ci } 855141cc406Sopenharmony_ci 856141cc406Sopenharmony_ci /* now scale... */ 857141cc406Sopenharmony_ci if( 0 == dev->scaleStep ) { 858141cc406Sopenharmony_ci 859141cc406Sopenharmony_ci /* binary scaling */ 860141cc406Sopenharmony_ci ddax = 0; 861141cc406Sopenharmony_ci x = 0; 862141cc406Sopenharmony_ci memset( ob, 0, dev->DataInf.dwAppBytesPerLine ); 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_ci for( i = 0; i < dev->DataInf.dwPhysBytesPerLine*8; i++ ) { 865141cc406Sopenharmony_ci 866141cc406Sopenharmony_ci ddax -= 1000; 867141cc406Sopenharmony_ci 868141cc406Sopenharmony_ci while( ddax < 0 ) { 869141cc406Sopenharmony_ci 870141cc406Sopenharmony_ci tmp = ib[(i>>3)]; 871141cc406Sopenharmony_ci 872141cc406Sopenharmony_ci if((x>>3) < dev->DataInf.dwAppBytesPerLine ) { 873141cc406Sopenharmony_ci if( 0 != (tmp &= (1 << ((~(i & 0x7))&0x7)))) 874141cc406Sopenharmony_ci ob[x>>3] |= (1 << ((~(x & 0x7))&0x7)); 875141cc406Sopenharmony_ci } 876141cc406Sopenharmony_ci x++; 877141cc406Sopenharmony_ci ddax += dev->scaleIzoom; 878141cc406Sopenharmony_ci } 879141cc406Sopenharmony_ci } 880141cc406Sopenharmony_ci 881141cc406Sopenharmony_ci } else { 882141cc406Sopenharmony_ci 883141cc406Sopenharmony_ci /* color and gray scaling */ 884141cc406Sopenharmony_ci ddax = 0; 885141cc406Sopenharmony_ci x = 0; 886141cc406Sopenharmony_ci for( i = 0; i < dev->DataInf.dwPhysBytesPerLine*dev->scaleStep; 887141cc406Sopenharmony_ci i+=dev->scaleStep ) { 888141cc406Sopenharmony_ci 889141cc406Sopenharmony_ci ddax -= 1000; 890141cc406Sopenharmony_ci 891141cc406Sopenharmony_ci while( ddax < 0 ) { 892141cc406Sopenharmony_ci 893141cc406Sopenharmony_ci for( j = 0; j < (u_long)dev->scaleStep; j++ ) { 894141cc406Sopenharmony_ci 895141cc406Sopenharmony_ci if((x+j) < dev->DataInf.dwAppBytesPerLine ) { 896141cc406Sopenharmony_ci ob[x+j] = ib[i+j]; 897141cc406Sopenharmony_ci } 898141cc406Sopenharmony_ci } 899141cc406Sopenharmony_ci x += dev->scaleStep; 900141cc406Sopenharmony_ci ddax += dev->scaleIzoom; 901141cc406Sopenharmony_ci } 902141cc406Sopenharmony_ci } 903141cc406Sopenharmony_ci } 904141cc406Sopenharmony_ci} 905141cc406Sopenharmony_ci 906141cc406Sopenharmony_ci/* END U12_IMAGE.C ..........................................................*/ 907