1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) Marian Eichholz 2001 3141cc406Sopenharmony_ci This file is part of the SANE package. 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 6141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 7141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 8141cc406Sopenharmony_ci License, or (at your option) any later version. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 11141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13141cc406Sopenharmony_ci General Public License for more details. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 16141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 19141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 22141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 23141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 24141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 25141cc406Sopenharmony_ci account of linking the SANE library code into it. 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 28141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 29141cc406Sopenharmony_ci License. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 32141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 33141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 36141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 37141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 38141cc406Sopenharmony_ci*/ 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci/* ====================================================================== 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ciUserspace scan tool for the Microtek 3600 scanner 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_cicolor scan routine 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci(C) Marian Eichholz 2001 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci====================================================================== */ 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#include "sm3600-scantool.h" 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_ci#define ORDER_RGB "012" 53141cc406Sopenharmony_ci#define ORDER_BRG "120" 54141cc406Sopenharmony_ci 55141cc406Sopenharmony_ci/* ********************************************************************** 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ciReadNextColorLine() 58141cc406Sopenharmony_ci 59141cc406Sopenharmony_ci********************************************************************** */ 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_cistatic TState ReadNextColorLine(PTInstance this) 62141cc406Sopenharmony_ci{ 63141cc406Sopenharmony_ci int iWrite,i; 64141cc406Sopenharmony_ci int iRead; /* read position in raw line */ 65141cc406Sopenharmony_ci int nInterpolator; 66141cc406Sopenharmony_ci int iOffsetR,iOffsetG,iOffsetB; 67141cc406Sopenharmony_ci short *pchLineSwap; 68141cc406Sopenharmony_ci TBool bVisible; 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci bVisible=false; 71141cc406Sopenharmony_ci do { 72141cc406Sopenharmony_ci iWrite=0; 73141cc406Sopenharmony_ci while (iWrite<3*this->state.cxMax) /* max 1 time in reality */ 74141cc406Sopenharmony_ci { 75141cc406Sopenharmony_ci while (iWrite<3*this->state.cxMax && 76141cc406Sopenharmony_ci this->state.iBulkReadPos<this->state.cchBulk) 77141cc406Sopenharmony_ci this->state.ppchLines[0][iWrite++] = 78141cc406Sopenharmony_ci this->state.pchBuf[this->state.iBulkReadPos++]; 79141cc406Sopenharmony_ci if (iWrite<3*this->state.cxMax) /* we need an additional chunk */ 80141cc406Sopenharmony_ci { 81141cc406Sopenharmony_ci if (this->state.bLastBulk) 82141cc406Sopenharmony_ci return SANE_STATUS_EOF; 83141cc406Sopenharmony_ci this->state.cchBulk=BulkReadBuffer(this,this->state.pchBuf, 84141cc406Sopenharmony_ci USB_CHUNK_SIZE); 85141cc406Sopenharmony_ci dprintf(DEBUG_SCAN,"bulk read: %d byte(s), line #%d\n", 86141cc406Sopenharmony_ci this->state.cchBulk, this->state.iLine); 87141cc406Sopenharmony_ci if (this->bWriteRaw) 88141cc406Sopenharmony_ci fwrite(this->state.pchBuf,1,this->state.cchBulk,this->fhScan); 89141cc406Sopenharmony_ci INST_ASSERT(); 90141cc406Sopenharmony_ci if (this->state.cchBulk!=USB_CHUNK_SIZE) 91141cc406Sopenharmony_ci this->state.bLastBulk=true; 92141cc406Sopenharmony_ci this->state.iBulkReadPos=0; 93141cc406Sopenharmony_ci } 94141cc406Sopenharmony_ci } /* while raw line buffer acquiring */ 95141cc406Sopenharmony_ci this->state.iLine++; 96141cc406Sopenharmony_ci if (this->state.iLine>2*this->state.ySensorSkew) 97141cc406Sopenharmony_ci { 98141cc406Sopenharmony_ci bVisible=true; 99141cc406Sopenharmony_ci iOffsetR=(this->state.szOrder[0]-'0')*this->state.cxMax; 100141cc406Sopenharmony_ci iOffsetG=(this->state.szOrder[1]-'0')*this->state.cxMax; 101141cc406Sopenharmony_ci iOffsetB=(this->state.szOrder[2]-'0')*this->state.cxMax; 102141cc406Sopenharmony_ci for (nInterpolator=100, iWrite=0, iRead=0; 103141cc406Sopenharmony_ci iRead<3*this->state.cxMax && iWrite<this->state.cchLineOut; 104141cc406Sopenharmony_ci iRead++) 105141cc406Sopenharmony_ci { 106141cc406Sopenharmony_ci nInterpolator+=this->state.nFixAspect; 107141cc406Sopenharmony_ci if (nInterpolator<100) continue; /* res. reduction */ 108141cc406Sopenharmony_ci nInterpolator-=100; 109141cc406Sopenharmony_ci /* dprintf(DEBUG_SCAN," i=%d",iTo); */ 110141cc406Sopenharmony_ci /* the first scan lines only fill the line backlog buffer */ 111141cc406Sopenharmony_ci { 112141cc406Sopenharmony_ci /* dprintf(DEBUG_SCAN,"assembling line %d\n",++this->state.iLine); */ 113141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]= 114141cc406Sopenharmony_ci this->state.ppchLines[2*this->state.ySensorSkew][iRead+iOffsetR]; 115141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]= 116141cc406Sopenharmony_ci this->state.ppchLines[1*this->state.ySensorSkew][iRead+iOffsetG]; 117141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]= 118141cc406Sopenharmony_ci this->state.ppchLines[0*this->state.ySensorSkew][iRead+iOffsetB]; 119141cc406Sopenharmony_ci } 120141cc406Sopenharmony_ci } 121141cc406Sopenharmony_ci } /* if visible line */ 122141cc406Sopenharmony_ci /* cycle backlog buffers */ 123141cc406Sopenharmony_ci pchLineSwap=this->state.ppchLines[this->state.cBacklog-1]; 124141cc406Sopenharmony_ci for (i=this->state.cBacklog-2; i>=0; i--) 125141cc406Sopenharmony_ci this->state.ppchLines[i+1]=this->state.ppchLines[i]; 126141cc406Sopenharmony_ci this->state.ppchLines[0]=pchLineSwap; 127141cc406Sopenharmony_ci } while (!bVisible); 128141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 129141cc406Sopenharmony_ci} 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci/* ====================================================================== 132141cc406Sopenharmony_ci 133141cc406Sopenharmony_ciStartScanColor() 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_ci====================================================================== */ 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci/* Parameter are in resolution units! */ 138141cc406Sopenharmony_ci__SM3600EXPORT__ 139141cc406Sopenharmony_ciTState StartScanColor(TInstance *this) 140141cc406Sopenharmony_ci{ 141141cc406Sopenharmony_ci 142141cc406Sopenharmony_ci /* live could be easy: Simple calculate a window, start the scan, 143141cc406Sopenharmony_ci get the data and get off. It dimply does not work. We have to 144141cc406Sopenharmony_ci deal with the fact, that the pixels are reported with color scan 145141cc406Sopenharmony_ci line by color scan line, and have to be rearranged to RGB 146141cc406Sopenharmony_ci triples. They even ar enot always in RGB order, but mostly in BRG 147141cc406Sopenharmony_ci order. And they have a skew of 2/300 inch , given by the slider 148141cc406Sopenharmony_ci construction. Thus, we have to deal with several buffers, some 149141cc406Sopenharmony_ci interpolation, and related management stuff. */ 150141cc406Sopenharmony_ci int i; 151141cc406Sopenharmony_ci if (this->state.bScanning) 152141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_DEVICE_BUSY,"scan active"); 153141cc406Sopenharmony_ci memset(&(this->state),0,sizeof(this->state)); 154141cc406Sopenharmony_ci this->state.ReadProc =ReadNextColorLine; 155141cc406Sopenharmony_ci this->state.ySensorSkew=0; 156141cc406Sopenharmony_ci 157141cc406Sopenharmony_ci GetAreaSize(this); 158141cc406Sopenharmony_ci 159141cc406Sopenharmony_ci switch (this->param.res) 160141cc406Sopenharmony_ci { 161141cc406Sopenharmony_ci case 200: this->state.ySensorSkew=1; break; 162141cc406Sopenharmony_ci case 300: this->state.ySensorSkew=2; break; 163141cc406Sopenharmony_ci case 600: this->state.ySensorSkew=4; break; 164141cc406Sopenharmony_ci default: break; 165141cc406Sopenharmony_ci } 166141cc406Sopenharmony_ci /* since we need 2*this->state.ySensorSkew additional scan lines for de-skewing of 167141cc406Sopenharmony_ci the sensor lines, we enlarge the window and shorten the initial movement 168141cc406Sopenharmony_ci accordingly */ 169141cc406Sopenharmony_ci this->state.cyTotalPath = 170141cc406Sopenharmony_ci this->param.y/2-(2*this->state.ySensorSkew)*600/this->param.res; 171141cc406Sopenharmony_ci DoJog(this,this->state.cyTotalPath); INST_ASSERT(); 172141cc406Sopenharmony_ci this->state.cyTotalPath += 173141cc406Sopenharmony_ci (this->state.cyPixel+2*this->state.ySensorSkew) 174141cc406Sopenharmony_ci *600/this->param.res; /* for jogging back */ 175141cc406Sopenharmony_ci 176141cc406Sopenharmony_ci /* 177141cc406Sopenharmony_ci regular scan is asynchronously, that is, 178141cc406Sopenharmony_ci the scanning is issued, and the driver does bulk reads, 179141cc406Sopenharmony_ci until there are no data left. 180141cc406Sopenharmony_ci Each line has a full R, G and B subline, 8bit each sample. 181141cc406Sopenharmony_ci */ 182141cc406Sopenharmony_ci { 183141cc406Sopenharmony_ci unsigned char uchRegs[]={ 184141cc406Sopenharmony_ci 0xFC /*!!R_SPOS!!*/, 0x00 /*R_SPOSH*/, 0x24 /*!!0x03!!*/, 185141cc406Sopenharmony_ci 0xB0 /*!!R_SWID!!*/, 0xC4 /*!!R_SWIDH!!*/, 186141cc406Sopenharmony_ci 1,0, 187141cc406Sopenharmony_ci 0xFF /*!!0x08!!*/, 0xFF /*!!0x09!!*/, 188141cc406Sopenharmony_ci 0x22 /*!!R_LEN!!*/, 0x07 /*!!R_LENH!!*/, 0x6D /*0x0C*/, 189141cc406Sopenharmony_ci 0x70 /*0x0D*/, 0x69 /*0x0E*/, 0xD0 /*0x0F*/, 190141cc406Sopenharmony_ci 0x00 /*0x10*/, 0x00 /*0x11*/, 0x42 /*!!0x12!!*/, 191141cc406Sopenharmony_ci 0x15 /*0x13*/, 0x84 /*!!0x14!!*/, 0x2A /*0x15*/, 192141cc406Sopenharmony_ci 0xC5 /*!!0x16!!*/, 0x40 /*0x17*/, 0xC5 /*!!0x18!!*/, 193141cc406Sopenharmony_ci 0x40 /*0x19*/, 0xFF /*0x1A*/, 0x01 /*0x1B*/, 194141cc406Sopenharmony_ci 0x88 /*0x1C*/, 0x40 /*0x1D*/, 0x4C /*0x1E*/, 195141cc406Sopenharmony_ci 0x50 /*0x1F*/, 0x00 /*0x20*/, 0x0C /*0x21*/, 196141cc406Sopenharmony_ci 0x21 /*0x22*/, 0xF0 /*0x23*/, 0x40 /*0x24*/, 197141cc406Sopenharmony_ci 0x00 /*0x25*/, 0x0A /*0x26*/, 0xF0 /*0x27*/, 198141cc406Sopenharmony_ci 0x00 /*0x28*/, 0x00 /*0x29*/, 0x4E /*0x2A*/, 199141cc406Sopenharmony_ci 0xF0 /*0x2B*/, 0x00 /*0x2C*/, 0x00 /*0x2D*/, 200141cc406Sopenharmony_ci 0x4E /*0x2E*/, 0x80 /*R_CCAL*/, 0x80 /*R_CCAL2*/, 201141cc406Sopenharmony_ci 0x80 /*R_CCAL3*/, 0x0B /*0x32*/, 0x2D /*0x33*/, 202141cc406Sopenharmony_ci 0x43 /*!!0x34!!*/, 0x29 /*0x35*/, 0x00 /*0x36*/, 203141cc406Sopenharmony_ci 0x00 /*0x37*/, 0x00 /*0x38*/, 0x00 /*0x39*/, 204141cc406Sopenharmony_ci 0x00 /*0x3A*/, 0x00 /*0x3B*/, 0xFF /*0x3C*/, 205141cc406Sopenharmony_ci 0x0F /*0x3D*/, 0x00 /*0x3E*/, 0x00 /*0x3F*/, 206141cc406Sopenharmony_ci 0x01 /*0x40*/, 0x00 /*0x41*/, 0x80 /*R_CSTAT*/, 207141cc406Sopenharmony_ci 0x03 /*0x43*/, 0x01 /*R_LMP*/, 0x00 /*0x45*/, 208141cc406Sopenharmony_ci 0x39 /*R_CTL*/, 0xC5 /*!!0x47!!*/, 0x40 /*0x48*/, 209141cc406Sopenharmony_ci 0x9E /*0x49*/, 0x8C /*0x4A*/ }; 210141cc406Sopenharmony_ci RegWriteArray(this,R_ALL, NUM_SCANREGS, uchRegs); 211141cc406Sopenharmony_ci RegWrite(this,R_SPOS, 2, this->param.x/2 + this->calibration.xMargin); 212141cc406Sopenharmony_ci RegWrite(this,R_SLEN, 2, 213141cc406Sopenharmony_ci this->state.cyWindow+ 214141cc406Sopenharmony_ci (2*this->state.ySensorSkew)*600/this->param.res); 215141cc406Sopenharmony_ci this->state.szOrder=ORDER_BRG; 216141cc406Sopenharmony_ci RegWrite(this,R_CCAL, 3, this->calibration.rgbBias); INST_ASSERT(); /* 0xBBGGRR */ 217141cc406Sopenharmony_ci switch (this->param.res) 218141cc406Sopenharmony_ci { 219141cc406Sopenharmony_ci case 75: 220141cc406Sopenharmony_ci RegWrite(this,R_XRES,1, 0x20); /* ups, can do only 100 dpi horizontal */ 221141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, 0xC000 | this->state.cxWindow); 222141cc406Sopenharmony_ci RegWrite(this,0x34, 1, 0x83); /* halves the vertical resolution */ 223141cc406Sopenharmony_ci RegWrite(this,0x47,1,0xC0); /* reduces the speed a bit */ 224141cc406Sopenharmony_ci break; 225141cc406Sopenharmony_ci case 100: 226141cc406Sopenharmony_ci RegWrite(this,R_XRES,1, 0x20); 227141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, 0xC000 | this->state.cxWindow); 228141cc406Sopenharmony_ci RegWrite(this,0x34, 1, 0x63); /* halves the vertical resolution */ 229141cc406Sopenharmony_ci RegWrite(this,0x47,1,0xC0); /* reduces the speed a bit */ 230141cc406Sopenharmony_ci /* I have no idea, what these differences are good for. The seem to produce 231141cc406Sopenharmony_ci a slight blue presence. 232141cc406Sopenharmony_ci RegWrite(this,0x16, 1, 0xC0); RegWrite(this,0x18, 1, 0xC0); 233141cc406Sopenharmony_ci RegWrite(this,0x12, 1, 0x40); RegWrite(this,0x10, 2, 0x0728); 234141cc406Sopenharmony_ci RegWrite(this,0x14, 1, 0x80); */ 235141cc406Sopenharmony_ci break; 236141cc406Sopenharmony_ci case 200: 237141cc406Sopenharmony_ci RegWrite(this,R_XRES,1, 0x24); 238141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, 0xC000 | this->state.cxWindow); 239141cc406Sopenharmony_ci break; 240141cc406Sopenharmony_ci case 300: 241141cc406Sopenharmony_ci RegWrite(this,0x08,2, 0x6A6A); 242141cc406Sopenharmony_ci RegWrite(this,R_XRES,1, 0x2A); 243141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, 0x4000 | this->state.cxWindow); 244141cc406Sopenharmony_ci RegWrite(this,0x34, 1, 0x03); /* halves the vertical resolution */ 245141cc406Sopenharmony_ci RegWrite(this,0x47,1,0xC0); /* reduces the speed a bit */ 246141cc406Sopenharmony_ci this->state.szOrder=ORDER_RGB; 247141cc406Sopenharmony_ci break; 248141cc406Sopenharmony_ci case 600: 249141cc406Sopenharmony_ci RegWrite(this,R_XRES,1, 0x3F); 250141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, 0xC000 | this->state.cxWindow); 251141cc406Sopenharmony_ci RegWrite(this,0x34, 1, 0x03); /* halves the vertical resolution */ 252141cc406Sopenharmony_ci RegWrite(this,0x47,1,0xC2); /* reduces the speed a bit */ 253141cc406Sopenharmony_ci break; 254141cc406Sopenharmony_ci case 1200: 255141cc406Sopenharmony_ci /* not supported, since the driver supports only 600 dpi in color */ 256141cc406Sopenharmony_ci break; 257141cc406Sopenharmony_ci } 258141cc406Sopenharmony_ci } 259141cc406Sopenharmony_ci 260141cc406Sopenharmony_ci /* setup gamma tables */ 261141cc406Sopenharmony_ci RegWrite(this,0x41,1,0x03); /* gamma, RGB */ 262141cc406Sopenharmony_ci RegWrite(this,0x40,1,0x28); /* offset FIFO 8*3 (GAMMA)+16 KB(gain) spared */ 263141cc406Sopenharmony_ci /* 264141cc406Sopenharmony_ci hey, surprise: Although the color lines are sent in a strange order, 265141cc406Sopenharmony_ci the gamma tables are mapped constantly to the sensors (i.e. RGB) 266141cc406Sopenharmony_ci */ 267141cc406Sopenharmony_ci UploadGammaTable(this,0x0000,this->agammaR); 268141cc406Sopenharmony_ci UploadGammaTable(this,0x2000,this->agammaG); 269141cc406Sopenharmony_ci UploadGammaTable(this,0x4000,this->agammaB); 270141cc406Sopenharmony_ci INST_ASSERT(); 271141cc406Sopenharmony_ci 272141cc406Sopenharmony_ci UploadGainCorrection(this,0x6000); 273141cc406Sopenharmony_ci INST_ASSERT(); 274141cc406Sopenharmony_ci 275141cc406Sopenharmony_ci /* enough for 1/100 inch sensor distance */ 276141cc406Sopenharmony_ci this->state.cBacklog=1+2*this->state.ySensorSkew; 277141cc406Sopenharmony_ci 278141cc406Sopenharmony_ci /* allocate raw line buffers */ 279141cc406Sopenharmony_ci this->state.ppchLines=calloc(this->state.cBacklog,sizeof(short*)); 280141cc406Sopenharmony_ci this->state.pchBuf=malloc(0x8000); 281141cc406Sopenharmony_ci if (!this->state.ppchLines || !this->state.pchBuf) 282141cc406Sopenharmony_ci return FreeState(this,SetError(this, 283141cc406Sopenharmony_ci SANE_STATUS_NO_MEM,"no buffers available")); 284141cc406Sopenharmony_ci 285141cc406Sopenharmony_ci for (i=0; i<this->state.cBacklog; i++) 286141cc406Sopenharmony_ci { 287141cc406Sopenharmony_ci this->state.ppchLines[i]=calloc(1,3*this->state.cxMax*sizeof(short)); /* must be less than 0x8000 */ 288141cc406Sopenharmony_ci if (!this->state.ppchLines[i]) 289141cc406Sopenharmony_ci return FreeState(this, 290141cc406Sopenharmony_ci SetError(this,SANE_STATUS_NO_MEM, 291141cc406Sopenharmony_ci "no line buffer available")); 292141cc406Sopenharmony_ci } 293141cc406Sopenharmony_ci 294141cc406Sopenharmony_ci /* calculate and prepare intermediate line transfer buffer */ 295141cc406Sopenharmony_ci 296141cc406Sopenharmony_ci this->state.cchLineOut=3*this->state.cxPixel; 297141cc406Sopenharmony_ci this->state.pchLineOut = malloc(this->state.cchLineOut); 298141cc406Sopenharmony_ci if (!this->state.pchLineOut) 299141cc406Sopenharmony_ci return FreeState(this,SetError(this, 300141cc406Sopenharmony_ci SANE_STATUS_NO_MEM, 301141cc406Sopenharmony_ci "no buffers available")); 302141cc406Sopenharmony_ci 303141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0x39); /* #1532[005.0] */ 304141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0x79); /* #1533[005.0] */ 305141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0xF9); /* #1534[005.0] */ 306141cc406Sopenharmony_ci INST_ASSERT(); 307141cc406Sopenharmony_ci 308141cc406Sopenharmony_ci this->state.bScanning = true; 309141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 310141cc406Sopenharmony_ci} 311