1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 1996, 1997 Andreas Beck 3141cc406Sopenharmony_ci Copyright (C) 2000, 2001 Michael Herder <crapsite@gmx.net> 4141cc406Sopenharmony_ci Copyright (C) 2001, 2002 Henning Meier-Geinitz <henning@meier-geinitz.de> 5141cc406Sopenharmony_ci Copyright (C) 2008 Stéphane Voltz <stef.dev@free.fr> 6141cc406Sopenharmony_ci This file is part of the SANE package. 7141cc406Sopenharmony_ci 8141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 9141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 10141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 11141cc406Sopenharmony_ci License, or (at your option) any later version. 12141cc406Sopenharmony_ci 13141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 14141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 15141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16141cc406Sopenharmony_ci General Public License for more details. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 19141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 22141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 23141cc406Sopenharmony_ci 24141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 25141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 26141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 27141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 28141cc406Sopenharmony_ci account of linking the SANE library code into it. 29141cc406Sopenharmony_ci 30141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 31141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 32141cc406Sopenharmony_ci License. 33141cc406Sopenharmony_ci 34141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 35141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 36141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 37141cc406Sopenharmony_ci 38141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 39141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 40141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. */ 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ci#define BUILD 9 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci#include "../include/sane/config.h" 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#include <stdlib.h> 47141cc406Sopenharmony_ci#include <string.h> 48141cc406Sopenharmony_ci#include <stdio.h> 49141cc406Sopenharmony_ci#include <unistd.h> 50141cc406Sopenharmony_ci#include <fcntl.h> 51141cc406Sopenharmony_ci#include <errno.h> 52141cc406Sopenharmony_ci#include <sys/time.h> 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ci#include "../include/sane/sane.h" 55141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 56141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci#define BACKEND_NAME pnm 59141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_ci#ifndef PATH_MAX 62141cc406Sopenharmony_ci# define PATH_MAX 1024 63141cc406Sopenharmony_ci#endif 64141cc406Sopenharmony_ci 65141cc406Sopenharmony_ci#define MAGIC (void *)0xab730324 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_cistatic int is_open = 0; 68141cc406Sopenharmony_cistatic int rgb_comp = 0; 69141cc406Sopenharmony_cistatic int three_pass = 0; 70141cc406Sopenharmony_cistatic int hand_scanner = 0; 71141cc406Sopenharmony_cistatic int pass = 0; 72141cc406Sopenharmony_cistatic char filename[PATH_MAX] = "/tmp/input.ppm"; 73141cc406Sopenharmony_cistatic SANE_Word status_none = SANE_TRUE; 74141cc406Sopenharmony_cistatic SANE_Word status_eof = SANE_FALSE; 75141cc406Sopenharmony_cistatic SANE_Word status_jammed = SANE_FALSE; 76141cc406Sopenharmony_cistatic SANE_Word status_nodocs = SANE_FALSE; 77141cc406Sopenharmony_cistatic SANE_Word status_coveropen = SANE_FALSE; 78141cc406Sopenharmony_cistatic SANE_Word status_ioerror = SANE_FALSE; 79141cc406Sopenharmony_cistatic SANE_Word status_nomem = SANE_FALSE; 80141cc406Sopenharmony_cistatic SANE_Word status_accessdenied = SANE_FALSE; 81141cc406Sopenharmony_cistatic SANE_Word test_option = 0; 82141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 83141cc406Sopenharmony_cistatic SANE_Word warming_up = SANE_FALSE; 84141cc406Sopenharmony_cistatic struct timeval start; 85141cc406Sopenharmony_ci#endif 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_cistatic SANE_Fixed bright = 0; 88141cc406Sopenharmony_cistatic SANE_Word res = 75; 89141cc406Sopenharmony_cistatic SANE_Fixed contr = 0; 90141cc406Sopenharmony_cistatic SANE_Bool gray = SANE_FALSE; 91141cc406Sopenharmony_cistatic SANE_Bool usegamma = SANE_FALSE; 92141cc406Sopenharmony_cistatic SANE_Word gamma[4][256]; 93141cc406Sopenharmony_cistatic enum 94141cc406Sopenharmony_ci{ 95141cc406Sopenharmony_ci ppm_bitmap, 96141cc406Sopenharmony_ci ppm_greyscale, 97141cc406Sopenharmony_ci ppm_color 98141cc406Sopenharmony_ci} 99141cc406Sopenharmony_cippm_type = ppm_color; 100141cc406Sopenharmony_cistatic FILE *infile = NULL; 101141cc406Sopenharmony_cistatic const SANE_Word resbit_list[] = { 102141cc406Sopenharmony_ci 17, 103141cc406Sopenharmony_ci 75, 90, 100, 120, 135, 150, 165, 180, 195, 104141cc406Sopenharmony_ci 200, 210, 225, 240, 255, 270, 285, 300 105141cc406Sopenharmony_ci}; 106141cc406Sopenharmony_cistatic const SANE_Range percentage_range = { 107141cc406Sopenharmony_ci SANE_FIX(-100), /* minimum */ 108141cc406Sopenharmony_ci SANE_FIX(100), /* maximum */ 109141cc406Sopenharmony_ci SANE_FIX(0) /* quantization */ 110141cc406Sopenharmony_ci}; 111141cc406Sopenharmony_cistatic const SANE_Range gamma_range = { 112141cc406Sopenharmony_ci 0, /* minimum */ 113141cc406Sopenharmony_ci 255, /* maximum */ 114141cc406Sopenharmony_ci 0 /* quantization */ 115141cc406Sopenharmony_ci}; 116141cc406Sopenharmony_citypedef enum 117141cc406Sopenharmony_ci{ 118141cc406Sopenharmony_ci opt_num_opts = 0, 119141cc406Sopenharmony_ci opt_source_group, 120141cc406Sopenharmony_ci opt_filename, 121141cc406Sopenharmony_ci opt_resolution, 122141cc406Sopenharmony_ci opt_enhancement_group, 123141cc406Sopenharmony_ci opt_brightness, 124141cc406Sopenharmony_ci opt_contrast, 125141cc406Sopenharmony_ci opt_grayify, 126141cc406Sopenharmony_ci opt_three_pass, 127141cc406Sopenharmony_ci opt_hand_scanner, 128141cc406Sopenharmony_ci opt_default_enhancements, 129141cc406Sopenharmony_ci opt_read_only, 130141cc406Sopenharmony_ci opt_gamma_group, 131141cc406Sopenharmony_ci opt_custom_gamma, 132141cc406Sopenharmony_ci opt_gamma, 133141cc406Sopenharmony_ci opt_gamma_r, 134141cc406Sopenharmony_ci opt_gamma_g, 135141cc406Sopenharmony_ci opt_gamma_b, 136141cc406Sopenharmony_ci opt_status_group, 137141cc406Sopenharmony_ci opt_status, 138141cc406Sopenharmony_ci opt_status_eof, 139141cc406Sopenharmony_ci opt_status_jammed, 140141cc406Sopenharmony_ci opt_status_nodocs, 141141cc406Sopenharmony_ci opt_status_coveropen, 142141cc406Sopenharmony_ci opt_status_ioerror, 143141cc406Sopenharmony_ci opt_status_nomem, 144141cc406Sopenharmony_ci opt_status_accessdenied, 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_ci /* must come last: */ 147141cc406Sopenharmony_ci num_options 148141cc406Sopenharmony_ci} 149141cc406Sopenharmony_cipnm_opts; 150141cc406Sopenharmony_ci 151141cc406Sopenharmony_cistatic SANE_Option_Descriptor sod[] = { 152141cc406Sopenharmony_ci { /* opt_num_opts */ 153141cc406Sopenharmony_ci SANE_NAME_NUM_OPTIONS, 154141cc406Sopenharmony_ci SANE_TITLE_NUM_OPTIONS, 155141cc406Sopenharmony_ci SANE_DESC_NUM_OPTIONS, 156141cc406Sopenharmony_ci SANE_TYPE_INT, 157141cc406Sopenharmony_ci SANE_UNIT_NONE, 158141cc406Sopenharmony_ci sizeof (SANE_Word), 159141cc406Sopenharmony_ci SANE_CAP_SOFT_DETECT, 160141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 161141cc406Sopenharmony_ci {NULL} 162141cc406Sopenharmony_ci } 163141cc406Sopenharmony_ci , 164141cc406Sopenharmony_ci { /* opt_source_group */ 165141cc406Sopenharmony_ci "", 166141cc406Sopenharmony_ci SANE_I18N ("Source Selection"), 167141cc406Sopenharmony_ci "", 168141cc406Sopenharmony_ci SANE_TYPE_GROUP, 169141cc406Sopenharmony_ci SANE_UNIT_NONE, 170141cc406Sopenharmony_ci 0, 171141cc406Sopenharmony_ci 0, 172141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 173141cc406Sopenharmony_ci {NULL} 174141cc406Sopenharmony_ci } 175141cc406Sopenharmony_ci , 176141cc406Sopenharmony_ci { /* opt_filename */ 177141cc406Sopenharmony_ci SANE_NAME_FILE, 178141cc406Sopenharmony_ci SANE_TITLE_FILE, 179141cc406Sopenharmony_ci SANE_DESC_FILE, 180141cc406Sopenharmony_ci SANE_TYPE_STRING, 181141cc406Sopenharmony_ci SANE_UNIT_NONE, 182141cc406Sopenharmony_ci sizeof (filename), 183141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 184141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 185141cc406Sopenharmony_ci {NULL} 186141cc406Sopenharmony_ci } 187141cc406Sopenharmony_ci , 188141cc406Sopenharmony_ci { 189141cc406Sopenharmony_ci /* opt_resolution */ 190141cc406Sopenharmony_ci SANE_NAME_SCAN_RESOLUTION, 191141cc406Sopenharmony_ci SANE_TITLE_SCAN_RESOLUTION, 192141cc406Sopenharmony_ci SANE_DESC_SCAN_RESOLUTION, 193141cc406Sopenharmony_ci SANE_TYPE_INT, 194141cc406Sopenharmony_ci SANE_UNIT_DPI, 195141cc406Sopenharmony_ci sizeof (SANE_Word), 196141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC, 197141cc406Sopenharmony_ci SANE_CONSTRAINT_WORD_LIST, 198141cc406Sopenharmony_ci {(SANE_String_Const *) resbit_list} 199141cc406Sopenharmony_ci } 200141cc406Sopenharmony_ci , 201141cc406Sopenharmony_ci { /* opt_enhancement_group */ 202141cc406Sopenharmony_ci "", 203141cc406Sopenharmony_ci SANE_I18N ("Image Enhancement"), 204141cc406Sopenharmony_ci "", 205141cc406Sopenharmony_ci SANE_TYPE_GROUP, 206141cc406Sopenharmony_ci SANE_UNIT_NONE, 207141cc406Sopenharmony_ci 0, 208141cc406Sopenharmony_ci 0, 209141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 210141cc406Sopenharmony_ci {NULL} 211141cc406Sopenharmony_ci } 212141cc406Sopenharmony_ci , 213141cc406Sopenharmony_ci { /* opt_brightness */ 214141cc406Sopenharmony_ci SANE_NAME_BRIGHTNESS, 215141cc406Sopenharmony_ci SANE_TITLE_BRIGHTNESS, 216141cc406Sopenharmony_ci SANE_DESC_BRIGHTNESS, 217141cc406Sopenharmony_ci SANE_TYPE_FIXED, 218141cc406Sopenharmony_ci SANE_UNIT_PERCENT, 219141cc406Sopenharmony_ci sizeof (SANE_Word), 220141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 221141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 222141cc406Sopenharmony_ci {(SANE_String_Const *) & percentage_range} /* this is ANSI conformant! */ 223141cc406Sopenharmony_ci } 224141cc406Sopenharmony_ci , 225141cc406Sopenharmony_ci { /* opt_contrast */ 226141cc406Sopenharmony_ci SANE_NAME_CONTRAST, 227141cc406Sopenharmony_ci SANE_TITLE_CONTRAST, 228141cc406Sopenharmony_ci SANE_DESC_CONTRAST, 229141cc406Sopenharmony_ci SANE_TYPE_FIXED, 230141cc406Sopenharmony_ci SANE_UNIT_PERCENT, 231141cc406Sopenharmony_ci sizeof (SANE_Word), 232141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 233141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 234141cc406Sopenharmony_ci {(SANE_String_Const *) & percentage_range} /* this is ANSI conformant! */ 235141cc406Sopenharmony_ci } 236141cc406Sopenharmony_ci , 237141cc406Sopenharmony_ci { /* opt_grayify */ 238141cc406Sopenharmony_ci "grayify", 239141cc406Sopenharmony_ci SANE_I18N ("Grayify"), 240141cc406Sopenharmony_ci SANE_I18N ("Load the image as grayscale."), 241141cc406Sopenharmony_ci SANE_TYPE_BOOL, 242141cc406Sopenharmony_ci SANE_UNIT_NONE, 243141cc406Sopenharmony_ci sizeof (SANE_Word), 244141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 245141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 246141cc406Sopenharmony_ci {NULL} 247141cc406Sopenharmony_ci } 248141cc406Sopenharmony_ci , 249141cc406Sopenharmony_ci { /* opt_three_pass */ 250141cc406Sopenharmony_ci "three-pass", 251141cc406Sopenharmony_ci SANE_I18N ("Three-Pass Simulation"), 252141cc406Sopenharmony_ci SANE_I18N 253141cc406Sopenharmony_ci ("Simulate a three-pass scanner by returning 3 separate frames. " 254141cc406Sopenharmony_ci "For kicks, it returns green, then blue, then red."), 255141cc406Sopenharmony_ci SANE_TYPE_BOOL, 256141cc406Sopenharmony_ci SANE_UNIT_NONE, 257141cc406Sopenharmony_ci sizeof (SANE_Word), 258141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 259141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 260141cc406Sopenharmony_ci {NULL} 261141cc406Sopenharmony_ci } 262141cc406Sopenharmony_ci , 263141cc406Sopenharmony_ci { /* opt_hand_scanner */ 264141cc406Sopenharmony_ci "hand-scanner", 265141cc406Sopenharmony_ci SANE_I18N ("Hand-Scanner Simulation"), 266141cc406Sopenharmony_ci SANE_I18N ("Simulate a hand-scanner. Hand-scanners often do not know the " 267141cc406Sopenharmony_ci "image height a priori. Instead, they return a height of -1. " 268141cc406Sopenharmony_ci "Setting this option allows one to test whether a frontend can " 269141cc406Sopenharmony_ci "handle this correctly."), 270141cc406Sopenharmony_ci SANE_TYPE_BOOL, 271141cc406Sopenharmony_ci SANE_UNIT_NONE, 272141cc406Sopenharmony_ci sizeof (SANE_Word), 273141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 274141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 275141cc406Sopenharmony_ci {NULL} 276141cc406Sopenharmony_ci } 277141cc406Sopenharmony_ci , 278141cc406Sopenharmony_ci { /* opt_default_enhancements */ 279141cc406Sopenharmony_ci "default-enhancements", 280141cc406Sopenharmony_ci SANE_I18N ("Defaults"), 281141cc406Sopenharmony_ci SANE_I18N ("Set default values for enhancement controls (brightness & " 282141cc406Sopenharmony_ci "contrast)."), 283141cc406Sopenharmony_ci SANE_TYPE_BUTTON, 284141cc406Sopenharmony_ci SANE_UNIT_NONE, 285141cc406Sopenharmony_ci 0, 286141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 287141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 288141cc406Sopenharmony_ci {NULL} 289141cc406Sopenharmony_ci } 290141cc406Sopenharmony_ci , 291141cc406Sopenharmony_ci { /* opt_read_only */ 292141cc406Sopenharmony_ci "read-only", 293141cc406Sopenharmony_ci SANE_I18N ("Read only test-option"), 294141cc406Sopenharmony_ci SANE_I18N ("Let's see whether frontends can treat this right"), 295141cc406Sopenharmony_ci SANE_TYPE_INT, 296141cc406Sopenharmony_ci SANE_UNIT_PERCENT, 297141cc406Sopenharmony_ci sizeof (SANE_Word), 298141cc406Sopenharmony_ci SANE_CAP_SOFT_DETECT, 299141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 300141cc406Sopenharmony_ci {NULL} 301141cc406Sopenharmony_ci } 302141cc406Sopenharmony_ci , 303141cc406Sopenharmony_ci { /* opt_gamma_group */ 304141cc406Sopenharmony_ci "", 305141cc406Sopenharmony_ci SANE_I18N ("Gamma Tables"), 306141cc406Sopenharmony_ci "", 307141cc406Sopenharmony_ci SANE_TYPE_GROUP, 308141cc406Sopenharmony_ci SANE_UNIT_NONE, 309141cc406Sopenharmony_ci 0, 310141cc406Sopenharmony_ci 0, 311141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 312141cc406Sopenharmony_ci {NULL} 313141cc406Sopenharmony_ci } 314141cc406Sopenharmony_ci , 315141cc406Sopenharmony_ci { /* opt_custom_gamma */ 316141cc406Sopenharmony_ci SANE_NAME_CUSTOM_GAMMA, 317141cc406Sopenharmony_ci SANE_TITLE_CUSTOM_GAMMA, 318141cc406Sopenharmony_ci SANE_DESC_CUSTOM_GAMMA, 319141cc406Sopenharmony_ci SANE_TYPE_BOOL, 320141cc406Sopenharmony_ci SANE_UNIT_NONE, 321141cc406Sopenharmony_ci sizeof (SANE_Word), 322141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 323141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 324141cc406Sopenharmony_ci {NULL} 325141cc406Sopenharmony_ci } 326141cc406Sopenharmony_ci , 327141cc406Sopenharmony_ci { /* opt_gamma */ 328141cc406Sopenharmony_ci SANE_NAME_GAMMA_VECTOR, 329141cc406Sopenharmony_ci SANE_TITLE_GAMMA_VECTOR, 330141cc406Sopenharmony_ci SANE_DESC_GAMMA_VECTOR, 331141cc406Sopenharmony_ci SANE_TYPE_INT, 332141cc406Sopenharmony_ci SANE_UNIT_NONE, 333141cc406Sopenharmony_ci sizeof (SANE_Word) * 256, 334141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE, 335141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 336141cc406Sopenharmony_ci {(SANE_String_Const *) & gamma_range} 337141cc406Sopenharmony_ci } 338141cc406Sopenharmony_ci , 339141cc406Sopenharmony_ci { /* opt_gamma_r */ 340141cc406Sopenharmony_ci SANE_NAME_GAMMA_VECTOR_R, 341141cc406Sopenharmony_ci SANE_TITLE_GAMMA_VECTOR_R, 342141cc406Sopenharmony_ci SANE_DESC_GAMMA_VECTOR_R, 343141cc406Sopenharmony_ci SANE_TYPE_INT, 344141cc406Sopenharmony_ci SANE_UNIT_NONE, 345141cc406Sopenharmony_ci sizeof (SANE_Word) * 256, 346141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE, 347141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 348141cc406Sopenharmony_ci {(SANE_String_Const *) & gamma_range} 349141cc406Sopenharmony_ci } 350141cc406Sopenharmony_ci , 351141cc406Sopenharmony_ci { /* opt_gamma_g */ 352141cc406Sopenharmony_ci SANE_NAME_GAMMA_VECTOR_G, 353141cc406Sopenharmony_ci SANE_TITLE_GAMMA_VECTOR_G, 354141cc406Sopenharmony_ci SANE_DESC_GAMMA_VECTOR_G, 355141cc406Sopenharmony_ci SANE_TYPE_INT, 356141cc406Sopenharmony_ci SANE_UNIT_NONE, 357141cc406Sopenharmony_ci sizeof (SANE_Word) * 256, 358141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE, 359141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 360141cc406Sopenharmony_ci {(SANE_String_Const *) & gamma_range} 361141cc406Sopenharmony_ci } 362141cc406Sopenharmony_ci , 363141cc406Sopenharmony_ci { /* opt_gamma_b */ 364141cc406Sopenharmony_ci SANE_NAME_GAMMA_VECTOR_B, 365141cc406Sopenharmony_ci SANE_TITLE_GAMMA_VECTOR_B, 366141cc406Sopenharmony_ci SANE_DESC_GAMMA_VECTOR_B, 367141cc406Sopenharmony_ci SANE_TYPE_INT, 368141cc406Sopenharmony_ci SANE_UNIT_NONE, 369141cc406Sopenharmony_ci sizeof (SANE_Word) * 256, 370141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE, 371141cc406Sopenharmony_ci SANE_CONSTRAINT_RANGE, 372141cc406Sopenharmony_ci {(SANE_String_Const *) & gamma_range} 373141cc406Sopenharmony_ci } 374141cc406Sopenharmony_ci , 375141cc406Sopenharmony_ci { /* opt_status_group */ 376141cc406Sopenharmony_ci "", 377141cc406Sopenharmony_ci SANE_I18N ("Status Code Simulation"), 378141cc406Sopenharmony_ci "", 379141cc406Sopenharmony_ci SANE_TYPE_GROUP, 380141cc406Sopenharmony_ci SANE_UNIT_NONE, 381141cc406Sopenharmony_ci 0, 382141cc406Sopenharmony_ci SANE_CAP_ADVANCED, 383141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 384141cc406Sopenharmony_ci {NULL} 385141cc406Sopenharmony_ci } 386141cc406Sopenharmony_ci , 387141cc406Sopenharmony_ci { /* opt_status */ 388141cc406Sopenharmony_ci "status", 389141cc406Sopenharmony_ci SANE_I18N ("Do not force status code"), 390141cc406Sopenharmony_ci SANE_I18N ("Do not force the backend to return a status code."), 391141cc406Sopenharmony_ci SANE_TYPE_BOOL, 392141cc406Sopenharmony_ci SANE_UNIT_NONE, 393141cc406Sopenharmony_ci sizeof (SANE_Bool), 394141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 395141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 396141cc406Sopenharmony_ci {NULL} 397141cc406Sopenharmony_ci } 398141cc406Sopenharmony_ci , 399141cc406Sopenharmony_ci { /* opt_status_eof */ 400141cc406Sopenharmony_ci "status-eof", 401141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_EOF"), 402141cc406Sopenharmony_ci SANE_I18N ("Force the backend to return the status code SANE_STATUS_EOF " 403141cc406Sopenharmony_ci "after sane_read() has been called."), 404141cc406Sopenharmony_ci SANE_TYPE_BOOL, 405141cc406Sopenharmony_ci SANE_UNIT_NONE, 406141cc406Sopenharmony_ci sizeof (SANE_Bool), 407141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 408141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 409141cc406Sopenharmony_ci {NULL} 410141cc406Sopenharmony_ci } 411141cc406Sopenharmony_ci , 412141cc406Sopenharmony_ci { /* opt_status_jammed */ 413141cc406Sopenharmony_ci "status-jammed", 414141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_JAMMED"), 415141cc406Sopenharmony_ci SANE_I18N 416141cc406Sopenharmony_ci ("Force the backend to return the status code SANE_STATUS_JAMMED " 417141cc406Sopenharmony_ci "after sane_read() has been called."), 418141cc406Sopenharmony_ci SANE_TYPE_BOOL, 419141cc406Sopenharmony_ci SANE_UNIT_NONE, 420141cc406Sopenharmony_ci sizeof (SANE_Bool), 421141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 422141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 423141cc406Sopenharmony_ci {NULL} 424141cc406Sopenharmony_ci } 425141cc406Sopenharmony_ci , 426141cc406Sopenharmony_ci { /* opt_status_nodocs */ 427141cc406Sopenharmony_ci "status-nodocs", 428141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_NO_DOCS"), 429141cc406Sopenharmony_ci SANE_I18N ("Force the backend to return the status code " 430141cc406Sopenharmony_ci "SANE_STATUS_NO_DOCS after sane_read() has been called."), 431141cc406Sopenharmony_ci SANE_TYPE_BOOL, 432141cc406Sopenharmony_ci SANE_UNIT_NONE, 433141cc406Sopenharmony_ci sizeof (SANE_Bool), 434141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 435141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 436141cc406Sopenharmony_ci {NULL} 437141cc406Sopenharmony_ci } 438141cc406Sopenharmony_ci , 439141cc406Sopenharmony_ci { /* opt_status_coveropen */ 440141cc406Sopenharmony_ci "status-coveropen", 441141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_COVER_OPEN"), 442141cc406Sopenharmony_ci SANE_I18N ("Force the backend to return the status code " 443141cc406Sopenharmony_ci "SANE_STATUS_COVER_OPEN after sane_read() has been called."), 444141cc406Sopenharmony_ci SANE_TYPE_BOOL, 445141cc406Sopenharmony_ci SANE_UNIT_NONE, 446141cc406Sopenharmony_ci sizeof (SANE_Bool), 447141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 448141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 449141cc406Sopenharmony_ci {NULL} 450141cc406Sopenharmony_ci } 451141cc406Sopenharmony_ci , 452141cc406Sopenharmony_ci { /* opt_status_ioerror */ 453141cc406Sopenharmony_ci "status-ioerror", 454141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_IO_ERROR"), 455141cc406Sopenharmony_ci SANE_I18N ("Force the backend to return the status code " 456141cc406Sopenharmony_ci "SANE_STATUS_IO_ERROR after sane_read() has been called."), 457141cc406Sopenharmony_ci SANE_TYPE_BOOL, 458141cc406Sopenharmony_ci SANE_UNIT_NONE, 459141cc406Sopenharmony_ci sizeof (SANE_Bool), 460141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 461141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 462141cc406Sopenharmony_ci {NULL} 463141cc406Sopenharmony_ci } 464141cc406Sopenharmony_ci , 465141cc406Sopenharmony_ci { /* opt_status_nomem */ 466141cc406Sopenharmony_ci "status-nomem", 467141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_NO_MEM"), 468141cc406Sopenharmony_ci SANE_I18N 469141cc406Sopenharmony_ci ("Force the backend to return the status code SANE_STATUS_NO_MEM " 470141cc406Sopenharmony_ci "after sane_read() has been called."), 471141cc406Sopenharmony_ci SANE_TYPE_BOOL, 472141cc406Sopenharmony_ci SANE_UNIT_NONE, 473141cc406Sopenharmony_ci sizeof (SANE_Bool), 474141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 475141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 476141cc406Sopenharmony_ci {NULL} 477141cc406Sopenharmony_ci } 478141cc406Sopenharmony_ci , 479141cc406Sopenharmony_ci { /* opt_status_accessdenied */ 480141cc406Sopenharmony_ci "status-accessdenied", 481141cc406Sopenharmony_ci SANE_I18N ("Return SANE_STATUS_ACCESS_DENIED"), 482141cc406Sopenharmony_ci SANE_I18N ("Force the backend to return the status code " 483141cc406Sopenharmony_ci "SANE_STATUS_ACCESS_DENIED after sane_read() has been called."), 484141cc406Sopenharmony_ci SANE_TYPE_BOOL, 485141cc406Sopenharmony_ci SANE_UNIT_NONE, 486141cc406Sopenharmony_ci sizeof (SANE_Bool), 487141cc406Sopenharmony_ci SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT, 488141cc406Sopenharmony_ci SANE_CONSTRAINT_NONE, 489141cc406Sopenharmony_ci {NULL} 490141cc406Sopenharmony_ci } 491141cc406Sopenharmony_ci}; 492141cc406Sopenharmony_ci 493141cc406Sopenharmony_cistatic SANE_Parameters parms = { 494141cc406Sopenharmony_ci SANE_FRAME_RGB, 495141cc406Sopenharmony_ci 0, 496141cc406Sopenharmony_ci 0, /* Number of bytes returned per scan line: */ 497141cc406Sopenharmony_ci 0, /* Number of pixels per scan line. */ 498141cc406Sopenharmony_ci 0, /* Number of lines for the current scan. */ 499141cc406Sopenharmony_ci 8, /* Number of bits per sample. */ 500141cc406Sopenharmony_ci}; 501141cc406Sopenharmony_ci 502141cc406Sopenharmony_ci/* This library is a demo implementation of a SANE backend. It 503141cc406Sopenharmony_ci implements a virtual device, a PNM file-filter. */ 504141cc406Sopenharmony_ciSANE_Status 505141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 506141cc406Sopenharmony_ci{ 507141cc406Sopenharmony_ci DBG_INIT (); 508141cc406Sopenharmony_ci 509141cc406Sopenharmony_ci DBG (2, "sane_init: version_code %s 0, authorize %s 0\n", 510141cc406Sopenharmony_ci version_code == 0 ? "=" : "!=", authorize == 0 ? "=" : "!="); 511141cc406Sopenharmony_ci DBG (1, "sane_init: SANE pnm backend version %d.%d.%d from %s\n", 512141cc406Sopenharmony_ci SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 513141cc406Sopenharmony_ci 514141cc406Sopenharmony_ci if (version_code) 515141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 516141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 517141cc406Sopenharmony_ci} 518141cc406Sopenharmony_ci 519141cc406Sopenharmony_civoid 520141cc406Sopenharmony_cisane_exit (void) 521141cc406Sopenharmony_ci{ 522141cc406Sopenharmony_ci DBG (2, "sane_exit\n"); 523141cc406Sopenharmony_ci return; 524141cc406Sopenharmony_ci} 525141cc406Sopenharmony_ci 526141cc406Sopenharmony_ci/* Device select/open/close */ 527141cc406Sopenharmony_ci 528141cc406Sopenharmony_cistatic const SANE_Device dev[] = { 529141cc406Sopenharmony_ci { 530141cc406Sopenharmony_ci "0", 531141cc406Sopenharmony_ci "Noname", 532141cc406Sopenharmony_ci "PNM file reader", 533141cc406Sopenharmony_ci "virtual device"}, 534141cc406Sopenharmony_ci { 535141cc406Sopenharmony_ci "1", 536141cc406Sopenharmony_ci "Noname", 537141cc406Sopenharmony_ci "PNM file reader", 538141cc406Sopenharmony_ci "virtual device"}, 539141cc406Sopenharmony_ci#ifdef SANE_STATUS_HW_LOCKED 540141cc406Sopenharmony_ci { 541141cc406Sopenharmony_ci "locked", 542141cc406Sopenharmony_ci "Noname", 543141cc406Sopenharmony_ci "Hardware locked", 544141cc406Sopenharmony_ci "virtual device"}, 545141cc406Sopenharmony_ci#endif 546141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 547141cc406Sopenharmony_ci { 548141cc406Sopenharmony_ci "warmup", 549141cc406Sopenharmony_ci "Noname", 550141cc406Sopenharmony_ci "Always warming up", 551141cc406Sopenharmony_ci "virtual device"}, 552141cc406Sopenharmony_ci#endif 553141cc406Sopenharmony_ci}; 554141cc406Sopenharmony_ci 555141cc406Sopenharmony_ciSANE_Status 556141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 557141cc406Sopenharmony_ci{ 558141cc406Sopenharmony_ci static const SANE_Device *devlist[] = { 559141cc406Sopenharmony_ci dev + 0, dev + 1, 560141cc406Sopenharmony_ci#ifdef SANE_STATUS_HW_LOCKED 561141cc406Sopenharmony_ci dev + 2, 562141cc406Sopenharmony_ci#endif 563141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 564141cc406Sopenharmony_ci dev + 3, 565141cc406Sopenharmony_ci#endif 566141cc406Sopenharmony_ci 0 567141cc406Sopenharmony_ci }; 568141cc406Sopenharmony_ci 569141cc406Sopenharmony_ci DBG (2, "sane_get_devices: local_only = %d\n", local_only); 570141cc406Sopenharmony_ci *device_list = devlist; 571141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 572141cc406Sopenharmony_ci} 573141cc406Sopenharmony_ci 574141cc406Sopenharmony_ciSANE_Status 575141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle * handle) 576141cc406Sopenharmony_ci{ 577141cc406Sopenharmony_ci int i; 578141cc406Sopenharmony_ci 579141cc406Sopenharmony_ci if (!devicename) 580141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 581141cc406Sopenharmony_ci DBG (2, "sane_open: devicename = \"%s\"\n", devicename); 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci if (!devicename[0]) 584141cc406Sopenharmony_ci i = 0; 585141cc406Sopenharmony_ci else 586141cc406Sopenharmony_ci for (i = 0; i < NELEMS (dev); ++i) 587141cc406Sopenharmony_ci if (strcmp (devicename, dev[i].name) == 0) 588141cc406Sopenharmony_ci break; 589141cc406Sopenharmony_ci if (i >= NELEMS (dev)) 590141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 591141cc406Sopenharmony_ci 592141cc406Sopenharmony_ci if (is_open) 593141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 594141cc406Sopenharmony_ci 595141cc406Sopenharmony_ci is_open = 1; 596141cc406Sopenharmony_ci *handle = MAGIC; 597141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 598141cc406Sopenharmony_ci { 599141cc406Sopenharmony_ci gamma[0][i] = i; 600141cc406Sopenharmony_ci gamma[1][i] = i; 601141cc406Sopenharmony_ci gamma[2][i] = i; 602141cc406Sopenharmony_ci gamma[3][i] = i; 603141cc406Sopenharmony_ci } 604141cc406Sopenharmony_ci 605141cc406Sopenharmony_ci#ifdef SANE_STATUS_HW_LOCKED 606141cc406Sopenharmony_ci if(strncmp(devicename,"locked",6)==0) 607141cc406Sopenharmony_ci return SANE_STATUS_HW_LOCKED; 608141cc406Sopenharmony_ci#endif 609141cc406Sopenharmony_ci 610141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 611141cc406Sopenharmony_ci if(strncmp(devicename,"warmup",6)==0) 612141cc406Sopenharmony_ci { 613141cc406Sopenharmony_ci warming_up = SANE_TRUE; 614141cc406Sopenharmony_ci start.tv_sec = 0; 615141cc406Sopenharmony_ci } 616141cc406Sopenharmony_ci#endif 617141cc406Sopenharmony_ci 618141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 619141cc406Sopenharmony_ci} 620141cc406Sopenharmony_ci 621141cc406Sopenharmony_civoid 622141cc406Sopenharmony_cisane_close (SANE_Handle handle) 623141cc406Sopenharmony_ci{ 624141cc406Sopenharmony_ci DBG (2, "sane_close\n"); 625141cc406Sopenharmony_ci if (handle == MAGIC) 626141cc406Sopenharmony_ci is_open = 0; 627141cc406Sopenharmony_ci} 628141cc406Sopenharmony_ci 629141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 630141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 631141cc406Sopenharmony_ci{ 632141cc406Sopenharmony_ci DBG (2, "sane_get_option_descriptor: option = %d\n", option); 633141cc406Sopenharmony_ci if (handle != MAGIC || !is_open) 634141cc406Sopenharmony_ci return NULL; /* wrong device */ 635141cc406Sopenharmony_ci if (option < 0 || option >= NELEMS (sod)) 636141cc406Sopenharmony_ci return NULL; 637141cc406Sopenharmony_ci return &sod[option]; 638141cc406Sopenharmony_ci} 639141cc406Sopenharmony_ci 640141cc406Sopenharmony_ciSANE_Status 641141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 642141cc406Sopenharmony_ci SANE_Action action, void *value, SANE_Int * info) 643141cc406Sopenharmony_ci{ 644141cc406Sopenharmony_ci SANE_Int myinfo = 0; 645141cc406Sopenharmony_ci SANE_Status status; 646141cc406Sopenharmony_ci int v; 647141cc406Sopenharmony_ci v = 75; 648141cc406Sopenharmony_ci 649141cc406Sopenharmony_ci DBG (2, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n", 650141cc406Sopenharmony_ci handle, option, action, value, (void *) info); 651141cc406Sopenharmony_ci 652141cc406Sopenharmony_ci if (handle != MAGIC || !is_open) 653141cc406Sopenharmony_ci { 654141cc406Sopenharmony_ci DBG (1, "sane_control_option: unknown handle or not open\n"); 655141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* Unknown handle ... */ 656141cc406Sopenharmony_ci } 657141cc406Sopenharmony_ci 658141cc406Sopenharmony_ci if (option < 0 || option >= NELEMS (sod)) 659141cc406Sopenharmony_ci { 660141cc406Sopenharmony_ci DBG (1, "sane_control_option: option %d < 0 or >= number of options\n", 661141cc406Sopenharmony_ci option); 662141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* Unknown option ... */ 663141cc406Sopenharmony_ci } 664141cc406Sopenharmony_ci 665141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (sod[option].cap)) 666141cc406Sopenharmony_ci { 667141cc406Sopenharmony_ci DBG (4, "sane_control_option: option is inactive\n"); 668141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 669141cc406Sopenharmony_ci } 670141cc406Sopenharmony_ci 671141cc406Sopenharmony_ci switch (action) 672141cc406Sopenharmony_ci { 673141cc406Sopenharmony_ci case SANE_ACTION_SET_AUTO: 674141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (sod[option].cap)) 675141cc406Sopenharmony_ci { 676141cc406Sopenharmony_ci DBG (4, "sane_control_option: option is not settable\n"); 677141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 678141cc406Sopenharmony_ci } 679141cc406Sopenharmony_ci status = sanei_constrain_value (sod + option, (void *) &v, &myinfo); 680141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 681141cc406Sopenharmony_ci return status; 682141cc406Sopenharmony_ci switch (option) 683141cc406Sopenharmony_ci { 684141cc406Sopenharmony_ci case opt_resolution: 685141cc406Sopenharmony_ci res = 75; 686141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 687141cc406Sopenharmony_ci break; 688141cc406Sopenharmony_ci default: 689141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 690141cc406Sopenharmony_ci } 691141cc406Sopenharmony_ci break; 692141cc406Sopenharmony_ci case SANE_ACTION_SET_VALUE: 693141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (sod[option].cap)) 694141cc406Sopenharmony_ci { 695141cc406Sopenharmony_ci DBG (4, "sane_control_option: option is not settable\n"); 696141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 697141cc406Sopenharmony_ci } 698141cc406Sopenharmony_ci status = sanei_constrain_value (sod + option, value, &myinfo); 699141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 700141cc406Sopenharmony_ci return status; 701141cc406Sopenharmony_ci switch (option) 702141cc406Sopenharmony_ci { 703141cc406Sopenharmony_ci case opt_filename: 704141cc406Sopenharmony_ci if ((strlen (value) + 1) > sizeof (filename)) 705141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 706141cc406Sopenharmony_ci strcpy (filename, value); 707141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 708141cc406Sopenharmony_ci break; 709141cc406Sopenharmony_ci case opt_resolution: 710141cc406Sopenharmony_ci res = *(SANE_Word *) value; 711141cc406Sopenharmony_ci break; 712141cc406Sopenharmony_ci case opt_brightness: 713141cc406Sopenharmony_ci bright = *(SANE_Word *) value; 714141cc406Sopenharmony_ci break; 715141cc406Sopenharmony_ci case opt_contrast: 716141cc406Sopenharmony_ci contr = *(SANE_Word *) value; 717141cc406Sopenharmony_ci break; 718141cc406Sopenharmony_ci case opt_grayify: 719141cc406Sopenharmony_ci gray = !!*(SANE_Word *) value; 720141cc406Sopenharmony_ci if (usegamma) 721141cc406Sopenharmony_ci { 722141cc406Sopenharmony_ci if (gray) 723141cc406Sopenharmony_ci { 724141cc406Sopenharmony_ci sod[opt_gamma].cap &= ~SANE_CAP_INACTIVE; 725141cc406Sopenharmony_ci sod[opt_gamma_r].cap |= SANE_CAP_INACTIVE; 726141cc406Sopenharmony_ci sod[opt_gamma_g].cap |= SANE_CAP_INACTIVE; 727141cc406Sopenharmony_ci sod[opt_gamma_b].cap |= SANE_CAP_INACTIVE; 728141cc406Sopenharmony_ci } 729141cc406Sopenharmony_ci else 730141cc406Sopenharmony_ci { 731141cc406Sopenharmony_ci sod[opt_gamma].cap |= SANE_CAP_INACTIVE; 732141cc406Sopenharmony_ci sod[opt_gamma_r].cap &= ~SANE_CAP_INACTIVE; 733141cc406Sopenharmony_ci sod[opt_gamma_g].cap &= ~SANE_CAP_INACTIVE; 734141cc406Sopenharmony_ci sod[opt_gamma_b].cap &= ~SANE_CAP_INACTIVE; 735141cc406Sopenharmony_ci } 736141cc406Sopenharmony_ci } 737141cc406Sopenharmony_ci else 738141cc406Sopenharmony_ci { 739141cc406Sopenharmony_ci sod[opt_gamma].cap |= SANE_CAP_INACTIVE; 740141cc406Sopenharmony_ci sod[opt_gamma_r].cap |= SANE_CAP_INACTIVE; 741141cc406Sopenharmony_ci sod[opt_gamma_g].cap |= SANE_CAP_INACTIVE; 742141cc406Sopenharmony_ci sod[opt_gamma_b].cap |= SANE_CAP_INACTIVE; 743141cc406Sopenharmony_ci } 744141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; 745141cc406Sopenharmony_ci break; 746141cc406Sopenharmony_ci case opt_three_pass: 747141cc406Sopenharmony_ci three_pass = !!*(SANE_Word *) value; 748141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 749141cc406Sopenharmony_ci break; 750141cc406Sopenharmony_ci case opt_hand_scanner: 751141cc406Sopenharmony_ci hand_scanner = !!*(SANE_Word *) value; 752141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 753141cc406Sopenharmony_ci break; 754141cc406Sopenharmony_ci case opt_default_enhancements: 755141cc406Sopenharmony_ci bright = contr = 0; 756141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 757141cc406Sopenharmony_ci break; 758141cc406Sopenharmony_ci case opt_custom_gamma: 759141cc406Sopenharmony_ci usegamma = *(SANE_Word *) value; 760141cc406Sopenharmony_ci /* activate/deactivate gamma */ 761141cc406Sopenharmony_ci if (usegamma) 762141cc406Sopenharmony_ci { 763141cc406Sopenharmony_ci test_option = 100; 764141cc406Sopenharmony_ci if (gray) 765141cc406Sopenharmony_ci { 766141cc406Sopenharmony_ci sod[opt_gamma].cap &= ~SANE_CAP_INACTIVE; 767141cc406Sopenharmony_ci sod[opt_gamma_r].cap |= SANE_CAP_INACTIVE; 768141cc406Sopenharmony_ci sod[opt_gamma_g].cap |= SANE_CAP_INACTIVE; 769141cc406Sopenharmony_ci sod[opt_gamma_b].cap |= SANE_CAP_INACTIVE; 770141cc406Sopenharmony_ci } 771141cc406Sopenharmony_ci else 772141cc406Sopenharmony_ci { 773141cc406Sopenharmony_ci sod[opt_gamma].cap |= SANE_CAP_INACTIVE; 774141cc406Sopenharmony_ci sod[opt_gamma_r].cap &= ~SANE_CAP_INACTIVE; 775141cc406Sopenharmony_ci sod[opt_gamma_g].cap &= ~SANE_CAP_INACTIVE; 776141cc406Sopenharmony_ci sod[opt_gamma_b].cap &= ~SANE_CAP_INACTIVE; 777141cc406Sopenharmony_ci } 778141cc406Sopenharmony_ci } 779141cc406Sopenharmony_ci else 780141cc406Sopenharmony_ci { 781141cc406Sopenharmony_ci test_option = 0; 782141cc406Sopenharmony_ci sod[opt_gamma].cap |= SANE_CAP_INACTIVE; 783141cc406Sopenharmony_ci sod[opt_gamma_r].cap |= SANE_CAP_INACTIVE; 784141cc406Sopenharmony_ci sod[opt_gamma_g].cap |= SANE_CAP_INACTIVE; 785141cc406Sopenharmony_ci sod[opt_gamma_b].cap |= SANE_CAP_INACTIVE; 786141cc406Sopenharmony_ci } 787141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 788141cc406Sopenharmony_ci break; 789141cc406Sopenharmony_ci case opt_gamma: 790141cc406Sopenharmony_ci memcpy (&gamma[0][0], (SANE_Word *) value, 791141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 792141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 793141cc406Sopenharmony_ci break; 794141cc406Sopenharmony_ci case opt_gamma_r: 795141cc406Sopenharmony_ci memcpy (&gamma[1][0], (SANE_Word *) value, 796141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 797141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 798141cc406Sopenharmony_ci break; 799141cc406Sopenharmony_ci case opt_gamma_g: 800141cc406Sopenharmony_ci memcpy (&gamma[2][0], (SANE_Word *) value, 801141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 802141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 803141cc406Sopenharmony_ci break; 804141cc406Sopenharmony_ci case opt_gamma_b: 805141cc406Sopenharmony_ci memcpy (&gamma[3][0], (SANE_Word *) value, 806141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 807141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 808141cc406Sopenharmony_ci break; 809141cc406Sopenharmony_ci /* status */ 810141cc406Sopenharmony_ci case opt_status: 811141cc406Sopenharmony_ci status_none = *(SANE_Word *) value; 812141cc406Sopenharmony_ci if (status_none) 813141cc406Sopenharmony_ci { 814141cc406Sopenharmony_ci status_eof = SANE_FALSE; 815141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 816141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 817141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 818141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 819141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 820141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 821141cc406Sopenharmony_ci } 822141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 823141cc406Sopenharmony_ci break; 824141cc406Sopenharmony_ci case opt_status_eof: 825141cc406Sopenharmony_ci status_eof = *(SANE_Word *) value; 826141cc406Sopenharmony_ci if (status_eof) 827141cc406Sopenharmony_ci { 828141cc406Sopenharmony_ci status_none = SANE_FALSE; 829141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 830141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 831141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 832141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 833141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 834141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 835141cc406Sopenharmony_ci } 836141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 837141cc406Sopenharmony_ci break; 838141cc406Sopenharmony_ci case opt_status_jammed: 839141cc406Sopenharmony_ci status_jammed = *(SANE_Word *) value; 840141cc406Sopenharmony_ci if (status_jammed) 841141cc406Sopenharmony_ci { 842141cc406Sopenharmony_ci status_eof = SANE_FALSE; 843141cc406Sopenharmony_ci status_none = SANE_FALSE; 844141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 845141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 846141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 847141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 848141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 849141cc406Sopenharmony_ci } 850141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 851141cc406Sopenharmony_ci break; 852141cc406Sopenharmony_ci case opt_status_nodocs: 853141cc406Sopenharmony_ci status_nodocs = *(SANE_Word *) value; 854141cc406Sopenharmony_ci if (status_nodocs) 855141cc406Sopenharmony_ci { 856141cc406Sopenharmony_ci status_eof = SANE_FALSE; 857141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 858141cc406Sopenharmony_ci status_none = SANE_FALSE; 859141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 860141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 861141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 862141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 863141cc406Sopenharmony_ci } 864141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 865141cc406Sopenharmony_ci break; 866141cc406Sopenharmony_ci case opt_status_coveropen: 867141cc406Sopenharmony_ci status_coveropen = *(SANE_Word *) value; 868141cc406Sopenharmony_ci if (status_coveropen) 869141cc406Sopenharmony_ci { 870141cc406Sopenharmony_ci status_eof = SANE_FALSE; 871141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 872141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 873141cc406Sopenharmony_ci status_none = SANE_FALSE; 874141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 875141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 876141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 877141cc406Sopenharmony_ci } 878141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 879141cc406Sopenharmony_ci break; 880141cc406Sopenharmony_ci case opt_status_ioerror: 881141cc406Sopenharmony_ci status_ioerror = *(SANE_Word *) value; 882141cc406Sopenharmony_ci if (status_ioerror) 883141cc406Sopenharmony_ci { 884141cc406Sopenharmony_ci status_eof = SANE_FALSE; 885141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 886141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 887141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 888141cc406Sopenharmony_ci status_none = SANE_FALSE; 889141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 890141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 891141cc406Sopenharmony_ci } 892141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 893141cc406Sopenharmony_ci break; 894141cc406Sopenharmony_ci case opt_status_nomem: 895141cc406Sopenharmony_ci status_nomem = *(SANE_Word *) value; 896141cc406Sopenharmony_ci if (status_nomem) 897141cc406Sopenharmony_ci { 898141cc406Sopenharmony_ci status_eof = SANE_FALSE; 899141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 900141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 901141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 902141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 903141cc406Sopenharmony_ci status_none = SANE_FALSE; 904141cc406Sopenharmony_ci status_accessdenied = SANE_FALSE; 905141cc406Sopenharmony_ci } 906141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 907141cc406Sopenharmony_ci break; 908141cc406Sopenharmony_ci case opt_status_accessdenied: 909141cc406Sopenharmony_ci status_accessdenied = *(SANE_Word *) value; 910141cc406Sopenharmony_ci if (status_accessdenied) 911141cc406Sopenharmony_ci { 912141cc406Sopenharmony_ci status_eof = SANE_FALSE; 913141cc406Sopenharmony_ci status_jammed = SANE_FALSE; 914141cc406Sopenharmony_ci status_nodocs = SANE_FALSE; 915141cc406Sopenharmony_ci status_coveropen = SANE_FALSE; 916141cc406Sopenharmony_ci status_ioerror = SANE_FALSE; 917141cc406Sopenharmony_ci status_nomem = SANE_FALSE; 918141cc406Sopenharmony_ci status_none = SANE_FALSE; 919141cc406Sopenharmony_ci } 920141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 921141cc406Sopenharmony_ci break; 922141cc406Sopenharmony_ci default: 923141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 924141cc406Sopenharmony_ci } 925141cc406Sopenharmony_ci break; 926141cc406Sopenharmony_ci case SANE_ACTION_GET_VALUE: 927141cc406Sopenharmony_ci switch (option) 928141cc406Sopenharmony_ci { 929141cc406Sopenharmony_ci case opt_num_opts: 930141cc406Sopenharmony_ci *(SANE_Word *) value = NELEMS (sod); 931141cc406Sopenharmony_ci break; 932141cc406Sopenharmony_ci case opt_filename: 933141cc406Sopenharmony_ci strcpy (value, filename); 934141cc406Sopenharmony_ci break; 935141cc406Sopenharmony_ci case opt_resolution: 936141cc406Sopenharmony_ci *(SANE_Word *) value = res; 937141cc406Sopenharmony_ci break; 938141cc406Sopenharmony_ci case opt_brightness: 939141cc406Sopenharmony_ci *(SANE_Word *) value = bright; 940141cc406Sopenharmony_ci break; 941141cc406Sopenharmony_ci case opt_contrast: 942141cc406Sopenharmony_ci *(SANE_Word *) value = contr; 943141cc406Sopenharmony_ci break; 944141cc406Sopenharmony_ci case opt_grayify: 945141cc406Sopenharmony_ci *(SANE_Word *) value = gray; 946141cc406Sopenharmony_ci break; 947141cc406Sopenharmony_ci case opt_three_pass: 948141cc406Sopenharmony_ci *(SANE_Word *) value = three_pass; 949141cc406Sopenharmony_ci break; 950141cc406Sopenharmony_ci case opt_hand_scanner: 951141cc406Sopenharmony_ci *(SANE_Word *) value = hand_scanner; 952141cc406Sopenharmony_ci break; 953141cc406Sopenharmony_ci case opt_read_only: 954141cc406Sopenharmony_ci *(SANE_Word *) value = test_option; 955141cc406Sopenharmony_ci break; 956141cc406Sopenharmony_ci case opt_custom_gamma: 957141cc406Sopenharmony_ci *(SANE_Word *) value = usegamma; 958141cc406Sopenharmony_ci break; 959141cc406Sopenharmony_ci case opt_gamma: 960141cc406Sopenharmony_ci memcpy ((SANE_Word *) value, &gamma[0][0], 961141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 962141cc406Sopenharmony_ci break; 963141cc406Sopenharmony_ci case opt_gamma_r: 964141cc406Sopenharmony_ci memcpy ((SANE_Word *) value, &gamma[1][0], 965141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 966141cc406Sopenharmony_ci break; 967141cc406Sopenharmony_ci case opt_gamma_g: 968141cc406Sopenharmony_ci memcpy ((SANE_Word *) value, &gamma[2][0], 969141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 970141cc406Sopenharmony_ci break; 971141cc406Sopenharmony_ci case opt_gamma_b: 972141cc406Sopenharmony_ci memcpy ((SANE_Word *) value, &gamma[3][0], 973141cc406Sopenharmony_ci 256 * sizeof (SANE_Word)); 974141cc406Sopenharmony_ci break; 975141cc406Sopenharmony_ci case opt_status: 976141cc406Sopenharmony_ci *(SANE_Word *) value = status_none; 977141cc406Sopenharmony_ci break; 978141cc406Sopenharmony_ci case opt_status_eof: 979141cc406Sopenharmony_ci *(SANE_Word *) value = status_eof; 980141cc406Sopenharmony_ci break; 981141cc406Sopenharmony_ci case opt_status_jammed: 982141cc406Sopenharmony_ci *(SANE_Word *) value = status_jammed; 983141cc406Sopenharmony_ci break; 984141cc406Sopenharmony_ci case opt_status_nodocs: 985141cc406Sopenharmony_ci *(SANE_Word *) value = status_nodocs; 986141cc406Sopenharmony_ci break; 987141cc406Sopenharmony_ci case opt_status_coveropen: 988141cc406Sopenharmony_ci *(SANE_Word *) value = status_coveropen; 989141cc406Sopenharmony_ci break; 990141cc406Sopenharmony_ci case opt_status_ioerror: 991141cc406Sopenharmony_ci *(SANE_Word *) value = status_ioerror; 992141cc406Sopenharmony_ci break; 993141cc406Sopenharmony_ci case opt_status_nomem: 994141cc406Sopenharmony_ci *(SANE_Word *) value = status_nomem; 995141cc406Sopenharmony_ci break; 996141cc406Sopenharmony_ci case opt_status_accessdenied: 997141cc406Sopenharmony_ci *(SANE_Word *) value = status_accessdenied; 998141cc406Sopenharmony_ci break; 999141cc406Sopenharmony_ci default: 1000141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1001141cc406Sopenharmony_ci } 1002141cc406Sopenharmony_ci break; 1003141cc406Sopenharmony_ci } 1004141cc406Sopenharmony_ci if (info) 1005141cc406Sopenharmony_ci *info = myinfo; 1006141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1007141cc406Sopenharmony_ci} 1008141cc406Sopenharmony_ci 1009141cc406Sopenharmony_cistatic void 1010141cc406Sopenharmony_ciget_line (char *buf, int len, FILE * f) 1011141cc406Sopenharmony_ci{ 1012141cc406Sopenharmony_ci do 1013141cc406Sopenharmony_ci fgets (buf, len, f); 1014141cc406Sopenharmony_ci while (*buf == '#'); 1015141cc406Sopenharmony_ci} 1016141cc406Sopenharmony_ci 1017141cc406Sopenharmony_cistatic int 1018141cc406Sopenharmony_cigetparmfromfile (void) 1019141cc406Sopenharmony_ci{ 1020141cc406Sopenharmony_ci FILE *fn; 1021141cc406Sopenharmony_ci int x, y; 1022141cc406Sopenharmony_ci char buf[1024]; 1023141cc406Sopenharmony_ci 1024141cc406Sopenharmony_ci parms.depth = 8; 1025141cc406Sopenharmony_ci parms.bytes_per_line = parms.pixels_per_line = parms.lines = 0; 1026141cc406Sopenharmony_ci if ((fn = fopen (filename, "rb")) == NULL) 1027141cc406Sopenharmony_ci { 1028141cc406Sopenharmony_ci DBG (1, "getparmfromfile: unable to open file \"%s\"\n", filename); 1029141cc406Sopenharmony_ci return -1; 1030141cc406Sopenharmony_ci } 1031141cc406Sopenharmony_ci 1032141cc406Sopenharmony_ci /* Skip comments. */ 1033141cc406Sopenharmony_ci do 1034141cc406Sopenharmony_ci get_line (buf, sizeof (buf), fn); 1035141cc406Sopenharmony_ci while (*buf == '#'); 1036141cc406Sopenharmony_ci if (!strncmp (buf, "P4", 2)) 1037141cc406Sopenharmony_ci { 1038141cc406Sopenharmony_ci /* Binary monochrome. */ 1039141cc406Sopenharmony_ci parms.depth = 1; 1040141cc406Sopenharmony_ci ppm_type = ppm_bitmap; 1041141cc406Sopenharmony_ci } 1042141cc406Sopenharmony_ci else if (!strncmp (buf, "P5", 2)) 1043141cc406Sopenharmony_ci { 1044141cc406Sopenharmony_ci /* Grayscale. */ 1045141cc406Sopenharmony_ci parms.depth = 8; 1046141cc406Sopenharmony_ci ppm_type = ppm_greyscale; 1047141cc406Sopenharmony_ci } 1048141cc406Sopenharmony_ci else if (!strncmp (buf, "P6", 2)) 1049141cc406Sopenharmony_ci { 1050141cc406Sopenharmony_ci /* Color. */ 1051141cc406Sopenharmony_ci parms.depth = 8; 1052141cc406Sopenharmony_ci ppm_type = ppm_color; 1053141cc406Sopenharmony_ci } 1054141cc406Sopenharmony_ci else 1055141cc406Sopenharmony_ci { 1056141cc406Sopenharmony_ci DBG (1, "getparmfromfile: %s is not a recognized PPM\n", filename); 1057141cc406Sopenharmony_ci fclose (fn); 1058141cc406Sopenharmony_ci return -1; 1059141cc406Sopenharmony_ci } 1060141cc406Sopenharmony_ci 1061141cc406Sopenharmony_ci /* Skip comments. */ 1062141cc406Sopenharmony_ci do 1063141cc406Sopenharmony_ci get_line (buf, sizeof (buf), fn); 1064141cc406Sopenharmony_ci while (*buf == '#'); 1065141cc406Sopenharmony_ci sscanf (buf, "%d %d", &x, &y); 1066141cc406Sopenharmony_ci 1067141cc406Sopenharmony_ci parms.last_frame = SANE_TRUE; 1068141cc406Sopenharmony_ci parms.bytes_per_line = (ppm_type == ppm_bitmap) ? (x + 7) / 8 : x; 1069141cc406Sopenharmony_ci parms.pixels_per_line = x; 1070141cc406Sopenharmony_ci if (hand_scanner) 1071141cc406Sopenharmony_ci parms.lines = -1; 1072141cc406Sopenharmony_ci else 1073141cc406Sopenharmony_ci parms.lines = y; 1074141cc406Sopenharmony_ci if ((ppm_type == ppm_greyscale) || (ppm_type == ppm_bitmap) || gray) 1075141cc406Sopenharmony_ci parms.format = SANE_FRAME_GRAY; 1076141cc406Sopenharmony_ci else 1077141cc406Sopenharmony_ci { 1078141cc406Sopenharmony_ci if (three_pass) 1079141cc406Sopenharmony_ci { 1080141cc406Sopenharmony_ci parms.format = SANE_FRAME_RED + (pass + 1) % 3; 1081141cc406Sopenharmony_ci parms.last_frame = (pass >= 2); 1082141cc406Sopenharmony_ci } 1083141cc406Sopenharmony_ci else 1084141cc406Sopenharmony_ci { 1085141cc406Sopenharmony_ci parms.format = SANE_FRAME_RGB; 1086141cc406Sopenharmony_ci parms.bytes_per_line *= 3; 1087141cc406Sopenharmony_ci } 1088141cc406Sopenharmony_ci } 1089141cc406Sopenharmony_ci fclose (fn); 1090141cc406Sopenharmony_ci return 0; 1091141cc406Sopenharmony_ci} 1092141cc406Sopenharmony_ci 1093141cc406Sopenharmony_ciSANE_Status 1094141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 1095141cc406Sopenharmony_ci{ 1096141cc406Sopenharmony_ci int rc = SANE_STATUS_GOOD; 1097141cc406Sopenharmony_ci 1098141cc406Sopenharmony_ci DBG (2, "sane_get_parameters\n"); 1099141cc406Sopenharmony_ci if (handle != MAGIC || !is_open) 1100141cc406Sopenharmony_ci rc = SANE_STATUS_INVAL; /* Unknown handle ... */ 1101141cc406Sopenharmony_ci else if (getparmfromfile ()) 1102141cc406Sopenharmony_ci rc = SANE_STATUS_INVAL; 1103141cc406Sopenharmony_ci *params = parms; 1104141cc406Sopenharmony_ci return rc; 1105141cc406Sopenharmony_ci} 1106141cc406Sopenharmony_ci 1107141cc406Sopenharmony_ciSANE_Status 1108141cc406Sopenharmony_cisane_start (SANE_Handle handle) 1109141cc406Sopenharmony_ci{ 1110141cc406Sopenharmony_ci char buf[1024]; 1111141cc406Sopenharmony_ci int nlines; 1112141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 1113141cc406Sopenharmony_ci struct timeval current; 1114141cc406Sopenharmony_ci#endif 1115141cc406Sopenharmony_ci 1116141cc406Sopenharmony_ci DBG (2, "sane_start\n"); 1117141cc406Sopenharmony_ci rgb_comp = 0; 1118141cc406Sopenharmony_ci if (handle != MAGIC || !is_open) 1119141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* Unknown handle ... */ 1120141cc406Sopenharmony_ci 1121141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 1122141cc406Sopenharmony_ci if(warming_up == SANE_TRUE) 1123141cc406Sopenharmony_ci { 1124141cc406Sopenharmony_ci gettimeofday(¤t,NULL); 1125141cc406Sopenharmony_ci if(current.tv_sec-start.tv_sec>5) 1126141cc406Sopenharmony_ci { 1127141cc406Sopenharmony_ci start.tv_sec = current.tv_sec; 1128141cc406Sopenharmony_ci return SANE_STATUS_WARMING_UP; 1129141cc406Sopenharmony_ci } 1130141cc406Sopenharmony_ci if(current.tv_sec-start.tv_sec<5) 1131141cc406Sopenharmony_ci return SANE_STATUS_WARMING_UP; 1132141cc406Sopenharmony_ci } 1133141cc406Sopenharmony_ci#endif 1134141cc406Sopenharmony_ci 1135141cc406Sopenharmony_ci if (infile != NULL) 1136141cc406Sopenharmony_ci { 1137141cc406Sopenharmony_ci fclose (infile); 1138141cc406Sopenharmony_ci infile = NULL; 1139141cc406Sopenharmony_ci if (!three_pass || ++pass >= 3) 1140141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1141141cc406Sopenharmony_ci } 1142141cc406Sopenharmony_ci 1143141cc406Sopenharmony_ci if (getparmfromfile ()) 1144141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1145141cc406Sopenharmony_ci 1146141cc406Sopenharmony_ci if ((infile = fopen (filename, "rb")) == NULL) 1147141cc406Sopenharmony_ci { 1148141cc406Sopenharmony_ci DBG (1, "sane_start: unable to open file \"%s\"\n", filename); 1149141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1150141cc406Sopenharmony_ci } 1151141cc406Sopenharmony_ci 1152141cc406Sopenharmony_ci /* Skip the header (only two lines for a bitmap). */ 1153141cc406Sopenharmony_ci nlines = (ppm_type == ppm_bitmap) ? 1 : 0; 1154141cc406Sopenharmony_ci while (nlines < 3) 1155141cc406Sopenharmony_ci { 1156141cc406Sopenharmony_ci /* Skip comments. */ 1157141cc406Sopenharmony_ci get_line (buf, sizeof (buf), infile); 1158141cc406Sopenharmony_ci if (*buf != '#') 1159141cc406Sopenharmony_ci nlines++; 1160141cc406Sopenharmony_ci } 1161141cc406Sopenharmony_ci 1162141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1163141cc406Sopenharmony_ci} 1164141cc406Sopenharmony_ci 1165141cc406Sopenharmony_cistatic SANE_Int rgblength = 0; 1166141cc406Sopenharmony_cistatic SANE_Byte *rgbbuf = 0; 1167141cc406Sopenharmony_cistatic SANE_Byte rgbleftover[3] = { 0, 0, 0 }; 1168141cc406Sopenharmony_ci 1169141cc406Sopenharmony_ciSANE_Status 1170141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * data, 1171141cc406Sopenharmony_ci SANE_Int max_length, SANE_Int * length) 1172141cc406Sopenharmony_ci{ 1173141cc406Sopenharmony_ci int len, x, hlp; 1174141cc406Sopenharmony_ci 1175141cc406Sopenharmony_ci DBG (2, "sane_read: max_length = %d, rgbleftover = {%d, %d, %d}\n", 1176141cc406Sopenharmony_ci max_length, rgbleftover[0], rgbleftover[1], rgbleftover[2]); 1177141cc406Sopenharmony_ci if (!length) 1178141cc406Sopenharmony_ci { 1179141cc406Sopenharmony_ci DBG (1, "sane_read: length == NULL\n"); 1180141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1181141cc406Sopenharmony_ci } 1182141cc406Sopenharmony_ci *length = 0; 1183141cc406Sopenharmony_ci if (!data) 1184141cc406Sopenharmony_ci { 1185141cc406Sopenharmony_ci DBG (1, "sane_read: data == NULL\n"); 1186141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1187141cc406Sopenharmony_ci } 1188141cc406Sopenharmony_ci if (handle != MAGIC) 1189141cc406Sopenharmony_ci { 1190141cc406Sopenharmony_ci DBG (1, "sane_read: unknown handle\n"); 1191141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1192141cc406Sopenharmony_ci } 1193141cc406Sopenharmony_ci if (!is_open) 1194141cc406Sopenharmony_ci { 1195141cc406Sopenharmony_ci DBG (1, "sane_read: call sane_open first\n"); 1196141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1197141cc406Sopenharmony_ci } 1198141cc406Sopenharmony_ci if (!infile) 1199141cc406Sopenharmony_ci { 1200141cc406Sopenharmony_ci DBG (1, "sane_read: scan was cancelled\n"); 1201141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 1202141cc406Sopenharmony_ci } 1203141cc406Sopenharmony_ci if (feof (infile)) 1204141cc406Sopenharmony_ci { 1205141cc406Sopenharmony_ci DBG (2, "sane_read: EOF reached\n"); 1206141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1207141cc406Sopenharmony_ci } 1208141cc406Sopenharmony_ci 1209141cc406Sopenharmony_ci if (status_jammed == SANE_TRUE) 1210141cc406Sopenharmony_ci return SANE_STATUS_JAMMED; 1211141cc406Sopenharmony_ci if (status_eof == SANE_TRUE) 1212141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1213141cc406Sopenharmony_ci if (status_nodocs == SANE_TRUE) 1214141cc406Sopenharmony_ci return SANE_STATUS_NO_DOCS; 1215141cc406Sopenharmony_ci if (status_coveropen == SANE_TRUE) 1216141cc406Sopenharmony_ci return SANE_STATUS_COVER_OPEN; 1217141cc406Sopenharmony_ci if (status_ioerror == SANE_TRUE) 1218141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1219141cc406Sopenharmony_ci if (status_nomem == SANE_TRUE) 1220141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1221141cc406Sopenharmony_ci if (status_accessdenied == SANE_TRUE) 1222141cc406Sopenharmony_ci return SANE_STATUS_ACCESS_DENIED; 1223141cc406Sopenharmony_ci 1224141cc406Sopenharmony_ci /* Allocate a buffer for the RGB values. */ 1225141cc406Sopenharmony_ci if (ppm_type == ppm_color && (gray || three_pass)) 1226141cc406Sopenharmony_ci { 1227141cc406Sopenharmony_ci SANE_Byte *p, *q, *rgbend; 1228141cc406Sopenharmony_ci if (rgbbuf == 0 || rgblength < 3 * max_length) 1229141cc406Sopenharmony_ci { 1230141cc406Sopenharmony_ci /* Allocate a new rgbbuf. */ 1231141cc406Sopenharmony_ci free (rgbbuf); 1232141cc406Sopenharmony_ci rgblength = 3 * max_length; 1233141cc406Sopenharmony_ci rgbbuf = malloc (rgblength); 1234141cc406Sopenharmony_ci if (rgbbuf == 0) 1235141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1236141cc406Sopenharmony_ci } 1237141cc406Sopenharmony_ci else 1238141cc406Sopenharmony_ci rgblength = 3 * max_length; 1239141cc406Sopenharmony_ci 1240141cc406Sopenharmony_ci /* Copy any leftovers into the buffer. */ 1241141cc406Sopenharmony_ci q = rgbbuf; 1242141cc406Sopenharmony_ci p = rgbleftover + 1; 1243141cc406Sopenharmony_ci while (p - rgbleftover <= rgbleftover[0]) 1244141cc406Sopenharmony_ci *q++ = *p++; 1245141cc406Sopenharmony_ci 1246141cc406Sopenharmony_ci /* Slurp in the RGB buffer. */ 1247141cc406Sopenharmony_ci len = fread (q, 1, rgblength - rgbleftover[0], infile); 1248141cc406Sopenharmony_ci rgbend = rgbbuf + len; 1249141cc406Sopenharmony_ci 1250141cc406Sopenharmony_ci q = data; 1251141cc406Sopenharmony_ci if (gray) 1252141cc406Sopenharmony_ci { 1253141cc406Sopenharmony_ci /* Zip through the buffer, converting color data to grayscale. */ 1254141cc406Sopenharmony_ci for (p = rgbbuf; p < rgbend; p += 3) 1255141cc406Sopenharmony_ci *q++ = ((long) p[0] + p[1] + p[2]) / 3; 1256141cc406Sopenharmony_ci } 1257141cc406Sopenharmony_ci else 1258141cc406Sopenharmony_ci { 1259141cc406Sopenharmony_ci /* Zip through the buffer, extracting data for this pass. */ 1260141cc406Sopenharmony_ci for (p = (rgbbuf + (pass + 1) % 3); p < rgbend; p += 3) 1261141cc406Sopenharmony_ci *q++ = *p; 1262141cc406Sopenharmony_ci } 1263141cc406Sopenharmony_ci 1264141cc406Sopenharmony_ci /* Save any leftovers in the array. */ 1265141cc406Sopenharmony_ci rgbleftover[0] = len % 3; 1266141cc406Sopenharmony_ci p = rgbbuf + (len - rgbleftover[0]); 1267141cc406Sopenharmony_ci q = rgbleftover + 1; 1268141cc406Sopenharmony_ci while (p < rgbend) 1269141cc406Sopenharmony_ci *q++ = *p++; 1270141cc406Sopenharmony_ci 1271141cc406Sopenharmony_ci len /= 3; 1272141cc406Sopenharmony_ci } 1273141cc406Sopenharmony_ci else 1274141cc406Sopenharmony_ci /* Suck in as much of the file as possible, since it's already in the 1275141cc406Sopenharmony_ci correct format. */ 1276141cc406Sopenharmony_ci len = fread (data, 1, max_length, infile); 1277141cc406Sopenharmony_ci 1278141cc406Sopenharmony_ci if (len == 0) 1279141cc406Sopenharmony_ci { 1280141cc406Sopenharmony_ci if (feof (infile)) 1281141cc406Sopenharmony_ci { 1282141cc406Sopenharmony_ci DBG (2, "sane_read: EOF reached\n"); 1283141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1284141cc406Sopenharmony_ci } 1285141cc406Sopenharmony_ci else 1286141cc406Sopenharmony_ci { 1287141cc406Sopenharmony_ci DBG (1, "sane_read: error while reading file (%s)\n", 1288141cc406Sopenharmony_ci strerror (errno)); 1289141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1290141cc406Sopenharmony_ci } 1291141cc406Sopenharmony_ci } 1292141cc406Sopenharmony_ci 1293141cc406Sopenharmony_ci if (parms.depth == 8) 1294141cc406Sopenharmony_ci { 1295141cc406Sopenharmony_ci /* Do the transformations ... DEMO ONLY ! THIS MAKES NO SENSE ! */ 1296141cc406Sopenharmony_ci for (x = 0; x < len; x++) 1297141cc406Sopenharmony_ci { 1298141cc406Sopenharmony_ci hlp = *((unsigned char *) data + x) - 128; 1299141cc406Sopenharmony_ci hlp *= (contr + (100 << SANE_FIXED_SCALE_SHIFT)); 1300141cc406Sopenharmony_ci hlp /= 100 << SANE_FIXED_SCALE_SHIFT; 1301141cc406Sopenharmony_ci hlp += (bright >> SANE_FIXED_SCALE_SHIFT) + 128; 1302141cc406Sopenharmony_ci if (hlp < 0) 1303141cc406Sopenharmony_ci hlp = 0; 1304141cc406Sopenharmony_ci if (hlp > 255) 1305141cc406Sopenharmony_ci hlp = 255; 1306141cc406Sopenharmony_ci *(data + x) = hlp; 1307141cc406Sopenharmony_ci } 1308141cc406Sopenharmony_ci /*gamma */ 1309141cc406Sopenharmony_ci if (usegamma) 1310141cc406Sopenharmony_ci { 1311141cc406Sopenharmony_ci unsigned char uc; 1312141cc406Sopenharmony_ci if (gray) 1313141cc406Sopenharmony_ci { 1314141cc406Sopenharmony_ci for (x = 0; x < len; x++) 1315141cc406Sopenharmony_ci { 1316141cc406Sopenharmony_ci uc = *((unsigned char *) data + x); 1317141cc406Sopenharmony_ci uc = gamma[0][uc]; 1318141cc406Sopenharmony_ci *(data + x) = uc; 1319141cc406Sopenharmony_ci } 1320141cc406Sopenharmony_ci } 1321141cc406Sopenharmony_ci else 1322141cc406Sopenharmony_ci { 1323141cc406Sopenharmony_ci for (x = 0; x < len; x++) 1324141cc406Sopenharmony_ci { 1325141cc406Sopenharmony_ci if (parms.format == SANE_FRAME_RGB) 1326141cc406Sopenharmony_ci { 1327141cc406Sopenharmony_ci uc = *((unsigned char *) (data + x)); 1328141cc406Sopenharmony_ci uc = (unsigned char) gamma[rgb_comp + 1][(int) uc]; 1329141cc406Sopenharmony_ci *((unsigned char *) data + x) = uc; 1330141cc406Sopenharmony_ci rgb_comp += 1; 1331141cc406Sopenharmony_ci if (rgb_comp > 2) 1332141cc406Sopenharmony_ci rgb_comp = 0; 1333141cc406Sopenharmony_ci } 1334141cc406Sopenharmony_ci else 1335141cc406Sopenharmony_ci { 1336141cc406Sopenharmony_ci int f = 0; 1337141cc406Sopenharmony_ci if (parms.format == SANE_FRAME_RED) 1338141cc406Sopenharmony_ci f = 1; 1339141cc406Sopenharmony_ci if (parms.format == SANE_FRAME_GREEN) 1340141cc406Sopenharmony_ci f = 2; 1341141cc406Sopenharmony_ci if (parms.format == SANE_FRAME_BLUE) 1342141cc406Sopenharmony_ci f = 3; 1343141cc406Sopenharmony_ci if (f) 1344141cc406Sopenharmony_ci { 1345141cc406Sopenharmony_ci uc = *((unsigned char *) (data + x)); 1346141cc406Sopenharmony_ci uc = (unsigned char) gamma[f][(int) uc]; 1347141cc406Sopenharmony_ci *((unsigned char *) data + x) = uc; 1348141cc406Sopenharmony_ci } 1349141cc406Sopenharmony_ci } 1350141cc406Sopenharmony_ci } 1351141cc406Sopenharmony_ci } 1352141cc406Sopenharmony_ci } 1353141cc406Sopenharmony_ci } 1354141cc406Sopenharmony_ci *length = len; 1355141cc406Sopenharmony_ci DBG (2, "sane_read: read %d bytes\n", len); 1356141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1357141cc406Sopenharmony_ci} 1358141cc406Sopenharmony_ci 1359141cc406Sopenharmony_civoid 1360141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 1361141cc406Sopenharmony_ci{ 1362141cc406Sopenharmony_ci DBG (2, "sane_cancel: handle = %p\n", handle); 1363141cc406Sopenharmony_ci pass = 0; 1364141cc406Sopenharmony_ci if (infile != NULL) 1365141cc406Sopenharmony_ci { 1366141cc406Sopenharmony_ci fclose (infile); 1367141cc406Sopenharmony_ci infile = NULL; 1368141cc406Sopenharmony_ci } 1369141cc406Sopenharmony_ci return; 1370141cc406Sopenharmony_ci} 1371141cc406Sopenharmony_ci 1372141cc406Sopenharmony_ciSANE_Status 1373141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 1374141cc406Sopenharmony_ci{ 1375141cc406Sopenharmony_ci DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle, 1376141cc406Sopenharmony_ci non_blocking); 1377141cc406Sopenharmony_ci if (!infile) 1378141cc406Sopenharmony_ci { 1379141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: not scanning\n"); 1380141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1381141cc406Sopenharmony_ci } 1382141cc406Sopenharmony_ci if (non_blocking) 1383141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1384141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1385141cc406Sopenharmony_ci} 1386141cc406Sopenharmony_ci 1387141cc406Sopenharmony_ciSANE_Status 1388141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 1389141cc406Sopenharmony_ci{ 1390141cc406Sopenharmony_ci DBG (2, "sane_get_select_fd: handle = %p, fd %s 0\n", handle, 1391141cc406Sopenharmony_ci fd ? "!=" : "="); 1392141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1393141cc406Sopenharmony_ci} 1394