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_ci====================================================================== */ 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#include <stdarg.h> 47141cc406Sopenharmony_ci#include <unistd.h> 48141cc406Sopenharmony_ci#include "sm3600-scantool.h" 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci/* ********************************************************************** 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_cidprintf(DEBUG_XXXX, format, ...) 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ciPut a debug message on STDERR (or whatever). The message is prefixed with 55141cc406Sopenharmony_cia "debug:" and given, if the current debugging flags contain the given 56141cc406Sopenharmony_ciflag "ulType". 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci********************************************************************** */ 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci#ifdef INSANE_VERSION 61141cc406Sopenharmony_civoid DBG(int nLevel, const char *szFormat, ...) 62141cc406Sopenharmony_ci{ 63141cc406Sopenharmony_ci szFormat++; 64141cc406Sopenharmony_ci} 65141cc406Sopenharmony_ci#endif 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci__SM3600EXPORT__ 68141cc406Sopenharmony_civoid debug_printf(unsigned long ulType, const char *szFormat, ...) 69141cc406Sopenharmony_ci{ 70141cc406Sopenharmony_ci va_list ap; 71141cc406Sopenharmony_ci if ((ulDebugMask & ulType)!=ulType) return; 72141cc406Sopenharmony_ci if (*szFormat=='~') 73141cc406Sopenharmony_ci szFormat++; 74141cc406Sopenharmony_ci else 75141cc406Sopenharmony_ci fprintf(stderr,"debug:"); 76141cc406Sopenharmony_ci va_start(ap,szFormat); 77141cc406Sopenharmony_ci vfprintf(stderr,szFormat,ap); 78141cc406Sopenharmony_ci va_end(ap); 79141cc406Sopenharmony_ci} 80141cc406Sopenharmony_ci 81141cc406Sopenharmony_ci/* ********************************************************************** 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ciSetError(error, format, ...) 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_ciThe program is aborted, all handles and resources are freed (this 86141cc406Sopenharmony_cibeing global) and the user gets a nice panic screen :-) 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci********************************************************************** */ 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci__SM3600EXPORT__ 91141cc406Sopenharmony_ciint SetError(TInstance *this, int nError, const char *szFormat, ...) 92141cc406Sopenharmony_ci{ 93141cc406Sopenharmony_ci va_list ap; 94141cc406Sopenharmony_ci if (this->nErrorState) return 0; /* do not overwrite error state */ 95141cc406Sopenharmony_ci this->nErrorState=nError; 96141cc406Sopenharmony_ci this->szErrorReason=malloc(500); 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci if (szFormat!=NULL && this->szErrorReason) 99141cc406Sopenharmony_ci { 100141cc406Sopenharmony_ci va_start(ap,szFormat); 101141cc406Sopenharmony_ci vsnprintf(this->szErrorReason,499,szFormat,ap); 102141cc406Sopenharmony_ci va_end(ap); 103141cc406Sopenharmony_ci this->szErrorReason[499]='\0'; 104141cc406Sopenharmony_ci } 105141cc406Sopenharmony_ci return nError; 106141cc406Sopenharmony_ci} 107141cc406Sopenharmony_ci 108141cc406Sopenharmony_ci#ifdef INSANE_VERSION 109141cc406Sopenharmony_ci 110141cc406Sopenharmony_ci/* ********************************************************************** 111141cc406Sopenharmony_ci 112141cc406Sopenharmony_ciDumpBuffer(fh,pch,cch) 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci********************************************************************** */ 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_ci__SM3600EXPORT__ 117141cc406Sopenharmony_civoid DumpBuffer(FILE *fh, const char *pch, int cch) 118141cc406Sopenharmony_ci{ 119141cc406Sopenharmony_ci int i=0; 120141cc406Sopenharmony_ci while (i<cch) 121141cc406Sopenharmony_ci { 122141cc406Sopenharmony_ci if (!(i & 15)) 123141cc406Sopenharmony_ci { 124141cc406Sopenharmony_ci if (i) fprintf(fh,"\n"); 125141cc406Sopenharmony_ci fprintf(fh,"%04X:",i); 126141cc406Sopenharmony_ci } 127141cc406Sopenharmony_ci fprintf(fh," %02X",(unsigned char)pch[i]); 128141cc406Sopenharmony_ci i++; 129141cc406Sopenharmony_ci } 130141cc406Sopenharmony_ci fprintf(fh,"\n"); 131141cc406Sopenharmony_ci} 132141cc406Sopenharmony_ci 133141cc406Sopenharmony_ci#endif 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_ci/* ********************************************************************** 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ciFreeState() 138141cc406Sopenharmony_ci 139141cc406Sopenharmony_ciFrees all dynamical memory for scan buffering. 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_ci********************************************************************** */ 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci__SM3600EXPORT__ 144141cc406Sopenharmony_ciTState FreeState(TInstance *this, TState nReturn) 145141cc406Sopenharmony_ci{ 146141cc406Sopenharmony_ci if (this->state.ppchLines) 147141cc406Sopenharmony_ci { 148141cc406Sopenharmony_ci int i; 149141cc406Sopenharmony_ci for (i=0; i<this->state.cBacklog; i++) 150141cc406Sopenharmony_ci { 151141cc406Sopenharmony_ci if (this->state.ppchLines[i]) 152141cc406Sopenharmony_ci free(this->state.ppchLines[i]); 153141cc406Sopenharmony_ci } 154141cc406Sopenharmony_ci free(this->state.ppchLines); 155141cc406Sopenharmony_ci } 156141cc406Sopenharmony_ci if (this->state.pchLineOut) free(this->state.pchLineOut); 157141cc406Sopenharmony_ci if (this->state.pchBuf) free(this->state.pchBuf); 158141cc406Sopenharmony_ci this->state.pchBuf =NULL; 159141cc406Sopenharmony_ci this->state.pchLineOut=NULL; 160141cc406Sopenharmony_ci this->state.ppchLines =NULL; 161141cc406Sopenharmony_ci return nReturn; 162141cc406Sopenharmony_ci} 163141cc406Sopenharmony_ci 164141cc406Sopenharmony_ci/* ====================================================================== 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ciEndScan() 167141cc406Sopenharmony_ci 168141cc406Sopenharmony_ci====================================================================== */ 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_ci__SM3600EXPORT__ 171141cc406Sopenharmony_ciTState EndScan(TInstance *this) 172141cc406Sopenharmony_ci{ 173141cc406Sopenharmony_ci if (!this->state.bScanning) return SANE_STATUS_GOOD; 174141cc406Sopenharmony_ci /* move slider back to start */ 175141cc406Sopenharmony_ci this->state.bScanning=false; 176141cc406Sopenharmony_ci FreeState(this,0); 177141cc406Sopenharmony_ci INST_ASSERT(); 178141cc406Sopenharmony_ci return DoJog(this,-this->state.cyTotalPath); 179141cc406Sopenharmony_ci} 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci/* ====================================================================== 182141cc406Sopenharmony_ci 183141cc406Sopenharmony_ciTState CancelScan(TInstance *this) 184141cc406Sopenharmony_ci 185141cc406Sopenharmony_ci====================================================================== */ 186141cc406Sopenharmony_ci 187141cc406Sopenharmony_ci__SM3600EXPORT__ 188141cc406Sopenharmony_ciTState CancelScan(TInstance *this) 189141cc406Sopenharmony_ci{ 190141cc406Sopenharmony_ci TBool bCanceled; 191141cc406Sopenharmony_ci DBG(DEBUG_INFO,"CancelScan() called\n"); 192141cc406Sopenharmony_ci 193141cc406Sopenharmony_ci this->state.cyTotalPath-=RegRead(this,R_POS,2); 194141cc406Sopenharmony_ci DBG(DEBUG_JUNK,"stepping back %d steps\n",this->state.cyTotalPath); 195141cc406Sopenharmony_ci /* this->state.cyTotalPath=0; */ 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ci usleep(200); 198141cc406Sopenharmony_ci DoReset(this); 199141cc406Sopenharmony_ci EndScan(this); /* and step back! */ 200141cc406Sopenharmony_ci 201141cc406Sopenharmony_ci DBG(DEBUG_JUNK,"cs4: %d\n",(int)this->nErrorState); 202141cc406Sopenharmony_ci bCanceled=this->state.bCanceled; 203141cc406Sopenharmony_ci this->state.bCanceled=false; /* re-enable Origination! */ 204141cc406Sopenharmony_ci if (!this->bOptSkipOriginate) 205141cc406Sopenharmony_ci DoOriginate(this,false); /* have an error here... */ 206141cc406Sopenharmony_ci this->state.bCanceled=bCanceled; 207141cc406Sopenharmony_ci DBG(DEBUG_JUNK,"cs5: %d\n",(int)this->nErrorState); 208141cc406Sopenharmony_ci INST_ASSERT(); 209141cc406Sopenharmony_ci DBG(DEBUG_INFO,"cs6: ok.\n"); 210141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; /* or shall be say GOOD? */ 211141cc406Sopenharmony_ci} 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci 214141cc406Sopenharmony_ci/* ====================================================================== 215141cc406Sopenharmony_ci 216141cc406Sopenharmony_ciReadChunk() 217141cc406Sopenharmony_ci 218141cc406Sopenharmony_ci====================================================================== */ 219141cc406Sopenharmony_ci 220141cc406Sopenharmony_ci__SM3600EXPORT__ 221141cc406Sopenharmony_ciTState ReadChunk(TInstance *this, unsigned char *achOut, 222141cc406Sopenharmony_ci int cchMax, int *pcchRead) 223141cc406Sopenharmony_ci{ 224141cc406Sopenharmony_ci /* have we to copy more than we have? */ 225141cc406Sopenharmony_ci /* can the current line fill the buffer ? */ 226141cc406Sopenharmony_ci int rc; 227141cc406Sopenharmony_ci *pcchRead=0; 228141cc406Sopenharmony_ci INST_ASSERT(); 229141cc406Sopenharmony_ci if (!this->state.bScanning) 230141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; /* deferred cancel? */ 231141cc406Sopenharmony_ci if (this->state.bCanceled) /* deferred cancellation? */ 232141cc406Sopenharmony_ci return CancelScan(this); 233141cc406Sopenharmony_ci INST_ASSERT(); 234141cc406Sopenharmony_ci /* 22.4.2001: This took me hard, harder, hardest:*/ 235141cc406Sopenharmony_ci 236141cc406Sopenharmony_ci /* We need to fill the line buffer with at least a *rest* of a 237141cc406Sopenharmony_ci line. A single line will do. */ 238141cc406Sopenharmony_ci /* Thus, "iLine>0" is a suitable condition. */ 239141cc406Sopenharmony_ci /* Without the preread, there will a dummy line be read, if the 240141cc406Sopenharmony_ci target buffer is large enough.*/ 241141cc406Sopenharmony_ci if (this->state.iLine) 242141cc406Sopenharmony_ci rc=SANE_STATUS_GOOD; 243141cc406Sopenharmony_ci else 244141cc406Sopenharmony_ci rc=(*(this->state.ReadProc))(this); /* preread one line */ 245141cc406Sopenharmony_ci if (rc!=SANE_STATUS_GOOD) return rc; 246141cc406Sopenharmony_ci dprintf(DEBUG_BUFFER,"Chunk-Init: cchMax = %d\n",cchMax); 247141cc406Sopenharmony_ci while (this->state.iReadPos + cchMax > this->state.cchLineOut) 248141cc406Sopenharmony_ci { 249141cc406Sopenharmony_ci int cch; 250141cc406Sopenharmony_ci /* copy rest of the line into target */ 251141cc406Sopenharmony_ci cch = this->state.cchLineOut - this->state.iReadPos; 252141cc406Sopenharmony_ci memcpy(achOut, 253141cc406Sopenharmony_ci this->state.pchLineOut+this->state.iReadPos, 254141cc406Sopenharmony_ci cch); 255141cc406Sopenharmony_ci cchMax-=cch; /* advance parameters */ 256141cc406Sopenharmony_ci achOut+=cch; 257141cc406Sopenharmony_ci (*pcchRead)+=cch; 258141cc406Sopenharmony_ci this->state.iReadPos=0; 259141cc406Sopenharmony_ci rc=(*(this->state.ReadProc))(this); 260141cc406Sopenharmony_ci dprintf(DEBUG_BUFFER,"Chunk-Read: cchMax = %d\n",cchMax); 261141cc406Sopenharmony_ci if (rc!=SANE_STATUS_GOOD) 262141cc406Sopenharmony_ci return rc; /* should be NOT(!) EOF, but then: good and away! */ 263141cc406Sopenharmony_ci } 264141cc406Sopenharmony_ci dprintf(DEBUG_BUFFER,"Chunk-Exit: cchMax = %d\n",cchMax); 265141cc406Sopenharmony_ci if (!cchMax) return SANE_STATUS_GOOD; /* now everything fits! */ 266141cc406Sopenharmony_ci (*pcchRead) += cchMax; 267141cc406Sopenharmony_ci memcpy(achOut, 268141cc406Sopenharmony_ci this->state.pchLineOut+this->state.iReadPos, 269141cc406Sopenharmony_ci cchMax); 270141cc406Sopenharmony_ci this->state.iReadPos += cchMax; 271141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 272141cc406Sopenharmony_ci} 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci/* ====================================================================== 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ciGetAreaSize() 277141cc406Sopenharmony_ci 278141cc406Sopenharmony_ci====================================================================== */ 279141cc406Sopenharmony_ci 280141cc406Sopenharmony_ci__SM3600EXPORT__ 281141cc406Sopenharmony_civoid GetAreaSize(TInstance *this) 282141cc406Sopenharmony_ci{ 283141cc406Sopenharmony_ci /* this->state.cxPixel : pixels, we *want* (after interpolation) 284141cc406Sopenharmony_ci this->state.cxMax : pixels, we *need* (before interpolation) */ 285141cc406Sopenharmony_ci int nRefResX,nRefResY; 286141cc406Sopenharmony_ci nRefResX=nRefResY=this->param.res; 287141cc406Sopenharmony_ci switch (this->param.res) 288141cc406Sopenharmony_ci { 289141cc406Sopenharmony_ci case 75: nRefResX=100; this->state.nFixAspect=75; break; 290141cc406Sopenharmony_ci default: this->state.nFixAspect=100; break; 291141cc406Sopenharmony_ci } 292141cc406Sopenharmony_ci this->state.cxPixel =this->param.cx*this->param.res/1200; 293141cc406Sopenharmony_ci this->state.cyPixel =this->param.cy*this->param.res/1200; 294141cc406Sopenharmony_ci this->state.cxMax =this->state.cxPixel*100/this->state.nFixAspect; 295141cc406Sopenharmony_ci this->state.cxWindow =this->state.cxMax*600/nRefResX; 296141cc406Sopenharmony_ci this->state.cyWindow =this->state.cyPixel*600/nRefResY; 297141cc406Sopenharmony_ci dprintf(DEBUG_SCAN,"requesting %d[600] %d[real] %d[raw]\n", 298141cc406Sopenharmony_ci this->state.cxWindow,this->state.cxPixel,this->state.cxMax); 299141cc406Sopenharmony_ci} 300141cc406Sopenharmony_ci 301141cc406Sopenharmony_ci/* ====================================================================== 302141cc406Sopenharmony_ci 303141cc406Sopenharmony_ciResetCalibration() 304141cc406Sopenharmony_ci 305141cc406Sopenharmony_ciFree calibration data. The Instance can be safely released afterwards. 306141cc406Sopenharmony_ci 307141cc406Sopenharmony_ci====================================================================== */ 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci__SM3600EXPORT__ 310141cc406Sopenharmony_civoid ResetCalibration(TInstance *this) 311141cc406Sopenharmony_ci{ 312141cc406Sopenharmony_ci if (this->calibration.achStripeY) 313141cc406Sopenharmony_ci free(this->calibration.achStripeY); 314141cc406Sopenharmony_ci if (this->calibration.achStripeR) 315141cc406Sopenharmony_ci free(this->calibration.achStripeR); 316141cc406Sopenharmony_ci if (this->calibration.achStripeG) 317141cc406Sopenharmony_ci free(this->calibration.achStripeG); 318141cc406Sopenharmony_ci if (this->calibration.achStripeB) 319141cc406Sopenharmony_ci free(this->calibration.achStripeB); 320141cc406Sopenharmony_ci /* reset all handles, pointers, flags */ 321141cc406Sopenharmony_ci memset(&(this->calibration),0,sizeof(this->calibration)); 322141cc406Sopenharmony_ci /* TODO: type specific margins */ 323141cc406Sopenharmony_ci this->calibration.xMargin=200; 324141cc406Sopenharmony_ci this->calibration.yMargin=0x019D; 325141cc406Sopenharmony_ci this->calibration.nHoleGray=10; 326141cc406Sopenharmony_ci this->calibration.rgbBias=0x888884; 327141cc406Sopenharmony_ci this->calibration.nBarGray=0xC0; 328141cc406Sopenharmony_ci} 329141cc406Sopenharmony_ci 330141cc406Sopenharmony_ci/* ====================================================================== 331141cc406Sopenharmony_ci 332141cc406Sopenharmony_ciInitGammaTables() 333141cc406Sopenharmony_ci 334141cc406Sopenharmony_ciInit gammy tables and gain tables within controller memory. 335141cc406Sopenharmony_ci 336141cc406Sopenharmony_ci====================================================================== */ 337141cc406Sopenharmony_ci 338141cc406Sopenharmony_ci__SM3600EXPORT__ 339141cc406Sopenharmony_ciTState InitGammaTables(TInstance *this, int nBrightness, int nContrast) 340141cc406Sopenharmony_ci{ 341141cc406Sopenharmony_ci long i; 342141cc406Sopenharmony_ci long lOffset; 343141cc406Sopenharmony_ci long lScale; 344141cc406Sopenharmony_ci /* the rescaling is done with temporary zero translation to 2048 */ 345141cc406Sopenharmony_ci lOffset=(nBrightness-128)*16; /* signed! */ 346141cc406Sopenharmony_ci lScale=(nContrast+128)*100; /* in percent */ 347141cc406Sopenharmony_ci for (i=0; i<4096; i++) 348141cc406Sopenharmony_ci { 349141cc406Sopenharmony_ci int n=(int)((i+lOffset)*lScale/12800L+2048L); 350141cc406Sopenharmony_ci if (n<0) n=0; 351141cc406Sopenharmony_ci else if (n>4095) n=4095; 352141cc406Sopenharmony_ci this->agammaY[i]=n; 353141cc406Sopenharmony_ci this->agammaR[i]=n; 354141cc406Sopenharmony_ci this->agammaG[i]=n; 355141cc406Sopenharmony_ci this->agammaB[i]=n; 356141cc406Sopenharmony_ci } 357141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 358141cc406Sopenharmony_ci} 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci#ifdef INSANE_VERSION 361141cc406Sopenharmony_ci 362141cc406Sopenharmony_ci/* ====================================================================== 363141cc406Sopenharmony_ci 364141cc406Sopenharmony_ciDoScanFile() 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ciTop level caller for scantool. 367141cc406Sopenharmony_ci 368141cc406Sopenharmony_ci====================================================================== */ 369141cc406Sopenharmony_ci 370141cc406Sopenharmony_ci#define APP_CHUNK_SIZE 0x8000 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci__SM3600EXPORT__ 373141cc406Sopenharmony_ciTState DoScanFile(TInstance *this) 374141cc406Sopenharmony_ci{ 375141cc406Sopenharmony_ci int cx,cy; 376141cc406Sopenharmony_ci long lcchRead; 377141cc406Sopenharmony_ci TState rc; 378141cc406Sopenharmony_ci char *achBuf; 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_ci achBuf=malloc(APP_CHUNK_SIZE); 381141cc406Sopenharmony_ci rc=SANE_STATUS_GOOD; /* make compiler happy */ 382141cc406Sopenharmony_ci rc=InitGammaTables(this, this->param.nBrightness, this->param.nContrast); 383141cc406Sopenharmony_ci if (rc!=SANE_STATUS_GOOD) return rc; 384141cc406Sopenharmony_ci if (this->mode==color) 385141cc406Sopenharmony_ci rc=StartScanColor(this); 386141cc406Sopenharmony_ci else 387141cc406Sopenharmony_ci rc=StartScanGray(this); 388141cc406Sopenharmony_ci cx=this->state.cxPixel; 389141cc406Sopenharmony_ci cy=this->state.cyPixel; 390141cc406Sopenharmony_ci if (this->bVerbose) 391141cc406Sopenharmony_ci fprintf(stderr,"scanning %d by %d\n",cx,cy); 392141cc406Sopenharmony_ci if (this->fhScan && !this->bWriteRaw && !this->pchPageBuffer) 393141cc406Sopenharmony_ci { 394141cc406Sopenharmony_ci switch (this->mode) 395141cc406Sopenharmony_ci { 396141cc406Sopenharmony_ci case color: fprintf(this->fhScan,"P6\n%d %d\n255\n",cx,cy); 397141cc406Sopenharmony_ci break; 398141cc406Sopenharmony_ci case gray: fprintf(this->fhScan,"P5\n%d %d\n255\n",cx,cy); 399141cc406Sopenharmony_ci break; 400141cc406Sopenharmony_ci default: fprintf(this->fhScan,"P4\n%d %d\n",cx,cy); 401141cc406Sopenharmony_ci break; 402141cc406Sopenharmony_ci } 403141cc406Sopenharmony_ci } 404141cc406Sopenharmony_ci lcchRead=0L; 405141cc406Sopenharmony_ci while (!rc) 406141cc406Sopenharmony_ci { 407141cc406Sopenharmony_ci int cch; 408141cc406Sopenharmony_ci cch=0; 409141cc406Sopenharmony_ci rc=ReadChunk(this,achBuf,APP_CHUNK_SIZE,&cch); 410141cc406Sopenharmony_ci if (cch>0 && this->fhScan && cch<=APP_CHUNK_SIZE) 411141cc406Sopenharmony_ci { 412141cc406Sopenharmony_ci if (this->pchPageBuffer) 413141cc406Sopenharmony_ci { 414141cc406Sopenharmony_ci#ifdef SM3600_DEBUGPAGEBUFFER 415141cc406Sopenharmony_ci if (this->bVerbose) 416141cc406Sopenharmony_ci fprintf(stderr,"ichPageBuffer:%d, cch:%d, cchPageBuffer:%d\n", 417141cc406Sopenharmony_ci this->ichPageBuffer,cch,this->cchPageBuffer); 418141cc406Sopenharmony_ci#endif 419141cc406Sopenharmony_ci CHECK_ASSERTION(this->ichPageBuffer+cch<=this->cchPageBuffer); 420141cc406Sopenharmony_ci memcpy(this->pchPageBuffer+this->ichPageBuffer, 421141cc406Sopenharmony_ci achBuf,cch); 422141cc406Sopenharmony_ci this->ichPageBuffer+=cch; 423141cc406Sopenharmony_ci } 424141cc406Sopenharmony_ci else if (!this->bWriteRaw) 425141cc406Sopenharmony_ci fwrite(achBuf,1,cch,this->fhScan); 426141cc406Sopenharmony_ci lcchRead+=cch; 427141cc406Sopenharmony_ci } 428141cc406Sopenharmony_ci } 429141cc406Sopenharmony_ci free(achBuf); 430141cc406Sopenharmony_ci if (this->bVerbose) 431141cc406Sopenharmony_ci fprintf(stderr,"read %ld image byte(s)\n",lcchRead); 432141cc406Sopenharmony_ci EndScan(this); 433141cc406Sopenharmony_ci INST_ASSERT(); 434141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 435141cc406Sopenharmony_ci} 436141cc406Sopenharmony_ci 437141cc406Sopenharmony_ci#endif 438