1141cc406Sopenharmony_ci/*............................................................................. 2141cc406Sopenharmony_ci * Project : SANE library for Plustek flatbed scanners. 3141cc406Sopenharmony_ci *............................................................................. 4141cc406Sopenharmony_ci */ 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci/** @file plustek-usbmap.c 7141cc406Sopenharmony_ci * @brief Creating and manipulating lookup tables. 8141cc406Sopenharmony_ci * 9141cc406Sopenharmony_ci * Based on sources acquired from Plustek Inc.<br> 10141cc406Sopenharmony_ci * Copyright (C) 2001-2007 Gerhard Jaeger <gerhard@gjaeger.de> 11141cc406Sopenharmony_ci * 12141cc406Sopenharmony_ci * History: 13141cc406Sopenharmony_ci * - 0.40 - starting version of the USB support 14141cc406Sopenharmony_ci * - 0.41 - fixed brightness problem for lineart mode 15141cc406Sopenharmony_ci * - 0.42 - removed preset of linear gamma tables 16141cc406Sopenharmony_ci * - 0.43 - no changes 17141cc406Sopenharmony_ci * - 0.44 - map inversion for negatatives now only upon user request 18141cc406Sopenharmony_ci * - 0.45 - no changes 19141cc406Sopenharmony_ci * - 0.46 - no changes 20141cc406Sopenharmony_ci * - 0.47 - cleanup work 21141cc406Sopenharmony_ci * - 0.48 - added support for binary from color scans 22141cc406Sopenharmony_ci * - 0.49 - changed usb_MapDownload 23141cc406Sopenharmony_ci * - 0.50 - cleanup 24141cc406Sopenharmony_ci * - 0.51 - no changes 25141cc406Sopenharmony_ci * - 0.52 - no changes 26141cc406Sopenharmony_ci * . 27141cc406Sopenharmony_ci * <hr> 28141cc406Sopenharmony_ci * This file is part of the SANE package. 29141cc406Sopenharmony_ci * 30141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or 31141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as 32141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 33141cc406Sopenharmony_ci * License, or (at your option) any later version. 34141cc406Sopenharmony_ci * 35141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 36141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 37141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 38141cc406Sopenharmony_ci * General Public License for more details. 39141cc406Sopenharmony_ci * 40141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License 41141cc406Sopenharmony_ci * along with this program. If not, see <https://www.gnu.org/licenses/>. 42141cc406Sopenharmony_ci * 43141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for 44141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE. 45141cc406Sopenharmony_ci * 46141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files 47141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the 48141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public 49141cc406Sopenharmony_ci * License. Your use of that executable is in no way restricted on 50141cc406Sopenharmony_ci * account of linking the SANE library code into it. 51141cc406Sopenharmony_ci * 52141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why 53141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public 54141cc406Sopenharmony_ci * License. 55141cc406Sopenharmony_ci * 56141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in 57141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that 58141cc406Sopenharmony_ci * those changes may be distributed with this exception intact. 59141cc406Sopenharmony_ci * 60141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice 61141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications. 62141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice. 63141cc406Sopenharmony_ci * <hr> 64141cc406Sopenharmony_ci */ 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_ci#define _MAP_SIZE 4096 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_cistatic SANE_Byte a_bMap[_MAP_SIZE * 3]; 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci/** adjust according to brightness and contrast 71141cc406Sopenharmony_ci */ 72141cc406Sopenharmony_cistatic void usb_MapAdjust( Plustek_Device *dev ) 73141cc406Sopenharmony_ci{ 74141cc406Sopenharmony_ci int i, tabLen; 75141cc406Sopenharmony_ci double b, c, tmp; 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_ci tabLen = _MAP_SIZE; 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_ci /* adjust brightness (b) and contrast (c) using the function: 80141cc406Sopenharmony_ci * 81141cc406Sopenharmony_ci * s(x,y) = (s(x,y) + b) * c 82141cc406Sopenharmony_ci * b = [-127, 127] 83141cc406Sopenharmony_ci * c = [0,2] 84141cc406Sopenharmony_ci */ 85141cc406Sopenharmony_ci b = ((double)dev->scanning.sParam.brightness * 192.0)/100.0; 86141cc406Sopenharmony_ci c = ((double)dev->scanning.sParam.contrast + 100.0)/100.0; 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci DBG( _DBG_INFO, "* brightness = %i -> %i\n", 89141cc406Sopenharmony_ci dev->scanning.sParam.brightness, (u_char)b); 90141cc406Sopenharmony_ci DBG( _DBG_INFO, "* contrast = %i -> %.3f\n", 91141cc406Sopenharmony_ci dev->scanning.sParam.contrast, c); 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci if( dev->scanning.sParam.brightness == 0 && dev->scanning.sParam.contrast ) 94141cc406Sopenharmony_ci return; 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_ci for( i = 0; i < tabLen; i++ ) { 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci tmp = ((double)(a_bMap[i] + b)) * c; 99141cc406Sopenharmony_ci if( tmp < 0 ) tmp = 0; 100141cc406Sopenharmony_ci if( tmp > 255 ) tmp = 255; 101141cc406Sopenharmony_ci a_bMap[i] = (u_char)tmp; 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci tmp = ((double)(a_bMap[tabLen+i] + b)) * c; 104141cc406Sopenharmony_ci if( tmp < 0 ) tmp = 0; 105141cc406Sopenharmony_ci if( tmp > 255 ) tmp = 255; 106141cc406Sopenharmony_ci a_bMap[tabLen+i] = (u_char)tmp; 107141cc406Sopenharmony_ci 108141cc406Sopenharmony_ci tmp = ((double)(a_bMap[tabLen*2+i] + b)) * c; 109141cc406Sopenharmony_ci if( tmp < 0 ) tmp = 0; 110141cc406Sopenharmony_ci if( tmp > 255 ) tmp = 255; 111141cc406Sopenharmony_ci a_bMap[tabLen*2+i] = (u_char)tmp; 112141cc406Sopenharmony_ci } 113141cc406Sopenharmony_ci} 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_ci/** 116141cc406Sopenharmony_ci */ 117141cc406Sopenharmony_cistatic SANE_Bool usb_MapDownload( Plustek_Device *dev ) 118141cc406Sopenharmony_ci{ 119141cc406Sopenharmony_ci ScanDef *scanning = &dev->scanning; 120141cc406Sopenharmony_ci DCapsDef *sc = &dev->usbDev.Caps; 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci int color; 123141cc406Sopenharmony_ci int i, threshold; 124141cc406Sopenharmony_ci SANE_Byte value; 125141cc406Sopenharmony_ci SANE_Bool fInverse = 0; 126141cc406Sopenharmony_ci 127141cc406Sopenharmony_ci DBG( _DBG_INFO, "usb_MapDownload()\n" ); 128141cc406Sopenharmony_ci 129141cc406Sopenharmony_ci /* the maps are have been already set */ 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci /* do the brightness and contrast adjustment ... */ 132141cc406Sopenharmony_ci if( scanning->sParam.bDataType != SCANDATATYPE_BW ) 133141cc406Sopenharmony_ci usb_MapAdjust( dev ); 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_ci if( !usbio_WriteReg( dev->fd, 7, 0)) 136141cc406Sopenharmony_ci return SANE_FALSE; 137141cc406Sopenharmony_ci 138141cc406Sopenharmony_ci /* we download all the time all three color maps, as we run 139141cc406Sopenharmony_ci * into trouble elsewhere on CanoScan models using gray mode 140141cc406Sopenharmony_ci */ 141141cc406Sopenharmony_ci for( color = 0; color < 3; color++) { 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci /* select color */ 144141cc406Sopenharmony_ci value = (color << 2)+2; 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_ci /* set gamma color selector */ 147141cc406Sopenharmony_ci usbio_WriteReg( dev->fd, 0x03, value ); 148141cc406Sopenharmony_ci usbio_WriteReg( dev->fd, 0x04, 0 ); 149141cc406Sopenharmony_ci usbio_WriteReg( dev->fd, 0x05, 0 ); 150141cc406Sopenharmony_ci 151141cc406Sopenharmony_ci /* write the gamma table entry to merlin */ 152141cc406Sopenharmony_ci if((scanning->sParam.bDataType == SCANDATATYPE_BW) || 153141cc406Sopenharmony_ci (scanning->fGrayFromColor > 7 )) { 154141cc406Sopenharmony_ci 155141cc406Sopenharmony_ci threshold = (int)((double)scanning->sParam.brightness * 156141cc406Sopenharmony_ci (_MAP_SIZE/200.0)) + (_MAP_SIZE/2); 157141cc406Sopenharmony_ci threshold = _MAP_SIZE - threshold; 158141cc406Sopenharmony_ci if(threshold < 0) 159141cc406Sopenharmony_ci threshold = 0; 160141cc406Sopenharmony_ci if(threshold > (int)_MAP_SIZE) 161141cc406Sopenharmony_ci threshold = _MAP_SIZE; 162141cc406Sopenharmony_ci 163141cc406Sopenharmony_ci DBG(_DBG_INFO, "* Threshold is at %u brightness=%i\n", 164141cc406Sopenharmony_ci threshold, scanning->sParam.brightness ); 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ci for(i = 0; i < threshold; i++) 167141cc406Sopenharmony_ci a_bMap[color*_MAP_SIZE + i] = 0; 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_ci for(i = threshold; i < _MAP_SIZE; i++) 170141cc406Sopenharmony_ci a_bMap[color*_MAP_SIZE + i] = 255; 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci fInverse = 1; 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_ci } else { 175141cc406Sopenharmony_ci fInverse = 0; 176141cc406Sopenharmony_ci } 177141cc406Sopenharmony_ci 178141cc406Sopenharmony_ci if( /*scanning->dwFlag & SCANFLAG_Pseudo48 && */ 179141cc406Sopenharmony_ci (scanning->sParam.bSource == SOURCE_Negative) && 180141cc406Sopenharmony_ci (sc->workaroundFlag &_WAF_INV_NEGATIVE_MAP)) { 181141cc406Sopenharmony_ci fInverse ^= 1; 182141cc406Sopenharmony_ci } 183141cc406Sopenharmony_ci 184141cc406Sopenharmony_ci if( fInverse ) { 185141cc406Sopenharmony_ci 186141cc406Sopenharmony_ci u_char map[_MAP_SIZE]; 187141cc406Sopenharmony_ci u_char *pMap = a_bMap+color*_MAP_SIZE; 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci DBG( _DBG_INFO, "* Inverting Map\n" ); 190141cc406Sopenharmony_ci 191141cc406Sopenharmony_ci for( i = 0; i < _MAP_SIZE; i++, pMap++ ) 192141cc406Sopenharmony_ci map[i] = ~*pMap; 193141cc406Sopenharmony_ci 194141cc406Sopenharmony_ci sanei_lm983x_write( dev->fd, 0x06, map, _MAP_SIZE, SANE_FALSE ); 195141cc406Sopenharmony_ci 196141cc406Sopenharmony_ci } else { 197141cc406Sopenharmony_ci DBG( _DBG_INFO, "* downloading map %u...\n", color ); 198141cc406Sopenharmony_ci sanei_lm983x_write( dev->fd, 0x06, a_bMap+color*_MAP_SIZE, 199141cc406Sopenharmony_ci _MAP_SIZE, SANE_FALSE ); 200141cc406Sopenharmony_ci } 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_ci } /* for each color */ 203141cc406Sopenharmony_ci 204141cc406Sopenharmony_ci DBG( _DBG_INFO, "usb_MapDownload() done.\n" ); 205141cc406Sopenharmony_ci return SANE_TRUE; 206141cc406Sopenharmony_ci} 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_ci/* END PLUSTEK-USBMAP.C .....................................................*/ 209