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_cigrayscale 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/* ********************************************************************** 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ciDoScanGray() 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci********************************************************************** */ 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci#define LINE_THRESHOLD 0x800 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_cistatic unsigned char uchRegs075[]={ 61141cc406Sopenharmony_ci /*R_SPOS*/ 0xFC, /*R_SPOSH*/ 0x00, /*0x03*/ 0x20, 62141cc406Sopenharmony_ci /*R_SWID*/ 0xB0, /*R_SWIDH*/ 0x04, /*R_STPS*/ 0x06, 63141cc406Sopenharmony_ci /*R_STPSH*/ 0x00, /*0x08*/ 0x00, /*0x09*/ 0x3F, 64141cc406Sopenharmony_ci /*R_LEN*/ 0x28, /*R_LENH*/ 0x07, /*0x0C*/ 0x6D, 65141cc406Sopenharmony_ci /*0x0D*/ 0x70, /*0x0E*/ 0x69, /*0x0F*/ 0xD0, 66141cc406Sopenharmony_ci /*0x10*/ 0x00, /*0x11*/ 0x00, /*0x12*/ 0x40, 67141cc406Sopenharmony_ci /*0x13*/ 0x15, /*0x14*/ 0x80, /*0x15*/ 0x2A, 68141cc406Sopenharmony_ci /*0x16*/ 0xC0, /*0x17*/ 0x40, /*0x18*/ 0xC0, 69141cc406Sopenharmony_ci /*0x19*/ 0x40, /*0x1A*/ 0xFF, /*0x1B*/ 0x01, 70141cc406Sopenharmony_ci /*0x1C*/ 0x88, /*0x1D*/ 0x40, /*0x1E*/ 0x4C, 71141cc406Sopenharmony_ci /*0x1F*/ 0x50, /*0x20*/ 0x00, /*0x21*/ 0x0C, 72141cc406Sopenharmony_ci /*0x22*/ 0x21, /*0x23*/ 0xF0, /*0x24*/ 0x40, 73141cc406Sopenharmony_ci /*0x25*/ 0x00, /*0x26*/ 0x0A, /*0x27*/ 0xF0, 74141cc406Sopenharmony_ci /*0x28*/ 0x00, /*0x29*/ 0x00, /*0x2A*/ 0x4E, 75141cc406Sopenharmony_ci /*0x2B*/ 0xF0, /*0x2C*/ 0x00, /*0x2D*/ 0x00, 76141cc406Sopenharmony_ci /*0x2E*/ 0x4E, /*R_CCAL*/ 0x80, /*R_CCAL2*/ 0x80, 77141cc406Sopenharmony_ci /*R_CCAL3*/ 0x80, /*0x32*/ 0xC9, /*0x33*/ 0x20, 78141cc406Sopenharmony_ci /*0x34*/ 0x83, /*0x35*/ 0x29, /*0x36*/ 0x00, 79141cc406Sopenharmony_ci /*0x37*/ 0x00, /*0x38*/ 0x00, /*0x39*/ 0x00, 80141cc406Sopenharmony_ci /*0x3A*/ 0x00, /*0x3B*/ 0x00, /*0x3C*/ 0xFF, 81141cc406Sopenharmony_ci /*0x3D*/ 0x0F, /*0x3E*/ 0x00, /*0x3F*/ 0x00, 82141cc406Sopenharmony_ci /*0x40*/ 0x01, /*0x41*/ 0x00, /*R_CSTAT*/ 0x00, 83141cc406Sopenharmony_ci /*0x43*/ 0x03, /*R_LMP*/ 0x01, /*0x45*/ 0x00, 84141cc406Sopenharmony_ci /*R_CTL*/ 0x39, /*0x47*/ 0xC0, /*0x48*/ 0x40, 85141cc406Sopenharmony_ci /*0x49*/ 0x9E, /*0x4A*/ 0x8C }; 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_cistatic unsigned char uchRegs100[]={ 88141cc406Sopenharmony_ci /*R_SPOS*/ 0xFC, /*R_SPOSH*/ 0x00, /*0x03*/ 0x20, 89141cc406Sopenharmony_ci /*R_SWID*/ 0xB0, /*R_SWIDH*/ 0x04, /*R_STPS*/ 0x06, 90141cc406Sopenharmony_ci /*R_STPSH*/ 0x00, /*0x08*/ 0x00, /*0x09*/ 0x3F, 91141cc406Sopenharmony_ci /*R_LEN*/ 0x34, /*R_LENH*/ 0x07, /*0x0C*/ 0x6D, 92141cc406Sopenharmony_ci /*0x0D*/ 0x70, /*0x0E*/ 0x69, /*0x0F*/ 0xD0, 93141cc406Sopenharmony_ci /*0x10*/ 0x00, /*0x11*/ 0x00, /*0x12*/ 0x42, 94141cc406Sopenharmony_ci /*0x13*/ 0x15, /*0x14*/ 0x84, /*0x15*/ 0x2A, 95141cc406Sopenharmony_ci /*0x16*/ 0xC2, /*0x17*/ 0x40, /*0x18*/ 0xC2, 96141cc406Sopenharmony_ci /*0x19*/ 0x40, /*0x1A*/ 0xFF, /*0x1B*/ 0x01, 97141cc406Sopenharmony_ci /*0x1C*/ 0x88, /*0x1D*/ 0x40, /*0x1E*/ 0x4C, 98141cc406Sopenharmony_ci /*0x1F*/ 0x50, /*0x20*/ 0x00, /*0x21*/ 0x0C, 99141cc406Sopenharmony_ci /*0x22*/ 0x21, /*0x23*/ 0xF0, /*0x24*/ 0x40, 100141cc406Sopenharmony_ci /*0x25*/ 0x00, /*0x26*/ 0x0A, /*0x27*/ 0xF0, 101141cc406Sopenharmony_ci /*0x28*/ 0x00, /*0x29*/ 0x00, /*0x2A*/ 0x4E, 102141cc406Sopenharmony_ci /*0x2B*/ 0xF0, /*0x2C*/ 0x00, /*0x2D*/ 0x00, 103141cc406Sopenharmony_ci /*0x2E*/ 0x4E, /*R_CCAL*/ 0x80, /*R_CCAL2*/ 0x80, 104141cc406Sopenharmony_ci /*R_CCAL3*/ 0x80, /*0x32*/ 0xC9, /*0x33*/ 0x20, 105141cc406Sopenharmony_ci /*0x34*/ 0x63, /*0x35*/ 0x29, /*0x36*/ 0x00, 106141cc406Sopenharmony_ci /*0x37*/ 0x00, /*0x38*/ 0x00, /*0x39*/ 0x00, 107141cc406Sopenharmony_ci /*0x3A*/ 0x00, /*0x3B*/ 0x00, /*0x3C*/ 0xFF, 108141cc406Sopenharmony_ci /*0x3D*/ 0x0F, /*0x3E*/ 0x00, /*0x3F*/ 0x00, 109141cc406Sopenharmony_ci /*0x40*/ 0x01, /*0x41*/ 0x00, /*R_CSTAT*/ 0x80, 110141cc406Sopenharmony_ci /*0x43*/ 0x03, /*R_LMP*/ 0x01, /*0x45*/ 0x00, 111141cc406Sopenharmony_ci /*R_CTL*/ 0x39, /*0x47*/ 0xC2, /*0x48*/ 0x40, 112141cc406Sopenharmony_ci /*0x49*/ 0x9E, /*0x4A*/ 0x8C }; 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_cistatic unsigned char uchRegs200[]={ 115141cc406Sopenharmony_ci /*R_SPOS*/ 0xFC, /*R_SPOSH*/ 0x00, /*0x03*/ 0x24, 116141cc406Sopenharmony_ci /*R_SWID*/ 0xB0, /*R_SWIDH*/ 0x04, /*R_STPS*/ 0x06, 117141cc406Sopenharmony_ci /*R_STPSH*/ 0x00, /*0x08*/ 0x00, /*0x09*/ 0x3F, 118141cc406Sopenharmony_ci /*R_LEN*/ 0x22, /*R_LENH*/ 0x07, /*0x0C*/ 0x6D, 119141cc406Sopenharmony_ci /*0x0D*/ 0x70, /*0x0E*/ 0x69, /*0x0F*/ 0xD0, 120141cc406Sopenharmony_ci /*0x10*/ 0x00, /*0x11*/ 0x00, /*0x12*/ 0x42, 121141cc406Sopenharmony_ci /*0x13*/ 0x15, /*0x14*/ 0x42, /*0x15*/ 0x15, 122141cc406Sopenharmony_ci /*0x16*/ 0x42, /*0x17*/ 0x15, /*0x18*/ 0x42, 123141cc406Sopenharmony_ci /*0x19*/ 0x15, /*0x1A*/ 0x07, /*0x1B*/ 0x00, 124141cc406Sopenharmony_ci /*0x1C*/ 0x08, /*0x1D*/ 0x12, /*0x1E*/ 0x4C, 125141cc406Sopenharmony_ci /*0x1F*/ 0x50, /*0x20*/ 0x00, /*0x21*/ 0x0C, 126141cc406Sopenharmony_ci /*0x22*/ 0x21, /*0x23*/ 0xF0, /*0x24*/ 0x40, 127141cc406Sopenharmony_ci /*0x25*/ 0x00, /*0x26*/ 0x0A, /*0x27*/ 0xF0, 128141cc406Sopenharmony_ci /*0x28*/ 0x00, /*0x29*/ 0x00, /*0x2A*/ 0x4E, 129141cc406Sopenharmony_ci /*0x2B*/ 0xF0, /*0x2C*/ 0x00, /*0x2D*/ 0x00, 130141cc406Sopenharmony_ci /*0x2E*/ 0x4E, /*R_CCAL*/ 0x80, /*R_CCAL2*/ 0x80, 131141cc406Sopenharmony_ci /*R_CCAL3*/ 0x80, /*0x32*/ 0xC9, /*0x33*/ 0x20, 132141cc406Sopenharmony_ci /*0x34*/ 0x43, /*0x35*/ 0x29, /*0x36*/ 0x00, 133141cc406Sopenharmony_ci /*0x37*/ 0x00, /*0x38*/ 0x00, /*0x39*/ 0x00, 134141cc406Sopenharmony_ci /*0x3A*/ 0x00, /*0x3B*/ 0x00, /*0x3C*/ 0xFF, 135141cc406Sopenharmony_ci /*0x3D*/ 0x0F, /*0x3E*/ 0x00, /*0x3F*/ 0x00, 136141cc406Sopenharmony_ci /*0x40*/ 0x01, /*0x41*/ 0x00, /*R_CSTAT*/ 0x80, 137141cc406Sopenharmony_ci /*0x43*/ 0x03, /*R_LMP*/ 0x01, /*0x45*/ 0x00, 138141cc406Sopenharmony_ci /*R_CTL*/ 0x39, /*0x47*/ 0x42, /*0x48*/ 0x15, 139141cc406Sopenharmony_ci /*0x49*/ 0x9E, /*0x4A*/ 0x8C }; 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_cistatic unsigned char uchRegs300[]={ 142141cc406Sopenharmony_ci /*R_SPOS*/ 0xFC, /*R_SPOSH*/ 0x00, /*0x03*/ 0x2A, 143141cc406Sopenharmony_ci /*R_SWID*/ 0xB0, /*R_SWIDH*/ 0x04, /*R_STPS*/ 0x06, 144141cc406Sopenharmony_ci /*R_STPSH*/ 0x00, /*0x08*/ 0x00, /*0x09*/ 0x2A, 145141cc406Sopenharmony_ci /*R_LEN*/ 0x16, /*R_LENH*/ 0x07, /*0x0C*/ 0x6D, 146141cc406Sopenharmony_ci /*0x0D*/ 0x70, /*0x0E*/ 0x69, /*0x0F*/ 0xD0, 147141cc406Sopenharmony_ci /*0x10*/ 0x00, /*0x11*/ 0x00, /*0x12*/ 0x40, 148141cc406Sopenharmony_ci /*0x13*/ 0x15, /*0x14*/ 0x40, /*0x15*/ 0x15, 149141cc406Sopenharmony_ci /*0x16*/ 0x40, /*0x17*/ 0x15, /*0x18*/ 0x40, 150141cc406Sopenharmony_ci /*0x19*/ 0x15, /*0x1A*/ 0x07, /*0x1B*/ 0x00, 151141cc406Sopenharmony_ci /*0x1C*/ 0x08, /*0x1D*/ 0x12, /*0x1E*/ 0x4C, 152141cc406Sopenharmony_ci /*0x1F*/ 0x50, /*0x20*/ 0x00, /*0x21*/ 0x0C, 153141cc406Sopenharmony_ci /*0x22*/ 0x21, /*0x23*/ 0xF0, /*0x24*/ 0x40, 154141cc406Sopenharmony_ci /*0x25*/ 0x00, /*0x26*/ 0x0A, /*0x27*/ 0xF0, 155141cc406Sopenharmony_ci /*0x28*/ 0x00, /*0x29*/ 0x00, /*0x2A*/ 0x4E, 156141cc406Sopenharmony_ci /*0x2B*/ 0xF0, /*0x2C*/ 0x00, /*0x2D*/ 0x00, 157141cc406Sopenharmony_ci /*0x2E*/ 0x4E, /*R_CCAL*/ 0x80, /*R_CCAL2*/ 0x80, 158141cc406Sopenharmony_ci /*R_CCAL3*/ 0x80, /*0x32*/ 0xC9, /*0x33*/ 0x20, 159141cc406Sopenharmony_ci /*0x34*/ 0x03, /*0x35*/ 0x29, /*0x36*/ 0x00, 160141cc406Sopenharmony_ci /*0x37*/ 0x00, /*0x38*/ 0x00, /*0x39*/ 0x00, 161141cc406Sopenharmony_ci /*0x3A*/ 0x00, /*0x3B*/ 0x00, /*0x3C*/ 0xFF, 162141cc406Sopenharmony_ci /*0x3D*/ 0x0F, /*0x3E*/ 0x00, /*0x3F*/ 0x00, 163141cc406Sopenharmony_ci /*0x40*/ 0x01, /*0x41*/ 0x00, /*R_CSTAT*/ 0x80, 164141cc406Sopenharmony_ci /*0x43*/ 0x03, /*R_LMP*/ 0x01, /*0x45*/ 0x00, 165141cc406Sopenharmony_ci /*R_CTL*/ 0x39, /*0x47*/ 0x40, /*0x48*/ 0x15, 166141cc406Sopenharmony_ci /*0x49*/ 0x96, /*0x4A*/ 0x8C }; 167141cc406Sopenharmony_ci 168141cc406Sopenharmony_cistatic unsigned char uchRegs600[]={ 169141cc406Sopenharmony_ci /*R_SPOS*/ 0xFC, /*R_SPOSH*/ 0x00, /*0x03*/ 0x3F, 170141cc406Sopenharmony_ci /*R_SWID*/ 0xB0, /*R_SWIDH*/ 0x04, /*R_STPS*/ 0x06, 171141cc406Sopenharmony_ci /*R_STPSH*/ 0x00, /*0x08*/ 0x00, /*0x09*/ 0x3F, 172141cc406Sopenharmony_ci /*R_LEN*/ 0x16, /*R_LENH*/ 0x07, /*0x0C*/ 0x6D, 173141cc406Sopenharmony_ci /*0x0D*/ 0x70, /*0x0E*/ 0x69, /*0x0F*/ 0xD0, 174141cc406Sopenharmony_ci /*0x10*/ 0x00, /*0x11*/ 0x00, /*0x12*/ 0x42, 175141cc406Sopenharmony_ci /*0x13*/ 0x15, /*0x14*/ 0x42, /*0x15*/ 0x15, 176141cc406Sopenharmony_ci /*0x16*/ 0x42, /*0x17*/ 0x15, /*0x18*/ 0x42, 177141cc406Sopenharmony_ci /*0x19*/ 0x15, /*0x1A*/ 0x07, /*0x1B*/ 0x00, 178141cc406Sopenharmony_ci /*0x1C*/ 0x08, /*0x1D*/ 0x12, /*0x1E*/ 0x4C, 179141cc406Sopenharmony_ci /*0x1F*/ 0x50, /*0x20*/ 0x00, /*0x21*/ 0x0C, 180141cc406Sopenharmony_ci /*0x22*/ 0x21, /*0x23*/ 0xF0, /*0x24*/ 0x40, 181141cc406Sopenharmony_ci /*0x25*/ 0x00, /*0x26*/ 0x0A, /*0x27*/ 0xF0, 182141cc406Sopenharmony_ci /*0x28*/ 0x00, /*0x29*/ 0x00, /*0x2A*/ 0x4E, 183141cc406Sopenharmony_ci /*0x2B*/ 0xF0, /*0x2C*/ 0x00, /*0x2D*/ 0x00, 184141cc406Sopenharmony_ci /*0x2E*/ 0x4E, /*R_CCAL*/ 0x80, /*R_CCAL2*/ 0x80, 185141cc406Sopenharmony_ci /*R_CCAL3*/ 0x80, /*0x32*/ 0xC9, /*0x33*/ 0x20, 186141cc406Sopenharmony_ci /*0x34*/ 0x03, /*0x35*/ 0x29, /*0x36*/ 0x00, 187141cc406Sopenharmony_ci /*0x37*/ 0x00, /*0x38*/ 0x00, /*0x39*/ 0x00, 188141cc406Sopenharmony_ci /*0x3A*/ 0x00, /*0x3B*/ 0x00, /*0x3C*/ 0xFF, 189141cc406Sopenharmony_ci /*0x3D*/ 0x0F, /*0x3E*/ 0x00, /*0x3F*/ 0x00, 190141cc406Sopenharmony_ci /*0x40*/ 0x01, /*0x41*/ 0x00, /*R_CSTAT*/ 0x80, 191141cc406Sopenharmony_ci /*0x43*/ 0x03, /*R_LMP*/ 0x01, /*0x45*/ 0x00, 192141cc406Sopenharmony_ci /*R_CTL*/ 0x39, /*0x47*/ 0x42, /*0x48*/ 0x15, 193141cc406Sopenharmony_ci /*0x49*/ 0x96, /*0x4A*/ 0x8C }; 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci/* ====================================================================== 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ciReadNextGrayLine() 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci====================================================================== */ 200141cc406Sopenharmony_ci 201141cc406Sopenharmony_cistatic TState ReadNextGrayLine(PTInstance this) 202141cc406Sopenharmony_ci{ 203141cc406Sopenharmony_ci int iWrite; 204141cc406Sopenharmony_ci int iDot; 205141cc406Sopenharmony_ci unsigned char chBits; 206141cc406Sopenharmony_ci int iRead; /* read position in raw line */ 207141cc406Sopenharmony_ci int nInterpolator; 208141cc406Sopenharmony_ci 209141cc406Sopenharmony_ci iWrite=0; 210141cc406Sopenharmony_ci 211141cc406Sopenharmony_ci while (iWrite<this->state.cxMax) /* max 1 time in reality */ 212141cc406Sopenharmony_ci { 213141cc406Sopenharmony_ci while (iWrite<this->state.cxMax && 214141cc406Sopenharmony_ci this->state.iBulkReadPos<this->state.cchBulk) 215141cc406Sopenharmony_ci this->state.ppchLines[0][iWrite++] += /* add! */ 216141cc406Sopenharmony_ci this->state.pchBuf[this->state.iBulkReadPos++]<<4; 217141cc406Sopenharmony_ci if (iWrite<this->state.cxMax) /* we need an additional chunk */ 218141cc406Sopenharmony_ci { 219141cc406Sopenharmony_ci if (this->state.bLastBulk) 220141cc406Sopenharmony_ci return SANE_STATUS_EOF; 221141cc406Sopenharmony_ci this->state.cchBulk=BulkReadBuffer(this,this->state.pchBuf, 222141cc406Sopenharmony_ci USB_CHUNK_SIZE); 223141cc406Sopenharmony_ci dprintf(DEBUG_SCAN,"bulk read: %d byte(s), line #%d\n", 224141cc406Sopenharmony_ci this->state.cchBulk, this->state.iLine); 225141cc406Sopenharmony_ci if (this->bWriteRaw) 226141cc406Sopenharmony_ci fwrite(this->state.pchBuf,1,this->state.cchBulk,this->fhScan); 227141cc406Sopenharmony_ci INST_ASSERT(); 228141cc406Sopenharmony_ci if (this->state.cchBulk!=USB_CHUNK_SIZE) 229141cc406Sopenharmony_ci this->state.bLastBulk=true; 230141cc406Sopenharmony_ci this->state.iBulkReadPos=0; 231141cc406Sopenharmony_ci } 232141cc406Sopenharmony_ci } /* while raw line buffer acquiring */ 233141cc406Sopenharmony_ci this->state.iLine++; 234141cc406Sopenharmony_ci iDot=0; chBits=0; /* init pixelbuffer */ 235141cc406Sopenharmony_ci for (nInterpolator=50, iWrite=0, iRead=0; 236141cc406Sopenharmony_ci iRead<this->state.cxMax; 237141cc406Sopenharmony_ci iRead++) 238141cc406Sopenharmony_ci { 239141cc406Sopenharmony_ci nInterpolator+=this->state.nFixAspect; 240141cc406Sopenharmony_ci if (nInterpolator<100) continue; /* res. reduction */ 241141cc406Sopenharmony_ci nInterpolator-=100; 242141cc406Sopenharmony_ci if (iWrite>=this->state.cchLineOut) continue; 243141cc406Sopenharmony_ci /* dprintf(DEBUG_SCAN," i=%d",iTo); */ 244141cc406Sopenharmony_ci if (this->mode==gray) 245141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]= 246141cc406Sopenharmony_ci this->state.ppchLines[0][iRead]>>4; 247141cc406Sopenharmony_ci else 248141cc406Sopenharmony_ci { 249141cc406Sopenharmony_ci unsigned char chBit; /* 1=white */ 250141cc406Sopenharmony_ci if (this->mode==line) 251141cc406Sopenharmony_ci chBit=(this->state.ppchLines[0][iRead]<LINE_THRESHOLD); 252141cc406Sopenharmony_ci else 253141cc406Sopenharmony_ci { 254141cc406Sopenharmony_ci short nError=this->state.ppchLines[0][iRead]; 255141cc406Sopenharmony_ci /* printf("(%d)",nError); */ 256141cc406Sopenharmony_ci if (nError>=0xFF0) 257141cc406Sopenharmony_ci { 258141cc406Sopenharmony_ci nError-=0xFF0; 259141cc406Sopenharmony_ci chBit=0; 260141cc406Sopenharmony_ci } 261141cc406Sopenharmony_ci else 262141cc406Sopenharmony_ci chBit=1; 263141cc406Sopenharmony_ci /* since I sketched the Floyd-Steinberg 264141cc406Sopenharmony_ci algorithm from heart, I have no idea, if 265141cc406Sopenharmony_ci there is room for improvement in the 266141cc406Sopenharmony_ci coefficients. If You know, please drop 267141cc406Sopenharmony_ci me a line (eichholz@computer.org, 1.4.2001) */ 268141cc406Sopenharmony_ci#define FASTDITHER 269141cc406Sopenharmony_ci#ifdef FASTDITHER 270141cc406Sopenharmony_ci this->state.ppchLines[0][iRead+1]+=(nError>>2); /* 8/16 */ 271141cc406Sopenharmony_ci this->state.ppchLines[1][iRead+1]+=(nError>>1); 272141cc406Sopenharmony_ci this->state.ppchLines[1][iRead] +=(nError>>2); /* 8/16 */ 273141cc406Sopenharmony_ci#else 274141cc406Sopenharmony_ci this->state.ppchLines[0][iRead+1]+=(nError*5)>>4; 275141cc406Sopenharmony_ci this->state.ppchLines[1][iRead+1]+=(nError*8)>>4; 276141cc406Sopenharmony_ci this->state.ppchLines[1][iRead] +=(nError*3)>>4; 277141cc406Sopenharmony_ci#endif 278141cc406Sopenharmony_ci } 279141cc406Sopenharmony_ci chBits=(chBits<<1)|chBit; 280141cc406Sopenharmony_ci iDot++; 281141cc406Sopenharmony_ci if (iDot==8 && iWrite<this->state.cchLineOut) 282141cc406Sopenharmony_ci { 283141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]=chBits; 284141cc406Sopenharmony_ci iDot=0; chBits=0; 285141cc406Sopenharmony_ci } 286141cc406Sopenharmony_ci } /* gray pixel postprocessing */ 287141cc406Sopenharmony_ci } /* line postprocessing */ 288141cc406Sopenharmony_ci if (iDot && iWrite<this->state.cchLineOut) 289141cc406Sopenharmony_ci this->state.pchLineOut[iWrite++]=chBits; 290141cc406Sopenharmony_ci /* cycle the history lines and clear the preread buffer*/ 291141cc406Sopenharmony_ci { 292141cc406Sopenharmony_ci short *p=this->state.ppchLines[0]; 293141cc406Sopenharmony_ci this->state.ppchLines[0]=this->state.ppchLines[1]; 294141cc406Sopenharmony_ci this->state.ppchLines[1]=p; 295141cc406Sopenharmony_ci memset(this->state.ppchLines[1],0,(this->state.cxMax+1)*sizeof(short)); 296141cc406Sopenharmony_ci } 297141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 298141cc406Sopenharmony_ci} 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci/* ====================================================================== 301141cc406Sopenharmony_ci 302141cc406Sopenharmony_ciStartScanGray() 303141cc406Sopenharmony_ci 304141cc406Sopenharmony_ci====================================================================== */ 305141cc406Sopenharmony_ci 306141cc406Sopenharmony_ci__SM3600EXPORT__ 307141cc406Sopenharmony_ciTState StartScanGray(TInstance *this) 308141cc406Sopenharmony_ci{ 309141cc406Sopenharmony_ci unsigned char *puchRegs; 310141cc406Sopenharmony_ci int i; 311141cc406Sopenharmony_ci if (this->state.bScanning) 312141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_DEVICE_BUSY,"scan active"); 313141cc406Sopenharmony_ci memset(&(this->state),0,sizeof(TScanState)); 314141cc406Sopenharmony_ci this->state.ReadProc =ReadNextGrayLine; 315141cc406Sopenharmony_ci puchRegs=NULL; 316141cc406Sopenharmony_ci switch (this->param.res) 317141cc406Sopenharmony_ci { 318141cc406Sopenharmony_ci case 75: puchRegs=uchRegs075; break; 319141cc406Sopenharmony_ci case 100: puchRegs=uchRegs100; break; 320141cc406Sopenharmony_ci case 200: puchRegs=uchRegs200; break; 321141cc406Sopenharmony_ci case 300: puchRegs=uchRegs300; break; 322141cc406Sopenharmony_ci case 600: puchRegs=uchRegs600; break; 323141cc406Sopenharmony_ci } 324141cc406Sopenharmony_ci GetAreaSize(this); 325141cc406Sopenharmony_ci this->state.cyTotalPath = this->param.y/2; 326141cc406Sopenharmony_ci DoJog(this,this->state.cyTotalPath); 327141cc406Sopenharmony_ci INST_ASSERT(); 328141cc406Sopenharmony_ci this->state.cyTotalPath += this->param.cy/2; /* for jogging back */ 329141cc406Sopenharmony_ci 330141cc406Sopenharmony_ci /* 331141cc406Sopenharmony_ci regular scan is asynchronously, that is, 332141cc406Sopenharmony_ci the scanning is issued, and the driver does bulk reads, 333141cc406Sopenharmony_ci until there are no data left. 334141cc406Sopenharmony_ci */ 335141cc406Sopenharmony_ci RegWriteArray(this,R_ALL, NUM_SCANREGS, puchRegs); INST_ASSERT(); 336141cc406Sopenharmony_ci RegWrite(this,R_SPOS, 2, 337141cc406Sopenharmony_ci this->param.x/2+this->calibration.xMargin); INST_ASSERT(); 338141cc406Sopenharmony_ci RegWrite(this,R_SLEN, 2, this->state.cyWindow); INST_ASSERT(); 339141cc406Sopenharmony_ci RegWrite(this,R_SWID, 2, this->state.cxWindow); INST_ASSERT(); 340141cc406Sopenharmony_ci RegWrite(this,R_STPS, 2, 0); INST_ASSERT(); 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci /* upload gamma table */ 343141cc406Sopenharmony_ci RegWrite(this,0x41,1,0x01); /* gamma, gray */ 344141cc406Sopenharmony_ci RegWrite(this,0x40,1,0x20); /* FIFO at 0x08000 */ 345141cc406Sopenharmony_ci UploadGammaTable(this,0,this->agammaY); INST_ASSERT(); 346141cc406Sopenharmony_ci 347141cc406Sopenharmony_ci UploadGainCorrection(this, 0x2000); 348141cc406Sopenharmony_ci INST_ASSERT(); 349141cc406Sopenharmony_ci 350141cc406Sopenharmony_ci /* for halftone dithering we need one history line */ 351141cc406Sopenharmony_ci this->state.pchBuf=malloc(USB_CHUNK_SIZE); 352141cc406Sopenharmony_ci this->state.cBacklog=2; 353141cc406Sopenharmony_ci this->state.ppchLines=calloc(this->state.cBacklog,sizeof(short *)); 354141cc406Sopenharmony_ci if (!this->state.pchBuf || !this->state.ppchLines) 355141cc406Sopenharmony_ci return FreeState(this,SetError(this, 356141cc406Sopenharmony_ci SANE_STATUS_NO_MEM,"no buffers available")); 357141cc406Sopenharmony_ci for (i=0; i<this->state.cBacklog; i++) 358141cc406Sopenharmony_ci { 359141cc406Sopenharmony_ci this->state.ppchLines[i]=calloc(this->state.cxMax+1, 360141cc406Sopenharmony_ci sizeof(short)); /* 1 dummy at right edge */ 361141cc406Sopenharmony_ci if (!this->state.ppchLines[i]) 362141cc406Sopenharmony_ci return FreeState(this,SetError(this, 363141cc406Sopenharmony_ci SANE_STATUS_NO_MEM,"no buffers available")); 364141cc406Sopenharmony_ci } 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci /* calculate and prepare intermediate line transfer buffer */ 367141cc406Sopenharmony_ci 368141cc406Sopenharmony_ci this->state.cchLineOut=(this->mode==gray) 369141cc406Sopenharmony_ci ? this->state.cxPixel 370141cc406Sopenharmony_ci : (this->state.cxPixel+7)/8; 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci this->state.pchLineOut = malloc(this->state.cchLineOut); 373141cc406Sopenharmony_ci if (!this->state.pchLineOut) 374141cc406Sopenharmony_ci return FreeState(this,SetError(this, 375141cc406Sopenharmony_ci SANE_STATUS_NO_MEM, 376141cc406Sopenharmony_ci "no buffers available")); 377141cc406Sopenharmony_ci 378141cc406Sopenharmony_ci /* start the unit, when all buffers are available */ 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0x39); INST_ASSERT(); 381141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0x79); INST_ASSERT(); 382141cc406Sopenharmony_ci RegWrite(this,R_CTL, 1, 0xF9); INST_ASSERT(); 383141cc406Sopenharmony_ci 384141cc406Sopenharmony_ci this->state.bScanning = true; 385141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 386141cc406Sopenharmony_ci} 387