1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci Copyright (C) 2000-2005 Mustek. 4141cc406Sopenharmony_ci Originally maintained by Mustek 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci Copyright (C) 2001-2005 by Henning Meier-Geinitz. 7141cc406Sopenharmony_ci 8141cc406Sopenharmony_ci This file is part of the SANE package. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 11141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 12141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 13141cc406Sopenharmony_ci License, or (at your option) any later version. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 16141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 17141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18141cc406Sopenharmony_ci General Public License for more details. 19141cc406Sopenharmony_ci 20141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 21141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 22141cc406Sopenharmony_ci 23141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 24141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 25141cc406Sopenharmony_ci 26141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 27141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 28141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 29141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 30141cc406Sopenharmony_ci account of linking the SANE library code into it. 31141cc406Sopenharmony_ci 32141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 33141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 34141cc406Sopenharmony_ci License. 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 37141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 38141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 41141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 42141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci This file implements a SANE backend for the Mustek BearPaw 2448 TA Pro 45141cc406Sopenharmony_ci and similar USB2 scanners. */ 46141cc406Sopenharmony_ci 47141cc406Sopenharmony_ci#define BUILD 10 48141cc406Sopenharmony_ci 49141cc406Sopenharmony_ci#include "../include/sane/config.h" 50141cc406Sopenharmony_ci 51141cc406Sopenharmony_ci#include <ctype.h> 52141cc406Sopenharmony_ci#include <errno.h> 53141cc406Sopenharmony_ci#include <fcntl.h> 54141cc406Sopenharmony_ci#include <limits.h> 55141cc406Sopenharmony_ci#include <signal.h> 56141cc406Sopenharmony_ci#include <stdio.h> 57141cc406Sopenharmony_ci#include <stdlib.h> 58141cc406Sopenharmony_ci#include <string.h> 59141cc406Sopenharmony_ci#include <unistd.h> 60141cc406Sopenharmony_ci#include <math.h> 61141cc406Sopenharmony_ci 62141cc406Sopenharmony_ci#include <sys/time.h> 63141cc406Sopenharmony_ci#include <sys/types.h> 64141cc406Sopenharmony_ci#include <sys/wait.h> 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_ci#include "../include/sane/sane.h" 67141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 68141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci#define BACKEND_NAME mustek_usb2 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 73141cc406Sopenharmony_ci#include "mustek_usb2_high.c" 74141cc406Sopenharmony_ci 75141cc406Sopenharmony_ci#include "mustek_usb2.h" 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_cistatic SANE_Int num_devices; 78141cc406Sopenharmony_cistatic const SANE_Device **devlist = 0; 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_cistatic const SANE_Range u8_range = { 81141cc406Sopenharmony_ci 0, /* minimum */ 82141cc406Sopenharmony_ci 255, /* maximum */ 83141cc406Sopenharmony_ci 0 /* quantization */ 84141cc406Sopenharmony_ci}; 85141cc406Sopenharmony_cistatic SANE_Range x_range = { 86141cc406Sopenharmony_ci SANE_FIX (0.0), /* minimum */ 87141cc406Sopenharmony_ci SANE_FIX (8.3 * MM_PER_INCH), /* maximum */ 88141cc406Sopenharmony_ci SANE_FIX (0.0) /* quantization */ 89141cc406Sopenharmony_ci}; 90141cc406Sopenharmony_ci 91141cc406Sopenharmony_cistatic SANE_Range y_range = { 92141cc406Sopenharmony_ci SANE_FIX (0.0), /* minimum */ 93141cc406Sopenharmony_ci SANE_FIX (11.6 * MM_PER_INCH), /* maximum */ 94141cc406Sopenharmony_ci SANE_FIX (0.0) /* quantization */ 95141cc406Sopenharmony_ci}; 96141cc406Sopenharmony_ci 97141cc406Sopenharmony_cistatic SANE_Range gamma_range = { 98141cc406Sopenharmony_ci SANE_FIX (0.01), /* minimum */ 99141cc406Sopenharmony_ci SANE_FIX (5.0), /* maximum */ 100141cc406Sopenharmony_ci SANE_FIX (0.01) /* quantization */ 101141cc406Sopenharmony_ci}; 102141cc406Sopenharmony_cistatic SANE_String_Const mode_list[] = { 103141cc406Sopenharmony_ci SANE_I18N ("Color48"), 104141cc406Sopenharmony_ci SANE_I18N ("Color24"), 105141cc406Sopenharmony_ci SANE_I18N ("Gray16"), 106141cc406Sopenharmony_ci SANE_I18N ("Gray8"), 107141cc406Sopenharmony_ci SANE_VALUE_SCAN_MODE_LINEART, 108141cc406Sopenharmony_ci 0 109141cc406Sopenharmony_ci}; 110141cc406Sopenharmony_ci 111141cc406Sopenharmony_cistatic SANE_String_Const negative_mode_list[] = { 112141cc406Sopenharmony_ci SANE_I18N ("Color24"), 113141cc406Sopenharmony_ci 0 114141cc406Sopenharmony_ci}; 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_cistatic SANE_String_Const source_list[] = { 117141cc406Sopenharmony_ci SANE_I18N ("Reflective"), 118141cc406Sopenharmony_ci SANE_I18N ("Positive"), 119141cc406Sopenharmony_ci SANE_I18N ("Negative"), 120141cc406Sopenharmony_ci 0 121141cc406Sopenharmony_ci}; 122141cc406Sopenharmony_cistatic Scanner_Model mustek_A2nu2_model = { 123141cc406Sopenharmony_ci "mustek-A2nu2", /* Name */ 124141cc406Sopenharmony_ci "Mustek", /* Device vendor string */ 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci "BearPaw 2448TA Pro", /* Device model name */ 127141cc406Sopenharmony_ci "", /* Name of the firmware file */ 128141cc406Sopenharmony_ci 129141cc406Sopenharmony_ci {1200, 600, 300, 150, 75, 0}, /* possible resolutions */ 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci SANE_FIX (0.0), /* Start of scan area in mm (x) */ 132141cc406Sopenharmony_ci SANE_FIX (0.0), /* Start of scan area in mm (y) */ 133141cc406Sopenharmony_ci SANE_FIX (8.3 * MM_PER_INCH), /* Size of scan area in mm (x) */ 134141cc406Sopenharmony_ci SANE_FIX (11.6 * MM_PER_INCH), /* Size of scan area in mm (y) */ 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ 137141cc406Sopenharmony_ci SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ 138141cc406Sopenharmony_ci SANE_FIX (1.46 * MM_PER_INCH), /* Size of scan area in TA mode in mm (x) */ 139141cc406Sopenharmony_ci SANE_FIX (6.45 * MM_PER_INCH), /* Size of scan area in TA mode in mm (y) */ 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_ci 0, /* Order of the CCD/CIS colors 0:RO_RGB 1:RO_BGR */ 142141cc406Sopenharmony_ci SANE_FIX (2.0), /* Default gamma value */ 143141cc406Sopenharmony_ci 144141cc406Sopenharmony_ci SANE_FALSE, /* Is this a CIS scanner? */ 145141cc406Sopenharmony_ci 0 /* Which flags are needed for this scanner? */ 146141cc406Sopenharmony_ci /* Setup and tested */ 147141cc406Sopenharmony_ci}; 148141cc406Sopenharmony_ci 149141cc406Sopenharmony_ci 150141cc406Sopenharmony_ci/* Forward declarations */ 151141cc406Sopenharmony_ci 152141cc406Sopenharmony_cistatic SANE_Bool GetDeviceStatus (void); 153141cc406Sopenharmony_cistatic SANE_Bool PowerControl (SANE_Bool isLampOn, SANE_Bool isTaLampOn); 154141cc406Sopenharmony_cistatic SANE_Bool CarriageHome (void); 155141cc406Sopenharmony_cistatic SANE_Bool SetParameters (LPSETPARAMETERS pSetParameters); 156141cc406Sopenharmony_cistatic SANE_Bool GetParameters (LPGETPARAMETERS pGetParameters); 157141cc406Sopenharmony_cistatic SANE_Bool StartScan (void); 158141cc406Sopenharmony_cistatic SANE_Bool ReadScannedData (LPIMAGEROWS pImageRows); 159141cc406Sopenharmony_cistatic SANE_Bool StopScan (void); 160141cc406Sopenharmony_cistatic SANE_Bool IsTAConnected (void); 161141cc406Sopenharmony_cistatic void AutoLevel (SANE_Byte *lpSource, SCANMODE scanMode, unsigned short ScanLines, 162141cc406Sopenharmony_ci unsigned int BytesPerLine); 163141cc406Sopenharmony_cistatic size_t max_string_size (const SANE_String_Const strings[]); 164141cc406Sopenharmony_cistatic SANE_Status calc_parameters (Mustek_Scanner * s); 165141cc406Sopenharmony_ci#ifdef SANE_UNUSED 166141cc406Sopenharmony_cistatic SANE_Bool GetGammaInfo (LPGAMMAINFO pGamaInfo); 167141cc406Sopenharmony_cistatic SANE_Bool GetKeyStatus (SANE_Byte * pKey); 168141cc406Sopenharmony_cistatic void QBetChange (SANE_Byte *lpSource, SCANMODE scanMode, unsigned short ScanLines, 169141cc406Sopenharmony_ci unsigned int BytesPerLine); 170141cc406Sopenharmony_cistatic void QBETDetectAutoLevel (void *pDIB, unsigned int ImageWidth, unsigned int ImageHeight); 171141cc406Sopenharmony_ci#endif 172141cc406Sopenharmony_ci 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_ci 175141cc406Sopenharmony_cistatic size_t 176141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 177141cc406Sopenharmony_ci{ 178141cc406Sopenharmony_ci size_t size, max_size = 0; 179141cc406Sopenharmony_ci SANE_Int i; 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 182141cc406Sopenharmony_ci { 183141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 184141cc406Sopenharmony_ci if (size > max_size) 185141cc406Sopenharmony_ci max_size = size; 186141cc406Sopenharmony_ci } 187141cc406Sopenharmony_ci return max_size; 188141cc406Sopenharmony_ci} 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_cistatic SANE_Status 191141cc406Sopenharmony_cicalc_parameters (Mustek_Scanner * s) 192141cc406Sopenharmony_ci{ 193141cc406Sopenharmony_ci SANE_String val, val_source; 194141cc406Sopenharmony_ci val = s->val[OPT_MODE].s; 195141cc406Sopenharmony_ci val_source = s->val[OPT_SOURCE].s; 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci if (strcmp (val, "Color48") == 0) /* Color48 */ 200141cc406Sopenharmony_ci { 201141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RGB; 202141cc406Sopenharmony_ci s->params.depth = 16; 203141cc406Sopenharmony_ci s->setpara.smScanMode = SM_RGB48; 204141cc406Sopenharmony_ci if (s->val[OPT_PREVIEW].w) 205141cc406Sopenharmony_ci { 206141cc406Sopenharmony_ci DBG (DBG_DET, "calc_parameters : preview set ScanMode SM_RGB24\n"); 207141cc406Sopenharmony_ci s->params.depth = 8; 208141cc406Sopenharmony_ci s->setpara.smScanMode = SM_RGB24; 209141cc406Sopenharmony_ci } 210141cc406Sopenharmony_ci } 211141cc406Sopenharmony_ci else if (strcmp (val, "Color24") == 0) /* Color24 */ 212141cc406Sopenharmony_ci { 213141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RGB; 214141cc406Sopenharmony_ci s->params.depth = 8; 215141cc406Sopenharmony_ci s->setpara.smScanMode = SM_RGB24; 216141cc406Sopenharmony_ci } 217141cc406Sopenharmony_ci else if (strcmp (val, "Gray16") == 0) 218141cc406Sopenharmony_ci { 219141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 220141cc406Sopenharmony_ci s->params.depth = 16; 221141cc406Sopenharmony_ci s->setpara.smScanMode = SM_GRAY16; 222141cc406Sopenharmony_ci if (s->val[OPT_PREVIEW].w) 223141cc406Sopenharmony_ci { 224141cc406Sopenharmony_ci s->params.depth = 8; 225141cc406Sopenharmony_ci DBG (DBG_DET, "calc_parameters : preview set ScanMode SM_GRAY\n"); 226141cc406Sopenharmony_ci s->setpara.smScanMode = SM_GRAY; 227141cc406Sopenharmony_ci } 228141cc406Sopenharmony_ci } 229141cc406Sopenharmony_ci else if (strcmp (val, "Gray8") == 0) 230141cc406Sopenharmony_ci { 231141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 232141cc406Sopenharmony_ci s->params.depth = 8; 233141cc406Sopenharmony_ci s->setpara.smScanMode = SM_GRAY; 234141cc406Sopenharmony_ci } 235141cc406Sopenharmony_ci else if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0) 236141cc406Sopenharmony_ci { 237141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 238141cc406Sopenharmony_ci s->params.depth = 1; 239141cc406Sopenharmony_ci s->setpara.smScanMode = SM_TEXT; 240141cc406Sopenharmony_ci } 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci /*set Scan Source */ 243141cc406Sopenharmony_ci DBG (DBG_DET, "calc_parameters :scan Source = %s\n", val_source); 244141cc406Sopenharmony_ci if (strcmp (val_source, "Reflective") == 0) 245141cc406Sopenharmony_ci { 246141cc406Sopenharmony_ci s->setpara.ssScanSource = SS_Reflective; 247141cc406Sopenharmony_ci } 248141cc406Sopenharmony_ci else if (strcmp (val_source, "Positive") == 0) 249141cc406Sopenharmony_ci { 250141cc406Sopenharmony_ci s->setpara.ssScanSource = SS_Positive; 251141cc406Sopenharmony_ci } 252141cc406Sopenharmony_ci else if (strcmp (val_source, "Negative") == 0) 253141cc406Sopenharmony_ci { 254141cc406Sopenharmony_ci s->setpara.ssScanSource = SS_Negative; 255141cc406Sopenharmony_ci } 256141cc406Sopenharmony_ci 257141cc406Sopenharmony_ci 258141cc406Sopenharmony_ci s->setpara.fmArea.x1 = 259141cc406Sopenharmony_ci (unsigned short) ((SANE_UNFIX (s->val[OPT_TL_X].w) * 300.0) / MM_PER_INCH + 0.5); 260141cc406Sopenharmony_ci s->setpara.fmArea.x2 = 261141cc406Sopenharmony_ci (unsigned short) ((SANE_UNFIX (s->val[OPT_BR_X].w) * 300.0) / MM_PER_INCH + 0.5); 262141cc406Sopenharmony_ci s->setpara.fmArea.y1 = 263141cc406Sopenharmony_ci (unsigned short) ((SANE_UNFIX (s->val[OPT_TL_Y].w) * 300.0) / MM_PER_INCH + 0.5); 264141cc406Sopenharmony_ci s->setpara.fmArea.y2 = 265141cc406Sopenharmony_ci (unsigned short) ((SANE_UNFIX (s->val[OPT_BR_Y].w) * 300.0) / MM_PER_INCH + 0.5); 266141cc406Sopenharmony_ci 267141cc406Sopenharmony_ci if (s->val[OPT_PREVIEW].w) 268141cc406Sopenharmony_ci { 269141cc406Sopenharmony_ci s->setpara.fmArea.y1 = s->setpara.fmArea.y1 + PER_ADD_START_LINES; 270141cc406Sopenharmony_ci s->setpara.fmArea.x1 += PRE_ADD_START_X; 271141cc406Sopenharmony_ci } /*just for range bug. */ 272141cc406Sopenharmony_ci 273141cc406Sopenharmony_ci s->setpara.pfPixelFlavor = PF_BlackIs0; 274141cc406Sopenharmony_ci s->setpara.wLinearThreshold = s->val[OPT_THRESHOLD].w; 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ci s->setpara.wTargetDPI = s->val[OPT_RESOLUTION].w; 277141cc406Sopenharmony_ci if (s->val[OPT_PREVIEW].w) 278141cc406Sopenharmony_ci { 279141cc406Sopenharmony_ci s->setpara.wTargetDPI = 75; 280141cc406Sopenharmony_ci } 281141cc406Sopenharmony_ci 282141cc406Sopenharmony_ci s->setpara.pGammaTable = NULL; 283141cc406Sopenharmony_ci 284141cc406Sopenharmony_ci s->params.pixels_per_line = 285141cc406Sopenharmony_ci (SANE_Int) ((s->setpara.fmArea.x2 - 286141cc406Sopenharmony_ci s->setpara.fmArea.x1) * s->setpara.wTargetDPI / 300.0 + 0.5); 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci switch (s->params.format) 289141cc406Sopenharmony_ci { 290141cc406Sopenharmony_ci case SANE_FRAME_RGB: 291141cc406Sopenharmony_ci if (s->params.depth == 8) 292141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line * 3; 293141cc406Sopenharmony_ci if (s->params.depth == 16) 294141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line * 6; 295141cc406Sopenharmony_ci break; 296141cc406Sopenharmony_ci case SANE_FRAME_GRAY: 297141cc406Sopenharmony_ci if (s->params.depth == 1) 298141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line / 8; 299141cc406Sopenharmony_ci if (s->params.depth == 8) 300141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line; 301141cc406Sopenharmony_ci if (s->params.depth == 16) 302141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line * 2; 303141cc406Sopenharmony_ci break; 304141cc406Sopenharmony_ci default: 305141cc406Sopenharmony_ci DBG (DBG_DET, "sane_star:sane params .format = %d\n", s->params.format); 306141cc406Sopenharmony_ci } 307141cc406Sopenharmony_ci 308141cc406Sopenharmony_ci s->params.lines = 309141cc406Sopenharmony_ci (SANE_Int) ((s->setpara.fmArea.y2 - 310141cc406Sopenharmony_ci s->setpara.fmArea.y1) * s->setpara.wTargetDPI / 300 + 0.5); 311141cc406Sopenharmony_ci 312141cc406Sopenharmony_ci DBG (DBG_FUNC, "calc_parameters: end\n"); 313141cc406Sopenharmony_ci 314141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 315141cc406Sopenharmony_ci} 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_cistatic SANE_Status 318141cc406Sopenharmony_ciinit_options (Mustek_Scanner * s) 319141cc406Sopenharmony_ci{ 320141cc406Sopenharmony_ci SANE_Int option, count; 321141cc406Sopenharmony_ci SANE_Word *dpi_list; /*Resolution Support */ 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci DBG (DBG_FUNC, "init_options: start\n"); 324141cc406Sopenharmony_ci 325141cc406Sopenharmony_ci memset (s->opt, 0, sizeof (s->opt)); 326141cc406Sopenharmony_ci memset (s->val, 0, sizeof (s->val)); 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_ci for (option = 0; option < NUM_OPTIONS; ++option) 329141cc406Sopenharmony_ci { 330141cc406Sopenharmony_ci s->opt[option].size = sizeof (SANE_Word); 331141cc406Sopenharmony_ci s->opt[option].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 332141cc406Sopenharmony_ci } 333141cc406Sopenharmony_ci /* Option num */ 334141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; 335141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 336141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 337141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 338141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 339141cc406Sopenharmony_ci s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 340141cc406Sopenharmony_ci 341141cc406Sopenharmony_ci /* "Mode" group: */ 342141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode"); 343141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].desc = ""; 344141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 345141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].size = 0; 346141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].cap = 0; 347141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 348141cc406Sopenharmony_ci 349141cc406Sopenharmony_ci /* scan mode */ 350141cc406Sopenharmony_ci s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 351141cc406Sopenharmony_ci s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 352141cc406Sopenharmony_ci s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 353141cc406Sopenharmony_ci s->opt[OPT_MODE].type = SANE_TYPE_STRING; 354141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 355141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 356141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 357141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup ("Color24"); 358141cc406Sopenharmony_ci 359141cc406Sopenharmony_ci /* Scan Source */ 360141cc406Sopenharmony_ci s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE; 361141cc406Sopenharmony_ci s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE; 362141cc406Sopenharmony_ci s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE; 363141cc406Sopenharmony_ci s->opt[OPT_SOURCE].type = SANE_TYPE_STRING; 364141cc406Sopenharmony_ci s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 365141cc406Sopenharmony_ci s->opt[OPT_SOURCE].size = max_string_size (source_list); 366141cc406Sopenharmony_ci s->opt[OPT_SOURCE].constraint.string_list = source_list; 367141cc406Sopenharmony_ci s->val[OPT_SOURCE].s = strdup ("Reflective"); 368141cc406Sopenharmony_ci 369141cc406Sopenharmony_ci if (!IsTAConnected ()) 370141cc406Sopenharmony_ci { 371141cc406Sopenharmony_ci DISABLE (OPT_SOURCE); 372141cc406Sopenharmony_ci } 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci 375141cc406Sopenharmony_ci /* resolution */ 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci for (count = 0; s->model.dpi_values[count] != 0; count++) 378141cc406Sopenharmony_ci { 379141cc406Sopenharmony_ci } 380141cc406Sopenharmony_ci dpi_list = malloc ((count + 1) * sizeof (SANE_Word)); 381141cc406Sopenharmony_ci if (!dpi_list) 382141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 383141cc406Sopenharmony_ci dpi_list[0] = count; 384141cc406Sopenharmony_ci 385141cc406Sopenharmony_ci for (count = 0; s->model.dpi_values[count] != 0; count++) 386141cc406Sopenharmony_ci dpi_list[count + 1] = s->model.dpi_values[count]; 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 389141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; 390141cc406Sopenharmony_ci 391141cc406Sopenharmony_ci 392141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 393141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; 394141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 395141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; 396141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint.word_list = dpi_list; 397141cc406Sopenharmony_ci s->val[OPT_RESOLUTION].w = 300; 398141cc406Sopenharmony_ci 399141cc406Sopenharmony_ci /* preview */ 400141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; 401141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; 402141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; 403141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 404141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; 405141cc406Sopenharmony_ci s->val[OPT_PREVIEW].w = SANE_FALSE; 406141cc406Sopenharmony_ci 407141cc406Sopenharmony_ci /* "Debug" group: */ 408141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].title = SANE_I18N ("Debugging Options"); 409141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].desc = ""; 410141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].type = SANE_TYPE_GROUP; 411141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].size = 0; 412141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].cap = 0; 413141cc406Sopenharmony_ci s->opt[OPT_DEBUG_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 414141cc406Sopenharmony_ci 415141cc406Sopenharmony_ci /* auto warmup */ 416141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].name = "auto-warmup"; 417141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].title = SANE_I18N ("Automatic warmup"); 418141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].desc = 419141cc406Sopenharmony_ci SANE_I18N ("Warm-up until the lamp's brightness is constant " 420141cc406Sopenharmony_ci "instead of insisting on 40 seconds warm-up time."); 421141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].type = SANE_TYPE_BOOL; 422141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].unit = SANE_UNIT_NONE; 423141cc406Sopenharmony_ci s->opt[OPT_AUTO_WARMUP].constraint_type = SANE_CONSTRAINT_NONE; 424141cc406Sopenharmony_ci s->val[OPT_AUTO_WARMUP].w = SANE_FALSE; 425141cc406Sopenharmony_ci if (s->model.is_cis) 426141cc406Sopenharmony_ci DISABLE (OPT_AUTO_WARMUP); 427141cc406Sopenharmony_ci 428141cc406Sopenharmony_ci /* "Enhancement" group: */ 429141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement"); 430141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 431141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 432141cc406Sopenharmony_ci 433141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].size = 0; 434141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 435141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 436141cc406Sopenharmony_ci 437141cc406Sopenharmony_ci /* threshold */ 438141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 439141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 440141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 441141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT; 442141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE; 443141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 444141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint.range = &u8_range; 445141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 446141cc406Sopenharmony_ci s->val[OPT_THRESHOLD].w = DEF_LINEARTTHRESHOLD; 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci /* internal gamma value */ 449141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].name = "gamma-value"; 450141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].title = SANE_I18N ("Gamma value"); 451141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].desc = 452141cc406Sopenharmony_ci SANE_I18N ("Sets the gamma value of all channels."); 453141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].type = SANE_TYPE_FIXED; 454141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].unit = SANE_UNIT_NONE; 455141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].constraint_type = SANE_CONSTRAINT_RANGE; 456141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].constraint.range = &gamma_range; 457141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VALUE].cap |= SANE_CAP_EMULATED; 458141cc406Sopenharmony_ci s->val[OPT_GAMMA_VALUE].w = s->model.default_gamma_value; 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VALUE); 461141cc406Sopenharmony_ci 462141cc406Sopenharmony_ci /* "Geometry" group: */ 463141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry"); 464141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].desc = ""; 465141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 466141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 467141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].size = 0; 468141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci x_range.max = s->model.x_size; 471141cc406Sopenharmony_ci y_range.max = s->model.y_size; 472141cc406Sopenharmony_ci 473141cc406Sopenharmony_ci /* top-left x */ 474141cc406Sopenharmony_ci s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 475141cc406Sopenharmony_ci s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 476141cc406Sopenharmony_ci s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 477141cc406Sopenharmony_ci s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 478141cc406Sopenharmony_ci s->opt[OPT_TL_X].unit = SANE_UNIT_MM; 479141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 480141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range = &x_range; 481141cc406Sopenharmony_ci 482141cc406Sopenharmony_ci s->val[OPT_TL_X].w = 0; 483141cc406Sopenharmony_ci 484141cc406Sopenharmony_ci /* top-left y */ 485141cc406Sopenharmony_ci s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 486141cc406Sopenharmony_ci s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 487141cc406Sopenharmony_ci s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 488141cc406Sopenharmony_ci s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 489141cc406Sopenharmony_ci s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 490141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 491141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range = &y_range; 492141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = 0; 493141cc406Sopenharmony_ci 494141cc406Sopenharmony_ci /* bottom-right x */ 495141cc406Sopenharmony_ci s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 496141cc406Sopenharmony_ci s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 497141cc406Sopenharmony_ci s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 498141cc406Sopenharmony_ci s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 499141cc406Sopenharmony_ci s->opt[OPT_BR_X].unit = SANE_UNIT_MM; 500141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 501141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range = &x_range; 502141cc406Sopenharmony_ci s->val[OPT_BR_X].w = x_range.max; 503141cc406Sopenharmony_ci 504141cc406Sopenharmony_ci /* bottom-right y */ 505141cc406Sopenharmony_ci s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 506141cc406Sopenharmony_ci s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 507141cc406Sopenharmony_ci s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 508141cc406Sopenharmony_ci s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 509141cc406Sopenharmony_ci s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 510141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 511141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range = &y_range; 512141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = y_range.max; 513141cc406Sopenharmony_ci 514141cc406Sopenharmony_ci calc_parameters (s); 515141cc406Sopenharmony_ci 516141cc406Sopenharmony_ci DBG (DBG_FUNC, "init_options: exit\n"); 517141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 518141cc406Sopenharmony_ci} 519141cc406Sopenharmony_ci 520141cc406Sopenharmony_ci/***************************** Code from spicall.c *****************************/ 521141cc406Sopenharmony_ci 522141cc406Sopenharmony_cistatic SANE_Byte * g_lpNegImageData = NULL; 523141cc406Sopenharmony_cistatic SANE_Bool g_bIsFirstGetNegData = TRUE; 524141cc406Sopenharmony_cistatic SANE_Bool g_bIsMallocNegData = FALSE; 525141cc406Sopenharmony_cistatic unsigned int g_dwAlreadyGetNegLines = 0; 526141cc406Sopenharmony_ci 527141cc406Sopenharmony_ci/********************************************************************** 528141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 529141cc406Sopenharmony_ciRoutine Description: 530141cc406Sopenharmony_ci Check the device connect status 531141cc406Sopenharmony_ciParameters: 532141cc406Sopenharmony_ci none 533141cc406Sopenharmony_ciReturn value: 534141cc406Sopenharmony_ci if the device is connected 535141cc406Sopenharmony_ci return TRUE 536141cc406Sopenharmony_ci else 537141cc406Sopenharmony_ci return FALSE 538141cc406Sopenharmony_ci***********************************************************************/ 539141cc406Sopenharmony_cistatic SANE_Bool 540141cc406Sopenharmony_ciGetDeviceStatus () 541141cc406Sopenharmony_ci{ 542141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetDeviceStatus: start\n"); 543141cc406Sopenharmony_ci return MustScanner_GetScannerState (); 544141cc406Sopenharmony_ci} 545141cc406Sopenharmony_ci 546141cc406Sopenharmony_ci/********************************************************************** 547141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 548141cc406Sopenharmony_ciRoutine Description: 549141cc406Sopenharmony_ci Turn the lamp on or off 550141cc406Sopenharmony_ciParameters: 551141cc406Sopenharmony_ci isLampOn: turn the lamp on or off 552141cc406Sopenharmony_ci isTALampOn: turn the TA lamp on or off 553141cc406Sopenharmony_ciReturn value: 554141cc406Sopenharmony_ci if operation success 555141cc406Sopenharmony_ci return TRUE 556141cc406Sopenharmony_ci else 557141cc406Sopenharmony_ci return FALSE 558141cc406Sopenharmony_ci***********************************************************************/ 559141cc406Sopenharmony_cistatic SANE_Bool 560141cc406Sopenharmony_ciPowerControl (SANE_Bool isLampOn, SANE_Bool isTALampOn) 561141cc406Sopenharmony_ci{ 562141cc406Sopenharmony_ci DBG (DBG_FUNC, "PowerControl: start\n"); 563141cc406Sopenharmony_ci return MustScanner_PowerControl (isLampOn, isTALampOn); 564141cc406Sopenharmony_ci} 565141cc406Sopenharmony_ci 566141cc406Sopenharmony_ci/********************************************************************** 567141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 568141cc406Sopenharmony_ciRoutine Description: 569141cc406Sopenharmony_ci Turn the carriage home 570141cc406Sopenharmony_ciParameters: 571141cc406Sopenharmony_ci none 572141cc406Sopenharmony_ciReturn value: 573141cc406Sopenharmony_ci if the operation success 574141cc406Sopenharmony_ci return TRUE 575141cc406Sopenharmony_ci else 576141cc406Sopenharmony_ci return FALSE 577141cc406Sopenharmony_ci***********************************************************************/ 578141cc406Sopenharmony_cistatic SANE_Bool 579141cc406Sopenharmony_ciCarriageHome () 580141cc406Sopenharmony_ci{ 581141cc406Sopenharmony_ci DBG (DBG_FUNC, "CarriageHome: start\n"); 582141cc406Sopenharmony_ci return MustScanner_BackHome (); 583141cc406Sopenharmony_ci} 584141cc406Sopenharmony_ci 585141cc406Sopenharmony_ci#ifdef SANE_UNUSED 586141cc406Sopenharmony_ci/********************************************************************** 587141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 588141cc406Sopenharmony_ciRoutine Description: 589141cc406Sopenharmony_ci Get gamma input/output bit count 590141cc406Sopenharmony_ciParameters: 591141cc406Sopenharmony_ci pGammaInfo: the gamma information 592141cc406Sopenharmony_ciReturn value: 593141cc406Sopenharmony_ci if the operation success 594141cc406Sopenharmony_ci return TRUE 595141cc406Sopenharmony_ci else 596141cc406Sopenharmony_ci return FALSE 597141cc406Sopenharmony_ci***********************************************************************/ 598141cc406Sopenharmony_cistatic SANE_Bool 599141cc406Sopenharmony_ciGetGammaInfo (LPGAMMAINFO pGammaInfo) 600141cc406Sopenharmony_ci{ 601141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetGammaInfo: start\n"); 602141cc406Sopenharmony_ci 603141cc406Sopenharmony_ci switch (pGammaInfo->smScanMode) 604141cc406Sopenharmony_ci { 605141cc406Sopenharmony_ci case SM_GRAY: 606141cc406Sopenharmony_ci pGammaInfo->wInputGammaBits = 12; 607141cc406Sopenharmony_ci pGammaInfo->wOutputGammaBits = 8; 608141cc406Sopenharmony_ci break; 609141cc406Sopenharmony_ci case SM_RGB24: 610141cc406Sopenharmony_ci pGammaInfo->wInputGammaBits = 12; 611141cc406Sopenharmony_ci pGammaInfo->wOutputGammaBits = 8; 612141cc406Sopenharmony_ci break; 613141cc406Sopenharmony_ci case SM_GRAY16: 614141cc406Sopenharmony_ci pGammaInfo->wInputGammaBits = 16; 615141cc406Sopenharmony_ci pGammaInfo->wOutputGammaBits = 16; 616141cc406Sopenharmony_ci break; 617141cc406Sopenharmony_ci case SM_RGB48: 618141cc406Sopenharmony_ci pGammaInfo->wInputGammaBits = 16; 619141cc406Sopenharmony_ci pGammaInfo->wOutputGammaBits = 16; 620141cc406Sopenharmony_ci break; 621141cc406Sopenharmony_ci default: 622141cc406Sopenharmony_ci pGammaInfo->wInputGammaBits = 0; 623141cc406Sopenharmony_ci pGammaInfo->wOutputGammaBits = 0; 624141cc406Sopenharmony_ci return FALSE; 625141cc406Sopenharmony_ci } 626141cc406Sopenharmony_ci 627141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetGammaInfo: exit\n"); 628141cc406Sopenharmony_ci return TRUE; 629141cc406Sopenharmony_ci} 630141cc406Sopenharmony_ci#endif 631141cc406Sopenharmony_ci/********************************************************************** 632141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 633141cc406Sopenharmony_ciRoutine Description: 634141cc406Sopenharmony_ci set scan parameters 635141cc406Sopenharmony_ciParameters: 636141cc406Sopenharmony_ci pSetParameters: the information of scanning 637141cc406Sopenharmony_ciReturn value: 638141cc406Sopenharmony_ci if the operation success 639141cc406Sopenharmony_ci return TRUE 640141cc406Sopenharmony_ci else 641141cc406Sopenharmony_ci return FALSE 642141cc406Sopenharmony_ci***********************************************************************/ 643141cc406Sopenharmony_cistatic SANE_Bool 644141cc406Sopenharmony_ciSetParameters (LPSETPARAMETERS pSetParameters) 645141cc406Sopenharmony_ci{ 646141cc406Sopenharmony_ci unsigned short X1inTargetDpi; 647141cc406Sopenharmony_ci unsigned short Y1inTargetDpi; 648141cc406Sopenharmony_ci unsigned short X2inTargetDpi; 649141cc406Sopenharmony_ci unsigned short Y2inTargetDpi; 650141cc406Sopenharmony_ci 651141cc406Sopenharmony_ci DBG (DBG_FUNC, "SetParameters: start\n"); 652141cc406Sopenharmony_ci 653141cc406Sopenharmony_ci /*0. Reset */ 654141cc406Sopenharmony_ci if (ST_Reflective == g_ScanType) 655141cc406Sopenharmony_ci { 656141cc406Sopenharmony_ci Reflective_Reset (); 657141cc406Sopenharmony_ci } 658141cc406Sopenharmony_ci else 659141cc406Sopenharmony_ci { 660141cc406Sopenharmony_ci Transparent_Reset (); 661141cc406Sopenharmony_ci } 662141cc406Sopenharmony_ci 663141cc406Sopenharmony_ci /*1. Scan mode */ 664141cc406Sopenharmony_ci switch (pSetParameters->smScanMode) 665141cc406Sopenharmony_ci { 666141cc406Sopenharmony_ci case SM_TEXT: 667141cc406Sopenharmony_ci g_tiTarget.cmColorMode = CM_TEXT; 668141cc406Sopenharmony_ci break; 669141cc406Sopenharmony_ci case SM_GRAY: 670141cc406Sopenharmony_ci g_tiTarget.cmColorMode = CM_GRAY8; 671141cc406Sopenharmony_ci break; 672141cc406Sopenharmony_ci case SM_GRAY16: 673141cc406Sopenharmony_ci g_tiTarget.cmColorMode = CM_GRAY16; 674141cc406Sopenharmony_ci break; 675141cc406Sopenharmony_ci case SM_RGB24: 676141cc406Sopenharmony_ci g_tiTarget.cmColorMode = CM_RGB24; 677141cc406Sopenharmony_ci break; 678141cc406Sopenharmony_ci case SM_RGB48: 679141cc406Sopenharmony_ci g_tiTarget.cmColorMode = CM_RGB48; 680141cc406Sopenharmony_ci break; 681141cc406Sopenharmony_ci default: 682141cc406Sopenharmony_ci return FALSE; 683141cc406Sopenharmony_ci } 684141cc406Sopenharmony_ci 685141cc406Sopenharmony_ci /*2. Scan source */ 686141cc406Sopenharmony_ci g_ssScanSource = pSetParameters->ssScanSource; 687141cc406Sopenharmony_ci g_tiTarget.bScanSource = pSetParameters->ssScanSource; 688141cc406Sopenharmony_ci 689141cc406Sopenharmony_ci 690141cc406Sopenharmony_ci if (SS_Reflective == pSetParameters->ssScanSource) 691141cc406Sopenharmony_ci { 692141cc406Sopenharmony_ci g_ScanType = ST_Reflective; 693141cc406Sopenharmony_ci } 694141cc406Sopenharmony_ci else if (SS_Positive == pSetParameters->ssScanSource 695141cc406Sopenharmony_ci || SS_Negative == pSetParameters->ssScanSource 696141cc406Sopenharmony_ci || SS_ADF == pSetParameters->ssScanSource) 697141cc406Sopenharmony_ci { 698141cc406Sopenharmony_ci g_ScanType = ST_Transparent; 699141cc406Sopenharmony_ci } 700141cc406Sopenharmony_ci else 701141cc406Sopenharmony_ci { 702141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: ScanSource error\n"); 703141cc406Sopenharmony_ci return FALSE; 704141cc406Sopenharmony_ci } 705141cc406Sopenharmony_ci 706141cc406Sopenharmony_ci /*3. pixel flavor */ 707141cc406Sopenharmony_ci if (PF_BlackIs0 == pSetParameters->pfPixelFlavor 708141cc406Sopenharmony_ci || PF_WhiteIs0 == pSetParameters->pfPixelFlavor) 709141cc406Sopenharmony_ci { 710141cc406Sopenharmony_ci g_PixelFlavor = pSetParameters->pfPixelFlavor; 711141cc406Sopenharmony_ci } 712141cc406Sopenharmony_ci else 713141cc406Sopenharmony_ci { 714141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: PixelFlavor error\n"); 715141cc406Sopenharmony_ci return FALSE; 716141cc406Sopenharmony_ci } 717141cc406Sopenharmony_ci 718141cc406Sopenharmony_ci /*4. Scan area */ 719141cc406Sopenharmony_ci if (pSetParameters->fmArea.x1 >= pSetParameters->fmArea.x2) 720141cc406Sopenharmony_ci { 721141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: x1 > x2, error\n"); 722141cc406Sopenharmony_ci return FALSE; 723141cc406Sopenharmony_ci } 724141cc406Sopenharmony_ci if (pSetParameters->fmArea.y1 >= pSetParameters->fmArea.y2) 725141cc406Sopenharmony_ci { 726141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: y1 >= y2, error\n"); 727141cc406Sopenharmony_ci return FALSE; 728141cc406Sopenharmony_ci } 729141cc406Sopenharmony_ci if (pSetParameters->fmArea.x2 > MAX_SCANNING_WIDTH) /* Just for A4 size */ 730141cc406Sopenharmony_ci { 731141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: x2 > MAX_SCANNING_WIDTH, error\n"); 732141cc406Sopenharmony_ci return FALSE; 733141cc406Sopenharmony_ci } 734141cc406Sopenharmony_ci if (pSetParameters->fmArea.y2 > MAX_SCANNING_HEIGHT) /* Just for A4 size */ 735141cc406Sopenharmony_ci { 736141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: y2 > MAX_SCANNING_HEIGHT, error\n"); 737141cc406Sopenharmony_ci return FALSE; 738141cc406Sopenharmony_ci } 739141cc406Sopenharmony_ci 740141cc406Sopenharmony_ci X1inTargetDpi = 741141cc406Sopenharmony_ci (unsigned short) ((unsigned int) (pSetParameters->fmArea.x1) * 742141cc406Sopenharmony_ci (unsigned int) (pSetParameters->wTargetDPI) / 300L); 743141cc406Sopenharmony_ci Y1inTargetDpi = 744141cc406Sopenharmony_ci (unsigned short) ((unsigned int) (pSetParameters->fmArea.y1) * 745141cc406Sopenharmony_ci (unsigned int) (pSetParameters->wTargetDPI) / 300L); 746141cc406Sopenharmony_ci X2inTargetDpi = 747141cc406Sopenharmony_ci (unsigned short) ((unsigned int) (pSetParameters->fmArea.x2) * 748141cc406Sopenharmony_ci (unsigned int) (pSetParameters->wTargetDPI) / 300L); 749141cc406Sopenharmony_ci Y2inTargetDpi = 750141cc406Sopenharmony_ci (unsigned short) ((unsigned int) (pSetParameters->fmArea.y2) * 751141cc406Sopenharmony_ci (unsigned int) (pSetParameters->wTargetDPI) / 300L); 752141cc406Sopenharmony_ci 753141cc406Sopenharmony_ci g_tiTarget.isOptimalSpeed = TRUE; 754141cc406Sopenharmony_ci g_tiTarget.wDpi = pSetParameters->wTargetDPI; 755141cc406Sopenharmony_ci g_tiTarget.wX = X1inTargetDpi; 756141cc406Sopenharmony_ci g_tiTarget.wY = Y1inTargetDpi; 757141cc406Sopenharmony_ci g_tiTarget.wWidth = X2inTargetDpi - X1inTargetDpi; 758141cc406Sopenharmony_ci g_tiTarget.wHeight = Y2inTargetDpi - Y1inTargetDpi; 759141cc406Sopenharmony_ci 760141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: g_tiTarget.wDpi=%d\n", g_tiTarget.wDpi); 761141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: g_tiTarget.wX=%d\n", g_tiTarget.wX); 762141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: g_tiTarget.wY=%d\n", g_tiTarget.wY); 763141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: g_tiTarget.wWidth=%d\n", g_tiTarget.wWidth); 764141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: g_tiTarget.wHeight=%d\n", 765141cc406Sopenharmony_ci g_tiTarget.wHeight); 766141cc406Sopenharmony_ci 767141cc406Sopenharmony_ci /*5.Prepare */ 768141cc406Sopenharmony_ci if (FALSE == MustScanner_Prepare (g_tiTarget.bScanSource)) 769141cc406Sopenharmony_ci { 770141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: MustScanner_Prepare fail\n"); 771141cc406Sopenharmony_ci return FALSE; 772141cc406Sopenharmony_ci } 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci /*6. Linear threshold */ 775141cc406Sopenharmony_ci if (pSetParameters->wLinearThreshold > 256 776141cc406Sopenharmony_ci && pSetParameters->smScanMode == SM_TEXT) 777141cc406Sopenharmony_ci { 778141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: LinearThreshold error\n"); 779141cc406Sopenharmony_ci return FALSE; 780141cc406Sopenharmony_ci } 781141cc406Sopenharmony_ci else 782141cc406Sopenharmony_ci { 783141cc406Sopenharmony_ci g_wLineartThreshold = pSetParameters->wLinearThreshold; 784141cc406Sopenharmony_ci } 785141cc406Sopenharmony_ci 786141cc406Sopenharmony_ci /*7. Gamma table */ 787141cc406Sopenharmony_ci if (NULL != pSetParameters->pGammaTable) 788141cc406Sopenharmony_ci { 789141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: IN gamma table not NULL\n"); 790141cc406Sopenharmony_ci g_pGammaTable = pSetParameters->pGammaTable; 791141cc406Sopenharmony_ci g_isSelfGamma = FALSE; 792141cc406Sopenharmony_ci } 793141cc406Sopenharmony_ci else if (pSetParameters->smScanMode == SM_GRAY 794141cc406Sopenharmony_ci || pSetParameters->smScanMode == SM_RGB24) 795141cc406Sopenharmony_ci { 796141cc406Sopenharmony_ci unsigned short i; 797141cc406Sopenharmony_ci SANE_Byte byGammaData; 798141cc406Sopenharmony_ci double pow_d; 799141cc406Sopenharmony_ci double pow_z = (double) 10 / 16.0; 800141cc406Sopenharmony_ci 801141cc406Sopenharmony_ci g_pGammaTable = (unsigned short *) malloc (sizeof (unsigned short) * 4096 * 3); 802141cc406Sopenharmony_ci 803141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: gamma table malloc %ld Bytes\n", 804141cc406Sopenharmony_ci (long int) sizeof (unsigned short) * 4096 * 3); 805141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: address of g_pGammaTable=%p\n", 806141cc406Sopenharmony_ci (void *) g_pGammaTable); 807141cc406Sopenharmony_ci 808141cc406Sopenharmony_ci if (NULL == g_pGammaTable) 809141cc406Sopenharmony_ci { 810141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: gamma table malloc fail\n"); 811141cc406Sopenharmony_ci return FALSE; 812141cc406Sopenharmony_ci } 813141cc406Sopenharmony_ci g_isSelfGamma = TRUE; 814141cc406Sopenharmony_ci 815141cc406Sopenharmony_ci for (i = 0; i < 4096; i++) 816141cc406Sopenharmony_ci { 817141cc406Sopenharmony_ci pow_d = (double) i / (double) 4096; 818141cc406Sopenharmony_ci 819141cc406Sopenharmony_ci byGammaData = (SANE_Byte) (pow (pow_d, pow_z) * 255); 820141cc406Sopenharmony_ci 821141cc406Sopenharmony_ci *(g_pGammaTable + i) = byGammaData; 822141cc406Sopenharmony_ci *(g_pGammaTable + i + 4096) = byGammaData; 823141cc406Sopenharmony_ci *(g_pGammaTable + i + 8192) = byGammaData; 824141cc406Sopenharmony_ci } 825141cc406Sopenharmony_ci } 826141cc406Sopenharmony_ci else if (pSetParameters->smScanMode == SM_GRAY16 827141cc406Sopenharmony_ci || pSetParameters->smScanMode == SM_RGB48) 828141cc406Sopenharmony_ci { 829141cc406Sopenharmony_ci unsigned int i, wGammaData; 830141cc406Sopenharmony_ci g_pGammaTable = (unsigned short *) malloc (sizeof (unsigned short) * 65536 * 3); 831141cc406Sopenharmony_ci 832141cc406Sopenharmony_ci if (g_pGammaTable == NULL) 833141cc406Sopenharmony_ci { 834141cc406Sopenharmony_ci DBG (DBG_ERR, "SetParameters: gamma table malloc fail\n"); 835141cc406Sopenharmony_ci return FALSE; 836141cc406Sopenharmony_ci } 837141cc406Sopenharmony_ci g_isSelfGamma = TRUE; 838141cc406Sopenharmony_ci 839141cc406Sopenharmony_ci for (i = 0; i < 65536; i++) 840141cc406Sopenharmony_ci { 841141cc406Sopenharmony_ci wGammaData = 842141cc406Sopenharmony_ci (unsigned short) (pow ((((float) i) / 65536.0), (((float) 10) / 16.0)) * 843141cc406Sopenharmony_ci 65535); 844141cc406Sopenharmony_ci 845141cc406Sopenharmony_ci *(g_pGammaTable + i) = wGammaData; 846141cc406Sopenharmony_ci *(g_pGammaTable + i + 65536) = wGammaData; 847141cc406Sopenharmony_ci *(g_pGammaTable + i + 65536 * 2) = wGammaData; 848141cc406Sopenharmony_ci } 849141cc406Sopenharmony_ci } 850141cc406Sopenharmony_ci else 851141cc406Sopenharmony_ci { 852141cc406Sopenharmony_ci DBG (DBG_INFO, "SetParameters: set g_pGammaTable to NULL\n"); 853141cc406Sopenharmony_ci g_pGammaTable = NULL; 854141cc406Sopenharmony_ci } 855141cc406Sopenharmony_ci 856141cc406Sopenharmony_ci DBG (DBG_FUNC, "SetParameters: exit\n"); 857141cc406Sopenharmony_ci return TRUE; 858141cc406Sopenharmony_ci} 859141cc406Sopenharmony_ci 860141cc406Sopenharmony_ci/********************************************************************** 861141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 862141cc406Sopenharmony_ciRoutine Description: 863141cc406Sopenharmony_ci get the optical dpi and scan area 864141cc406Sopenharmony_ciParameters: 865141cc406Sopenharmony_ci pGetParameters: the information of scan 866141cc406Sopenharmony_ciReturn value: 867141cc406Sopenharmony_ci if the operation is success 868141cc406Sopenharmony_ci return TRUE 869141cc406Sopenharmony_ci else 870141cc406Sopenharmony_ci return FALSE 871141cc406Sopenharmony_ci***********************************************************************/ 872141cc406Sopenharmony_cistatic SANE_Bool 873141cc406Sopenharmony_ciGetParameters (LPGETPARAMETERS pGetParameters) 874141cc406Sopenharmony_ci{ 875141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetParameters: start\n"); 876141cc406Sopenharmony_ci if (ST_Reflective == g_ScanType) 877141cc406Sopenharmony_ci { 878141cc406Sopenharmony_ci if (FALSE == Reflective_ScanSuggest (&g_tiTarget, &g_ssSuggest)) 879141cc406Sopenharmony_ci { 880141cc406Sopenharmony_ci DBG (DBG_ERR, "GetParameters: Reflective_ScanSuggest error\n"); 881141cc406Sopenharmony_ci return FALSE; 882141cc406Sopenharmony_ci } 883141cc406Sopenharmony_ci } 884141cc406Sopenharmony_ci else 885141cc406Sopenharmony_ci { 886141cc406Sopenharmony_ci if (FALSE == Transparent_ScanSuggest (&g_tiTarget, &g_ssSuggest)) 887141cc406Sopenharmony_ci { 888141cc406Sopenharmony_ci DBG (DBG_ERR, "GetParameters: Transparent_ScanSuggest error\n"); 889141cc406Sopenharmony_ci return FALSE; 890141cc406Sopenharmony_ci } 891141cc406Sopenharmony_ci } 892141cc406Sopenharmony_ci 893141cc406Sopenharmony_ci pGetParameters->wSourceXDPI = g_ssSuggest.wXDpi; 894141cc406Sopenharmony_ci pGetParameters->wSourceYDPI = g_ssSuggest.wYDpi; 895141cc406Sopenharmony_ci pGetParameters->dwLength = (unsigned int) g_ssSuggest.wHeight; 896141cc406Sopenharmony_ci pGetParameters->dwLineByteWidth = g_ssSuggest.dwBytesPerRow; 897141cc406Sopenharmony_ci 898141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetParameters: exit\n"); 899141cc406Sopenharmony_ci 900141cc406Sopenharmony_ci return TRUE; 901141cc406Sopenharmony_ci} 902141cc406Sopenharmony_ci 903141cc406Sopenharmony_ci/********************************************************************** 904141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/13 905141cc406Sopenharmony_ci 906141cc406Sopenharmony_ciRoutine Description: 907141cc406Sopenharmony_ci start scan image 908141cc406Sopenharmony_ciParameters: 909141cc406Sopenharmony_ci none 910141cc406Sopenharmony_ciReturn value: 911141cc406Sopenharmony_ci if operation is success 912141cc406Sopenharmony_ci return TRUE 913141cc406Sopenharmony_ci else 914141cc406Sopenharmony_ci return FALSE 915141cc406Sopenharmony_ci***********************************************************************/ 916141cc406Sopenharmony_cistatic SANE_Bool 917141cc406Sopenharmony_ciStartScan () 918141cc406Sopenharmony_ci{ 919141cc406Sopenharmony_ci DBG (DBG_FUNC, "StartScan: start\n"); 920141cc406Sopenharmony_ci if (ST_Reflective == g_ScanType) 921141cc406Sopenharmony_ci { 922141cc406Sopenharmony_ci DBG (DBG_INFO, "StartScan: g_ScanType==ST_Reflective\n"); 923141cc406Sopenharmony_ci 924141cc406Sopenharmony_ci return Reflective_SetupScan (g_ssSuggest.cmScanMode, 925141cc406Sopenharmony_ci g_ssSuggest.wXDpi, 926141cc406Sopenharmony_ci g_ssSuggest.wYDpi, 927141cc406Sopenharmony_ci PF_BlackIs0, 928141cc406Sopenharmony_ci g_ssSuggest.wX, 929141cc406Sopenharmony_ci g_ssSuggest.wY, 930141cc406Sopenharmony_ci g_ssSuggest.wWidth, g_ssSuggest.wHeight); 931141cc406Sopenharmony_ci } 932141cc406Sopenharmony_ci else 933141cc406Sopenharmony_ci 934141cc406Sopenharmony_ci { 935141cc406Sopenharmony_ci 936141cc406Sopenharmony_ci DBG (DBG_INFO, "StartScan: g_ScanType==ST_Transparent\n"); 937141cc406Sopenharmony_ci 938141cc406Sopenharmony_ci return Transparent_SetupScan (g_ssSuggest.cmScanMode, 939141cc406Sopenharmony_ci g_ssSuggest.wXDpi, 940141cc406Sopenharmony_ci g_ssSuggest.wYDpi, 941141cc406Sopenharmony_ci PF_BlackIs0, 942141cc406Sopenharmony_ci g_ssSuggest.wX, 943141cc406Sopenharmony_ci g_ssSuggest.wY, 944141cc406Sopenharmony_ci g_ssSuggest.wWidth, g_ssSuggest.wHeight); 945141cc406Sopenharmony_ci } 946141cc406Sopenharmony_ci} 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci/********************************************************************** 949141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 950141cc406Sopenharmony_ciRoutine Description: 951141cc406Sopenharmony_ci Read the scanner data 952141cc406Sopenharmony_ciParameters: 953141cc406Sopenharmony_ci 954141cc406Sopenharmony_ci pImageRows: the information of the data 955141cc406Sopenharmony_ciReturn value: 956141cc406Sopenharmony_ci if the operation is seccuss 957141cc406Sopenharmony_ci return TRUE 958141cc406Sopenharmony_ci else 959141cc406Sopenharmony_ci return FALSE 960141cc406Sopenharmony_ci***********************************************************************/ 961141cc406Sopenharmony_cistatic SANE_Bool 962141cc406Sopenharmony_ciReadScannedData (LPIMAGEROWS pImageRows) 963141cc406Sopenharmony_ci{ 964141cc406Sopenharmony_ci SANE_Bool isRGBInvert; 965141cc406Sopenharmony_ci unsigned short Rows = 0; 966141cc406Sopenharmony_ci SANE_Byte *lpBlock = (SANE_Byte *) pImageRows->pBuffer; 967141cc406Sopenharmony_ci SANE_Byte *lpReturnData = (SANE_Byte *) pImageRows->pBuffer; 968141cc406Sopenharmony_ci int i = 0; 969141cc406Sopenharmony_ci 970141cc406Sopenharmony_ci DBG (DBG_FUNC, "ReadScannedData: start\n"); 971141cc406Sopenharmony_ci 972141cc406Sopenharmony_ci if (pImageRows->roRgbOrder == RO_RGB) 973141cc406Sopenharmony_ci isRGBInvert = FALSE; 974141cc406Sopenharmony_ci else 975141cc406Sopenharmony_ci isRGBInvert = TRUE; 976141cc406Sopenharmony_ci 977141cc406Sopenharmony_ci Rows = pImageRows->wWantedLineNum; 978141cc406Sopenharmony_ci 979141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: wanted Rows = %d\n", Rows); 980141cc406Sopenharmony_ci 981141cc406Sopenharmony_ci if (ST_Reflective == g_ScanType) 982141cc406Sopenharmony_ci { 983141cc406Sopenharmony_ci if (FALSE == Reflective_GetRows (lpBlock, &Rows, isRGBInvert)) 984141cc406Sopenharmony_ci return FALSE; 985141cc406Sopenharmony_ci } 986141cc406Sopenharmony_ci else if (SS_Positive == g_ssScanSource) 987141cc406Sopenharmony_ci { 988141cc406Sopenharmony_ci if (FALSE == Transparent_GetRows (lpBlock, &Rows, isRGBInvert)) 989141cc406Sopenharmony_ci return FALSE; 990141cc406Sopenharmony_ci } 991141cc406Sopenharmony_ci 992141cc406Sopenharmony_ci pImageRows->wXferedLineNum = Rows; 993141cc406Sopenharmony_ci 994141cc406Sopenharmony_ci if (g_PixelFlavor == PF_WhiteIs0 || g_ScanMode == CM_TEXT) 995141cc406Sopenharmony_ci { 996141cc406Sopenharmony_ci int TotalSize = Rows * g_ssSuggest.dwBytesPerRow; 997141cc406Sopenharmony_ci for (i = 0; i < TotalSize; i++) 998141cc406Sopenharmony_ci { 999141cc406Sopenharmony_ci *(lpBlock++) ^= 0xff; 1000141cc406Sopenharmony_ci } 1001141cc406Sopenharmony_ci } 1002141cc406Sopenharmony_ci 1003141cc406Sopenharmony_ci if (SS_Negative == g_ssScanSource) 1004141cc406Sopenharmony_ci { 1005141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: deal with the Negative\n"); 1006141cc406Sopenharmony_ci 1007141cc406Sopenharmony_ci if (g_bIsFirstGetNegData) 1008141cc406Sopenharmony_ci { 1009141cc406Sopenharmony_ci unsigned int TotalImgeSize = g_SWHeight * g_ssSuggest.dwBytesPerRow; 1010141cc406Sopenharmony_ci g_lpNegImageData = (SANE_Byte *) malloc (TotalImgeSize); 1011141cc406Sopenharmony_ci if (NULL != g_lpNegImageData) 1012141cc406Sopenharmony_ci { 1013141cc406Sopenharmony_ci SANE_Byte * lpTempData = g_lpNegImageData; 1014141cc406Sopenharmony_ci DBG (DBG_INFO, 1015141cc406Sopenharmony_ci "ReadScannedData: malloc the negative data is success!\n"); 1016141cc406Sopenharmony_ci g_bIsMallocNegData = TRUE; 1017141cc406Sopenharmony_ci if (!Transparent_GetRows 1018141cc406Sopenharmony_ci (g_lpNegImageData, &g_SWHeight, isRGBInvert)) 1019141cc406Sopenharmony_ci { 1020141cc406Sopenharmony_ci return FALSE; 1021141cc406Sopenharmony_ci } 1022141cc406Sopenharmony_ci 1023141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: get image data is over!\n"); 1024141cc406Sopenharmony_ci 1025141cc406Sopenharmony_ci for (i = 0; i < (int) TotalImgeSize; i++) 1026141cc406Sopenharmony_ci { 1027141cc406Sopenharmony_ci *(g_lpNegImageData++) ^= 0xff; 1028141cc406Sopenharmony_ci } 1029141cc406Sopenharmony_ci g_lpNegImageData = lpTempData; 1030141cc406Sopenharmony_ci AutoLevel (g_lpNegImageData, g_ScanMode, g_SWHeight, 1031141cc406Sopenharmony_ci g_ssSuggest.dwBytesPerRow); 1032141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: autolevel is ok\n"); 1033141cc406Sopenharmony_ci } 1034141cc406Sopenharmony_ci g_bIsFirstGetNegData = FALSE; 1035141cc406Sopenharmony_ci } 1036141cc406Sopenharmony_ci 1037141cc406Sopenharmony_ci if (g_bIsMallocNegData) 1038141cc406Sopenharmony_ci { 1039141cc406Sopenharmony_ci memcpy (pImageRows->pBuffer, 1040141cc406Sopenharmony_ci g_lpNegImageData + 1041141cc406Sopenharmony_ci g_ssSuggest.dwBytesPerRow * g_dwAlreadyGetNegLines, 1042141cc406Sopenharmony_ci g_ssSuggest.dwBytesPerRow * Rows); 1043141cc406Sopenharmony_ci 1044141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: copy the data over!\n"); 1045141cc406Sopenharmony_ci 1046141cc406Sopenharmony_ci g_dwAlreadyGetNegLines += Rows; 1047141cc406Sopenharmony_ci if (g_dwAlreadyGetNegLines >= g_SWHeight) 1048141cc406Sopenharmony_ci { 1049141cc406Sopenharmony_ci DBG (DBG_INFO, "ReadScannedData: free the image data!\n"); 1050141cc406Sopenharmony_ci free (g_lpNegImageData); 1051141cc406Sopenharmony_ci g_lpNegImageData = NULL; 1052141cc406Sopenharmony_ci g_bIsFirstGetNegData = TRUE; 1053141cc406Sopenharmony_ci g_dwAlreadyGetNegLines = 0; 1054141cc406Sopenharmony_ci g_bIsMallocNegData = FALSE; 1055141cc406Sopenharmony_ci } 1056141cc406Sopenharmony_ci } 1057141cc406Sopenharmony_ci else 1058141cc406Sopenharmony_ci { 1059141cc406Sopenharmony_ci int TotalSize = Rows * g_ssSuggest.dwBytesPerRow; 1060141cc406Sopenharmony_ci DBG (DBG_INFO, 1061141cc406Sopenharmony_ci "ReadScannedData: malloc the negative data is fail!\n"); 1062141cc406Sopenharmony_ci if (!Transparent_GetRows (lpReturnData, &Rows, isRGBInvert)) 1063141cc406Sopenharmony_ci { 1064141cc406Sopenharmony_ci return FALSE; 1065141cc406Sopenharmony_ci } 1066141cc406Sopenharmony_ci 1067141cc406Sopenharmony_ci for (i = 0; i < TotalSize; i++) 1068141cc406Sopenharmony_ci { 1069141cc406Sopenharmony_ci *(lpReturnData++) ^= 0xff; 1070141cc406Sopenharmony_ci } 1071141cc406Sopenharmony_ci pImageRows->wXferedLineNum = Rows; 1072141cc406Sopenharmony_ci 1073141cc406Sopenharmony_ci g_dwAlreadyGetNegLines += Rows; 1074141cc406Sopenharmony_ci if (g_dwAlreadyGetNegLines >= g_SWHeight) 1075141cc406Sopenharmony_ci { 1076141cc406Sopenharmony_ci g_bIsFirstGetNegData = TRUE; 1077141cc406Sopenharmony_ci g_dwAlreadyGetNegLines = 0; 1078141cc406Sopenharmony_ci g_bIsMallocNegData = FALSE; 1079141cc406Sopenharmony_ci } 1080141cc406Sopenharmony_ci } 1081141cc406Sopenharmony_ci 1082141cc406Sopenharmony_ci } 1083141cc406Sopenharmony_ci 1084141cc406Sopenharmony_ci DBG (DBG_FUNC, "ReadScannedData: leave ReadScannedData\n"); 1085141cc406Sopenharmony_ci 1086141cc406Sopenharmony_ci return TRUE; 1087141cc406Sopenharmony_ci} 1088141cc406Sopenharmony_ci 1089141cc406Sopenharmony_ci/********************************************************************** 1090141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1091141cc406Sopenharmony_ciRoutine Description: 1092141cc406Sopenharmony_ci Stop scan 1093141cc406Sopenharmony_ciParameters: 1094141cc406Sopenharmony_ci none 1095141cc406Sopenharmony_ciReturn value: 1096141cc406Sopenharmony_ci if operation is success 1097141cc406Sopenharmony_ci return TRUE 1098141cc406Sopenharmony_ci else 1099141cc406Sopenharmony_ci return FALSE 1100141cc406Sopenharmony_ci***********************************************************************/ 1101141cc406Sopenharmony_cistatic SANE_Bool 1102141cc406Sopenharmony_ciStopScan () 1103141cc406Sopenharmony_ci{ 1104141cc406Sopenharmony_ci SANE_Bool rt; 1105141cc406Sopenharmony_ci int i; 1106141cc406Sopenharmony_ci 1107141cc406Sopenharmony_ci DBG (DBG_FUNC, "StopScan: start\n"); 1108141cc406Sopenharmony_ci 1109141cc406Sopenharmony_ci /*stop read data and kill thread */ 1110141cc406Sopenharmony_ci if (ST_Reflective == g_ScanType) 1111141cc406Sopenharmony_ci { 1112141cc406Sopenharmony_ci rt = Reflective_StopScan (); 1113141cc406Sopenharmony_ci } 1114141cc406Sopenharmony_ci else 1115141cc406Sopenharmony_ci { 1116141cc406Sopenharmony_ci rt = Transparent_StopScan (); 1117141cc406Sopenharmony_ci } 1118141cc406Sopenharmony_ci 1119141cc406Sopenharmony_ci /*free gamma table */ 1120141cc406Sopenharmony_ci if (g_isSelfGamma && g_pGammaTable != NULL) 1121141cc406Sopenharmony_ci { 1122141cc406Sopenharmony_ci for (i = 0; i < 20; i++) 1123141cc406Sopenharmony_ci { 1124141cc406Sopenharmony_ci if (!g_isScanning) 1125141cc406Sopenharmony_ci { 1126141cc406Sopenharmony_ci free (g_pGammaTable); 1127141cc406Sopenharmony_ci g_pGammaTable = NULL; 1128141cc406Sopenharmony_ci break; 1129141cc406Sopenharmony_ci } 1130141cc406Sopenharmony_ci else 1131141cc406Sopenharmony_ci { 1132141cc406Sopenharmony_ci sleep (1); /*waiting ReadScannedData return. */ 1133141cc406Sopenharmony_ci } 1134141cc406Sopenharmony_ci } 1135141cc406Sopenharmony_ci } 1136141cc406Sopenharmony_ci 1137141cc406Sopenharmony_ci /*free image buffer */ 1138141cc406Sopenharmony_ci if (g_lpReadImageHead != NULL) 1139141cc406Sopenharmony_ci 1140141cc406Sopenharmony_ci { 1141141cc406Sopenharmony_ci free (g_lpReadImageHead); 1142141cc406Sopenharmony_ci g_lpReadImageHead = NULL; 1143141cc406Sopenharmony_ci } 1144141cc406Sopenharmony_ci 1145141cc406Sopenharmony_ci DBG (DBG_FUNC, "StopScan: exit\n"); 1146141cc406Sopenharmony_ci return rt; 1147141cc406Sopenharmony_ci} 1148141cc406Sopenharmony_ci 1149141cc406Sopenharmony_ci/********************************************************************** 1150141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1151141cc406Sopenharmony_ciRoutine Description: 1152141cc406Sopenharmony_ci Check the status of TA 1153141cc406Sopenharmony_ciParameters: 1154141cc406Sopenharmony_ci none 1155141cc406Sopenharmony_ciReturn value: 1156141cc406Sopenharmony_ci if operation is success 1157141cc406Sopenharmony_ci return TRUE 1158141cc406Sopenharmony_ci else 1159141cc406Sopenharmony_ci return FALSE 1160141cc406Sopenharmony_ci***********************************************************************/ 1161141cc406Sopenharmony_cistatic SANE_Bool 1162141cc406Sopenharmony_ciIsTAConnected () 1163141cc406Sopenharmony_ci{ 1164141cc406Sopenharmony_ci SANE_Bool hasTA; 1165141cc406Sopenharmony_ci 1166141cc406Sopenharmony_ci DBG (DBG_FUNC, "StopScan: start\n"); 1167141cc406Sopenharmony_ci 1168141cc406Sopenharmony_ci if (Asic_Open (&g_chip, g_pDeviceFile) != SANE_STATUS_GOOD) 1169141cc406Sopenharmony_ci { 1170141cc406Sopenharmony_ci return FALSE; 1171141cc406Sopenharmony_ci } 1172141cc406Sopenharmony_ci 1173141cc406Sopenharmony_ci if (Asic_IsTAConnected (&g_chip, &hasTA) != SANE_STATUS_GOOD) 1174141cc406Sopenharmony_ci { 1175141cc406Sopenharmony_ci Asic_Close (&g_chip); 1176141cc406Sopenharmony_ci return FALSE; 1177141cc406Sopenharmony_ci } 1178141cc406Sopenharmony_ci 1179141cc406Sopenharmony_ci Asic_Close (&g_chip); 1180141cc406Sopenharmony_ci 1181141cc406Sopenharmony_ci DBG (DBG_FUNC, "StopScan: exit\n"); 1182141cc406Sopenharmony_ci return hasTA; 1183141cc406Sopenharmony_ci} 1184141cc406Sopenharmony_ci 1185141cc406Sopenharmony_ci#ifdef SANE_UNUSED 1186141cc406Sopenharmony_ci/********************************************************************** 1187141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1188141cc406Sopenharmony_ciRoutine Description: 1189141cc406Sopenharmony_ci Get the status of the HK 1190141cc406Sopenharmony_ciParameters: 1191141cc406Sopenharmony_ci pKey: the status of key 1192141cc406Sopenharmony_ciReturn value: 1193141cc406Sopenharmony_ci if the operation is success 1194141cc406Sopenharmony_ci return TRUE 1195141cc406Sopenharmony_ci else 1196141cc406Sopenharmony_ci return FALSE 1197141cc406Sopenharmony_ci***********************************************************************/ 1198141cc406Sopenharmony_cistatic SANE_Bool 1199141cc406Sopenharmony_ciGetKeyStatus (SANE_Byte * pKey) 1200141cc406Sopenharmony_ci{ 1201141cc406Sopenharmony_ci SANE_Byte pKeyTemp = 0x00; 1202141cc406Sopenharmony_ci SANE_Status status = Asic_CheckFunctionKey (&g_chip, &pKeyTemp); 1203141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetKeyStatus: start\n"); 1204141cc406Sopenharmony_ci 1205141cc406Sopenharmony_ci if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile)) 1206141cc406Sopenharmony_ci { 1207141cc406Sopenharmony_ci DBG (DBG_ERR, "GetKeyStatus: Asic_Open is fail\n"); 1208141cc406Sopenharmony_ci return FALSE; 1209141cc406Sopenharmony_ci } 1210141cc406Sopenharmony_ci 1211141cc406Sopenharmony_ci if (SANE_STATUS_GOOD != status) 1212141cc406Sopenharmony_ci { 1213141cc406Sopenharmony_ci DBG (DBG_ERR, "GetKeyStatus: Asic_CheckFunctionKey is fail\n"); 1214141cc406Sopenharmony_ci return FALSE; 1215141cc406Sopenharmony_ci } 1216141cc406Sopenharmony_ci 1217141cc406Sopenharmony_ci if (0x01 == pKeyTemp) 1218141cc406Sopenharmony_ci { 1219141cc406Sopenharmony_ci *pKey = 0x01; /*Scan key pressed */ 1220141cc406Sopenharmony_ci } 1221141cc406Sopenharmony_ci 1222141cc406Sopenharmony_ci if (0x02 == pKeyTemp) 1223141cc406Sopenharmony_ci { 1224141cc406Sopenharmony_ci *pKey = 0x02; /*Copy key pressed */ 1225141cc406Sopenharmony_ci } 1226141cc406Sopenharmony_ci if (0x04 == pKeyTemp) 1227141cc406Sopenharmony_ci { 1228141cc406Sopenharmony_ci *pKey = 0x03; /*Fax key pressed */ 1229141cc406Sopenharmony_ci } 1230141cc406Sopenharmony_ci if (0x08 == pKeyTemp) 1231141cc406Sopenharmony_ci { 1232141cc406Sopenharmony_ci *pKey = 0x04; /*Email key pressed */ 1233141cc406Sopenharmony_ci } 1234141cc406Sopenharmony_ci if (0x10 == pKeyTemp) 1235141cc406Sopenharmony_ci { 1236141cc406Sopenharmony_ci *pKey = 0x05; /*Panel key pressed */ 1237141cc406Sopenharmony_ci } 1238141cc406Sopenharmony_ci 1239141cc406Sopenharmony_ci if (SANE_STATUS_GOOD != Asic_Close (&g_chip)) 1240141cc406Sopenharmony_ci { 1241141cc406Sopenharmony_ci DBG (DBG_ERR, "GetKeyStatus: Asic_Close is fail\n"); 1242141cc406Sopenharmony_ci return FALSE; 1243141cc406Sopenharmony_ci } 1244141cc406Sopenharmony_ci 1245141cc406Sopenharmony_ci DBG (DBG_FUNC, "GetKeyStatus: exit\n"); 1246141cc406Sopenharmony_ci return TRUE; 1247141cc406Sopenharmony_ci} 1248141cc406Sopenharmony_ci#endif 1249141cc406Sopenharmony_ci/********************************************************************** 1250141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1251141cc406Sopenharmony_ciRoutine Description: 1252141cc406Sopenharmony_ci Deal with the image with auto level 1253141cc406Sopenharmony_ciParameters: 1254141cc406Sopenharmony_ci lpSource: the data of image 1255141cc406Sopenharmony_ci scanMode: the scan mode 1256141cc406Sopenharmony_ci ScanLines: the rows of image 1257141cc406Sopenharmony_ci BytesPerLine: the bytes of per line 1258141cc406Sopenharmony_ciReturn value: 1259141cc406Sopenharmony_ci none 1260141cc406Sopenharmony_ci***********************************************************************/ 1261141cc406Sopenharmony_cistatic void 1262141cc406Sopenharmony_ciAutoLevel (SANE_Byte *lpSource, SCANMODE scanMode, unsigned short ScanLines, 1263141cc406Sopenharmony_ci unsigned int BytesPerLine) 1264141cc406Sopenharmony_ci{ 1265141cc406Sopenharmony_ci int ii; 1266141cc406Sopenharmony_ci unsigned int i, j; 1267141cc406Sopenharmony_ci unsigned int tLines, CountPixels, TotalImgSize; 1268141cc406Sopenharmony_ci unsigned short R, G, B, max_R, max_G, max_B, min_R, min_G, min_B; 1269141cc406Sopenharmony_ci float fmax_R, fmax_G, fmax_B; 1270141cc406Sopenharmony_ci unsigned int sum_R = 0, sum_G = 0, sum_B = 0; 1271141cc406Sopenharmony_ci unsigned int hisgram_R[256], hisgram_G[256], hisgram_B[256]; 1272141cc406Sopenharmony_ci 1273141cc406Sopenharmony_ci unsigned int iWidth = BytesPerLine / 3; 1274141cc406Sopenharmony_ci unsigned int iHeight = ScanLines; 1275141cc406Sopenharmony_ci SANE_Byte *pbmpdata = (SANE_Byte *) lpSource; 1276141cc406Sopenharmony_ci 1277141cc406Sopenharmony_ci unsigned short imin_threshold[3]; 1278141cc406Sopenharmony_ci unsigned short imax_threshold[3]; 1279141cc406Sopenharmony_ci 1280141cc406Sopenharmony_ci DBG (DBG_FUNC, "AutoLevel: start\n"); 1281141cc406Sopenharmony_ci 1282141cc406Sopenharmony_ci if (scanMode != CM_RGB24ext) 1283141cc406Sopenharmony_ci { 1284141cc406Sopenharmony_ci return; 1285141cc406Sopenharmony_ci } 1286141cc406Sopenharmony_ci 1287141cc406Sopenharmony_ci i = j = 0; 1288141cc406Sopenharmony_ci tLines = CountPixels = TotalImgSize = 0; 1289141cc406Sopenharmony_ci 1290141cc406Sopenharmony_ci TotalImgSize = iWidth * iHeight; 1291141cc406Sopenharmony_ci 1292141cc406Sopenharmony_ci 1293141cc406Sopenharmony_ci 1294141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 1295141cc406Sopenharmony_ci { 1296141cc406Sopenharmony_ci 1297141cc406Sopenharmony_ci hisgram_R[i] = 0; 1298141cc406Sopenharmony_ci hisgram_G[i] = 0; 1299141cc406Sopenharmony_ci hisgram_B[i] = 0; 1300141cc406Sopenharmony_ci } 1301141cc406Sopenharmony_ci 1302141cc406Sopenharmony_ci 1303141cc406Sopenharmony_ci DBG (DBG_INFO, "AutoLevel: init data is over\n"); 1304141cc406Sopenharmony_ci 1305141cc406Sopenharmony_ci /* Find min , max, mean */ 1306141cc406Sopenharmony_ci max_R = max_G = max_B = 0; 1307141cc406Sopenharmony_ci min_R = min_G = min_B = 255; 1308141cc406Sopenharmony_ci tLines = 0; 1309141cc406Sopenharmony_ci DBG (DBG_INFO, "AutoLevel: iHeight = %d, iWidth = %d\n", iHeight, iWidth); 1310141cc406Sopenharmony_ci 1311141cc406Sopenharmony_ci for (j = 0; j < iHeight; j++) 1312141cc406Sopenharmony_ci { 1313141cc406Sopenharmony_ci tLines = j * iWidth * 3; 1314141cc406Sopenharmony_ci 1315141cc406Sopenharmony_ci 1316141cc406Sopenharmony_ci for (i = 0; i < iWidth; i++) 1317141cc406Sopenharmony_ci { 1318141cc406Sopenharmony_ci R = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 2)); 1319141cc406Sopenharmony_ci G = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 1)); 1320141cc406Sopenharmony_ci B = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3)); 1321141cc406Sopenharmony_ci 1322141cc406Sopenharmony_ci max_R = _MAX (R, max_R); 1323141cc406Sopenharmony_ci max_G = _MAX (G, max_G); 1324141cc406Sopenharmony_ci max_B = _MAX (B, max_B); 1325141cc406Sopenharmony_ci 1326141cc406Sopenharmony_ci min_R = _MIN (R, min_R); 1327141cc406Sopenharmony_ci min_G = _MIN (G, min_G); 1328141cc406Sopenharmony_ci min_B = _MIN (B, min_B); 1329141cc406Sopenharmony_ci 1330141cc406Sopenharmony_ci hisgram_R[(SANE_Byte) R]++; 1331141cc406Sopenharmony_ci hisgram_G[(SANE_Byte) G]++; 1332141cc406Sopenharmony_ci hisgram_B[(SANE_Byte) B]++; 1333141cc406Sopenharmony_ci 1334141cc406Sopenharmony_ci sum_R += R; 1335141cc406Sopenharmony_ci sum_G += G; 1336141cc406Sopenharmony_ci sum_B += B; 1337141cc406Sopenharmony_ci 1338141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 2)) = (SANE_Byte) R; 1339141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 1)) = (SANE_Byte) G; 1340141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3)) = (SANE_Byte) B; 1341141cc406Sopenharmony_ci 1342141cc406Sopenharmony_ci CountPixels++; 1343141cc406Sopenharmony_ci } 1344141cc406Sopenharmony_ci 1345141cc406Sopenharmony_ci } 1346141cc406Sopenharmony_ci 1347141cc406Sopenharmony_ci DBG (DBG_INFO, "AutoLevel: Find min , max is over!\n"); 1348141cc406Sopenharmony_ci 1349141cc406Sopenharmony_ci 1350141cc406Sopenharmony_ci imin_threshold[0] = 0; 1351141cc406Sopenharmony_ci imin_threshold[1] = 0; 1352141cc406Sopenharmony_ci imin_threshold[2] = 0; 1353141cc406Sopenharmony_ci imax_threshold[0] = 0; 1354141cc406Sopenharmony_ci imax_threshold[1] = 0; 1355141cc406Sopenharmony_ci imax_threshold[2] = 0; 1356141cc406Sopenharmony_ci 1357141cc406Sopenharmony_ci for (ii = 0; ii < 256; ii++) 1358141cc406Sopenharmony_ci { 1359141cc406Sopenharmony_ci if (hisgram_R[ii] > 0) 1360141cc406Sopenharmony_ci if (hisgram_R[ii] >= imin_threshold[0]) 1361141cc406Sopenharmony_ci { 1362141cc406Sopenharmony_ci min_R = ii; 1363141cc406Sopenharmony_ci break; 1364141cc406Sopenharmony_ci } 1365141cc406Sopenharmony_ci } 1366141cc406Sopenharmony_ci 1367141cc406Sopenharmony_ci for (ii = 255; ii >= 0; ii--) 1368141cc406Sopenharmony_ci { 1369141cc406Sopenharmony_ci if (hisgram_R[ii] > 0) 1370141cc406Sopenharmony_ci if (hisgram_R[ii] >= imax_threshold[0]) 1371141cc406Sopenharmony_ci { 1372141cc406Sopenharmony_ci max_R = ii; 1373141cc406Sopenharmony_ci break; 1374141cc406Sopenharmony_ci } 1375141cc406Sopenharmony_ci } 1376141cc406Sopenharmony_ci 1377141cc406Sopenharmony_ci for (ii = 0; ii < 256; ii++) 1378141cc406Sopenharmony_ci { 1379141cc406Sopenharmony_ci if (hisgram_G[ii] > 0) 1380141cc406Sopenharmony_ci if (hisgram_G[ii] >= imin_threshold[1]) 1381141cc406Sopenharmony_ci { 1382141cc406Sopenharmony_ci min_G = ii; 1383141cc406Sopenharmony_ci break; 1384141cc406Sopenharmony_ci } 1385141cc406Sopenharmony_ci } 1386141cc406Sopenharmony_ci 1387141cc406Sopenharmony_ci for (ii = 255; ii >= 0; ii--) 1388141cc406Sopenharmony_ci { 1389141cc406Sopenharmony_ci if (hisgram_G[ii] > 0) 1390141cc406Sopenharmony_ci if (hisgram_G[ii] >= imax_threshold[1]) 1391141cc406Sopenharmony_ci { 1392141cc406Sopenharmony_ci max_G = ii; 1393141cc406Sopenharmony_ci break; 1394141cc406Sopenharmony_ci } 1395141cc406Sopenharmony_ci } 1396141cc406Sopenharmony_ci 1397141cc406Sopenharmony_ci for (ii = 0; ii < 256; ii++) 1398141cc406Sopenharmony_ci { 1399141cc406Sopenharmony_ci if (hisgram_B[ii] > 0) 1400141cc406Sopenharmony_ci if (hisgram_B[ii] >= imin_threshold[2]) 1401141cc406Sopenharmony_ci { 1402141cc406Sopenharmony_ci min_B = ii; 1403141cc406Sopenharmony_ci break; 1404141cc406Sopenharmony_ci } 1405141cc406Sopenharmony_ci } 1406141cc406Sopenharmony_ci 1407141cc406Sopenharmony_ci for (ii = 255; ii >= 0; ii--) 1408141cc406Sopenharmony_ci { 1409141cc406Sopenharmony_ci if (hisgram_B[ii] > 0) 1410141cc406Sopenharmony_ci if (hisgram_B[ii] >= imax_threshold[2]) 1411141cc406Sopenharmony_ci { 1412141cc406Sopenharmony_ci max_B = ii; 1413141cc406Sopenharmony_ci break; 1414141cc406Sopenharmony_ci } 1415141cc406Sopenharmony_ci } 1416141cc406Sopenharmony_ci 1417141cc406Sopenharmony_ci DBG (DBG_INFO, "AutoLevel: Set min , max is over!\n"); 1418141cc406Sopenharmony_ci 1419141cc406Sopenharmony_ci /*Autolevel: */ 1420141cc406Sopenharmony_ci sum_R = max_R - min_R; 1421141cc406Sopenharmony_ci sum_G = max_G - min_G; 1422141cc406Sopenharmony_ci sum_B = max_B - min_B; 1423141cc406Sopenharmony_ci 1424141cc406Sopenharmony_ci for (j = 0; j < iHeight; j++) 1425141cc406Sopenharmony_ci { 1426141cc406Sopenharmony_ci tLines = j * iWidth * 3; 1427141cc406Sopenharmony_ci for (i = 0; i < iWidth; i++) 1428141cc406Sopenharmony_ci { 1429141cc406Sopenharmony_ci R = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 2)); 1430141cc406Sopenharmony_ci G = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 1)); 1431141cc406Sopenharmony_ci B = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3)); 1432141cc406Sopenharmony_ci 1433141cc406Sopenharmony_ci /*R*/ if (sum_R == 0) 1434141cc406Sopenharmony_ci R = max_R; 1435141cc406Sopenharmony_ci else if (R < min_R) 1436141cc406Sopenharmony_ci R = 0; 1437141cc406Sopenharmony_ci else if (R <= 255) 1438141cc406Sopenharmony_ci { 1439141cc406Sopenharmony_ci fmax_R = ((float) ((R - min_R) * 255) / (float) sum_R); 1440141cc406Sopenharmony_ci R = (unsigned short) fmax_R; 1441141cc406Sopenharmony_ci fmax_R = (fmax_R - R) * 10; 1442141cc406Sopenharmony_ci 1443141cc406Sopenharmony_ci if (fmax_R >= 5) 1444141cc406Sopenharmony_ci R++; 1445141cc406Sopenharmony_ci } 1446141cc406Sopenharmony_ci if (R > 255) 1447141cc406Sopenharmony_ci R = 255; 1448141cc406Sopenharmony_ci 1449141cc406Sopenharmony_ci /*G*/ if (sum_G == 0) 1450141cc406Sopenharmony_ci G = max_G; 1451141cc406Sopenharmony_ci else if (G < min_G) 1452141cc406Sopenharmony_ci G = 0; 1453141cc406Sopenharmony_ci else if (G <= 255) 1454141cc406Sopenharmony_ci { 1455141cc406Sopenharmony_ci fmax_G = ((float) ((G - min_G) * 255) / (float) sum_G); 1456141cc406Sopenharmony_ci G = (unsigned short) fmax_G; 1457141cc406Sopenharmony_ci fmax_G = (fmax_G - G) * 10; 1458141cc406Sopenharmony_ci if (fmax_G >= 5) 1459141cc406Sopenharmony_ci G++; 1460141cc406Sopenharmony_ci 1461141cc406Sopenharmony_ci } 1462141cc406Sopenharmony_ci if (G > 255) 1463141cc406Sopenharmony_ci G = 255; 1464141cc406Sopenharmony_ci 1465141cc406Sopenharmony_ci /*B*/ if (sum_B == 0) 1466141cc406Sopenharmony_ci B = max_B; 1467141cc406Sopenharmony_ci else if (B < min_B) 1468141cc406Sopenharmony_ci B = 0; 1469141cc406Sopenharmony_ci else if (B <= 255) 1470141cc406Sopenharmony_ci { 1471141cc406Sopenharmony_ci fmax_B = ((float) (B - min_B) * 255 / (float) sum_B); 1472141cc406Sopenharmony_ci B = (unsigned short) fmax_B; 1473141cc406Sopenharmony_ci fmax_B = (fmax_B - B) * 10; 1474141cc406Sopenharmony_ci if (fmax_B >= 5) 1475141cc406Sopenharmony_ci B++; 1476141cc406Sopenharmony_ci } 1477141cc406Sopenharmony_ci if (B > 255) 1478141cc406Sopenharmony_ci B = 255; 1479141cc406Sopenharmony_ci 1480141cc406Sopenharmony_ci hisgram_R[(SANE_Byte) R]++; 1481141cc406Sopenharmony_ci hisgram_G[(SANE_Byte) G]++; 1482141cc406Sopenharmony_ci hisgram_B[(SANE_Byte) B]++; 1483141cc406Sopenharmony_ci 1484141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 2)) = (SANE_Byte) R; 1485141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 1)) = (SANE_Byte) G; 1486141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3)) = (SANE_Byte) B; 1487141cc406Sopenharmony_ci 1488141cc406Sopenharmony_ci } 1489141cc406Sopenharmony_ci } 1490141cc406Sopenharmony_ci 1491141cc406Sopenharmony_ci DBG (DBG_FUNC, "AutoLevel: exit\n"); 1492141cc406Sopenharmony_ci return; 1493141cc406Sopenharmony_ci} 1494141cc406Sopenharmony_ci 1495141cc406Sopenharmony_ci#ifdef SANE_UNUSED 1496141cc406Sopenharmony_ci/********************************************************************** 1497141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1498141cc406Sopenharmony_ciRoutine Description: 1499141cc406Sopenharmony_ci Deal with image with auto level 1500141cc406Sopenharmony_ciParameters: 1501141cc406Sopenharmony_ci pDIB: the data of image 1502141cc406Sopenharmony_ci ImageWidth: the width of image 1503141cc406Sopenharmony_ci ImageHeight: the height of image 1504141cc406Sopenharmony_ciReturn value: 1505141cc406Sopenharmony_ci none 1506141cc406Sopenharmony_ci***********************************************************************/ 1507141cc406Sopenharmony_cistatic void 1508141cc406Sopenharmony_ciQBETDetectAutoLevel (void *pDIB, unsigned int ImageWidth, unsigned int ImageHeight) 1509141cc406Sopenharmony_ci{ 1510141cc406Sopenharmony_ci unsigned short *pbmpdata; 1511141cc406Sopenharmony_ci float fRPercent = 0.0; 1512141cc406Sopenharmony_ci float fGPercent = 0.0; 1513141cc406Sopenharmony_ci float fBPercent = 0.0; 1514141cc406Sopenharmony_ci float fRSum, fGSum, fBSum; 1515141cc406Sopenharmony_ci 1516141cc406Sopenharmony_ci int i, j; 1517141cc406Sopenharmony_ci unsigned int tLines, CountPixels, TotalImgSize; 1518141cc406Sopenharmony_ci unsigned short R, G, B, max_R, max_G, max_B, min_R, min_G, min_B; 1519141cc406Sopenharmony_ci unsigned short wIndexR, wIndexG, wIndexB; 1520141cc406Sopenharmony_ci float fmax_R, fmax_G, fmax_B; 1521141cc406Sopenharmony_ci unsigned int sum_R = 0, sum_G = 0, sum_B = 0; 1522141cc406Sopenharmony_ci unsigned int hisgram_R[1024], hisgram_G[1024], hisgram_B[1024]; 1523141cc406Sopenharmony_ci 1524141cc406Sopenharmony_ci if (!pDIB) 1525141cc406Sopenharmony_ci { 1526141cc406Sopenharmony_ci return; 1527141cc406Sopenharmony_ci } 1528141cc406Sopenharmony_ci 1529141cc406Sopenharmony_ci pbmpdata = (unsigned short *) pDIB; 1530141cc406Sopenharmony_ci 1531141cc406Sopenharmony_ci CountPixels = 0; 1532141cc406Sopenharmony_ci TotalImgSize = ImageWidth * ImageHeight; 1533141cc406Sopenharmony_ci 1534141cc406Sopenharmony_ci 1535141cc406Sopenharmony_ci for (i = 0; i < 1024; i++) 1536141cc406Sopenharmony_ci { 1537141cc406Sopenharmony_ci 1538141cc406Sopenharmony_ci hisgram_R[i] = 0; 1539141cc406Sopenharmony_ci hisgram_G[i] = 0; 1540141cc406Sopenharmony_ci hisgram_B[i] = 0; 1541141cc406Sopenharmony_ci } 1542141cc406Sopenharmony_ci 1543141cc406Sopenharmony_ci 1544141cc406Sopenharmony_ci /*Find min , max, mean */ 1545141cc406Sopenharmony_ci max_R = max_G = max_B = 0; 1546141cc406Sopenharmony_ci min_R = min_G = min_B = 1023; 1547141cc406Sopenharmony_ci tLines = 0; 1548141cc406Sopenharmony_ci 1549141cc406Sopenharmony_ci for (j = 0; j < (int) ImageHeight; j++) 1550141cc406Sopenharmony_ci { 1551141cc406Sopenharmony_ci tLines = j * ImageWidth * 3; 1552141cc406Sopenharmony_ci for (i = 0; i < (int) ImageWidth; i++) 1553141cc406Sopenharmony_ci { 1554141cc406Sopenharmony_ci R = *(pbmpdata + (tLines + i * 3 + 2)); 1555141cc406Sopenharmony_ci G = *(pbmpdata + (tLines + i * 3 + 1)); 1556141cc406Sopenharmony_ci B = *(pbmpdata + (tLines + i * 3)); 1557141cc406Sopenharmony_ci 1558141cc406Sopenharmony_ci max_R = _MAX (R, max_R); 1559141cc406Sopenharmony_ci max_G = _MAX (G, max_G); 1560141cc406Sopenharmony_ci max_B = _MAX (B, max_B); 1561141cc406Sopenharmony_ci 1562141cc406Sopenharmony_ci min_R = _MIN (R, min_R); 1563141cc406Sopenharmony_ci min_G = _MIN (G, min_G); 1564141cc406Sopenharmony_ci min_B = _MIN (B, min_B); 1565141cc406Sopenharmony_ci 1566141cc406Sopenharmony_ci hisgram_R[R]++; 1567141cc406Sopenharmony_ci hisgram_G[G]++; 1568141cc406Sopenharmony_ci hisgram_B[B]++; 1569141cc406Sopenharmony_ci 1570141cc406Sopenharmony_ci sum_R += R; 1571141cc406Sopenharmony_ci sum_G += G; 1572141cc406Sopenharmony_ci sum_B += B; 1573141cc406Sopenharmony_ci 1574141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 2)) = R; 1575141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 1)) = G; 1576141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3)) = B; 1577141cc406Sopenharmony_ci 1578141cc406Sopenharmony_ci CountPixels++; 1579141cc406Sopenharmony_ci } 1580141cc406Sopenharmony_ci 1581141cc406Sopenharmony_ci } 1582141cc406Sopenharmony_ci 1583141cc406Sopenharmony_ci 1584141cc406Sopenharmony_ci fRSum = 0.0; 1585141cc406Sopenharmony_ci fGSum = 0.0; 1586141cc406Sopenharmony_ci fBSum = 0.0; 1587141cc406Sopenharmony_ci 1588141cc406Sopenharmony_ci wIndexR = 511; 1589141cc406Sopenharmony_ci wIndexG = 511; 1590141cc406Sopenharmony_ci wIndexB = 511; 1591141cc406Sopenharmony_ci 1592141cc406Sopenharmony_ci for (i = 0; i < 1024; i++) 1593141cc406Sopenharmony_ci { 1594141cc406Sopenharmony_ci fRSum += (float) hisgram_R[i]; 1595141cc406Sopenharmony_ci fRPercent = (fRSum / CountPixels) * 100; 1596141cc406Sopenharmony_ci if (fRPercent > 50) 1597141cc406Sopenharmony_ci { 1598141cc406Sopenharmony_ci wIndexR = i; 1599141cc406Sopenharmony_ci break; 1600141cc406Sopenharmony_ci } 1601141cc406Sopenharmony_ci 1602141cc406Sopenharmony_ci } 1603141cc406Sopenharmony_ci 1604141cc406Sopenharmony_ci for (i = 0; i < 1024; i++) 1605141cc406Sopenharmony_ci { 1606141cc406Sopenharmony_ci fGSum += (float) hisgram_G[i]; 1607141cc406Sopenharmony_ci fGPercent = (fGSum / CountPixels) * 100; 1608141cc406Sopenharmony_ci if (fGPercent > 50) 1609141cc406Sopenharmony_ci { 1610141cc406Sopenharmony_ci wIndexG = i; 1611141cc406Sopenharmony_ci break; 1612141cc406Sopenharmony_ci } 1613141cc406Sopenharmony_ci } 1614141cc406Sopenharmony_ci 1615141cc406Sopenharmony_ci for (i = 0; i < 1024; i++) 1616141cc406Sopenharmony_ci { 1617141cc406Sopenharmony_ci fBSum += (float) hisgram_B[i]; 1618141cc406Sopenharmony_ci fBPercent = (fBSum / CountPixels) * 100; 1619141cc406Sopenharmony_ci if (fBPercent > 50) 1620141cc406Sopenharmony_ci { 1621141cc406Sopenharmony_ci wIndexB = i; 1622141cc406Sopenharmony_ci break; 1623141cc406Sopenharmony_ci } 1624141cc406Sopenharmony_ci 1625141cc406Sopenharmony_ci } 1626141cc406Sopenharmony_ci 1627141cc406Sopenharmony_ci 1628141cc406Sopenharmony_ci fRSum = 0.0; 1629141cc406Sopenharmony_ci 1630141cc406Sopenharmony_ci for (i = wIndexR; i >= 0; i--) 1631141cc406Sopenharmony_ci { 1632141cc406Sopenharmony_ci fRSum += (float) hisgram_R[i]; 1633141cc406Sopenharmony_ci fRPercent = (fRSum / CountPixels) * 100; 1634141cc406Sopenharmony_ci if (fRPercent >= 48) 1635141cc406Sopenharmony_ci { 1636141cc406Sopenharmony_ci min_R = i; 1637141cc406Sopenharmony_ci break; 1638141cc406Sopenharmony_ci } 1639141cc406Sopenharmony_ci 1640141cc406Sopenharmony_ci } 1641141cc406Sopenharmony_ci 1642141cc406Sopenharmony_ci fRSum = 0.0; 1643141cc406Sopenharmony_ci for (i = wIndexR; i < 1024; i++) 1644141cc406Sopenharmony_ci { 1645141cc406Sopenharmony_ci fRSum += (float) hisgram_R[i]; 1646141cc406Sopenharmony_ci fRPercent = (fRSum / CountPixels) * 100; 1647141cc406Sopenharmony_ci if (fRPercent >= 47) 1648141cc406Sopenharmony_ci { 1649141cc406Sopenharmony_ci max_R = i; 1650141cc406Sopenharmony_ci break; 1651141cc406Sopenharmony_ci } 1652141cc406Sopenharmony_ci 1653141cc406Sopenharmony_ci } 1654141cc406Sopenharmony_ci 1655141cc406Sopenharmony_ci 1656141cc406Sopenharmony_ci fGSum = 0.0; 1657141cc406Sopenharmony_ci for (i = wIndexG; i >= 0; i--) 1658141cc406Sopenharmony_ci { 1659141cc406Sopenharmony_ci fGSum += (float) hisgram_G[i]; 1660141cc406Sopenharmony_ci fGPercent = (fGSum / CountPixels) * 100; 1661141cc406Sopenharmony_ci if (fGPercent >= 48) 1662141cc406Sopenharmony_ci { 1663141cc406Sopenharmony_ci min_G = i; 1664141cc406Sopenharmony_ci break; 1665141cc406Sopenharmony_ci } 1666141cc406Sopenharmony_ci 1667141cc406Sopenharmony_ci } 1668141cc406Sopenharmony_ci 1669141cc406Sopenharmony_ci fGSum = 0.0; 1670141cc406Sopenharmony_ci for (i = wIndexG; i < 1024; i++) 1671141cc406Sopenharmony_ci { 1672141cc406Sopenharmony_ci fGSum += (float) hisgram_G[i]; 1673141cc406Sopenharmony_ci fGPercent = (fGSum / CountPixels) * 100; 1674141cc406Sopenharmony_ci if (fGPercent >= 47) 1675141cc406Sopenharmony_ci { 1676141cc406Sopenharmony_ci max_G = i; 1677141cc406Sopenharmony_ci break; 1678141cc406Sopenharmony_ci } 1679141cc406Sopenharmony_ci 1680141cc406Sopenharmony_ci } 1681141cc406Sopenharmony_ci 1682141cc406Sopenharmony_ci fBSum = 0.0; 1683141cc406Sopenharmony_ci for (i = wIndexB; i >= 0; i--) 1684141cc406Sopenharmony_ci { 1685141cc406Sopenharmony_ci fBSum += (float) hisgram_B[i]; 1686141cc406Sopenharmony_ci fBPercent = (fBSum / CountPixels) * 100; 1687141cc406Sopenharmony_ci if (fBPercent >= 46) 1688141cc406Sopenharmony_ci { 1689141cc406Sopenharmony_ci min_B = i; 1690141cc406Sopenharmony_ci break; 1691141cc406Sopenharmony_ci } 1692141cc406Sopenharmony_ci 1693141cc406Sopenharmony_ci } 1694141cc406Sopenharmony_ci 1695141cc406Sopenharmony_ci fBSum = 0.0; 1696141cc406Sopenharmony_ci for (i = wIndexB; i < 1024; i++) 1697141cc406Sopenharmony_ci { 1698141cc406Sopenharmony_ci fBSum += (float) hisgram_B[i]; 1699141cc406Sopenharmony_ci fBPercent = (fBSum / CountPixels) * 100; 1700141cc406Sopenharmony_ci if (fBPercent >= 47) 1701141cc406Sopenharmony_ci { 1702141cc406Sopenharmony_ci max_B = i; 1703141cc406Sopenharmony_ci break; 1704141cc406Sopenharmony_ci } 1705141cc406Sopenharmony_ci 1706141cc406Sopenharmony_ci } 1707141cc406Sopenharmony_ci 1708141cc406Sopenharmony_ci 1709141cc406Sopenharmony_ci /*Autolevel: */ 1710141cc406Sopenharmony_ci sum_R = max_R - min_R; 1711141cc406Sopenharmony_ci sum_G = max_G - min_G; 1712141cc406Sopenharmony_ci sum_B = max_B - min_B; 1713141cc406Sopenharmony_ci 1714141cc406Sopenharmony_ci for (j = 0; j < (int) ImageHeight; j++) 1715141cc406Sopenharmony_ci { 1716141cc406Sopenharmony_ci tLines = j * ImageWidth * 3; 1717141cc406Sopenharmony_ci for (i = 0; i < (int) ImageWidth; i++) 1718141cc406Sopenharmony_ci { 1719141cc406Sopenharmony_ci R = *(pbmpdata + (tLines + i * 3 + 2)); 1720141cc406Sopenharmony_ci G = *(pbmpdata + (tLines + i * 3 + 1)); 1721141cc406Sopenharmony_ci B = *(pbmpdata + (tLines + i * 3)); 1722141cc406Sopenharmony_ci 1723141cc406Sopenharmony_ci 1724141cc406Sopenharmony_ci /*R*/ if (sum_R == 0) 1725141cc406Sopenharmony_ci R = max_R; 1726141cc406Sopenharmony_ci else if (R < min_R) 1727141cc406Sopenharmony_ci { 1728141cc406Sopenharmony_ci 1729141cc406Sopenharmony_ci R = 0; 1730141cc406Sopenharmony_ci } 1731141cc406Sopenharmony_ci else if ((R >= min_R) && (R <= 1023)) 1732141cc406Sopenharmony_ci { 1733141cc406Sopenharmony_ci fmax_R = ((float) ((R - min_R) * 923) / (float) sum_R) + 100; 1734141cc406Sopenharmony_ci R = (unsigned short) fmax_R; 1735141cc406Sopenharmony_ci fmax_R = (fmax_R - R) * 10; 1736141cc406Sopenharmony_ci if (fmax_R >= 5) 1737141cc406Sopenharmony_ci R++; 1738141cc406Sopenharmony_ci } 1739141cc406Sopenharmony_ci if (R > 1023) 1740141cc406Sopenharmony_ci R = 1023; 1741141cc406Sopenharmony_ci 1742141cc406Sopenharmony_ci /*G*/ if (sum_G == 0) 1743141cc406Sopenharmony_ci G = max_G; 1744141cc406Sopenharmony_ci else if (G < min_G) 1745141cc406Sopenharmony_ci { 1746141cc406Sopenharmony_ci 1747141cc406Sopenharmony_ci G = 0; 1748141cc406Sopenharmony_ci } 1749141cc406Sopenharmony_ci else if ((G >= min_G) && (G <= 1023)) 1750141cc406Sopenharmony_ci { 1751141cc406Sopenharmony_ci fmax_G = ((float) ((G - min_G) * 923) / (float) sum_G) + 100; 1752141cc406Sopenharmony_ci G = (unsigned short) fmax_G; 1753141cc406Sopenharmony_ci fmax_G = (fmax_G - G) * 10; 1754141cc406Sopenharmony_ci if (fmax_G >= 5) 1755141cc406Sopenharmony_ci G++; 1756141cc406Sopenharmony_ci } 1757141cc406Sopenharmony_ci if (G > 1023) 1758141cc406Sopenharmony_ci G = 1023; 1759141cc406Sopenharmony_ci 1760141cc406Sopenharmony_ci /*B*/ if (sum_B == 0) 1761141cc406Sopenharmony_ci B = max_B; 1762141cc406Sopenharmony_ci else if (B < min_R) 1763141cc406Sopenharmony_ci { 1764141cc406Sopenharmony_ci 1765141cc406Sopenharmony_ci B = 0; 1766141cc406Sopenharmony_ci } 1767141cc406Sopenharmony_ci else if ((B >= min_B) && (R <= 1023)) 1768141cc406Sopenharmony_ci { 1769141cc406Sopenharmony_ci fmax_B = ((float) (B - min_B) * 923 / (float) sum_B) + 100; 1770141cc406Sopenharmony_ci 1771141cc406Sopenharmony_ci B = (unsigned short) fmax_B; 1772141cc406Sopenharmony_ci fmax_B = (fmax_B - B) * 10; 1773141cc406Sopenharmony_ci if (fmax_B >= 5) 1774141cc406Sopenharmony_ci B++; 1775141cc406Sopenharmony_ci } 1776141cc406Sopenharmony_ci if (B > 1023) 1777141cc406Sopenharmony_ci B = 1023; 1778141cc406Sopenharmony_ci 1779141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 2)) = R; 1780141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 1)) = G; 1781141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3)) = B; 1782141cc406Sopenharmony_ci 1783141cc406Sopenharmony_ci } 1784141cc406Sopenharmony_ci } 1785141cc406Sopenharmony_ci 1786141cc406Sopenharmony_ci return; 1787141cc406Sopenharmony_ci} 1788141cc406Sopenharmony_ci#endif 1789141cc406Sopenharmony_ci 1790141cc406Sopenharmony_ci#ifdef SANE_UNUSED 1791141cc406Sopenharmony_ci/********************************************************************** 1792141cc406Sopenharmony_ciAuthor: Jack Date: 2005/05/14 1793141cc406Sopenharmony_ciRoutine Description: 1794141cc406Sopenharmony_ci Change the image data and deal with auto level 1795141cc406Sopenharmony_ciParameters: 1796141cc406Sopenharmony_ci lpSource: the data of image 1797141cc406Sopenharmony_ci scanMode: the scan mode 1798141cc406Sopenharmony_ci ScanLines: the rows of image 1799141cc406Sopenharmony_ci BytesPerLine: the bytes of per line 1800141cc406Sopenharmony_ciReturn value: 1801141cc406Sopenharmony_ci none 1802141cc406Sopenharmony_ci***********************************************************************/ 1803141cc406Sopenharmony_cistatic void 1804141cc406Sopenharmony_ciQBetChange (SANE_Byte *lpSource, SCANMODE scanMode, unsigned short ScanLines, 1805141cc406Sopenharmony_ci unsigned int BytesPerLine) 1806141cc406Sopenharmony_ci{ 1807141cc406Sopenharmony_ci unsigned short i, j; 1808141cc406Sopenharmony_ci unsigned int tLines, TotalImgSize; 1809141cc406Sopenharmony_ci unsigned short R1, G1, B1, R, G, B, R2, G2, B2, QBET_RGB = 0, PointF, PointB; 1810141cc406Sopenharmony_ci unsigned short *pwRGB; 1811141cc406Sopenharmony_ci 1812141cc406Sopenharmony_ci int k; 1813141cc406Sopenharmony_ci 1814141cc406Sopenharmony_ci unsigned int ImageWidth = BytesPerLine / 3; 1815141cc406Sopenharmony_ci unsigned int ImageHeight = ScanLines; 1816141cc406Sopenharmony_ci SANE_Byte *pbmpdata = (SANE_Byte *) lpSource; 1817141cc406Sopenharmony_ci 1818141cc406Sopenharmony_ci if (scanMode != CM_RGB24ext) 1819141cc406Sopenharmony_ci { 1820141cc406Sopenharmony_ci return; 1821141cc406Sopenharmony_ci } 1822141cc406Sopenharmony_ci 1823141cc406Sopenharmony_ci 1824141cc406Sopenharmony_ci TotalImgSize = ImageWidth * ImageHeight * 3 * 2; 1825141cc406Sopenharmony_ci if ((pwRGB = (unsigned short *) malloc (TotalImgSize)) == NULL) 1826141cc406Sopenharmony_ci { 1827141cc406Sopenharmony_ci return; 1828141cc406Sopenharmony_ci } 1829141cc406Sopenharmony_ci 1830141cc406Sopenharmony_ci 1831141cc406Sopenharmony_ci for (j = 0; j < ImageHeight; j++) 1832141cc406Sopenharmony_ci { 1833141cc406Sopenharmony_ci tLines = j * ImageWidth * 3; 1834141cc406Sopenharmony_ci for (i = 0; i < ImageWidth; i++) 1835141cc406Sopenharmony_ci { 1836141cc406Sopenharmony_ci if (i == 0) 1837141cc406Sopenharmony_ci { 1838141cc406Sopenharmony_ci R1 = R = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 2)); 1839141cc406Sopenharmony_ci G1 = G = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 1)); 1840141cc406Sopenharmony_ci B1 = B = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3)); 1841141cc406Sopenharmony_ci R2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3 + 2)); 1842141cc406Sopenharmony_ci G2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3 + 1)); 1843141cc406Sopenharmony_ci B2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3)); 1844141cc406Sopenharmony_ci } 1845141cc406Sopenharmony_ci else if (i == (ImageWidth - 1)) 1846141cc406Sopenharmony_ci { 1847141cc406Sopenharmony_ci R1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3 + 2)); 1848141cc406Sopenharmony_ci G1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3 + 1)); 1849141cc406Sopenharmony_ci B1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3)); 1850141cc406Sopenharmony_ci R2 = R = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 2)); 1851141cc406Sopenharmony_ci G2 = G = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 1)); 1852141cc406Sopenharmony_ci B2 = B = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3)); 1853141cc406Sopenharmony_ci } 1854141cc406Sopenharmony_ci else 1855141cc406Sopenharmony_ci { 1856141cc406Sopenharmony_ci R1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3 + 2)); 1857141cc406Sopenharmony_ci G1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3 + 1)); 1858141cc406Sopenharmony_ci B1 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i - 1) * 3)); 1859141cc406Sopenharmony_ci 1860141cc406Sopenharmony_ci R = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 2)); 1861141cc406Sopenharmony_ci G = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3 + 1)); 1862141cc406Sopenharmony_ci B = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + i * 3)); 1863141cc406Sopenharmony_ci 1864141cc406Sopenharmony_ci R2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3 + 2)); 1865141cc406Sopenharmony_ci G2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3 + 1)); 1866141cc406Sopenharmony_ci B2 = (unsigned short) (SANE_Byte) * (pbmpdata + (tLines + (i + 1) * 3)); 1867141cc406Sopenharmony_ci } 1868141cc406Sopenharmony_ci 1869141cc406Sopenharmony_ci R1 = R1 & 0x0003; 1870141cc406Sopenharmony_ci G1 = G1 & 0x0003; 1871141cc406Sopenharmony_ci B1 = B1 & 0x0003; 1872141cc406Sopenharmony_ci 1873141cc406Sopenharmony_ci R2 = R2 & 0x0003; 1874141cc406Sopenharmony_ci G2 = G2 & 0x0003; 1875141cc406Sopenharmony_ci B2 = B2 & 0x0003; 1876141cc406Sopenharmony_ci for (k = 0; k < 3; k++) 1877141cc406Sopenharmony_ci { 1878141cc406Sopenharmony_ci if (k == 0) 1879141cc406Sopenharmony_ci { 1880141cc406Sopenharmony_ci PointF = R1; 1881141cc406Sopenharmony_ci PointB = R2; 1882141cc406Sopenharmony_ci } 1883141cc406Sopenharmony_ci else if (k == 1) 1884141cc406Sopenharmony_ci { 1885141cc406Sopenharmony_ci PointF = G1; 1886141cc406Sopenharmony_ci PointB = G2; 1887141cc406Sopenharmony_ci } 1888141cc406Sopenharmony_ci else if (k == 2) 1889141cc406Sopenharmony_ci { 1890141cc406Sopenharmony_ci PointF = B1; 1891141cc406Sopenharmony_ci PointB = B2; 1892141cc406Sopenharmony_ci } 1893141cc406Sopenharmony_ci 1894141cc406Sopenharmony_ci switch (PointF) 1895141cc406Sopenharmony_ci { 1896141cc406Sopenharmony_ci case 0: 1897141cc406Sopenharmony_ci case 1: 1898141cc406Sopenharmony_ci if (PointB == 0) 1899141cc406Sopenharmony_ci QBET_RGB = 0xFFFC; 1900141cc406Sopenharmony_ci else if (PointB == 1) 1901141cc406Sopenharmony_ci QBET_RGB = 0xFFFC; 1902141cc406Sopenharmony_ci else if (PointB == 2) 1903141cc406Sopenharmony_ci QBET_RGB = 0xFFFD; 1904141cc406Sopenharmony_ci else if (PointB == 3) 1905141cc406Sopenharmony_ci QBET_RGB = 0xFFFE; 1906141cc406Sopenharmony_ci break; 1907141cc406Sopenharmony_ci case 2: 1908141cc406Sopenharmony_ci if (PointB == 0) 1909141cc406Sopenharmony_ci QBET_RGB = 0xFFFD; 1910141cc406Sopenharmony_ci else if (PointB == 1) 1911141cc406Sopenharmony_ci QBET_RGB = 0xFFFD; 1912141cc406Sopenharmony_ci else if (PointB == 2) 1913141cc406Sopenharmony_ci QBET_RGB = 0xFFFF; 1914141cc406Sopenharmony_ci else if (PointB == 3) 1915141cc406Sopenharmony_ci QBET_RGB = 0xFFFF; 1916141cc406Sopenharmony_ci break; 1917141cc406Sopenharmony_ci case 3: 1918141cc406Sopenharmony_ci if (PointB == 0) 1919141cc406Sopenharmony_ci QBET_RGB = 0xFFFE; 1920141cc406Sopenharmony_ci else if (PointB == 1) 1921141cc406Sopenharmony_ci QBET_RGB = 0xFFFE; 1922141cc406Sopenharmony_ci else if (PointB == 2) 1923141cc406Sopenharmony_ci QBET_RGB = 0xFFFF; 1924141cc406Sopenharmony_ci else if (PointB == 3) 1925141cc406Sopenharmony_ci QBET_RGB = 0xFFFF; 1926141cc406Sopenharmony_ci break; 1927141cc406Sopenharmony_ci default: 1928141cc406Sopenharmony_ci break; 1929141cc406Sopenharmony_ci } 1930141cc406Sopenharmony_ci 1931141cc406Sopenharmony_ci if (k == 0) 1932141cc406Sopenharmony_ci { 1933141cc406Sopenharmony_ci R = R << 2; 1934141cc406Sopenharmony_ci R = R + 0x0003; 1935141cc406Sopenharmony_ci R = R & QBET_RGB; 1936141cc406Sopenharmony_ci } 1937141cc406Sopenharmony_ci else if (k == 1) 1938141cc406Sopenharmony_ci { 1939141cc406Sopenharmony_ci G = G << 2; 1940141cc406Sopenharmony_ci G = G + 0x0003; 1941141cc406Sopenharmony_ci G = G & QBET_RGB; 1942141cc406Sopenharmony_ci } 1943141cc406Sopenharmony_ci else if (k == 2) 1944141cc406Sopenharmony_ci { 1945141cc406Sopenharmony_ci B = B << 2; 1946141cc406Sopenharmony_ci B = B + 0x0003; 1947141cc406Sopenharmony_ci B = B & QBET_RGB; 1948141cc406Sopenharmony_ci } 1949141cc406Sopenharmony_ci 1950141cc406Sopenharmony_ci } 1951141cc406Sopenharmony_ci 1952141cc406Sopenharmony_ci *(pwRGB + (tLines + i * 3 + 2)) = R; 1953141cc406Sopenharmony_ci *(pwRGB + (tLines + i * 3 + 1)) = G; 1954141cc406Sopenharmony_ci *(pwRGB + (tLines + i * 3)) = B; 1955141cc406Sopenharmony_ci 1956141cc406Sopenharmony_ci } 1957141cc406Sopenharmony_ci 1958141cc406Sopenharmony_ci } 1959141cc406Sopenharmony_ci 1960141cc406Sopenharmony_ci 1961141cc406Sopenharmony_ci QBETDetectAutoLevel (pwRGB, ImageWidth, ImageHeight); 1962141cc406Sopenharmony_ci 1963141cc406Sopenharmony_ci 1964141cc406Sopenharmony_ci for (j = 0; j < ImageHeight; j++) 1965141cc406Sopenharmony_ci { 1966141cc406Sopenharmony_ci tLines = j * ImageWidth * 3; 1967141cc406Sopenharmony_ci 1968141cc406Sopenharmony_ci for (i = 0; i < ImageWidth; i++) 1969141cc406Sopenharmony_ci { 1970141cc406Sopenharmony_ci R = *(pwRGB + (tLines + i * 3 + 2)); 1971141cc406Sopenharmony_ci G = *(pwRGB + (tLines + i * 3 + 1)); 1972141cc406Sopenharmony_ci B = *(pwRGB + (tLines + i * 3)); 1973141cc406Sopenharmony_ci 1974141cc406Sopenharmony_ci R = R >> 2; 1975141cc406Sopenharmony_ci G = G >> 2; 1976141cc406Sopenharmony_ci 1977141cc406Sopenharmony_ci B = B >> 2; 1978141cc406Sopenharmony_ci if (R > 255) 1979141cc406Sopenharmony_ci R = 255; 1980141cc406Sopenharmony_ci if (G > 255) 1981141cc406Sopenharmony_ci G = 255; 1982141cc406Sopenharmony_ci if (B > 255) 1983141cc406Sopenharmony_ci B = 255; 1984141cc406Sopenharmony_ci 1985141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 2)) = (SANE_Byte) R; 1986141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3 + 1)) = (SANE_Byte) G; 1987141cc406Sopenharmony_ci *(pbmpdata + (tLines + i * 3)) = (SANE_Byte) B; 1988141cc406Sopenharmony_ci 1989141cc406Sopenharmony_ci } 1990141cc406Sopenharmony_ci 1991141cc406Sopenharmony_ci } 1992141cc406Sopenharmony_ci 1993141cc406Sopenharmony_ci 1994141cc406Sopenharmony_ci if (pwRGB != NULL) 1995141cc406Sopenharmony_ci { 1996141cc406Sopenharmony_ci free (pwRGB); 1997141cc406Sopenharmony_ci } 1998141cc406Sopenharmony_ci 1999141cc406Sopenharmony_ci return; 2000141cc406Sopenharmony_ci} 2001141cc406Sopenharmony_ci#endif 2002141cc406Sopenharmony_ci 2003141cc406Sopenharmony_ci/****************************** SANE API functions *****************************/ 2004141cc406Sopenharmony_ci 2005141cc406Sopenharmony_ciSANE_Status 2006141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 2007141cc406Sopenharmony_ci{ 2008141cc406Sopenharmony_ci DBG_INIT (); 2009141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_init: start\n"); 2010141cc406Sopenharmony_ci DBG (DBG_ERR, "SANE Mustek USB2 backend version %d.%d build %d from %s\n", 2011141cc406Sopenharmony_ci SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 2012141cc406Sopenharmony_ci 2013141cc406Sopenharmony_ci num_devices = 1; /* HOLD: only one device in this backend */ 2014141cc406Sopenharmony_ci 2015141cc406Sopenharmony_ci if (version_code != NULL) 2016141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 2017141cc406Sopenharmony_ci 2018141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_init: authorize %s null\n", authorize ? "!=" : "=="); 2019141cc406Sopenharmony_ci 2020141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_init: exit\n"); 2021141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2022141cc406Sopenharmony_ci} 2023141cc406Sopenharmony_ci 2024141cc406Sopenharmony_civoid 2025141cc406Sopenharmony_cisane_exit (void) 2026141cc406Sopenharmony_ci{ 2027141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_exit: start\n"); 2028141cc406Sopenharmony_ci 2029141cc406Sopenharmony_ci if (devlist != NULL) 2030141cc406Sopenharmony_ci { 2031141cc406Sopenharmony_ci free (devlist); 2032141cc406Sopenharmony_ci devlist = NULL; 2033141cc406Sopenharmony_ci } 2034141cc406Sopenharmony_ci 2035141cc406Sopenharmony_ci devlist = NULL; 2036141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_exit: exit\n"); 2037141cc406Sopenharmony_ci} 2038141cc406Sopenharmony_ci 2039141cc406Sopenharmony_ciSANE_Status 2040141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 2041141cc406Sopenharmony_ci{ 2042141cc406Sopenharmony_ci SANE_Int dev_num; 2043141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_devices: start: local_only = %s\n", 2044141cc406Sopenharmony_ci local_only == SANE_TRUE ? "true" : "false"); 2045141cc406Sopenharmony_ci 2046141cc406Sopenharmony_ci if (devlist != NULL) 2047141cc406Sopenharmony_ci { 2048141cc406Sopenharmony_ci free (devlist); 2049141cc406Sopenharmony_ci devlist = NULL; 2050141cc406Sopenharmony_ci } 2051141cc406Sopenharmony_ci 2052141cc406Sopenharmony_ci devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 2053141cc406Sopenharmony_ci if (devlist == NULL) 2054141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2055141cc406Sopenharmony_ci 2056141cc406Sopenharmony_ci dev_num = 0; 2057141cc406Sopenharmony_ci /* HOLD: This is ugly (only one scanner!) and should go to sane_init */ 2058141cc406Sopenharmony_ci if (GetDeviceStatus ()) 2059141cc406Sopenharmony_ci { 2060141cc406Sopenharmony_ci SANE_Device *sane_device; 2061141cc406Sopenharmony_ci 2062141cc406Sopenharmony_ci sane_device = malloc (sizeof (*sane_device)); 2063141cc406Sopenharmony_ci if (sane_device == NULL) 2064141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2065141cc406Sopenharmony_ci sane_device->name = strdup (device_name); 2066141cc406Sopenharmony_ci sane_device->vendor = strdup ("Mustek"); 2067141cc406Sopenharmony_ci sane_device->model = strdup ("BearPaw 2448 TA Pro"); 2068141cc406Sopenharmony_ci sane_device->type = strdup ("flatbed scanner"); 2069141cc406Sopenharmony_ci devlist[dev_num++] = sane_device; 2070141cc406Sopenharmony_ci } 2071141cc406Sopenharmony_ci devlist[dev_num] = 0; 2072141cc406Sopenharmony_ci *device_list = devlist; 2073141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_devices: exit\n"); 2074141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2075141cc406Sopenharmony_ci} 2076141cc406Sopenharmony_ci 2077141cc406Sopenharmony_ciSANE_Status 2078141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle * handle) 2079141cc406Sopenharmony_ci{ 2080141cc406Sopenharmony_ci Mustek_Scanner *s; 2081141cc406Sopenharmony_ci 2082141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_open: start :devicename = %s\n", devicename); 2083141cc406Sopenharmony_ci 2084141cc406Sopenharmony_ci if (!MustScanner_Init ()) 2085141cc406Sopenharmony_ci { 2086141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2087141cc406Sopenharmony_ci } 2088141cc406Sopenharmony_ci if (!PowerControl (SANE_FALSE, SANE_FALSE)) 2089141cc406Sopenharmony_ci { 2090141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2091141cc406Sopenharmony_ci } 2092141cc406Sopenharmony_ci if (!CarriageHome ()) 2093141cc406Sopenharmony_ci { 2094141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2095141cc406Sopenharmony_ci } 2096141cc406Sopenharmony_ci 2097141cc406Sopenharmony_ci s = malloc (sizeof (*s)); 2098141cc406Sopenharmony_ci if (s == NULL) 2099141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2100141cc406Sopenharmony_ci memset (s, 0, sizeof (*s)); 2101141cc406Sopenharmony_ci 2102141cc406Sopenharmony_ci s->gamma_table = NULL; 2103141cc406Sopenharmony_ci memcpy (&s->model, &mustek_A2nu2_model, sizeof (Scanner_Model)); 2104141cc406Sopenharmony_ci s->next = NULL; 2105141cc406Sopenharmony_ci s->bIsScanning = SANE_FALSE; 2106141cc406Sopenharmony_ci s->bIsReading = SANE_FALSE; 2107141cc406Sopenharmony_ci 2108141cc406Sopenharmony_ci init_options (s); 2109141cc406Sopenharmony_ci *handle = s; 2110141cc406Sopenharmony_ci 2111141cc406Sopenharmony_ci s->read_rows = 0; 2112141cc406Sopenharmony_ci s->scan_buffer_len = 0; 2113141cc406Sopenharmony_ci 2114141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_open: exit\n"); 2115141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2116141cc406Sopenharmony_ci} 2117141cc406Sopenharmony_ci 2118141cc406Sopenharmony_ci 2119141cc406Sopenharmony_civoid 2120141cc406Sopenharmony_cisane_close (SANE_Handle handle) 2121141cc406Sopenharmony_ci{ 2122141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2123141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_close: start\n"); 2124141cc406Sopenharmony_ci 2125141cc406Sopenharmony_ci PowerControl (SANE_FALSE, SANE_FALSE); 2126141cc406Sopenharmony_ci 2127141cc406Sopenharmony_ci CarriageHome (); 2128141cc406Sopenharmony_ci 2129141cc406Sopenharmony_ci if (NULL != g_pDeviceFile) 2130141cc406Sopenharmony_ci { 2131141cc406Sopenharmony_ci free (g_pDeviceFile); 2132141cc406Sopenharmony_ci g_pDeviceFile = NULL; 2133141cc406Sopenharmony_ci } 2134141cc406Sopenharmony_ci 2135141cc406Sopenharmony_ci if (s->Scan_data_buf != NULL) 2136141cc406Sopenharmony_ci free (s->Scan_data_buf); 2137141cc406Sopenharmony_ci 2138141cc406Sopenharmony_ci s->Scan_data_buf = NULL; 2139141cc406Sopenharmony_ci 2140141cc406Sopenharmony_ci free (handle); 2141141cc406Sopenharmony_ci 2142141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_close: exit\n"); 2143141cc406Sopenharmony_ci} 2144141cc406Sopenharmony_ci 2145141cc406Sopenharmony_ci 2146141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 2147141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 2148141cc406Sopenharmony_ci{ 2149141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2150141cc406Sopenharmony_ci 2151141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 2152141cc406Sopenharmony_ci return 0; 2153141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_option_descriptor: option = %s (%d)\n", 2154141cc406Sopenharmony_ci s->opt[option].name, option); 2155141cc406Sopenharmony_ci return s->opt + option; 2156141cc406Sopenharmony_ci} 2157141cc406Sopenharmony_ci 2158141cc406Sopenharmony_ci 2159141cc406Sopenharmony_ciSANE_Status 2160141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 2161141cc406Sopenharmony_ci SANE_Action action, void *val, SANE_Int * info) 2162141cc406Sopenharmony_ci{ 2163141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2164141cc406Sopenharmony_ci SANE_Status status; 2165141cc406Sopenharmony_ci SANE_Word cap; 2166141cc406Sopenharmony_ci SANE_Int myinfo = 0; 2167141cc406Sopenharmony_ci 2168141cc406Sopenharmony_ci DBG (DBG_FUNC, 2169141cc406Sopenharmony_ci "sane_control_option: start: action = %s, option = %s (%d)\n", 2170141cc406Sopenharmony_ci (action == SANE_ACTION_GET_VALUE) ? "get" : (action == 2171141cc406Sopenharmony_ci SANE_ACTION_SET_VALUE) ? 2172141cc406Sopenharmony_ci "set" : (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown", 2173141cc406Sopenharmony_ci s->opt[option].name, option); 2174141cc406Sopenharmony_ci 2175141cc406Sopenharmony_ci 2176141cc406Sopenharmony_ci if (info) 2177141cc406Sopenharmony_ci *info = 0; 2178141cc406Sopenharmony_ci 2179141cc406Sopenharmony_ci if (s->bIsScanning) 2180141cc406Sopenharmony_ci { 2181141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: don't call this function while " 2182141cc406Sopenharmony_ci "scanning\n"); 2183141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 2184141cc406Sopenharmony_ci } 2185141cc406Sopenharmony_ci if (option >= NUM_OPTIONS || option < 0) 2186141cc406Sopenharmony_ci { 2187141cc406Sopenharmony_ci DBG (DBG_ERR, 2188141cc406Sopenharmony_ci "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n", 2189141cc406Sopenharmony_ci option); 2190141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2191141cc406Sopenharmony_ci } 2192141cc406Sopenharmony_ci 2193141cc406Sopenharmony_ci cap = s->opt[option].cap; 2194141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 2195141cc406Sopenharmony_ci { 2196141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: option %d is inactive\n", option); 2197141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2198141cc406Sopenharmony_ci } 2199141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 2200141cc406Sopenharmony_ci { 2201141cc406Sopenharmony_ci switch (option) 2202141cc406Sopenharmony_ci { 2203141cc406Sopenharmony_ci /* word options: */ 2204141cc406Sopenharmony_ci case OPT_NUM_OPTS: 2205141cc406Sopenharmony_ci case OPT_RESOLUTION: 2206141cc406Sopenharmony_ci case OPT_PREVIEW: 2207141cc406Sopenharmony_ci case OPT_AUTO_WARMUP: 2208141cc406Sopenharmony_ci case OPT_GAMMA_VALUE: 2209141cc406Sopenharmony_ci case OPT_THRESHOLD: 2210141cc406Sopenharmony_ci case OPT_TL_X: 2211141cc406Sopenharmony_ci case OPT_TL_Y: 2212141cc406Sopenharmony_ci case OPT_BR_X: 2213141cc406Sopenharmony_ci case OPT_BR_Y: 2214141cc406Sopenharmony_ci *(SANE_Word *) val = s->val[option].w; 2215141cc406Sopenharmony_ci break; 2216141cc406Sopenharmony_ci /* string options: */ 2217141cc406Sopenharmony_ci case OPT_MODE: 2218141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 2219141cc406Sopenharmony_ci break; 2220141cc406Sopenharmony_ci 2221141cc406Sopenharmony_ci case OPT_SOURCE: 2222141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 2223141cc406Sopenharmony_ci break; 2224141cc406Sopenharmony_ci default: 2225141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: can't get unknown option %d\n", 2226141cc406Sopenharmony_ci option); 2227141cc406Sopenharmony_ci ; 2228141cc406Sopenharmony_ci } 2229141cc406Sopenharmony_ci } 2230141cc406Sopenharmony_ci else if (action == SANE_ACTION_SET_VALUE) 2231141cc406Sopenharmony_ci { 2232141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 2233141cc406Sopenharmony_ci { 2234141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: option %d is not settable\n", 2235141cc406Sopenharmony_ci option); 2236141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2237141cc406Sopenharmony_ci } 2238141cc406Sopenharmony_ci 2239141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, val, &myinfo); 2240141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2241141cc406Sopenharmony_ci { 2242141cc406Sopenharmony_ci DBG (2, "sane_control_option: sanei_constrain_value returned %s\n", 2243141cc406Sopenharmony_ci sane_strstatus (status)); 2244141cc406Sopenharmony_ci return status; 2245141cc406Sopenharmony_ci } 2246141cc406Sopenharmony_ci 2247141cc406Sopenharmony_ci switch (option) 2248141cc406Sopenharmony_ci { 2249141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 2250141cc406Sopenharmony_ci case OPT_RESOLUTION: 2251141cc406Sopenharmony_ci case OPT_PREVIEW: 2252141cc406Sopenharmony_ci case OPT_TL_X: 2253141cc406Sopenharmony_ci case OPT_TL_Y: 2254141cc406Sopenharmony_ci case OPT_BR_X: 2255141cc406Sopenharmony_ci case OPT_BR_Y: 2256141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 2257141cc406Sopenharmony_ci RIE (calc_parameters (s)); 2258141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2259141cc406Sopenharmony_ci break; 2260141cc406Sopenharmony_ci case OPT_THRESHOLD: 2261141cc406Sopenharmony_ci case OPT_AUTO_WARMUP: 2262141cc406Sopenharmony_ci case OPT_GAMMA_VALUE: 2263141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 2264141cc406Sopenharmony_ci break; 2265141cc406Sopenharmony_ci /* side-effect-free word-array options: */ 2266141cc406Sopenharmony_ci case OPT_MODE: 2267141cc406Sopenharmony_ci if (s->val[option].s) 2268141cc406Sopenharmony_ci free (s->val[option].s); 2269141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2270141cc406Sopenharmony_ci if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART) == 0) 2271141cc406Sopenharmony_ci { 2272141cc406Sopenharmony_ci ENABLE (OPT_THRESHOLD); 2273141cc406Sopenharmony_ci } 2274141cc406Sopenharmony_ci else 2275141cc406Sopenharmony_ci { 2276141cc406Sopenharmony_ci DISABLE (OPT_THRESHOLD); 2277141cc406Sopenharmony_ci } 2278141cc406Sopenharmony_ci RIE (calc_parameters (s)); 2279141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 2280141cc406Sopenharmony_ci break; 2281141cc406Sopenharmony_ci case OPT_SOURCE: 2282141cc406Sopenharmony_ci if (strcmp (s->val[option].s, val) != 0) 2283141cc406Sopenharmony_ci { /* something changed */ 2284141cc406Sopenharmony_ci if (s->val[option].s) 2285141cc406Sopenharmony_ci free (s->val[option].s); 2286141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2287141cc406Sopenharmony_ci if (strcmp (s->val[option].s, "Reflective") == 0) 2288141cc406Sopenharmony_ci { 2289141cc406Sopenharmony_ci PowerControl (SANE_TRUE, SANE_FALSE); 2290141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 2291141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 2292141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup ("Color24"); 2293141cc406Sopenharmony_ci x_range.max = s->model.x_size; 2294141cc406Sopenharmony_ci y_range.max = s->model.y_size; 2295141cc406Sopenharmony_ci } 2296141cc406Sopenharmony_ci else if (0 == strcmp (s->val[option].s, "Negative")) 2297141cc406Sopenharmony_ci { 2298141cc406Sopenharmony_ci PowerControl (SANE_FALSE, SANE_TRUE); 2299141cc406Sopenharmony_ci s->opt[OPT_MODE].size = 2300141cc406Sopenharmony_ci max_string_size (negative_mode_list); 2301141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = 2302141cc406Sopenharmony_ci negative_mode_list; 2303141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup ("Color24"); 2304141cc406Sopenharmony_ci x_range.max = s->model.x_size_ta; 2305141cc406Sopenharmony_ci y_range.max = s->model.y_size_ta; 2306141cc406Sopenharmony_ci } 2307141cc406Sopenharmony_ci else if (0 == strcmp (s->val[option].s, "Positive")) 2308141cc406Sopenharmony_ci { 2309141cc406Sopenharmony_ci PowerControl (SANE_FALSE, SANE_TRUE); 2310141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 2311141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 2312141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup ("Color24"); 2313141cc406Sopenharmony_ci x_range.max = s->model.x_size_ta; 2314141cc406Sopenharmony_ci y_range.max = s->model.y_size_ta; 2315141cc406Sopenharmony_ci } 2316141cc406Sopenharmony_ci } 2317141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 2318141cc406Sopenharmony_ci break; 2319141cc406Sopenharmony_ci default: 2320141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: can't set unknown option %d\n", 2321141cc406Sopenharmony_ci option); 2322141cc406Sopenharmony_ci } 2323141cc406Sopenharmony_ci } 2324141cc406Sopenharmony_ci else 2325141cc406Sopenharmony_ci { 2326141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_control_option: unknown action %d for option %d\n", 2327141cc406Sopenharmony_ci action, option); 2328141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2329141cc406Sopenharmony_ci } 2330141cc406Sopenharmony_ci if (info) 2331141cc406Sopenharmony_ci *info = myinfo; 2332141cc406Sopenharmony_ci 2333141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_control_option: exit\n"); 2334141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2335141cc406Sopenharmony_ci} 2336141cc406Sopenharmony_ci 2337141cc406Sopenharmony_ciSANE_Status 2338141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 2339141cc406Sopenharmony_ci{ 2340141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2341141cc406Sopenharmony_ci 2342141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_parameters: start\n"); 2343141cc406Sopenharmony_ci 2344141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_get_parameters :params.format = %d\n", 2345141cc406Sopenharmony_ci s->params.format); 2346141cc406Sopenharmony_ci 2347141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_get_parameters :params.depth = %d\n", s->params.depth); 2348141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_get_parameters :params.pixels_per_line = %d\n", 2349141cc406Sopenharmony_ci s->params.pixels_per_line); 2350141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_get_parameters :params.bytes_per_line = %d\n", 2351141cc406Sopenharmony_ci s->params.bytes_per_line); 2352141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_get_parameters :params.lines = %d\n", s->params.lines); 2353141cc406Sopenharmony_ci if (params != NULL) 2354141cc406Sopenharmony_ci *params = s->params; 2355141cc406Sopenharmony_ci 2356141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_parameters: exit\n"); 2357141cc406Sopenharmony_ci 2358141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2359141cc406Sopenharmony_ci 2360141cc406Sopenharmony_ci} 2361141cc406Sopenharmony_ci 2362141cc406Sopenharmony_ciSANE_Status 2363141cc406Sopenharmony_cisane_start (SANE_Handle handle) 2364141cc406Sopenharmony_ci{ 2365141cc406Sopenharmony_ci int i; 2366141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2367141cc406Sopenharmony_ci 2368141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_start: start\n"); 2369141cc406Sopenharmony_ci 2370141cc406Sopenharmony_ci s->scan_buffer_len = 0; 2371141cc406Sopenharmony_ci 2372141cc406Sopenharmony_ci calc_parameters (s); 2373141cc406Sopenharmony_ci 2374141cc406Sopenharmony_ci if (s->val[OPT_TL_X].w >= s->val[OPT_BR_X].w) 2375141cc406Sopenharmony_ci { 2376141cc406Sopenharmony_ci DBG (DBG_CRIT, 2377141cc406Sopenharmony_ci "sane_start: top left x >= bottom right x --- exiting\n"); 2378141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2379141cc406Sopenharmony_ci } 2380141cc406Sopenharmony_ci if (s->val[OPT_TL_Y].w >= s->val[OPT_BR_Y].w) 2381141cc406Sopenharmony_ci { 2382141cc406Sopenharmony_ci DBG (DBG_CRIT, 2383141cc406Sopenharmony_ci "sane_start: top left y >= bottom right y --- exiting\n"); 2384141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2385141cc406Sopenharmony_ci } 2386141cc406Sopenharmony_ci 2387141cc406Sopenharmony_ci s->setpara.pGammaTable = NULL; 2388141cc406Sopenharmony_ci 2389141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.fmArea.x1=%d\n", 2390141cc406Sopenharmony_ci s->setpara.fmArea.x1); 2391141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.fmArea.x2=%d\n", 2392141cc406Sopenharmony_ci s->setpara.fmArea.x2); 2393141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.fmArea.y1=%d\n", 2394141cc406Sopenharmony_ci s->setpara.fmArea.y1); 2395141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.fmArea.y2=%d\n", 2396141cc406Sopenharmony_ci s->setpara.fmArea.y2); 2397141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.pfPixelFlavor=%d\n", 2398141cc406Sopenharmony_ci s->setpara.pfPixelFlavor); 2399141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.wLinearThreshold=%d\n", 2400141cc406Sopenharmony_ci s->setpara.wLinearThreshold); 2401141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.wTargetDPI=%d\n", 2402141cc406Sopenharmony_ci s->setpara.wTargetDPI); 2403141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.smScanMode=%d\n", 2404141cc406Sopenharmony_ci s->setpara.smScanMode); 2405141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.ssScanSource =%d\n", 2406141cc406Sopenharmony_ci s->setpara.ssScanSource); 2407141cc406Sopenharmony_ci DBG (DBG_INFO, "Sane_start:setpara ,setpara.pGammaTable =%p\n", 2408141cc406Sopenharmony_ci (void *) s->setpara.pGammaTable); 2409141cc406Sopenharmony_ci 2410141cc406Sopenharmony_ci SetParameters (&s->setpara); 2411141cc406Sopenharmony_ci 2412141cc406Sopenharmony_ci GetParameters (&s->getpara); 2413141cc406Sopenharmony_ci 2414141cc406Sopenharmony_ci switch (s->params.format) 2415141cc406Sopenharmony_ci { 2416141cc406Sopenharmony_ci case SANE_FRAME_RGB: 2417141cc406Sopenharmony_ci if (s->params.depth == 8) 2418141cc406Sopenharmony_ci 2419141cc406Sopenharmony_ci s->params.pixels_per_line = s->getpara.dwLineByteWidth / 3; 2420141cc406Sopenharmony_ci if (s->params.depth == 16) 2421141cc406Sopenharmony_ci s->params.pixels_per_line = s->getpara.dwLineByteWidth / 6; 2422141cc406Sopenharmony_ci 2423141cc406Sopenharmony_ci 2424141cc406Sopenharmony_ci break; 2425141cc406Sopenharmony_ci case SANE_FRAME_GRAY: 2426141cc406Sopenharmony_ci if (s->params.depth == 1) 2427141cc406Sopenharmony_ci s->params.pixels_per_line = s->getpara.dwLineByteWidth * 8; 2428141cc406Sopenharmony_ci if (s->params.depth == 8) 2429141cc406Sopenharmony_ci s->params.pixels_per_line = s->getpara.dwLineByteWidth; 2430141cc406Sopenharmony_ci if (s->params.depth == 16) 2431141cc406Sopenharmony_ci s->params.pixels_per_line = s->getpara.dwLineByteWidth / 2; 2432141cc406Sopenharmony_ci break; 2433141cc406Sopenharmony_ci default: 2434141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_start: sane_params.format = %d\n", 2435141cc406Sopenharmony_ci s->params.format); 2436141cc406Sopenharmony_ci } 2437141cc406Sopenharmony_ci 2438141cc406Sopenharmony_ci s->params.bytes_per_line = s->getpara.dwLineByteWidth; 2439141cc406Sopenharmony_ci s->params.lines = s->getpara.dwLength; 2440141cc406Sopenharmony_ci 2441141cc406Sopenharmony_ci s->params.last_frame = TRUE; 2442141cc406Sopenharmony_ci 2443141cc406Sopenharmony_ci 2444141cc406Sopenharmony_ci s->read_rows = s->getpara.dwLength; 2445141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_start : read_rows = %d\n", s->read_rows); 2446141cc406Sopenharmony_ci 2447141cc406Sopenharmony_ci /*warmming up */ 2448141cc406Sopenharmony_ci if (s->val[OPT_AUTO_WARMUP].w) 2449141cc406Sopenharmony_ci { 2450141cc406Sopenharmony_ci for (i = 30; i > 0; i--) 2451141cc406Sopenharmony_ci { 2452141cc406Sopenharmony_ci sleep (1); 2453141cc406Sopenharmony_ci DBG (DBG_ERR, "warming up: %d\n", i); 2454141cc406Sopenharmony_ci } 2455141cc406Sopenharmony_ci } 2456141cc406Sopenharmony_ci DBG (DBG_INFO, "SCANNING ... \n"); 2457141cc406Sopenharmony_ci 2458141cc406Sopenharmony_ci s->bIsScanning = SANE_TRUE; 2459141cc406Sopenharmony_ci if (s->Scan_data_buf != NULL) 2460141cc406Sopenharmony_ci free (s->Scan_data_buf); 2461141cc406Sopenharmony_ci s->Scan_data_buf = NULL; 2462141cc406Sopenharmony_ci 2463141cc406Sopenharmony_ci s->Scan_data_buf = malloc (SCAN_BUFFER_SIZE * sizeof (SANE_Byte)); 2464141cc406Sopenharmony_ci if (s->Scan_data_buf == NULL) 2465141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2466141cc406Sopenharmony_ci 2467141cc406Sopenharmony_ci StartScan (); 2468141cc406Sopenharmony_ci 2469141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_start: exit\n"); 2470141cc406Sopenharmony_ci 2471141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2472141cc406Sopenharmony_ci} 2473141cc406Sopenharmony_ci 2474141cc406Sopenharmony_ciSANE_Status 2475141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 2476141cc406Sopenharmony_ci SANE_Int * len) 2477141cc406Sopenharmony_ci{ 2478141cc406Sopenharmony_ci 2479141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2480141cc406Sopenharmony_ci static SANE_Byte *tempbuf; 2481141cc406Sopenharmony_ci SANE_Int lines_to_read, lines_read; 2482141cc406Sopenharmony_ci IMAGEROWS image_row; 2483141cc406Sopenharmony_ci 2484141cc406Sopenharmony_ci int maxbuffersize = max_len; 2485141cc406Sopenharmony_ci 2486141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_read: start: max_len=%d\n", max_len); 2487141cc406Sopenharmony_ci 2488141cc406Sopenharmony_ci if (s == NULL) 2489141cc406Sopenharmony_ci { 2490141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_read: handle is null!\n"); 2491141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2492141cc406Sopenharmony_ci } 2493141cc406Sopenharmony_ci 2494141cc406Sopenharmony_ci if (buf == NULL) 2495141cc406Sopenharmony_ci { 2496141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_read: buf is null!\n"); 2497141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2498141cc406Sopenharmony_ci } 2499141cc406Sopenharmony_ci 2500141cc406Sopenharmony_ci if (len == NULL) 2501141cc406Sopenharmony_ci { 2502141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_read: len is null!\n"); 2503141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2504141cc406Sopenharmony_ci } 2505141cc406Sopenharmony_ci *len = 0; 2506141cc406Sopenharmony_ci if (!s->bIsScanning) 2507141cc406Sopenharmony_ci { 2508141cc406Sopenharmony_ci DBG (DBG_WARN, "sane_read: scan was cancelled, is over or has not been " 2509141cc406Sopenharmony_ci "initiated yet\n"); 2510141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 2511141cc406Sopenharmony_ci } 2512141cc406Sopenharmony_ci DBG (DBG_DBG, "sane_read: before read data read_row=%d\n", s->read_rows); 2513141cc406Sopenharmony_ci if (s->scan_buffer_len == 0) 2514141cc406Sopenharmony_ci { 2515141cc406Sopenharmony_ci if (s->read_rows > 0) 2516141cc406Sopenharmony_ci { 2517141cc406Sopenharmony_ci lines_to_read = SCAN_BUFFER_SIZE / s->getpara.dwLineByteWidth; 2518141cc406Sopenharmony_ci 2519141cc406Sopenharmony_ci if (lines_to_read > s->read_rows) 2520141cc406Sopenharmony_ci lines_to_read = s->read_rows; 2521141cc406Sopenharmony_ci 2522141cc406Sopenharmony_ci tempbuf = 2523141cc406Sopenharmony_ci (SANE_Byte *) malloc (sizeof (SANE_Byte) * lines_to_read * 2524141cc406Sopenharmony_ci s->getpara.dwLineByteWidth + 3 * 1024 + 1); 2525141cc406Sopenharmony_ci memset (tempbuf, 0, 2526141cc406Sopenharmony_ci sizeof (SANE_Byte) * lines_to_read * s->getpara.dwLineByteWidth + 2527141cc406Sopenharmony_ci 3 * 1024 + 1); 2528141cc406Sopenharmony_ci 2529141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_read: buffer size is %ld\n", 2530141cc406Sopenharmony_ci (long int) sizeof (SANE_Byte) * lines_to_read * s->getpara.dwLineByteWidth + 2531141cc406Sopenharmony_ci 3 * 1024 + 1); 2532141cc406Sopenharmony_ci 2533141cc406Sopenharmony_ci image_row.roRgbOrder = mustek_A2nu2_model.line_mode_color_order; 2534141cc406Sopenharmony_ci image_row.wWantedLineNum = lines_to_read; 2535141cc406Sopenharmony_ci image_row.pBuffer = (SANE_Byte *) tempbuf; 2536141cc406Sopenharmony_ci s->bIsReading = SANE_TRUE; 2537141cc406Sopenharmony_ci 2538141cc406Sopenharmony_ci if (!ReadScannedData (&image_row)) 2539141cc406Sopenharmony_ci { 2540141cc406Sopenharmony_ci DBG (DBG_ERR, "sane_read: ReadScannedData error\n"); 2541141cc406Sopenharmony_ci s->bIsReading = SANE_FALSE; 2542141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2543141cc406Sopenharmony_ci } 2544141cc406Sopenharmony_ci 2545141cc406Sopenharmony_ci DBG (DBG_DBG, "sane_read: Finish ReadScanedData\n"); 2546141cc406Sopenharmony_ci s->bIsReading = SANE_FALSE; 2547141cc406Sopenharmony_ci memset (s->Scan_data_buf, 0, SCAN_BUFFER_SIZE); 2548141cc406Sopenharmony_ci s->scan_buffer_len = 2549141cc406Sopenharmony_ci image_row.wXferedLineNum * s->getpara.dwLineByteWidth; 2550141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_read : s->scan_buffer_len = %ld\n", 2551141cc406Sopenharmony_ci (long int) s->scan_buffer_len); 2552141cc406Sopenharmony_ci 2553141cc406Sopenharmony_ci memcpy (s->Scan_data_buf, tempbuf, s->scan_buffer_len); 2554141cc406Sopenharmony_ci 2555141cc406Sopenharmony_ci DBG (DBG_DBG, "sane_read :after memcpy\n"); 2556141cc406Sopenharmony_ci free (tempbuf); 2557141cc406Sopenharmony_ci s->Scan_data_buf_start = s->Scan_data_buf; 2558141cc406Sopenharmony_ci s->read_rows -= image_row.wXferedLineNum; 2559141cc406Sopenharmony_ci 2560141cc406Sopenharmony_ci } 2561141cc406Sopenharmony_ci else 2562141cc406Sopenharmony_ci { 2563141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_read: scan finished -- exit\n"); 2564141cc406Sopenharmony_ci sane_cancel (handle); 2565141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2566141cc406Sopenharmony_ci } 2567141cc406Sopenharmony_ci } 2568141cc406Sopenharmony_ci if (s->scan_buffer_len == 0) 2569141cc406Sopenharmony_ci { 2570141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_read: scan finished -- exit\n"); 2571141cc406Sopenharmony_ci sane_cancel (handle); 2572141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2573141cc406Sopenharmony_ci } 2574141cc406Sopenharmony_ci 2575141cc406Sopenharmony_ci 2576141cc406Sopenharmony_ci 2577141cc406Sopenharmony_ci 2578141cc406Sopenharmony_ci lines_read = 2579141cc406Sopenharmony_ci (maxbuffersize < 2580141cc406Sopenharmony_ci (SANE_Int) s->scan_buffer_len) ? maxbuffersize : (SANE_Int) s->scan_buffer_len; 2581141cc406Sopenharmony_ci DBG (DBG_DBG, "sane_read: after %d\n", lines_read); 2582141cc406Sopenharmony_ci 2583141cc406Sopenharmony_ci *len = (SANE_Int) lines_read; 2584141cc406Sopenharmony_ci 2585141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_read : get lines_read = %d\n", lines_read); 2586141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_read : get *len = %d\n", *len); 2587141cc406Sopenharmony_ci memcpy (buf, s->Scan_data_buf_start, lines_read); 2588141cc406Sopenharmony_ci 2589141cc406Sopenharmony_ci s->scan_buffer_len -= lines_read; 2590141cc406Sopenharmony_ci s->Scan_data_buf_start += lines_read; 2591141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_read: exit\n"); 2592141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2593141cc406Sopenharmony_ci 2594141cc406Sopenharmony_ci} 2595141cc406Sopenharmony_ci 2596141cc406Sopenharmony_civoid 2597141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 2598141cc406Sopenharmony_ci{ 2599141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2600141cc406Sopenharmony_ci int i; 2601141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_cancel: start\n"); 2602141cc406Sopenharmony_ci if (s->bIsScanning) 2603141cc406Sopenharmony_ci { 2604141cc406Sopenharmony_ci s->bIsScanning = SANE_FALSE; 2605141cc406Sopenharmony_ci if (s->read_rows > 0) 2606141cc406Sopenharmony_ci { 2607141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_cancel: warning: is scanning\n"); 2608141cc406Sopenharmony_ci 2609141cc406Sopenharmony_ci } 2610141cc406Sopenharmony_ci else 2611141cc406Sopenharmony_ci { 2612141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_cancel: Scan finished\n"); 2613141cc406Sopenharmony_ci } 2614141cc406Sopenharmony_ci 2615141cc406Sopenharmony_ci StopScan (); 2616141cc406Sopenharmony_ci 2617141cc406Sopenharmony_ci CarriageHome (); 2618141cc406Sopenharmony_ci for (i = 0; i < 20; i++) 2619141cc406Sopenharmony_ci { 2620141cc406Sopenharmony_ci if (s->bIsReading == SANE_FALSE) 2621141cc406Sopenharmony_ci { 2622141cc406Sopenharmony_ci if (s->gamma_table != NULL) 2623141cc406Sopenharmony_ci { 2624141cc406Sopenharmony_ci free (s->gamma_table); 2625141cc406Sopenharmony_ci s->gamma_table = NULL; 2626141cc406Sopenharmony_ci break; 2627141cc406Sopenharmony_ci } 2628141cc406Sopenharmony_ci } 2629141cc406Sopenharmony_ci else 2630141cc406Sopenharmony_ci sleep (1); 2631141cc406Sopenharmony_ci } 2632141cc406Sopenharmony_ci if (s->Scan_data_buf != NULL) 2633141cc406Sopenharmony_ci { 2634141cc406Sopenharmony_ci free (s->Scan_data_buf); 2635141cc406Sopenharmony_ci s->Scan_data_buf = NULL; 2636141cc406Sopenharmony_ci s->Scan_data_buf_start = NULL; 2637141cc406Sopenharmony_ci } 2638141cc406Sopenharmony_ci 2639141cc406Sopenharmony_ci s->read_rows = 0; 2640141cc406Sopenharmony_ci s->scan_buffer_len = 0; 2641141cc406Sopenharmony_ci memset (&s->setpara, 0, sizeof (s->setpara)); 2642141cc406Sopenharmony_ci memset (&s->getpara, 0, sizeof (s->getpara)); 2643141cc406Sopenharmony_ci 2644141cc406Sopenharmony_ci } 2645141cc406Sopenharmony_ci else 2646141cc406Sopenharmony_ci { 2647141cc406Sopenharmony_ci DBG (DBG_INFO, "sane_cancel: do nothing\n"); 2648141cc406Sopenharmony_ci } 2649141cc406Sopenharmony_ci 2650141cc406Sopenharmony_ci 2651141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_cancel: exit\n"); 2652141cc406Sopenharmony_ci 2653141cc406Sopenharmony_ci} 2654141cc406Sopenharmony_ci 2655141cc406Sopenharmony_ciSANE_Status 2656141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 2657141cc406Sopenharmony_ci{ 2658141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2659141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_set_io_mode: handle = %p, non_blocking = %s\n", 2660141cc406Sopenharmony_ci handle, non_blocking == SANE_TRUE ? "true" : "false"); 2661141cc406Sopenharmony_ci if (!s->bIsScanning) 2662141cc406Sopenharmony_ci { 2663141cc406Sopenharmony_ci DBG (DBG_WARN, "sane_set_io_mode: not scanning\n"); 2664141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2665141cc406Sopenharmony_ci } 2666141cc406Sopenharmony_ci if (non_blocking) 2667141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2668141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2669141cc406Sopenharmony_ci} 2670141cc406Sopenharmony_ci 2671141cc406Sopenharmony_ciSANE_Status 2672141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 2673141cc406Sopenharmony_ci{ 2674141cc406Sopenharmony_ci Mustek_Scanner *s = handle; 2675141cc406Sopenharmony_ci DBG (DBG_FUNC, "sane_get_select_fd: handle = %p, fd = %p\n", handle, 2676141cc406Sopenharmony_ci (void *) fd); 2677141cc406Sopenharmony_ci if (!s->bIsScanning) 2678141cc406Sopenharmony_ci { 2679141cc406Sopenharmony_ci DBG (DBG_WARN, "%s", "sane_get_select_fd: not scanning\n"); 2680141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2681141cc406Sopenharmony_ci } 2682141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2683141cc406Sopenharmony_ci} 2684