home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / epsonsan.zip / epson_17062002.c next >
C/C++ Source or Header  |  2002-08-16  |  83KB  |  2,980 lines

  1. /* epson.c - SANE library for Epson flatbed (and film) scanners.
  2.  
  3.    based on Kazuhiro Sasayama previous
  4.    Work on epson.[ch] file from the SANE package.
  5.  
  6.    original code taken from sane-0.71
  7.    Copyright (C) 1997 Hypercore Software Design, Ltd.
  8.  
  9.    modifications (see detail below)
  10.    ---------------------------------
  11.    Copyright (C) 1998 Christian Bucher
  12.    Copyright (C) 1998 Kling & Hautzinger GmbH
  13.    Copyright (C) 1999 Clive Stubbings
  14.    
  15.    This file is part of the SANE package.
  16.  
  17.    This program is free software; you can redistribute it and/or
  18.    modify it under the terms of the GNU General Public License as
  19.    published by the Free Software Foundation; either version 2 of the
  20.    License, or (at your option) any later version.
  21.  
  22.    This program is distributed in the hope that it will be useful, but
  23.    WITHOUT ANY WARRANTY; without even the implied warranty of
  24.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  25.    General Public License for more details.
  26.  
  27.    You should have received a copy of the GNU General Public License
  28.    along with this program; if not, write to the Free Software
  29.    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  30.    MA 02111-1307, USA.
  31.  
  32.    As a special exception, the authors of SANE give permission for
  33.    additional uses of the libraries contained in this release of SANE.
  34.  
  35.    The exception is that, if you link a SANE library with other files
  36.    to produce an executable, this does not by itself cause the
  37.    resulting executable to be covered by the GNU General Public
  38.    License.  Your use of that executable is in no way restricted on
  39.    account of linking the SANE library code into it.
  40.  
  41.    This exception does not, however, invalidate any other reasons why
  42.    the executable file might be covered by the GNU General Public
  43.    License.
  44.  
  45.    If you submit changes to SANE to the maintainers to be included in
  46.    a subsequent release, you agree by submitting the changes that
  47.    those changes may be distributed with this exception intact.
  48.  
  49.    If you write modifications of your own for SANE, it is your choice
  50.    whether to permit this exception to apply to your modifications.
  51.    If you do not wish that, delete this exception notice.  */
  52.  
  53. /*    Style: K&R, 4 column hard tabs */
  54. /*
  55.      Changes
  56.         March-Sept 1999, Clive Stubbings, scanner@vjet.demon.co.uk
  57.             Support of Filmscan 200 scanner
  58.             Support for multiple devices
  59.             Lots of extra comments....
  60.         Oct 1999, Dave Hill <dave@minnie.demon.co.uk>
  61.             Better Support of GT7000 using Clive's Filmscan mods.
  62. 12/6/02 - better debug levels
  63.     < 10 user stuff
  64.     > 10 options and details
  65.     > 20 i/o routines, status, internal sane stuff etc
  66.     > 30 low level io status (scsi io routines)
  67.  
  68. */
  69.  
  70.  
  71. #ifdef _AIX
  72. # include <lalloca.h>        /* MUST come first for AIX! */
  73. #endif
  74.  
  75. #include <sane/config.h>
  76.  
  77. #include <lalloca.h>
  78.  
  79. #include <limits.h>
  80. #include <stdio.h>
  81. #include <string.h>
  82. #include <stdlib.h>
  83. #include <ctype.h>
  84. #include <assert.h>
  85. #include <math.h>
  86.  
  87. #include <sane/sane.h>
  88. #include <sane/saneopts.h>
  89. #include <sane/sanei_scsi.h>
  90. #include <sane/sanei_pio.h>
  91. #include "epson.h"
  92.  
  93. #define BACKEND_NAME    epson
  94. #include <sane/sanei_backend.h>
  95.  
  96. #include <sane/sanei_config.h>
  97. #define EPSON_CONFIG_FILE "epson.conf"
  98. #define DEFAULT_DEVNAME    "/dev/scanner"
  99.  
  100. #ifndef PATH_MAX
  101. # define PATH_MAX 1024
  102. #endif
  103.  
  104. #define TEST_UNIT_READY_COMMAND 0x00
  105. #define READ_6_COMMAND 0x08
  106. #define WRITE_6_COMMAND 0x0a
  107. #define INQUIRY_COMMAND 0x12
  108. #define TYPE_PROCESSOR 0x03
  109.  
  110. #define  walloc(x)    ( x *) malloc( sizeof( x) )
  111. #define  walloca(x)    ( x *) alloca( sizeof( x) )
  112.  
  113. /*
  114.  *    Epson ESC-I scanner control codes
  115.  */
  116. #define    STX    0x02
  117. #define    ACK    0x06
  118. #define    NAK    0x15
  119. #define    CAN    0x18
  120. #define    ESC    0x1B
  121.  
  122. #define    EPSON_LEVEL_A1        0
  123. #define    EPSON_LEVEL_A2        1
  124. #define    EPSON_LEVEL_B1        2
  125. #define    EPSON_LEVEL_B2        3
  126. #define    EPSON_LEVEL_B3        4
  127. #define    EPSON_LEVEL_B4        5
  128. #define    EPSON_LEVEL_B5        6
  129. #define    EPSON_LEVEL_B6        7
  130. #define    EPSON_LEVEL_B7        8         /* GT7000 */
  131. #define    EPSON_LEVEL_F5        9        /* Default for filmscan */
  132.  
  133. #define    EPSON_LEVEL_DEFAULT    EPSON_LEVEL_B3    /* For flatbeds only */
  134. typedef struct
  135.   {
  136.     char *level;
  137.  
  138.     int I:1            /* request identity             */
  139.      ,F:1            /* request status               */
  140.      ,S:1            /* request condition            */
  141.      ,C:1            /* set color mode               */
  142.      ,G:1            /* start scanning               */
  143.      ,D:1            /* set data format              */
  144.      ,R:1            /* set resolution               */
  145.      ,H:1            /* set zoom                     */
  146.      ,A:1            /* set scan area                */
  147.      ,L:1            /* set bright                   */
  148.      ,Z:1            /* set gamma                    */
  149.      ,B:1            /* set halftoning               */
  150.      ,M:1            /* set color correction         */
  151.      ,AT:1            /* initialize scanner           */
  152.      ,g:1            /* set speed                    */
  153.      ,d:1,            /* set lcount                   */
  154.      N:1,            /* set filmtype                 */
  155.      Q:1,            /* set sharpness                */
  156.      K:1,            /* set orientation              */
  157.      T:1,            /* Exposure Time                */
  158.      m:1,            /* Download colour correction   */
  159.      z:1            /* Download gamma table         */
  160.      ;
  161.   } EpsonCmdRec;
  162.  
  163. EpsonCmdRec epson_cmd[] =
  164. {
  165. /*
  166.          request identity
  167.          |  request status
  168.          |  |  request condition
  169.          |  |  |  set color mode
  170.          |  |  |  |  start scanning
  171.          |  |  |  |  |  set data format
  172.          |  |  |  |  |  |  set resolution                set filmtype
  173.          |  |  |  |  |  |  |  set zoom                   |  set sharpness
  174.          |  |  |  |  |  |  |  |  set scan area           |  |  set orientation
  175.          |  |  |  |  |  |  |  |  |  set brightness       |  |  |  exposure Time
  176.          |  |  |  |  |  |  |  |  |  |  set gamma         |  |  |  |  download colour corr'n
  177.          |  |  |  |  |  |  |  |  |  |  |  set halftoning |  |  |  |  |  download gamma table
  178.          |  |  |  |  |  |  |  |  |  |  |  |  set color correction |  |  |
  179.          |  |  |  |  |  |  |  |  |  |  |  |  |  initialize scanner|  |  |
  180.          |  |  |  |  |  |  |  |  |  |  |  |  |  |  set speed   |  |  |  |
  181.          |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  set lcount  |  |  |
  182.          |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
  183.  */
  184.   {"A1", 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
  185.   {"A2", 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  186.   {"B1", 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
  187.   {"B2", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  188.   {"B3", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  189.   {"B4", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  190.   {"B5", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  191.   {"B6", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0},
  192.   {"B7", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0},
  193.   {"F5", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
  194. };
  195.  
  196. /*
  197.  *    This enum and the DefaultCmdTable must match..
  198.  */
  199. enum {
  200.     RESET= 0, SET_MODE, SET_FILMTYPE, SET_SPEED, SET_RESOLUTION, SET_GAMMA, SET_SHARPNESS, SET_ZOOM,
  201.     SET_AREA, SET_DOWNLOAD_COLOUR, SET_DOWNLOAD_GAMMA, SET_ORIENTATION, SET_DEPTH, SET_HALFTONE,
  202.     SET_COLOUR, SET_LCOUNT, SET_BRIGHTNESS, SET_BAY, SET_EXPOSURETIME,
  203.     CMD_TABLE_SIZE
  204. };
  205.  
  206. /*
  207.  *    
  208.  */
  209. CmdEntry DefaultCmdTable[] = {
  210.         { RESET,            '@', "Reset/initialise",0, 0 },
  211.         { SET_MODE,         'C', "Set mode",        0, 1 },
  212.         { SET_FILMTYPE,     'N', "Set filmtype",    0, 1 },
  213.         { SET_SPEED,        'g', "Set speed",        0, 1 },
  214.         { SET_RESOLUTION,    'R', "Set resolution",    0, 4 },
  215.         { SET_GAMMA,        'Z', "Set gamma",        0, 1 },
  216.         { SET_SHARPNESS,    'Q', "Set sharpness",    0, 1 },
  217.         { SET_ZOOM,            'H', "Set zoom",        0, 2 },
  218.         { SET_AREA,            'A', "Set area",        0, 8 },
  219.         { SET_DOWNLOAD_COLOUR,    'm', "Download colour correction", 0, 9 },
  220.         { SET_DOWNLOAD_GAMMA,     'z', "Download gamma",    0, 257 },
  221.         { SET_ORIENTATION,    'K', "Set orientation",    0, 1 },
  222.         { SET_DEPTH,        'D', "Set depth",        0, 1 },
  223.         { SET_HALFTONE,        'B', "Set halftone",    0, 1 },
  224.         { SET_COLOUR,        'M', "Set colour corr.",0, 1 },
  225.         { SET_LCOUNT,        'd', "Set lcount",        0, 1 },
  226.         { SET_BRIGHTNESS,    'L', "Set brightness",    0, 1 },
  227.         { SET_BAY,            'P', "Set bay",            0, 2 },
  228.         { SET_EXPOSURETIME,    'T', "Set exposure-time",0, 4 }
  229.     };
  230.  
  231.  
  232. static unsigned char     neg_tval[4] = {2, 0x8e, 0x86, 0x92};
  233.  
  234. static Epson_Scanner    *handles = NULL;
  235. static Epson_Device        *devices = NULL;
  236. static int num_devices = 0;
  237.  
  238. /*
  239.  *    Structs for input data commands
  240.  */
  241. #pragma    pack(1)
  242.  
  243. typedef struct {
  244.     u_char code;
  245.     u_char status;
  246.     u_short count;
  247.     u_char buf[1];
  248.   } EpsonHdrRec, *EpsonHdr;
  249.  
  250. typedef struct {
  251.     u_char code;
  252.     u_char status;
  253.     u_short count;
  254.     u_char type;
  255.     u_char level;
  256.     u_char buf[1];
  257.   } EpsonIdentRec, *EpsonIdent;
  258.  
  259. #pragma    pack()
  260.  
  261.  
  262. /*
  263.  *    FILMTYPE OPTIONS - Command 'N'
  264.  */
  265. static const SANE_String_Const filmtype_list[] =
  266.     { "Positive Film", "Negative Film", "Positive Slide", "Negative Slide", NULL};
  267. static int filmtype_values[] = { 0, 1, 2, 3 };
  268. #define OPT_FILMTYPE_NEGATIVE 0x01
  269. #define OPT_FILMTYPE_SLIDE 0x02
  270.  
  271. /*
  272.  *    Mode changes all sorts of stuff.. These are values that are set based
  273.  *    on the current mode.. mode takes values 0-2 (binary, mono, colour)
  274.  */
  275. struct mode_param
  276. {
  277.   int color;
  278.   int mode_flags;
  279.   int dropout_mask;
  280.   int depth;
  281. };
  282.  
  283. static const struct mode_param mode_params[] =
  284. {
  285.   {0, 0x00, 0x30, 1},        /* Binary, 1 bit/pixel */
  286.   {0, 0x00, 0x30, 8},        /* Mono, grey scale (8bpp) */
  287.   {1, 0x02, 0x00, 8},        /* Colour */
  288. };
  289.  
  290. static const SANE_String_Const mode_list[] =
  291. {
  292.   "Binary",
  293.   "Gray",
  294.   "Color",
  295.   NULL
  296. };
  297.  
  298. static const SANE_String_Const bay_list[] =
  299. {
  300.   "Bay 1",
  301.   "Bay 2",
  302.   "Bay 3",
  303.   "Bay 4",
  304.   "Bay 5",
  305.   "Bay 6",
  306.   NULL
  307. };
  308.  
  309. static int dropout_params[] =
  310. {
  311.   0x00,
  312.   0x10,
  313.   0x20,
  314.   0x30,
  315. };
  316.  
  317. static const SANE_String_Const dropout_list[] =
  318. {
  319.   "None",
  320.   "Red",
  321.   "Green",
  322.   "Blue",
  323.   NULL
  324. };
  325.  
  326. static int halftone_params[] =
  327. {
  328.   0x01,
  329.   0x00,
  330.   0x10,
  331.   0x20,
  332.   0x80,
  333.   0x90,
  334.   0xa0,
  335.   0xb0
  336. };
  337.  
  338. static const SANE_String_Const halftone_list[] =
  339. {
  340.   "None",
  341.   "Halftone A",
  342.   "Halftone B",
  343.   "Halftone C",
  344.   NULL
  345. };
  346.  
  347. static const SANE_String_Const halftone_list_4[] =
  348. {
  349.   "None",
  350.   "Halftone A",
  351.   "Halftone B",
  352.   "Halftone C",
  353.   "Dither A",
  354.   "Dither B",
  355.   "Dither C",
  356.   "Dither D",
  357.   NULL
  358. };
  359.  
  360. static int brightness_params[] =
  361. {3, 2, 1, 0, -1, -2, -3};
  362.  
  363. static const SANE_String_Const brightness_list[] =
  364. {
  365.   "Very light"
  366.   ,"Lighter"
  367.   ,"Light"
  368.   ,"Normal"
  369.   ,"Dark"
  370.   ,"Darker"
  371.   ,"Very dark"
  372.   ,NULL
  373. };
  374.  
  375. /*
  376.  *    Sharpness - implemented on the FS200
  377.  */
  378. static int sharpness_params[] = {2, 1, 0, -1, -2};
  379. static const SANE_String_Const sharpness_list[] = {
  380.         "Very Sharp", "Sharpened", "Normal", "Softened", "Very Soft", NULL
  381.     };
  382.  
  383. /*
  384.  * Gamma - implemented on the FS200
  385.  */
  386. static int gamma_params[] = {1, 2, 0, 16, 32, 3};
  387. static const SANE_String_Const gamma_list[] = {
  388.         "CRT A (linear)", "CRT B (normal)", "Printer A", "Printer B", "Printer C", "Automatic (default)", NULL
  389.     };
  390.  
  391. #define OPT_GAMMA_USER 5
  392.  
  393. #define GAMMAVAL 0.37    /* 2.6 ish for display */
  394. /* #define GAMMAVAL 0.45    *//* 2.2 ish - the correct number really */
  395.  
  396. /*
  397.  * For the FS200 the only acceptable values are: 0, 1, 16, 32, 64, 128
  398.  * They select the type of 3x3 colour matrix to apply to the data
  399.  * during the scan
  400.  */
  401. static int colour_params[] = {128,0,32,64,16, 1};
  402. static const SANE_String_Const colour_list[] = {
  403.         "CRT","dot matrix","thermal transfer","ink jet","green/yellow","Automatic (default)", NULL
  404.     };
  405. #define OPT_COLOUR_USER    5
  406.  
  407. unsigned char colour_table[9] = {32,0,0, 0,32,0, 0,0,32};
  408. unsigned char slide_colour_table[9] = {0x2b, 0x07, 0x8d,  0x84, 0x1f, 0x83,  0x86, 0x85, 0x31};
  409.  
  410. /*
  411.  *    Lookuptable for slide exposure time vs 'T' exposure value to use full
  412.  *    dynamic range of scanner
  413.  */
  414. unsigned char pos_exposure_correction[256] = { 155, 155, 155, 155, 155, 155,
  415.     155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
  416.     155, 155, 155, 154, 154, 154, 154, 154, 154, 153, 153, 153, 153, 153,
  417.     153, 152, 152, 152, 152, 152, 152, 151, 151, 151, 151, 151, 151, 150,
  418.     150, 150, 150, 150, 150, 149, 149, 149, 149, 149, 149, 148, 148, 148,
  419.     148, 148, 148, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146,
  420.     145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 143, 143,
  421.     143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 141, 141, 141, 141,
  422.     141, 141, 140, 140, 140, 140, 140, 140, 139, 139, 139, 139, 139, 139,
  423.     138, 138, 138, 138, 138, 138, 138, 138, 137, 137, 137, 137, 137, 137,
  424.     137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
  425.     135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134,
  426.     134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 133, 133,
  427.     133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
  428.     131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
  429.     131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
  430.     130, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
  431.     129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  432.     128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
  433. };    
  434.  
  435. #if 0
  436. unsigned char neg_exposure_correction[256] = { 128, 128, 128, 128, 128,
  437.     128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  438.     128, 128, 128, 128, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
  439.     129, 129, 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 130,
  440.     130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131,
  441.     131, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, 132, 132, 132,
  442.     132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 133,
  443.     133, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 135, 135, 135,
  444.     135, 135, 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136,
  445.     136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138,
  446.     138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 140,
  447.     140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 142, 142, 142,
  448.     142, 142, 142, 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144,
  449.     144, 145, 145, 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 147,
  450.     147, 147, 147, 147, 148, 148, 148, 148, 148, 148, 149, 149, 149, 149,
  451.     149, 149, 150, 150, 150, 150, 150, 150, 151, 151, 151, 151, 151, 151,
  452.     152, 152, 152, 152, 152, 152, 153, 153, 153, 153, 153, 153, 154, 154,
  453.     154, 154, 154, 154, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
  454.     155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
  455. };    
  456. #endif
  457.  
  458.  
  459. SANE_Range zoom_range = {50, 200, 0};
  460. /*SANE_Range zoom_range = {50, 200};*/
  461.  
  462.  
  463. /*
  464.  *    Select image orientation ('K' command)
  465.  */
  466. static int orientation_params[] = {0,1,2,3};
  467. static const SANE_String_Const orientation_list_f[] = {
  468.         "Normal", "L<->R swapped", "Inverted", "Both", NULL
  469.     };
  470. /* For flatbed GT7000 */
  471. static const SANE_String_Const orientation_list_b[] = {
  472.         "Normal", "L<->R swapped", NULL
  473.     };
  474.  
  475.  
  476. /*
  477.  *    Internal decls
  478.  */
  479. static char *nstring(char *str, int len);
  480. static int scsi_write(int fd, const void *buf, size_t buf_size, SANE_Status * status);
  481. static int send(Epson_Scanner * s, const void *buf, size_t buf_size, SANE_Status * status);
  482. static int scsi_read(int fd, void *buf, size_t buf_size, SANE_Status * status);
  483. static int receive(Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status);
  484. static SANE_Status inquiry(int fd, int page_code, void *buf, size_t * buf_size);
  485. static SANE_Status expect_ack(Epson_Scanner * s);
  486. static SANE_Status epsonopen(const char *dev_name, Epson_Scanner *s);
  487. static void epsonclose (Epson_Scanner * s);
  488. static void setgammatable(unsigned char *gammatable, int min, int max, float gammaval);
  489.  
  490.  
  491. /*
  492.  *    S E T U P C O M M A N D S  -- Set up the scanner command table
  493.  */
  494. static void setupcommands(Epson_Device *hw, int type, int level)
  495. {
  496.     CmdEntry *cmdtab;
  497.     EpsonCmdRec    *ref;
  498.     int        n;
  499.     int        matched;
  500.  
  501.     cmdtab = hw->cmd2;
  502.     switch (type) {
  503.         case 'B':
  504.             ref = &epson_cmd[EPSON_LEVEL_DEFAULT];
  505.             break;
  506.         case 'F':
  507.             ref = &epson_cmd[EPSON_LEVEL_F5];
  508.             break;
  509.         default:
  510.             return;
  511.     }
  512.  
  513.     matched = 0;
  514.     for (n = 0; n < NELEMS(epson_cmd); n++) {
  515.         if ((type == epson_cmd[n].level[0]) && (level == epson_cmd[n].level[1])) {
  516.             ref = &epson_cmd[n];
  517.             matched = 1;
  518.             break;
  519.         }
  520.     }
  521.  
  522.     if (! matched)
  523.         DBG (1, "Unknown type %c or level %c, using %s\n", type, level, ref->level);
  524.  
  525.     hw->type = type;
  526.     hw->level = ref->level[1] - '0';
  527.     DBG (2, "hw->level 0x%02x\n", hw->level);
  528.     
  529.     if (ref->AT) cmdtab[RESET].enabled = 1;
  530.     if (ref->A) cmdtab[SET_AREA].enabled = 1;
  531.     if (ref->B) cmdtab[SET_HALFTONE].enabled = 1;
  532.     if (ref->C) cmdtab[SET_MODE].enabled = 1;
  533.     if (ref->D) cmdtab[SET_DEPTH].enabled = 1;
  534.     if (ref->H) cmdtab[SET_ZOOM].enabled = 1;
  535.     if (ref->K) cmdtab[SET_ORIENTATION].enabled = 1;
  536.     if (ref->L) cmdtab[SET_BRIGHTNESS].enabled = 1;
  537.     if (ref->M) cmdtab[SET_COLOUR].enabled = 1;
  538.     if (ref->N) cmdtab[SET_FILMTYPE].enabled = 1;
  539.     if (ref->Q) cmdtab[SET_SHARPNESS].enabled = 1;
  540.     if (ref->R) cmdtab[SET_RESOLUTION].enabled = 1;
  541.     if (ref->Z) cmdtab[SET_GAMMA].enabled = 1;
  542.     if (ref->d) cmdtab[SET_LCOUNT].enabled = 1;
  543.     if (ref->g) cmdtab[SET_SPEED].enabled = 1;
  544.     if (ref->T) cmdtab[SET_EXPOSURETIME].enabled = 1;
  545.     if (ref->z)    cmdtab[SET_DOWNLOAD_GAMMA].enabled = 1;
  546.     if (ref->m)    cmdtab[SET_DOWNLOAD_COLOUR].enabled = 1;
  547.  
  548.     if (hw->type == 'F') {
  549.         cmdtab[SET_BAY].enabled = 1;
  550.     }
  551.  
  552. }
  553.  
  554.  
  555. /*
  556.  *    S I M P L E C O M M A N D --  Send an <escape> command with 1 or 2
  557.  *                                    bytes of data
  558.  *
  559.  *    Send:    <escap><command code>
  560.  *    Expect:    <ack>
  561.  *    Send:    <data>[<data>]
  562.  *    Expect:    <ack>
  563.  *
  564.  *    If the command is not enabled for this scanner configuration, just
  565.  *    return a 'good' status and do nothing.
  566.  */
  567. static SANE_Status
  568. simplecommand(int command, Epson_Scanner *s, int value, int value2)
  569. {
  570.     SANE_Status status;
  571.     unsigned char data[2];
  572.     CmdEntry    *cmd;
  573.  
  574.     assert(command == s->hw->cmd2[command].command);
  575.  
  576.     cmd = &s->hw->cmd2[command];
  577.     if (cmd->enabled != 1) {
  578.         DBG(2, "Command %s not enabled - ignoring.\n", cmd->name);
  579.         return SANE_STATUS_GOOD;
  580.         }
  581.  
  582.     DBG(2, "Command: %s \'%c\' %d %d\n", cmd->name, cmd->code, value, value2);
  583.  
  584.     data[0] = ESC; 
  585.     data[1] = cmd->code;
  586.     send (s, data, 2, &status);
  587.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  588.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  589.         return status;
  590.     }
  591.  
  592.     data[0] = value; data[1] = value2;
  593.     send (s, data, cmd->length, &status);
  594.     if ((status = expect_ack (s)) != SANE_STATUS_GOOD)
  595.         DBG(2, "Command: %s \'%c\' %d %d - data failed\n", cmd->name, cmd->code, value, value2);
  596.  
  597.     return status;
  598. }
  599.  
  600. /*
  601.  *    I N P U T C O M M A N D  --  Execute an input command, grab response and return in EpsonHdr struct
  602.  *
  603.  *    Returns SANE_Status in *status
  604.  *    Returns NULL if failed or a malloc()'d EpsonHdr struct that must be
  605.  *    free()'d by caller    
  606.  */
  607. static EpsonHdr 
  608. inputcommand (Epson_Scanner * s, const u_char * cmd, size_t cmd_size, SANE_Status * status)
  609. {
  610.     EpsonHdr head;
  611.     u_char *buf;
  612.  
  613.     if ((head = walloc (EpsonHdrRec)) == NULL) {
  614.         *status = SANE_STATUS_NO_MEM;
  615.         return (EpsonHdr) 0;
  616.     }
  617.     send (s, cmd, cmd_size, status);
  618.  
  619.     if (*status != SANE_STATUS_GOOD) {
  620.         DBG(16,"Send failed\n");
  621.         free(head);
  622.         return (EpsonHdr) 0;
  623.     }
  624.  
  625.     buf = (u_char *) head;
  626.     if (s->hw->is_scsi)
  627.         receive (s, buf, 4, status);
  628.     else
  629.         receive (s, buf, 1, status);
  630.  
  631.     if (SANE_STATUS_GOOD != *status) {
  632.         free(head);
  633.         return (EpsonHdr) 0;
  634.     }
  635.  
  636.     buf++;
  637.     DBG (14, "code   %02x\n", (int) head->code);
  638.  
  639.     switch (head->code) {
  640.         default:
  641.             if (head->code == 0)
  642.                 DBG (1, "Incompatible printer port (probably bi/directional)\n");
  643.             else if (cmd[cmd_size - 1] == head->code)
  644.                 DBG (1, "Incompatible printer port (probably not bi/directional)\n");
  645.             DBG (2, "Illegal response of scanner for command: %02x\n", head->code);
  646.             break;
  647.  
  648.         case NAK:
  649.             DBG(3,"inputcommand - nak'd\n");
  650.         case ACK:
  651.             head->count = 0;
  652.             break;
  653.  
  654.         case STX:
  655.             if (!s->hw->is_scsi) {
  656.                 receive (s, buf, 3, status);
  657.             }
  658.             if (SANE_STATUS_GOOD != *status) {
  659.                 free(head);
  660.                 return (EpsonHdr) 0;
  661.             }
  662.             DBG (14, "status %02x\n", (int) head->status);
  663.             DBG (14, "count  %d\n", (int) head->count);
  664.  
  665. /* Only read rest of buffer if it exists! */
  666.  
  667.             if (head->count > 0) {
  668.                 if (NULL == (head = realloc (head, sizeof (EpsonHdrRec) + head->count))) {
  669.                     *status = SANE_STATUS_NO_MEM;
  670.                     free(head);
  671.                     return (EpsonHdr) 0;
  672.                 }
  673.  
  674.                 buf = head->buf;
  675.                 receive (s, buf, head->count, status);
  676.  
  677.                 if (SANE_STATUS_GOOD != *status) {
  678.                     free(head);
  679.                     return (EpsonHdr) 0;
  680.                 }
  681.  
  682. /*                buf += head->count; */
  683. /*                sanei_hexdmp( head, sizeof( EpsonHdrRec) + head->count, "epson"); */
  684.             }
  685.             break;
  686.     }
  687.  
  688.     return head;
  689. }
  690.  
  691.  
  692. /*
  693.  *    S E T _ R E S O L U T I O N --
  694.  */
  695. static SANE_Status
  696. set_resolution (Epson_Scanner * s, int xres, int yres)
  697. {
  698.     SANE_Status status;
  699.     unsigned char data[2], params[4];
  700.     CmdEntry    *cmd;
  701.  
  702.     assert(s->hw->cmd2[SET_RESOLUTION].command == SET_RESOLUTION);
  703.  
  704.     cmd = &s->hw->cmd2[SET_RESOLUTION];
  705.     if (cmd->enabled != 1)
  706.         return SANE_STATUS_GOOD;
  707.  
  708.  
  709.     DBG(2, "Command: %s \'%c\' %d %d\n", cmd->name, cmd->code, xres, yres);
  710.  
  711.     data[0] = ESC;
  712.     data[1] = cmd->code;
  713.     send (s, data, 2, &status);
  714.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  715.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  716.         return status;
  717.     }
  718.  
  719.     params[0] = xres;
  720.     params[1] = xres >> 8;
  721.     params[2] = yres;
  722.     params[3] = yres >> 8;
  723.     send (s, params, 4, &status);
  724.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD)
  725.         DBG(2, "Command: %s \'%c\' %d %d - data failed\n", cmd->name, cmd->code, xres, yres);
  726.  
  727.     return status;
  728. }
  729.  
  730. /*
  731.  *    S E T _ A R E A  --
  732.  */
  733. static SANE_Status
  734. set_area (Epson_Scanner * s, int x, int y, int width, int height)
  735. {
  736.     SANE_Status status;
  737.     unsigned char data[2], params[8];
  738.     CmdEntry    *cmd;
  739.  
  740.     assert(s->hw->cmd2[SET_AREA].command == SET_AREA);
  741.  
  742.     cmd = &s->hw->cmd2[SET_AREA];
  743.     if (cmd->enabled != 1)
  744.         return SANE_STATUS_GOOD;
  745.  
  746.  
  747.     DBG(2, "Command: %s \'%c\' %d %d %dx%d \n", cmd->name, cmd->code, x, y, width, height);
  748.  
  749.     data[0] = ESC;
  750.     data[1] = cmd->code;
  751.     send (s, data, 2, &status);
  752.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  753.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  754.         return status;
  755.     }
  756.  
  757.     params[0] = x;
  758.     params[1] = x >> 8;
  759.     params[2] = y;
  760.     params[3] = y >> 8;
  761.     params[4] = width;
  762.     params[5] = width >> 8;
  763.     params[6] = height;
  764.     params[7] = height >> 8;
  765.     send (s, params, 8, &status);
  766.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD)
  767.         DBG(2, "Command: %s \'%c\' %d %d %dx%d - data failed\n", cmd->name, cmd->code, x, y, width, height);
  768.  
  769.     return status;
  770. }
  771.  
  772. /*
  773.  *    S E T _ E X P O S U R E T I M E  --
  774.  *
  775.  */
  776. static SANE_Status
  777. set_exposuretime(Epson_Scanner * s)
  778. {
  779.     SANE_Status status;
  780.     unsigned char data[2];
  781.     CmdEntry    *cmd;
  782.     int        bay;
  783.     unsigned char *tvalptr;
  784.  
  785.     static unsigned char default_tval[4] = {2, 0x80, 0x80, 0x80};
  786.  
  787.     assert(s->hw->cmd2[SET_EXPOSURETIME].command == SET_EXPOSURETIME);
  788.  
  789.     cmd = &s->hw->cmd2[SET_EXPOSURETIME];
  790.     if (cmd->enabled != 1)
  791.         return SANE_STATUS_GOOD;
  792.  
  793.     bay = s->val[OPT_BAY];
  794.     assert(bay < EPSON_MAX_BAY);
  795.  
  796.     if (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE) {
  797.         tvalptr = neg_tval;
  798.     } else if (s->bay[bay].calibrated) {
  799.         tvalptr =  s->bay[bay].tvaltable;
  800.     } else
  801.         tvalptr = default_tval;
  802.  
  803.  
  804.     DBG(2, "Command: %s \'%c\' %d,%02x,%02x,%02x\n", cmd->name, cmd->code,
  805.         tvalptr[0], tvalptr[1], tvalptr[2], tvalptr[3]);
  806.  
  807.     data[0] = ESC;
  808.     data[1] = cmd->code;
  809.     send (s, data, 2, &status);
  810.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  811.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  812.         return status;
  813.     }
  814.  
  815.     send (s, tvalptr, cmd->length, &status);
  816.  
  817.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD)
  818.         DBG(2, "Command: %s \'%c\' - data failed\n", cmd->name, cmd->code);
  819.  
  820.     return(status);
  821. }
  822.  
  823. /*
  824.  *    S E T _ U S E R G A M M A  --
  825.  *
  826.  */
  827. static SANE_Status
  828. set_usergamma(Epson_Scanner * s)
  829. {
  830.     SANE_Status status;
  831.     unsigned char data[2], params[257];
  832.     CmdEntry    *cmd;
  833.     int        i, bay;
  834.     
  835.     assert(s->hw->cmd2[SET_DOWNLOAD_GAMMA].command == SET_DOWNLOAD_GAMMA);
  836.  
  837.     cmd = &s->hw->cmd2[SET_DOWNLOAD_GAMMA];
  838.     if (cmd->enabled != 1)
  839.         return SANE_STATUS_GOOD;
  840.  
  841. /* IF FILMSCAN */
  842.  
  843.     bay = s->val[OPT_BAY];
  844.  
  845.     /* If the bay is uncalibrated, set user gamma to linear... */
  846.  
  847.     if (!s->bay[bay].calibrated) {
  848.         if (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE) {
  849.             for (i=0; i<256; i++) {
  850.                 s->bay[bay].gammatableR[255 - i] = i;
  851.                 s->bay[bay].gammatableG[255 - i] = i;
  852.                 s->bay[bay].gammatableB[255 - i] = i;
  853.             }
  854.         } else {
  855.             for (i=0; i<256; i++) {
  856.                 s->bay[bay].gammatableR[i] = i;
  857.                 s->bay[bay].gammatableG[i] = i;
  858.                 s->bay[bay].gammatableB[i] = i;
  859.             }
  860.         }
  861.     }
  862.     
  863.     DBG(2, "Command: %s \'%c\'\n", cmd->name, cmd->code);
  864.  
  865.     for (i=0; i < 3; i++) {
  866.         data[0] = ESC;
  867.         data[1] = cmd->code;
  868.         send (s, data, 2, &status);
  869.         if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  870.             DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  871.             return status;
  872.         }
  873.  
  874.         switch (i) {
  875.             case 0:
  876.                 params[0] = 'R';
  877.                 memcpy(params+1, s->bay[bay].gammatableR, 256);
  878.                 break;
  879.             case 1:
  880.                 params[0] = 'G';
  881.                 memcpy(params+1, s->bay[bay].gammatableG, 256);
  882.                 break;
  883.             case 2:
  884.                 params[0] = 'B';
  885.                 memcpy(params+1, s->bay[bay].gammatableB, 256);
  886.                 break;
  887.         }
  888.         send (s, params, cmd->length, &status);
  889.  
  890.         if ((status = expect_ack(s)) != SANE_STATUS_GOOD)
  891.             DBG(2, "Command: %s \'%c\' - data failed\n", cmd->name, cmd->code);
  892.     }
  893.     return status;
  894. }
  895.  
  896.  
  897. /*
  898.  *    S E T _ U S E R C O L O U R
  899.  *
  900.  */
  901. static SANE_Status
  902. set_usercolour(Epson_Scanner * s, unsigned char *colourtable)
  903. {
  904.     SANE_Status status;
  905.     unsigned char data[2];
  906.     CmdEntry    *cmd;
  907.  
  908.     assert(s->hw->cmd2[SET_DOWNLOAD_COLOUR].command == SET_DOWNLOAD_COLOUR);
  909.  
  910.     cmd = &s->hw->cmd2[SET_DOWNLOAD_COLOUR];
  911.     if (cmd->enabled != 1)
  912.         return SANE_STATUS_GOOD;
  913.  
  914.  
  915.     DBG(2, "Command: %s \'%c\'\n", cmd->name, cmd->code);
  916.  
  917.     data[0] = ESC;
  918.     data[1] = cmd->code;
  919.     send (s, data, 2, &status);
  920.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  921.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  922.         return status;
  923.     }
  924.  
  925.     send (s, colourtable, 9, &status);
  926.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD)
  927.         DBG(2, "Command: %s \'%c\' - data failed\n", cmd->name, cmd->code);
  928.  
  929.     return status;
  930. }
  931.  
  932.  
  933. /*
  934.  *    R E S E T  --
  935.  */
  936. static SANE_Status
  937. reset(Epson_Scanner * s)
  938. {
  939.     SANE_Status status;
  940.     unsigned char data[2];
  941.     CmdEntry    *cmd;
  942.  
  943.     assert(s->hw->cmd2[RESET].command == RESET);
  944.  
  945.     cmd = &s->hw->cmd2[RESET];
  946.     if (cmd->enabled != 1)
  947.         return SANE_STATUS_GOOD;
  948.  
  949.     DBG(2, "Command: %s \'%c\'\n", cmd->name, cmd->code);
  950.  
  951.     data[0] = ESC;
  952.     data[1] = cmd->code;
  953.     send (s, data, 2, &status);
  954.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  955.         DBG(2, "Command: %s \'%c\' - issue failed\n", cmd->name, cmd->code);
  956.     }
  957.     return status;
  958. }
  959.  
  960.  
  961. /*
  962.  *    E J E C T  --
  963.  */
  964. static SANE_Status
  965. eject(Epson_Scanner * s)
  966. {
  967.     SANE_Status status;
  968.     unsigned char data[2];
  969.     EpsonHdr scanner_status;
  970.     int        i;
  971.  
  972.     if ((status = epsonopen(s->hw->sane.name, s)) != SANE_STATUS_GOOD)
  973.         return status;
  974.         scanner_status = (EpsonHdr)  inputcommand (s, "\033F", 2, &status);
  975.  
  976.     if (status == SANE_STATUS_GOOD) {
  977.         int i; unsigned char *ptr;
  978.         DBG(4, "esc-F status: %x %d\n", scanner_status->status, scanner_status->count);
  979.         for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  980.             DBG(4," %02x",*ptr);
  981.             if (i%10 == 0) DBG(4,"\n");
  982.         }
  983.         DBG(4,"\n");
  984.     }
  985.  
  986.     if (scanner_status)
  987.         free(scanner_status);
  988.  
  989.  
  990.     data[0] = 12;
  991.     send (s, data, 1, &status);
  992.     if ((status = expect_ack(s)) != SANE_STATUS_GOOD) {
  993.         DBG(2, "Command: eject  - issue failed\n");
  994.     }
  995.     for (i=0; i<6; i++)
  996.         s->bay[i].calibrated = 0;
  997.     epsonclose (s);
  998.     return status;
  999. }
  1000.  
  1001. /*
  1002.  *    C A L I B R A T E  --
  1003.  *
  1004.  */
  1005. static SANE_Status
  1006. calibrate(Epson_Scanner * s)
  1007. {
  1008.     unsigned char *image, *iptr, *gammatableR, *gammatableG, *gammatableB,
  1009.             *tvaltable;
  1010.     int        phase, isize, readsize, i, tval, red, green, blue;
  1011.     int        bay, filmtype;
  1012.     int        saved_resolution, saved_gammamode, saved_colourmode;
  1013.     int        red_min, blue_min, green_min, min;
  1014.     int        red_max, blue_max, green_max, max;
  1015.     float    luma;
  1016.     int        luma_min, luma_max;
  1017.     
  1018.     saved_resolution = s->val[OPT_RESOLUTION];
  1019.     s->val[OPT_RESOLUTION] = s->hw->dpi_range.min;
  1020.     saved_gammamode = s->val[OPT_GAMMA];
  1021.     s->val[OPT_GAMMA] = OPT_GAMMA_USER;
  1022.     saved_colourmode = s->val[OPT_COLOUR];
  1023.     s->val[OPT_COLOUR] = OPT_COLOUR_USER;
  1024.  
  1025.     
  1026.     bay = s->val[OPT_BAY];
  1027.     assert(bay < EPSON_MAX_BAY);
  1028.     filmtype = filmtype_values[s->val[OPT_FILMTYPE]];
  1029.     gammatableR = s->bay[bay].gammatableR;
  1030.     gammatableG = s->bay[bay].gammatableG;
  1031.     gammatableB = s->bay[bay].gammatableB;
  1032.     tvaltable =  s->bay[bay].tvaltable;
  1033.     tvaltable[0] = 2;
  1034.  
  1035. /*
  1036.  *    Set linear gamma table while we work out a better one..
  1037.  */
  1038.     if (filmtype & OPT_FILMTYPE_NEGATIVE) {
  1039.         for (i=0; i<256; i++) {
  1040.             gammatableR[255 - i] = i;
  1041.             gammatableG[255 - i] = i;
  1042.             gammatableB[255 - i] = i;
  1043.         }
  1044.     } else {
  1045.         for (i=0; i<256; i++) {
  1046.             gammatableR[i] = i;
  1047.             gammatableG[i] = i;
  1048.             gammatableB[i] = i;
  1049.         }
  1050.     }
  1051.     s->bay[bay].calibrated = 1;        /* indicate calibration so user tables are downloaded */
  1052.         
  1053.     DBG(1,"Calibrate\n");
  1054.     image = NULL;
  1055.  
  1056.     tval = 0x80;
  1057.     if (filmtype & OPT_FILMTYPE_NEGATIVE)
  1058.         phase = 1;        /* Only do gamma calcs for negs */
  1059.     else
  1060.         phase = 0;        /* Do dynamic range stretch for slides. */
  1061.  
  1062.     for ( ; phase <2; phase ++) {
  1063. /*
  1064.  *    Define INVESTIGATE to force it to try a range of tval values, rather than
  1065.  *    doing a table lookup..
  1066.  */
  1067. /* #define INVESTIGATE */
  1068. #ifdef INVESTIGATE
  1069.         for ( ; tval < 0xa0; tval +=2) {
  1070. #endif
  1071.             tvaltable[1] = tvaltable[2] = tvaltable[3] = tval;
  1072.     
  1073.             if (filmtype & OPT_FILMTYPE_NEGATIVE) {
  1074.                 tvaltable[1] = neg_tval[1];
  1075.                 tvaltable[2] = neg_tval[2];
  1076.                 tvaltable[3] = neg_tval[3];
  1077.             }
  1078.             DBG(1,"Calibrate: %x\n",tval);
  1079.             sane_start(s);
  1080.             isize = s->params.pixels_per_line * s->params.lines * 3;
  1081.             if (!image) image = (unsigned char *) malloc(isize);
  1082.             iptr = image;
  1083.             while (sane_read(s, iptr, isize - (iptr - image), &readsize) == SANE_STATUS_GOOD) {
  1084.                 DBG(1,"Calibrate: read %d, %d to go\n", readsize, isize - (iptr - image));
  1085.                 iptr += readsize;
  1086.             }
  1087.             iptr = image;
  1088.             red = green = blue = 0;
  1089.             red_max = green_max = blue_max = 0;
  1090.             red_min = green_min = blue_min = 255;
  1091.             luma_min = 255; luma_max = 0;
  1092.         
  1093.             for (i=0; i<isize/3; i++) {
  1094.                 if (*iptr > red_max)
  1095.                     red_max = *iptr;
  1096.                 if (*iptr < red_min)
  1097.                     red_min = *iptr;
  1098.                 luma = (float)*iptr * 0.299;
  1099.                 red += *iptr++;
  1100.         
  1101.                 if (*iptr > green_max)
  1102.                     green_max = *iptr;
  1103.                 if (*iptr < green_min)
  1104.                     green_min = *iptr;
  1105.                 luma += (float)*iptr * 0.587;
  1106.                 green += *iptr++;
  1107.         
  1108.                 if (*iptr > blue_max)
  1109.                     blue_max = *iptr;
  1110.                 if (*iptr < blue_min)
  1111.                     blue_min = *iptr;
  1112.                 luma += (float)*iptr * 0.114;
  1113.                 blue += *iptr++;
  1114.                 if (luma > luma_max)
  1115.                     luma_max = luma;
  1116.                 if (luma < luma_min)
  1117.                     luma_min = luma;
  1118.             }
  1119.             DBG(1,"Calibrate: average %3d %3d %3d\n", red/(isize/3), green/(isize/3), blue/(isize/3));
  1120.             DBG(1,"Calibrate: min     %3d %3d %3d\n", red_min, green_min, blue_min);
  1121.             DBG(1,"Calibrate: max     %3d %3d %3d\n", red_max, green_max, blue_max);
  1122.             DBG(1,"Calibrate: LUMA: min %d max %d\n\n", luma_min, luma_max);
  1123.     
  1124.             max = red_max;
  1125.             if (green_max > max)
  1126.                 max = green_max;
  1127.             if (blue_max > max)
  1128.                 max = blue_max;
  1129.     
  1130.             min = red_min;
  1131.             if (green_min < min)
  1132.                 min = green_min;
  1133.             if (blue_min < min)
  1134.                 min = blue_min;
  1135.     
  1136.  
  1137. #ifdef INVESTIGATE
  1138.             if (phase != 0)
  1139.                 break;
  1140.             if (max >= 255) {
  1141.                 if (tval > 0x80)
  1142.                     tval -= 1;
  1143.                 tvaltable[1] = tvaltable[2] = tvaltable[3] = tval;
  1144.                 break;
  1145.             }
  1146.         }
  1147. #else
  1148.         if (phase == 0) {
  1149.             tval = pos_exposure_correction[max];
  1150.             tvaltable[1] = tvaltable[2] = tvaltable[3] = tval;
  1151.         }
  1152. #endif
  1153.         if (phase == 1) {
  1154.             DBG(2,"Calibrate: Setting gamma table..\n");
  1155.  
  1156.         /*
  1157.          *    If Neg film/slide set gamma curves (RGB) and manage the
  1158.          *    'inverted' data
  1159.          */
  1160.             if (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE) {
  1161.  
  1162.  
  1163.             /*
  1164.              *    We set 255-min/max because the gamma correction will be applied
  1165.              *    to the (pre) inverted image in the scanner, where the active
  1166.              *    range of the image needs to be measured from 255 down
  1167.              *
  1168.              *    -GAMMAVAL gets setgammatable() to generate an inverting gamma..
  1169.              *    so we don't have to invert the image over here..
  1170.              */
  1171.                 setgammatable(gammatableR, 255-max, 255-min,  -GAMMAVAL);
  1172.                 setgammatable(gammatableG, 255-max, 255-min,  -GAMMAVAL);
  1173.                 setgammatable(gammatableB, 255-max, 255-min,  -GAMMAVAL);
  1174.             }
  1175.         /*
  1176.          *    Pos film/slide - simple gamma
  1177.          */
  1178.             else {
  1179.                 setgammatable(gammatableR, min, max, GAMMAVAL);
  1180.                 setgammatable(gammatableG, min, max, GAMMAVAL);
  1181.                 setgammatable(gammatableB, min, max, GAMMAVAL);
  1182.             }
  1183.         }
  1184.     }
  1185.     if (image) free(image);
  1186.  
  1187.     /*
  1188.      *    Restore all the real settings..
  1189.      */
  1190.     s->val[OPT_RESOLUTION] = saved_resolution;
  1191.     s->val[OPT_GAMMA] = saved_gammamode;
  1192.     s->val[OPT_COLOUR] = saved_colourmode;
  1193.     return(SANE_STATUS_GOOD);
  1194. }
  1195.  
  1196.                 
  1197. /*
  1198.  *    E P S O N O P E N  --
  1199.  */
  1200. static SANE_Status
  1201. epsonopen(const char *dev_name, Epson_Scanner *s)
  1202. {
  1203.     SANE_Status status;
  1204.  
  1205.     DBG(2, "epsonopen: Open %s %s\n", s->hw->is_scsi ? "scsi" : "pio", dev_name);
  1206.     if (s->hw->is_scsi) {
  1207.         if ((status = sanei_scsi_open (dev_name, &s->fd, NULL, NULL)) != SANE_STATUS_GOOD) {
  1208.             DBG (1, "epsonopen: open failed: %s\n", sane_strstatus(status));
  1209.         }
  1210.     } else {
  1211.         if ((status = sanei_pio_open (dev_name, &s->fd)) != SANE_STATUS_GOOD) {
  1212.             DBG (1, "epsonopen: %s: can't open %s as a parallel-port device\n", sane_strstatus (status), dev_name);
  1213.         }
  1214.     }
  1215.     return(status);
  1216. }
  1217.  
  1218.  
  1219. /*
  1220.  *    E P S O N C L O S E -- 
  1221.  */
  1222. static void 
  1223. epsonclose (Epson_Scanner * s)
  1224. {
  1225.  
  1226.   DBG(2, "epsonclose: Close device\n");
  1227.   assert(s->fd != -1);
  1228.   if (s->hw->is_scsi)
  1229.     sanei_scsi_close (s->fd);
  1230.   else
  1231.     sanei_pio_close (s->fd);
  1232.   s->fd = -1;
  1233.   return;
  1234. }
  1235.  
  1236.  
  1237.  
  1238. /*
  1239.  *    A T T A C H  --
  1240.  *
  1241.  */
  1242. static SANE_Status 
  1243. attach (const char *dev_name, Epson_Device * *devp)
  1244. {
  1245.     SANE_Status status;
  1246.     Epson_Device    epson_dev, *dev;
  1247.     Epson_Scanner    s;
  1248.     EpsonIdent ident;
  1249.     unsigned char buf[36], *ptr;
  1250.     size_t buf_size;
  1251.     char *str, *end;
  1252.     int        max_x, max_y, n, k;
  1253.  
  1254.     if (devp)
  1255.         *devp = 0;
  1256. /*
  1257.  *    make sure we have not already see this device
  1258.  */
  1259.     for (dev = devices; dev; dev = dev->next) {
  1260.         if (strcmp (dev->sane.name, dev_name) == 0) {
  1261.             if (devp)
  1262.                 *devp = dev;
  1263.             DBG(1, "attach: duplicate device %s\n", dev_name);
  1264.             return SANE_STATUS_GOOD;
  1265.         }
  1266.     }
  1267.  
  1268.     DBG(1, "attach: opening %s\n", dev_name);
  1269.  
  1270.     memset(&epson_dev, 0, sizeof(epson_dev));
  1271.     memset(&s, 0, sizeof(s));
  1272.     s.hw = &epson_dev;
  1273. /*    epson_dev.cmd = &epson_cmd[EPSON_LEVEL_DEFAULT]; */
  1274.     epson_dev.cmd2 = malloc(sizeof(CmdEntry) * CMD_TABLE_SIZE);
  1275.     memcpy(epson_dev.cmd2, DefaultCmdTable, sizeof(CmdEntry) * CMD_TABLE_SIZE);
  1276.  
  1277.     strtol(dev_name, &end, 0);
  1278.     if ((end == dev_name) || *end) {
  1279.         epson_dev.is_scsi = 1;
  1280.         DBG (3, "attach: is_scsi is %s\n", epson_dev.is_scsi?"true":"false");
  1281.     } else {
  1282.         epson_dev.is_scsi = 0;
  1283.     }
  1284.  
  1285.     if ((status = epsonopen(dev_name, &s)) != SANE_STATUS_GOOD) {
  1286.         return status;
  1287.     }
  1288.     if (epson_dev.is_scsi) {
  1289.  
  1290.         DBG (3, "attach: sending INQUIRY\n");
  1291.         buf_size = sizeof buf;
  1292.  
  1293.         /*
  1294.          *    Do basic check that we have an EPSON scanner before we do anything
  1295.          *    more dangerous.. ;-)
  1296.          */
  1297.         if ((status = inquiry (s.fd, 0, buf, &buf_size)) != SANE_STATUS_GOOD) {
  1298.             DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status));
  1299.             epsonclose (&s);
  1300.             return status;
  1301.         }
  1302.         if (buf[0] == TYPE_PROCESSOR && (strncmp(buf + 8, "EPSON", 5) == 0)) {
  1303.             if ((strncmp (buf + 16, "SCANNER ", 8) == 0) ||
  1304.                 (strncmp (buf + 14, "SCANNER ", 8) == 0)) {
  1305.                 DBG (3, "attach: conventional scanner\n");
  1306.                 epson_dev.sane.type = "Flatbed Scanner";
  1307.             } else if (strncmp (buf + 16, "FilmScan 200", 12) == 0) {
  1308.                 DBG (3, "attach: Filmscan\n");
  1309.                 epson_dev.sane.type = "Film Scanner";
  1310.             } else {
  1311.                 DBG (1, "attach: device doesn't look like an Epson scanner\n");
  1312.                 DBG (2, "attach: device is unknown product: \"%s\"\n",nstring(buf+16,16));
  1313.                 epsonclose (&s);
  1314.                 return SANE_STATUS_INVAL;
  1315.             }
  1316.             str = nstring(buf+16,16);
  1317.             epson_dev.sane.model = malloc(strlen(str)+1);
  1318.             strcpy((char *)epson_dev.sane.model, str);
  1319.         } else {
  1320.             DBG (1, "attach: device doesn't look like an Epson scanner\n");
  1321.             DBG (2, "attach: inquiry returned Processor: %s Vendor: \"%s\"\n",(buf[0] == TYPE_PROCESSOR)?"Yes":"No",nstring(buf+8,8));
  1322.             epsonclose (&s);
  1323.             return SANE_STATUS_INVAL;
  1324.         }
  1325.  
  1326.     } else {
  1327.         epson_dev.sane.type = "Scanner";
  1328.     }
  1329.  
  1330. /*
  1331.  *    We now believe we really have an epson scanner there to poke at.. so
  1332.  *    lets investigate it a bit more..
  1333.  */
  1334.  
  1335.     ident = (EpsonIdent) inputcommand (&s, "\033I", 2, &status);
  1336.     
  1337.     if (ident == NULL) {
  1338.         DBG (0, "ident failed\n");
  1339.         epsonclose(&s);
  1340.         if (epson_dev.sane.model)
  1341.             free((char *)epson_dev.sane.model);
  1342.         return status;
  1343.     }
  1344.  
  1345.     DBG (2, "type  %3c 0x%02x\n", ident->type, ident->type);
  1346.     DBG (2, "level %3c 0x%02x\n", ident->level, ident->level);
  1347.  
  1348. /*
  1349.  *    Ident
  1350.  *    =====
  1351.  *    Type B - Flat bed scanners GT5000/5500
  1352.  *    Type F - FilmScaners FS200
  1353.  */
  1354.     ptr = ident->buf;
  1355.     setupcommands(&epson_dev, ident->type, ident->level);
  1356. /*
  1357.  *    Since it takes 3 bytes to store 1 resolution vector, the max possible count
  1358.  *    for resolution entries is count/3 - it makes a safe guess for calloc size ;-)
  1359.  */
  1360.     epson_dev.res_list_size = 0;
  1361.     epson_dev.res_list = (SANE_Int *) calloc (ident->count/3, sizeof (SANE_Int));
  1362.  
  1363.     if (epson_dev.res_list == NULL) {
  1364.         DBG (0, "attach: resolution list calloc(%d) failed - no mem\n", ident->count/3);
  1365.         exit (0);
  1366.     }
  1367.  
  1368.  
  1369.     epson_dev.dpi_range.quant = 0;
  1370.     epson_dev.dpi_range.min = 0x7fff;
  1371.     epson_dev.dpi_range.max = 0;
  1372.     max_x = max_y = 0;
  1373.  
  1374.     for (n = ident->count; n; n -= k, ptr += k) {
  1375.         switch (*ptr) {
  1376.             case 'R': {
  1377.                 int val = ptr[2] << 8 | ptr[1];
  1378.                 epson_dev.res_list[epson_dev.res_list_size] = (SANE_Int) val;
  1379.                 epson_dev.res_list_size++;
  1380.                 DBG (3, "resolution (dpi): %d\n", val);
  1381.                 if (val < epson_dev.dpi_range.min)
  1382.                     epson_dev.dpi_range.min = val;
  1383.                 if (val > epson_dev.dpi_range.max)
  1384.                     epson_dev.dpi_range.max = val;
  1385.                 k = 3;
  1386.                 continue;
  1387.             }
  1388.             case 'A': {
  1389.                 max_x = ptr[2] << 8 | ptr[1];
  1390.                 max_y = ptr[4] << 8 | ptr[3];
  1391.  
  1392.                 DBG (3, "maximum scan area: %dx%d\n", max_x, max_y);
  1393.                 k = 5;
  1394.                 continue;
  1395.             }
  1396.             default:
  1397.                 break;
  1398.         }
  1399.         break;
  1400.     }
  1401.     if (epson_dev.dpi_range.min == 0x7fff)
  1402.         epson_dev.dpi_range.min = 0;
  1403.     DBG(2, "min dpi: %d, max dpi: %d\n",epson_dev.dpi_range.min,epson_dev.dpi_range.max);
  1404.     if (max_x) {
  1405.         epson_dev.x_range.min = 0;
  1406.         epson_dev.x_range.max = SANE_FIX (max_x * 25.4 / epson_dev.dpi_range.max);
  1407.         epson_dev.x_range.quant = 0;
  1408.     }
  1409.     if (max_y) {
  1410.         epson_dev.y_range.min = 0;
  1411.         epson_dev.y_range.max = SANE_FIX (max_y * 25.4 / epson_dev.dpi_range.max);
  1412.         epson_dev.y_range.quant = 0;
  1413.     }
  1414.     free(ident);
  1415. /*
  1416.  *    Set up remaining SANE identification info
  1417.  */
  1418.     epson_dev.sane.name = malloc(strlen(dev_name) + 1);
  1419.     strcpy ((char *)epson_dev.sane.name, dev_name);
  1420.  
  1421.     epson_dev.sane.vendor = "Epson";
  1422.  
  1423. /*
  1424.  *    Now make a real copy of the data to keep....
  1425.  */
  1426.     if ((dev = malloc (sizeof (*dev))) == NULL) {
  1427.         return SANE_STATUS_NO_MEM;
  1428.         if (epson_dev.sane.model)
  1429.             free((char *)epson_dev.sane.model);
  1430.     }
  1431.  
  1432.     memcpy(dev, &epson_dev, sizeof(epson_dev));
  1433.  
  1434.     num_devices++;
  1435.     dev->next = devices;
  1436.     devices = dev;
  1437.  
  1438.     if (devp)
  1439.         *devp = dev;
  1440.  
  1441.     {
  1442.         EpsonHdr scanner_status;
  1443.         scanner_status = (EpsonHdr)  inputcommand (&s, "\033F", 2, &status);
  1444.         if (status == SANE_STATUS_GOOD) {
  1445.             int i; unsigned char *ptr;
  1446.             DBG(4, "esc-F status: %x %d\n", scanner_status->status, scanner_status->count);
  1447.             for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  1448.                 DBG(4," %02x",*ptr);
  1449.                 if (i%10 == 0) DBG(4,"\n");
  1450.             }
  1451.             DBG(4,"\n");
  1452.         }
  1453.         free(scanner_status);
  1454.     
  1455.         scanner_status = (EpsonHdr)  inputcommand (&s, "\033f", 2, &status);
  1456.         if (status == SANE_STATUS_GOOD) {
  1457.             int i; unsigned char *ptr;
  1458.             DBG(4, "esc-f status: %x %d\n", scanner_status->status, scanner_status->count);
  1459.             for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  1460.                 DBG(4," %02x",*ptr);
  1461.                 if (i%10 == 0) DBG(4,"\n");
  1462.             }
  1463.             DBG(4,"\n");
  1464.         }
  1465.         free(scanner_status);
  1466.  
  1467.         scanner_status = (EpsonHdr)  inputcommand (&s, "\033S", 2, &status);
  1468.         if (status == SANE_STATUS_GOOD) {
  1469.             int i; unsigned char *ptr;
  1470.             DBG(1, "esc-S status: %x %d\n", scanner_status->status, scanner_status->count);
  1471.             for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  1472.                 DBG(4," %02x",*ptr);
  1473.                 if (i%10 == 0) DBG(4,"\n");
  1474.             }
  1475.             DBG(4,"\n");
  1476.         }
  1477.         free(scanner_status);
  1478.  
  1479.     }
  1480.     epsonclose(&s);
  1481.     return SANE_STATUS_GOOD;
  1482. }
  1483.  
  1484. /*
  1485.  *    A T T A C H _ O N E  --
  1486.  *
  1487.  */
  1488. static SANE_Status
  1489. attach_one (const char *dev)
  1490. {
  1491.     attach (dev, 0);
  1492.     return SANE_STATUS_GOOD;
  1493. }
  1494.  
  1495.  
  1496. /********************************************************************/
  1497. /*
  1498.  *    S A N E _ I N I T
  1499.  *
  1500.  */
  1501. SANE_Status
  1502. sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
  1503. {
  1504.     char line[PATH_MAX], *lptr;
  1505.     int    len;
  1506.     FILE *fp;
  1507.     char    *env;
  1508.     int        e1, e2, e3;
  1509.     DBG_INIT();
  1510. #if defined PACKAGE && defined VERSION
  1511.     DBG (2, "sane_init: " PACKAGE " " VERSION "\n");
  1512. #endif
  1513.  
  1514.     if (version_code != NULL)
  1515.         *version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
  1516.  
  1517. /*
  1518.  *    Look for a config file
  1519.  */
  1520.     if ((fp = sanei_config_open (EPSON_CONFIG_FILE))) {
  1521.         while (fgets (line, sizeof (line), fp)) {
  1522.             if (line[0] == '#')        /* ignore line comments */
  1523.                 continue;
  1524.             lptr = line;
  1525.             len = strlen (line);
  1526.             if (line[len - 1] == '\n')
  1527.                 line[--len] = '\0';
  1528.             while (*lptr && isspace(*lptr))
  1529.                 lptr++;
  1530.             if (!*lptr)
  1531.                 continue;            /* ignore empty lines */
  1532.             DBG (1, "sane_init \"%s\"\n", lptr);
  1533.             /*
  1534.              *    In case our config line needs processing. eg its like:
  1535.              *
  1536.              *        scsi VENDOR MODEL TYPE BUS CHANNEL ID LUN
  1537.              *
  1538.              *    then sort it out then call 'attach one'
  1539.              */
  1540.             sanei_config_attach_matching_devices (lptr, attach_one);
  1541.         }
  1542.         fclose (fp);
  1543. /*
  1544.  *    default to DEFAULT_DEVNAME instead of insisting on config file
  1545.  */
  1546.     } else {
  1547.         sanei_config_attach_matching_devices (DEFAULT_DEVNAME, attach_one);
  1548.     }
  1549. /*
  1550.  *    Look to see if there is a negative exposure correction in the env..
  1551.  */
  1552.     if ((env = getenv("EPSON_NEGATIVE_CORRECTION"))) {
  1553.         DBG(2, "Got environ neg correction \"%s\"\n", env);
  1554.         sscanf(env, "%d %d %d", &e1, &e2, &e3);
  1555.         neg_tval[1] = e1;
  1556.         neg_tval[2] = e2;
  1557.         neg_tval[3] = e3;        
  1558.     }
  1559.  
  1560.     return SANE_STATUS_GOOD;
  1561. }
  1562.  
  1563. /*
  1564.  *    S A N E _ E X I T  --
  1565.  *
  1566.  */
  1567. void
  1568. sane_exit (void)
  1569. {
  1570.     Epson_Device *dev, *next;
  1571.  
  1572.     DBG(1, "sane_exit:\n");
  1573. /*
  1574.  *    Clean up open handles...
  1575.  */
  1576.     while (handles)
  1577.            sane_close(handles);
  1578.        handles = NULL;
  1579.  
  1580. /*
  1581.  *    Clean up devices
  1582.  */
  1583.     for (dev = devices; dev; dev = next) {
  1584.         next = dev->next;
  1585.         if (dev->sane.model)
  1586.             free ((char *) dev->sane.model);
  1587.         if (dev->sane.name)
  1588.             free ((char *) dev->sane.name);
  1589.         if (dev->res_list)
  1590.             free(dev->res_list);
  1591.         free (dev);
  1592.     }
  1593.     devices = NULL;
  1594.     num_devices = 0;
  1595. }
  1596.  
  1597. /*
  1598.  *    S A N E _ G E T _ D E V I C E S  --
  1599.  *
  1600.  */
  1601. SANE_Status
  1602. sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
  1603. {
  1604.     static const SANE_Device **devlist = 0;
  1605.     Epson_Device *dev;
  1606.     int i;
  1607.  
  1608.     if (devlist)
  1609.         free (devlist);
  1610.  
  1611.     devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
  1612.     if (!devlist)
  1613.         return SANE_STATUS_NO_MEM;
  1614.  
  1615.     i = 0;
  1616.     for (dev = devices; i < num_devices; dev = dev->next)
  1617.         devlist[i++] = &dev->sane;
  1618.     devlist[i++] = 0;
  1619.  
  1620.     *device_list = devlist;
  1621.     return SANE_STATUS_GOOD;
  1622. }
  1623.  
  1624. /*
  1625.  *    I N I T _ O P T I O N S  --
  1626.  *
  1627.  */
  1628. static SANE_Status
  1629. init_options (Epson_Scanner * s)
  1630. {
  1631.     int i;
  1632.  
  1633.     DBG(10, "init_options\n");
  1634.     for (i = 0; i < NUM_OPTIONS; ++i) {
  1635.         s->opt[i].size = sizeof (SANE_Word);
  1636.         s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
  1637.     }
  1638.  
  1639.     s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
  1640.     s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
  1641.     s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
  1642.     s->val[OPT_NUM_OPTS] = NUM_OPTIONS;
  1643.  
  1644. /* "Scan Mode" group: */
  1645.  
  1646.     s->opt[OPT_MODE_GROUP].title = "Scan Mode";
  1647.     s->opt[OPT_MODE_GROUP].desc = "";
  1648.     s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
  1649.     s->opt[OPT_MODE_GROUP].cap = 0;
  1650.  
  1651. /* filmtype */
  1652.     s->opt[OPT_FILMTYPE].name = "filmtype";
  1653.     s->opt[OPT_FILMTYPE].title = "Film Type";
  1654.     s->opt[OPT_FILMTYPE].desc = "Selects the filmtype.";
  1655.     s->opt[OPT_FILMTYPE].type = SANE_TYPE_STRING;
  1656.     s->opt[OPT_FILMTYPE].size = 32;
  1657.     s->opt[OPT_FILMTYPE].cap |= SANE_CAP_ADVANCED;
  1658.     s->opt[OPT_FILMTYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1659.     s->opt[OPT_FILMTYPE].constraint.string_list = filmtype_list;
  1660.     s->val[OPT_FILMTYPE] = OPT_FILMTYPE_NEGATIVE;    /* Normal */
  1661.     if (!s->hw->cmd2[SET_FILMTYPE].enabled)
  1662.         s->opt[OPT_FILMTYPE].cap |= SANE_CAP_INACTIVE;
  1663.  
  1664. /* eject */
  1665.     s->opt[OPT_EJECT].name = "eject";
  1666.     s->opt[OPT_EJECT].title = "Eject film tray";
  1667.     s->opt[OPT_EJECT].desc = "Ejects the film tray";
  1668.     s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
  1669.     s->opt[OPT_EJECT].cap |= SANE_CAP_ADVANCED;
  1670.     if (s->hw->type != 'F')
  1671.         s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
  1672.  
  1673. /* calibrate */
  1674.     s->opt[OPT_CALIBRATE].name = "calibrate";
  1675.     s->opt[OPT_CALIBRATE].title = "calibrate";
  1676.     s->opt[OPT_CALIBRATE].desc = "calibrate";
  1677.     s->opt[OPT_CALIBRATE].type = SANE_TYPE_BUTTON;
  1678.     s->opt[OPT_CALIBRATE].cap |= SANE_CAP_ADVANCED;
  1679.     if (s->hw->type != 'F')
  1680.         s->opt[OPT_CALIBRATE].cap |= SANE_CAP_INACTIVE;
  1681.           
  1682. /* select bay */
  1683.     s->opt[OPT_BAY].name = "Bay";
  1684.     s->opt[OPT_BAY].title = "Select bay to scan";
  1685.     s->opt[OPT_BAY].desc = "select bay to scan";
  1686.     s->opt[OPT_BAY].type = SANE_TYPE_STRING;
  1687.     s->opt[OPT_BAY].size = 32;
  1688.     s->opt[OPT_BAY].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1689.     s->opt[OPT_BAY].constraint.string_list = bay_list;
  1690.     s->val[OPT_BAY] = 0;        /* Bay 1 */
  1691.     if (!s->hw->cmd2[SET_BAY].enabled)
  1692.         s->opt[OPT_BAY].cap |= SANE_CAP_INACTIVE;
  1693.  
  1694.   /* scan mode */
  1695.     s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
  1696.     s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
  1697.     s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
  1698.     s->opt[OPT_MODE].type = SANE_TYPE_STRING;
  1699.     s->opt[OPT_MODE].size = 32;
  1700.     s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1701.     s->opt[OPT_MODE].constraint.string_list = mode_list;
  1702.     s->val[OPT_MODE] = 0;        /* Binary */
  1703.  
  1704.   /* halftone */
  1705.   s->opt[OPT_HALFTONE].name = SANE_NAME_HALFTONE;
  1706.   s->opt[OPT_HALFTONE].title = SANE_TITLE_HALFTONE;
  1707.   s->opt[OPT_HALFTONE].desc = "Selects the halftone.";
  1708.   s->opt[OPT_HALFTONE].type = SANE_TYPE_STRING;
  1709.   s->opt[OPT_HALFTONE].size = 32;
  1710.   s->opt[OPT_HALFTONE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1711.   if (s->hw->level >= 4)
  1712.     s->opt[OPT_HALFTONE].constraint.string_list = halftone_list_4;
  1713.   else
  1714.     s->opt[OPT_HALFTONE].constraint.string_list = halftone_list;
  1715.   s->val[OPT_HALFTONE] = 1;    /* Halftone A */
  1716.     if ((!s->hw->cmd2[SET_HALFTONE].enabled) || (mode_params[s->val[OPT_MODE]].depth != 1))
  1717.         s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
  1718.  
  1719.   /* dropout */
  1720.   s->opt[OPT_DROPOUT].name = "dropout";
  1721.   s->opt[OPT_DROPOUT].title = "Dropout";
  1722.   s->opt[OPT_DROPOUT].desc = "Selects the dropout.";
  1723.   s->opt[OPT_DROPOUT].type = SANE_TYPE_STRING;
  1724.   s->opt[OPT_DROPOUT].size = 32;
  1725.   s->opt[OPT_DROPOUT].cap |= SANE_CAP_ADVANCED;
  1726.   s->opt[OPT_DROPOUT].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1727.   s->opt[OPT_DROPOUT].constraint.string_list = dropout_list;
  1728.   s->val[OPT_DROPOUT] = 0;    /* None */
  1729.     if ((s->hw->type == 'F') || (mode_params[s->val[OPT_MODE]].color))
  1730.         s->opt[OPT_DROPOUT].cap |= SANE_CAP_INACTIVE;
  1731.  
  1732.   /* brightness */
  1733.   if (!s->hw->cmd2[SET_BRIGHTNESS].enabled)
  1734.       s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
  1735.  
  1736.   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
  1737.   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
  1738.   s->opt[OPT_BRIGHTNESS].desc = "Selects the brightness.";
  1739.   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_STRING;
  1740.   s->opt[OPT_BRIGHTNESS].size = 32;
  1741.   s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_ADVANCED;
  1742.   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1743.   s->opt[OPT_BRIGHTNESS].constraint.string_list = brightness_list;
  1744.   s->val[OPT_BRIGHTNESS] = 3;    /* Normal */
  1745.  
  1746. /* sharpness */
  1747.     if (!s->hw->cmd2[SET_SHARPNESS].enabled)
  1748.         s->opt[OPT_SHARPNESS].cap |= SANE_CAP_INACTIVE;
  1749.  
  1750.     s->opt[OPT_SHARPNESS].name = "Sharpness";
  1751.     s->opt[OPT_SHARPNESS].title = "Sharpness";
  1752.     s->opt[OPT_SHARPNESS].desc = "Selects the sharpness.";
  1753.     s->opt[OPT_SHARPNESS].type = SANE_TYPE_STRING;
  1754.     s->opt[OPT_SHARPNESS].size = 32;
  1755.     s->opt[OPT_SHARPNESS].cap |= SANE_CAP_ADVANCED;
  1756.     s->opt[OPT_SHARPNESS].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1757.     s->opt[OPT_SHARPNESS].constraint.string_list = sharpness_list;
  1758.     s->val[OPT_SHARPNESS] = 2;    /* Normal */
  1759.  
  1760. /* resolution */
  1761.     s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
  1762.     s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
  1763.     s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
  1764.     s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
  1765.     s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
  1766.     s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
  1767.     s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
  1768.     s->val[OPT_RESOLUTION] = s->hw->dpi_range.min;
  1769.  
  1770. /* gamma */
  1771.     if (s->hw->type != 'F')
  1772.         s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
  1773.  
  1774.     s->opt[OPT_GAMMA].name = "gamma";
  1775.     s->opt[OPT_GAMMA].title = "Gamma";
  1776.     s->opt[OPT_GAMMA].desc = "Adjust scanner gamma correction";
  1777.     s->opt[OPT_GAMMA].type = SANE_TYPE_STRING;
  1778.     s->opt[OPT_GAMMA].size = 32;
  1779.     s->opt[OPT_GAMMA].cap |= SANE_CAP_ADVANCED;
  1780.     s->opt[OPT_GAMMA].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1781.     s->opt[OPT_GAMMA].constraint.string_list = gamma_list;
  1782.     s->val[OPT_GAMMA] = OPT_GAMMA_USER;    /* Automatic */
  1783.  
  1784. /* colour */
  1785.     if (s->hw->type != 'F')
  1786.         s->opt[OPT_COLOUR].cap |= SANE_CAP_INACTIVE;
  1787.  
  1788.     s->opt[OPT_COLOUR].name = "colour";
  1789.     s->opt[OPT_COLOUR].title = "colour";
  1790.     s->opt[OPT_COLOUR].desc = "colour";
  1791.     s->opt[OPT_COLOUR].type = SANE_TYPE_STRING;
  1792.     s->opt[OPT_COLOUR].size = 32;
  1793.     s->opt[OPT_COLOUR].cap |= SANE_CAP_ADVANCED;
  1794.     s->opt[OPT_COLOUR].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1795.     s->opt[OPT_COLOUR].constraint.string_list = colour_list;
  1796.     s->val[OPT_COLOUR] = OPT_COLOUR_USER;    /* Automatic */
  1797.  
  1798. /* zoom */
  1799.     if (!s->hw->cmd2[SET_ZOOM].enabled)
  1800.         s->opt[OPT_ZOOM].cap |= SANE_CAP_INACTIVE;
  1801.  
  1802.     s->opt[OPT_ZOOM].name = "zoom";
  1803.     s->opt[OPT_ZOOM].title = "Zoom";
  1804.     s->opt[OPT_ZOOM].desc = "Zoom part of the image";
  1805.     s->opt[OPT_ZOOM].type = SANE_TYPE_INT;
  1806.     s->opt[OPT_ZOOM].unit = SANE_UNIT_PERCENT;
  1807.     s->opt[OPT_ZOOM].constraint_type = SANE_CONSTRAINT_RANGE;
  1808.     s->opt[OPT_ZOOM].constraint.range = &zoom_range;
  1809.     s->val[OPT_ZOOM] = 100;
  1810.  
  1811. /* "Geometry" group: */
  1812.  
  1813.   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
  1814.   s->opt[OPT_GEOMETRY_GROUP].desc = "";
  1815.   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
  1816.   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
  1817.  
  1818.   /* top-left x */
  1819.   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
  1820.   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
  1821.   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
  1822.   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
  1823.   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
  1824.   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
  1825.   s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
  1826.   s->val[OPT_TL_X] = 0;
  1827.  
  1828.   /* top-left y */
  1829.   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
  1830.   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
  1831.   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
  1832.   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
  1833.   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
  1834.   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  1835.   s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
  1836.   s->val[OPT_TL_Y] = 0;
  1837.  
  1838.   /* bottom-right x */
  1839.   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
  1840.   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
  1841.   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
  1842.   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
  1843.   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
  1844.   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
  1845.   s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
  1846.   s->val[OPT_BR_X] = s->hw->x_range.max;
  1847.  
  1848.   /* bottom-right y */
  1849.   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
  1850.   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
  1851.   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
  1852.   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
  1853.   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
  1854.   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  1855.   s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
  1856.   s->val[OPT_BR_Y] = s->hw->y_range.max;
  1857.  
  1858. /* orientation */
  1859.     if (!s->hw->cmd2[SET_ORIENTATION].enabled)
  1860.         s->opt[OPT_ORIENTATION].cap |= SANE_CAP_INACTIVE;
  1861.  
  1862.     s->opt[OPT_ORIENTATION].name = "Orientation";
  1863.     s->opt[OPT_ORIENTATION].title = "Orientation";
  1864.     s->opt[OPT_ORIENTATION].desc = "Selects the orientation.";
  1865.     s->opt[OPT_ORIENTATION].type = SANE_TYPE_STRING;
  1866.     s->opt[OPT_ORIENTATION].size = 32;
  1867.     s->opt[OPT_ORIENTATION].cap |= SANE_CAP_ADVANCED;
  1868.     s->opt[OPT_ORIENTATION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  1869.     if (s->hw->type == 'F')
  1870.         s->opt[OPT_ORIENTATION].constraint.string_list = orientation_list_f;
  1871.     else
  1872.         s->opt[OPT_ORIENTATION].constraint.string_list = orientation_list_b;
  1873.     s->val[OPT_ORIENTATION] = 0;    /* Normal */
  1874.  
  1875.     return SANE_STATUS_GOOD;
  1876. }
  1877.  
  1878. /*
  1879.  *    S A N E _ O P E N  --
  1880.  *
  1881.  */
  1882. SANE_Status
  1883. sane_open (SANE_String_Const devicename, SANE_Handle * handle)
  1884. {
  1885.     Epson_Device *dev;
  1886.     Epson_Scanner *s;
  1887.     SANE_Status status;
  1888.  
  1889.  
  1890.     if (*devicename) {
  1891.         for (dev = devices; dev; dev = dev->next)
  1892.             if (strcmp (dev->sane.name, devicename) == 0)
  1893.                 break;
  1894.         if (!dev) {
  1895.             status = attach (devicename, &dev);
  1896.             if (status != SANE_STATUS_GOOD)
  1897.                 return status;
  1898.         }
  1899.     } else        /* empty devicename -> use first device */
  1900.         dev = devices;
  1901.  
  1902.     if (!dev)
  1903.         return SANE_STATUS_INVAL;
  1904.  
  1905.     if ((s = calloc (1, sizeof (Epson_Scanner))) == NULL)
  1906.         return SANE_STATUS_NO_MEM;
  1907.  
  1908.     s->fd = -1;
  1909.     s->hw = dev;
  1910.     s->needinit = 1;
  1911.  
  1912.     init_options(s);
  1913.  
  1914. /*
  1915.  *    insert newly opened handle into list of open handles:
  1916.  */
  1917.     s->next = handles;
  1918.     handles = s;
  1919.   
  1920.     *handle = (SANE_Handle) s;
  1921.     return SANE_STATUS_GOOD;
  1922. }
  1923.  
  1924. /*
  1925.  *    S A N E _ C L O S E  --
  1926.  *
  1927.  */
  1928. void
  1929. sane_close (SANE_Handle handle)
  1930. {
  1931.     Epson_Scanner *s, *prev;
  1932.  
  1933. /*
  1934.  *    find and remove handle from list of open handles:
  1935.  */
  1936.     prev = 0;
  1937.     for (s = handles; s; s = s->next) {
  1938.         if (s == handle)
  1939.             break;
  1940.         prev = s;
  1941.     }
  1942.     if (s) {
  1943.         DBG(1,"sane_close %s\n", s->hw->sane.name);
  1944.         if (prev)
  1945.             prev->next = s->next;
  1946.         else
  1947.             handles = s->next;
  1948.     
  1949.         if (s->buf)
  1950.             free (s->buf);
  1951.     
  1952.         if (s->fd != -1)
  1953.             epsonclose(s);
  1954.     
  1955.         free(handle);
  1956.     } else
  1957.         DBG(1,"sane_close: bad handle!\n");
  1958. }
  1959.  
  1960. /*
  1961.  *    S A N E _ G E T _ O P T I O N _ D E S C R I P T O R  --
  1962.  *
  1963.  *    Return pointer to the option descriptor for option 'option' of scanner 'handle'
  1964.  *
  1965.  */
  1966. const SANE_Option_Descriptor *
  1967. sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
  1968. {
  1969.     Epson_Scanner *s = (Epson_Scanner *) handle;
  1970.  
  1971.     DBG(25, "sane_get_option_descriptor %d\n", option);
  1972.     if (option < 0 || option >= NUM_OPTIONS)
  1973.         return NULL;
  1974.  
  1975.     return s->opt + option;
  1976. }
  1977.  
  1978. /*
  1979.  */
  1980. static const SANE_String_Const *
  1981. search_string_list (const SANE_String_Const * list, SANE_String value)
  1982. {
  1983.   while (*list != NULL && strcmp (value, *list) != 0)
  1984.     ++list;
  1985.  
  1986.   if (*list == NULL)
  1987.     return NULL;
  1988.  
  1989.   return list;
  1990. }
  1991.  
  1992. /*
  1993.  *    S A N E _ C O N T R O L _ O P T I O N  --
  1994.  *
  1995.  */
  1996. SANE_Status
  1997. sane_control_option (SANE_Handle handle, SANE_Int option,
  1998.              SANE_Action action, void *value,
  1999.              SANE_Int * info)
  2000. {
  2001.   Epson_Scanner *s = (Epson_Scanner *) handle;
  2002.   SANE_Status status;
  2003.   const SANE_String_Const *optptr;
  2004.   int        optval;
  2005.  
  2006.   DBG(25, "sane_control_option, action %d, option %d\n", action, option);
  2007.  
  2008.   if (option < 0 || option >= NUM_OPTIONS)
  2009.     return SANE_STATUS_INVAL;
  2010.  
  2011.   if (info != NULL)
  2012.     *info = 0;
  2013.  
  2014.     switch (action) {
  2015.         /*
  2016.          * Get the current value of an option
  2017.          */
  2018.         case SANE_ACTION_GET_VALUE:
  2019.             switch (option) {
  2020.                 /*
  2021.                  *    Simple SANE_TYPE_INT options
  2022.                  *        (SANE_CONSTRAINT_RANGE, SANE_CONSTRAINT_WORD_LIST)
  2023.                  */
  2024.                 case OPT_NUM_OPTS:
  2025.                 case OPT_RESOLUTION:
  2026.                 case OPT_TL_X:
  2027.                 case OPT_TL_Y:
  2028.                 case OPT_BR_X:
  2029.                 case OPT_BR_Y:
  2030.                 case OPT_ZOOM:
  2031.                     *(SANE_Word *) value = s->val[option];
  2032.                     break;
  2033.                 /*
  2034.                  *    Simple SANE_TYPE_STRING options
  2035.                  *        (SANE_CONSTRAINT_STRING_LIST)
  2036.                  */
  2037.                 case OPT_MODE:
  2038.                 case OPT_BAY:
  2039.                 case OPT_HALFTONE:
  2040.                 case OPT_DROPOUT:
  2041.                 case OPT_BRIGHTNESS:
  2042.                 case OPT_SHARPNESS:
  2043.                 case OPT_FILMTYPE:
  2044.                 case OPT_GAMMA:
  2045.                 case OPT_ORIENTATION:
  2046.                 case OPT_COLOUR:
  2047.                     strcpy ((char *) value, s->opt[option].constraint.string_list[s->val[option]]);
  2048.                     break;
  2049.                 /*
  2050.                  *    Anything else - reject
  2051.                  */
  2052.                 default:
  2053.                     return SANE_STATUS_INVAL;
  2054.             }
  2055.             break;
  2056.         /*
  2057.          *    Set an option to supplied value
  2058.          */
  2059.         case SANE_ACTION_SET_VALUE:
  2060.             /*
  2061.              *    First lets make sure the value we want make sense
  2062.              */
  2063.             status = sanei_constrain_value (s->opt + option, value, info);
  2064.             if (status != SANE_STATUS_GOOD)
  2065.                 return status;
  2066.             /*
  2067.              *    If its a string list then do a lookup to get the index into
  2068.              *    the list (we were passed a pointer to the string value)
  2069.              *    quit if we can't find it..
  2070.              */
  2071.             optptr = NULL; optval = 0;
  2072.             if (s->opt[option].constraint_type == SANE_CONSTRAINT_STRING_LIST) {
  2073.                 optptr = search_string_list (s->opt[option].constraint.string_list,
  2074.                        (char *) value);
  2075.                 if (optptr == NULL)
  2076.                     return SANE_STATUS_INVAL;
  2077.                 optval = optptr - s->opt[option].constraint.string_list;
  2078.                 DBG(1, "Opt %s, val %d\n", *optptr, optval);
  2079.             }
  2080.             /*
  2081.              *    Deal with each option in turn, doing any special processing
  2082.              *    as we go
  2083.              */
  2084.             switch (option) {
  2085.                 case OPT_EJECT:
  2086.                     eject(s);
  2087.                     break;
  2088.                 case OPT_CALIBRATE:
  2089.                     calibrate(s);
  2090.                     break;
  2091.                 /*
  2092.                  *    Resolution - look for nearest matching resolution
  2093.                  */
  2094.                 case OPT_RESOLUTION: {
  2095.                     int n, old;
  2096.                     int min_d = s->hw->res_list[s->hw->res_list_size - 1];
  2097.                     int v = *(SANE_Word *) value;
  2098.                     int best = v;
  2099.                     old = s->val[option];
  2100.  
  2101.                     for (n = 0; n < s->hw->res_list_size; n++) {
  2102.                         int d = abs (v - s->hw->res_list[n]);
  2103.  
  2104.                         if (d < min_d) {
  2105.                             min_d = d;
  2106.                             best = s->hw->res_list[n];
  2107.                         }
  2108.                     }
  2109.                     s->val[option] = (SANE_Word) best;
  2110.                     if (min_d != 0) {
  2111.                         DBG(2, "resolution was %d requested %d set to %d\n",old,v,best);
  2112.                         if (info)
  2113.                             *info |= SANE_INFO_INEXACT;
  2114.                     }                        
  2115.                     break;
  2116.                 }
  2117.                 case OPT_TL_X:
  2118.                 case OPT_TL_Y:
  2119.                 case OPT_BR_X:
  2120.                 case OPT_BR_Y:
  2121.                     if (info != NULL)
  2122.                         *info |= SANE_INFO_RELOAD_PARAMS;
  2123.                     /* fall through */
  2124.                 case OPT_ZOOM:
  2125.                     s->val[option] = *(SANE_Word *) value;
  2126.                     break;
  2127.                 /*
  2128.                  *    Mode - setting mode enables or disables a number of
  2129.                  *    other options...
  2130.                  */
  2131.                 case OPT_MODE:
  2132.                     if ((s->hw->type == 'F') || (mode_params[optval].depth != 1))
  2133.                         s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
  2134.                     else
  2135.                         s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE;
  2136.  
  2137.                     if ((s->hw->type == 'F') || mode_params[optval].color)
  2138.                         s->opt[OPT_DROPOUT].cap |= SANE_CAP_INACTIVE;
  2139.                     else
  2140.                         s->opt[OPT_DROPOUT].cap &= ~SANE_CAP_INACTIVE;
  2141.                     if (info) {
  2142.                         *info |= SANE_INFO_RELOAD_OPTIONS;
  2143.                         *info |= SANE_INFO_RELOAD_PARAMS;
  2144.                     }
  2145.                 /* fall through */
  2146.                 case OPT_HALFTONE:
  2147.                 case OPT_DROPOUT:
  2148.                 case OPT_BRIGHTNESS:
  2149.                 case OPT_FILMTYPE:
  2150.                 case OPT_SHARPNESS:
  2151.                 case OPT_GAMMA:
  2152.                 case OPT_COLOUR:
  2153.                 case OPT_BAY:
  2154.                 case OPT_ORIENTATION:
  2155.                     if (!(s->opt[option].cap & SANE_CAP_INACTIVE))
  2156.                         s->val[option] = optval;
  2157.                     break;
  2158.                 default:
  2159.                     return SANE_STATUS_INVAL;
  2160.             }
  2161.             break;
  2162.         default:
  2163.             return SANE_STATUS_INVAL;
  2164.     }
  2165.     return SANE_STATUS_GOOD;
  2166. }
  2167.  
  2168. /*
  2169.  *    S A N E _ G E T _ P A R A M E T E R S  --
  2170.  */
  2171. SANE_Status
  2172. sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
  2173. {
  2174.   Epson_Scanner *s = (Epson_Scanner *) handle;
  2175.   int ndpi;
  2176.  
  2177.   DBG(25, "sane_get_parameters()\n");
  2178.   memset (&s->params, 0, sizeof (SANE_Parameters));
  2179.  
  2180.   ndpi = s->val[OPT_RESOLUTION];
  2181.  
  2182.   s->params.pixels_per_line = (SANE_UNFIX(s->val[OPT_BR_X] - s->val[OPT_TL_X]) * s->val[OPT_ZOOM]) /100 / 25.4 * ndpi;
  2183.   s->params.lines = (SANE_UNFIX(s->val[OPT_BR_Y] - s->val[OPT_TL_Y]) * s->val[OPT_ZOOM]) / 100 / 25.4 * ndpi;
  2184.   /* pixels_per_line seems to be 8 * n.  */
  2185.   s->params.pixels_per_line = s->params.pixels_per_line & ~7;
  2186.  
  2187.   s->params.last_frame = SANE_TRUE;
  2188.   s->params.depth = mode_params[s->val[OPT_MODE]].depth;
  2189.   if (mode_params[s->val[OPT_MODE]].color)
  2190.     {
  2191.       s->params.format = SANE_FRAME_RGB;
  2192.       s->params.bytes_per_line = 3 * s->params.pixels_per_line;
  2193.     }
  2194.   else
  2195.     {
  2196.       s->params.format = SANE_FRAME_GRAY;
  2197.       s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8;
  2198.     }
  2199.  
  2200.   if (params != NULL)
  2201.     *params = s->params;
  2202.  
  2203.   return SANE_STATUS_GOOD;
  2204. }
  2205.  
  2206. /*
  2207.  * Debug stuff
  2208.  */
  2209. static int    red_min, red_max;
  2210. static int    green_min, green_max;
  2211. static int    blue_min, blue_max;
  2212.  
  2213. /*
  2214.  *    S A N E _ S T A R T  --  Setup and start a scan
  2215.  *
  2216.  *    Note, no scan data is read here - thats done in subsequent calls to
  2217.  *    sane_read()
  2218.  *
  2219.  */
  2220. SANE_Status
  2221. sane_start (SANE_Handle handle)
  2222. {
  2223.   Epson_Scanner *s = (Epson_Scanner *) handle;
  2224.   SANE_Status status;
  2225.   const struct mode_param *mparam;
  2226.   int ndpi;
  2227.   int left, top;
  2228.   int lcount;
  2229.  
  2230.     red_min = 255; red_max = 0;
  2231.     green_min = 255; green_max = 0;
  2232.     blue_min = 255; blue_max = 0;
  2233. /*
  2234.  * First ensure all the s->params values are updated..
  2235.  */
  2236.     status = sane_get_parameters (handle, NULL);
  2237.     if (status != SANE_STATUS_GOOD)
  2238.         return status;
  2239.  
  2240. /*
  2241.  *    Open the physical device.
  2242.  */
  2243.     if ((status = epsonopen(s->hw->sane.name, s)) != SANE_STATUS_GOOD)
  2244.         return status;
  2245.  
  2246. /*
  2247.  * INIT
  2248.  *
  2249.  *    Send an init to the scanner if needed.
  2250.  *    It wastes a lot of time on the filmscan moving the slide around if
  2251.  *    you send a reset every scan..
  2252.  */
  2253.     if (s->needinit) {
  2254.         reset(s);
  2255.         if (s->hw->type == 'F')
  2256.             s->needinit = 0;
  2257.     }
  2258.  
  2259. /* FILMTYPE */
  2260.     if ((status = simplecommand(SET_FILMTYPE, s, filmtype_values[s->val[OPT_FILMTYPE]],0)) != SANE_STATUS_GOOD) {
  2261.         DBG (1, "sane_start: set_filmtype failed: %s\n", sane_strstatus(status));
  2262.         return status;
  2263.     }
  2264.  
  2265. /* #define LINEMODE */
  2266. /* MODE */
  2267.     mparam = mode_params + s->val[OPT_MODE];
  2268.     /*
  2269.      *    For scanners > level 5 and when in colour mode set mode to
  2270.      *    be 0x13 otherwise take base bits from mode_params based on bitdepth
  2271.      *    and add in dropout mask bits
  2272.      */
  2273. #ifdef LINEMODE
  2274.     status = simplecommand(SET_MODE, s, 0x12, 0);
  2275. #else
  2276.     if (s->hw->level >= 5 && mparam->mode_flags == 0x02) {
  2277.         status = simplecommand(SET_MODE, s, 0x13, 0);
  2278.     } else
  2279.         status = simplecommand(SET_MODE, s, mparam->mode_flags
  2280.                | (mparam->dropout_mask & dropout_params[s->val[OPT_DROPOUT]]),0);
  2281. #endif
  2282.     if (status != SANE_STATUS_GOOD) {
  2283.         DBG (1, "sane_start: set_mode failed: %s\n", sane_strstatus (status));
  2284.         return status;
  2285.     }
  2286.  
  2287. /* DEPTH (number of bits/pixel) */
  2288.     if ((status = simplecommand(SET_DEPTH, s, s->params.depth, 0)) != SANE_STATUS_GOOD) {
  2289.         DBG (1, "sane_start: set_depth failed: %s\n", sane_strstatus (status));
  2290.         return status;
  2291.     }
  2292.  
  2293.  
  2294. /* EXPOSURE TIME */
  2295.     if ((status = set_exposuretime(s)) != SANE_STATUS_GOOD) {
  2296.         DBG (1, "sane_start: set_exposuretime failed: %s\n", sane_strstatus (status));
  2297.         return status;
  2298.     }
  2299.  
  2300.  
  2301. /* GAMMA */
  2302.     if ((status = set_usergamma(s)) != SANE_STATUS_GOOD) {
  2303.         DBG (1, "sane_start: set_usegamma failed: %s\n", sane_strstatus (status));
  2304.         return status;
  2305.     }
  2306.  
  2307.     if (s->opt[OPT_GAMMA].cap & SANE_CAP_INACTIVE)
  2308.         status = simplecommand(SET_GAMMA, s, s->params.depth == 1 ? 1 : 2, 0);
  2309.     else
  2310.         status = simplecommand(SET_GAMMA, s, gamma_params[s->val[OPT_GAMMA]], 0);
  2311.  
  2312.     if (status != SANE_STATUS_GOOD) {
  2313.         DBG (1, "sane_start: set_gamma failed: %s\n", sane_strstatus (status));
  2314.         return status;
  2315.     }
  2316.  
  2317. /* COLOUR */
  2318.  
  2319.     if (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE)
  2320.         status = set_usercolour(s, colour_table);
  2321.     else
  2322.         status = set_usercolour(s, slide_colour_table);
  2323.     if (status != SANE_STATUS_GOOD) {
  2324.         DBG (1, "sane_start: set_usercolour failed: %s\n", sane_strstatus (status));
  2325.         return status;
  2326.     }
  2327.     if (s->opt[OPT_COLOUR].cap & SANE_CAP_INACTIVE)
  2328.         status = simplecommand(SET_COLOUR, s, 0x80, 0);
  2329.     else
  2330.         status = simplecommand(SET_COLOUR, s, colour_params[s->val[OPT_COLOUR]], 0);
  2331.     if (status != SANE_STATUS_GOOD) {
  2332.         DBG (1, "sane_start: set_colour failed: %s\n", sane_strstatus (status));
  2333.         return status;
  2334.     }
  2335.  
  2336. /* HALFTONE */
  2337.     if ((status = simplecommand(SET_HALFTONE, s, halftone_params[s->val[OPT_HALFTONE]], 0)) != SANE_STATUS_GOOD) {
  2338.         DBG (1, "sane_start: set_halftone failed: %s\n", sane_strstatus (status));
  2339.         return status;
  2340.       }
  2341.  
  2342. /* BRIGHTNESS */
  2343.   status = simplecommand(SET_BRIGHTNESS, s, brightness_params[s->val[OPT_BRIGHTNESS]], 0);
  2344.   if (status != SANE_STATUS_GOOD)
  2345.     {
  2346.       DBG (1, "sane_start: set_brightness failed: %s\n", sane_strstatus (status));
  2347.       return status;
  2348.     }
  2349.  
  2350. /* SHARPNESS */
  2351.     if ((status = simplecommand(SET_SHARPNESS, s, sharpness_params[s->val[OPT_SHARPNESS]], 0)) != SANE_STATUS_GOOD) {
  2352.         DBG (1, "sane_start: set_sharpness failed: %s\n", sane_strstatus(status));
  2353.         return status;
  2354.     }
  2355.  
  2356. /* ZOOM */
  2357.     if ((status = simplecommand(SET_ZOOM, s, s->val[OPT_ZOOM], s->val[OPT_ZOOM])) != SANE_STATUS_GOOD) {
  2358.         DBG (1, "sane_start: set_zoom failed: %s\n", sane_strstatus(status));
  2359.         return status;
  2360.     }
  2361.     
  2362. /* ORIENTATION */
  2363.     if ((status = simplecommand(SET_ORIENTATION, s, orientation_params[s->val[OPT_ORIENTATION]], 0)) != SANE_STATUS_GOOD) {
  2364.         DBG (1, "sane_start: set_orientation failed: %s\n", sane_strstatus(status));
  2365.         return status;
  2366.     }
  2367.  
  2368. /* SPEED */
  2369.     if ((status = simplecommand(SET_SPEED, s, mode_params[s->val[OPT_MODE]].depth == 1 ? 1 : 0, 0)) != SANE_STATUS_GOOD) {
  2370.         DBG (1, "sane_start: set_speed failed: %s\n", sane_strstatus (status));
  2371.         return status;
  2372.     }
  2373.  
  2374. /* RESOLUTION */
  2375.     ndpi = s->val[OPT_RESOLUTION];
  2376.     if ((status = set_resolution (s, ndpi, ndpi)) != SANE_STATUS_GOOD) {
  2377.         DBG (1, "sane_start: set_resolution failed: %s\n", sane_strstatus (status));
  2378.         return status;
  2379.     }
  2380.  
  2381. /* SCAN AREA
  2382.  *
  2383.  *    Need to adjust for zoom and resolution. Calculate the (left, top) position
  2384.  *    as integers based on the SANE_Fixed point TL_X,TL_Y values.
  2385.  *    The width and height values have already been calculated in
  2386.  *    sane_get_parameters() and stored in
  2387.  *    s->params as the frontend needed them to calc memory requirements etc..
  2388.  */
  2389.     left = (SANE_UNFIX(s->val[OPT_TL_X]) * s->val[OPT_ZOOM]) / 100 / 25.4 * ndpi + 0.5;
  2390.     top = (SANE_UNFIX(s->val[OPT_TL_Y]) * s->val[OPT_ZOOM]) / 100 / 25.4 * ndpi + 0.5;
  2391.     status = set_area (s, left, top, s->params.pixels_per_line, s->params.lines);
  2392.     if (status != SANE_STATUS_GOOD) {
  2393.         DBG (1, "sane_start: set_area failed: %s\n", sane_strstatus(status));
  2394.         return status;
  2395.     }
  2396.  
  2397. /* LCOUNT
  2398.  *
  2399.  *    It is possible to get some scanners to block lines up and send them
  2400.  *    in chunks. Take care under Linux. The maximum size request for the
  2401.  *    /dev/sg? devices is set in the driver. Default is 4096. It can be
  2402.  *    overriden by SG_BIG_BUFF (probably in /usr/include/scsi/sg.h) but
  2403.  *    the kernel (or module) needs to have been compiled with it.
  2404.  *    man sane-scsi for more information
  2405.  */
  2406.     s->block = SANE_FALSE;
  2407.     lcount = 1;
  2408.  
  2409. /*
  2410.  *    For level 5 scanners, or level 4 when not colour we can use lcount
  2411.  *    I don't understand why set_lcount is enabled for A1-3 and B1-3
  2412.  *    scanners in epson_cmd[] above...
  2413.  */
  2414.     if (s->hw->level >= 5
  2415.         || (s->hw->level == 4 && !mode_params[s->val[OPT_MODE]].color)) {
  2416.         s->block = SANE_TRUE;
  2417.         lcount = sanei_scsi_max_request_size / s->params.bytes_per_line;
  2418. #ifdef LINEMODE
  2419.         lcount = (lcount /3) * 3;
  2420.         if (!lcount) lcount =1;
  2421. #endif
  2422.  
  2423. #if 0
  2424.         /*
  2425.          *    This is a useful bodge to test to see if you think you may
  2426.          *    have a BIG_BUFF problem.. Don't use 4096 - this includes
  2427.          *    command overhead etc..
  2428.          */
  2429.         if (s->params.bytes_per_line > 4000)
  2430.             lcount = 1;
  2431.         else
  2432.             lcount = 4000 / s->params.bytes_per_line;
  2433. #endif
  2434.         /* Lcount is stored in a single unsigned byte... */
  2435.         if (lcount > 255)
  2436.             lcount = 255;
  2437.  
  2438.         if (lcount == 0)
  2439.             return SANE_STATUS_NO_MEM;
  2440.  
  2441.         if ((status = simplecommand(SET_LCOUNT, s, lcount, 0)) != SANE_STATUS_GOOD) {
  2442.             DBG (1, "sane_start: set_lcount failed: %s\n", sane_strstatus (status));
  2443.             return status;
  2444.         }
  2445.     }
  2446. /* BAY */
  2447.     if ((status = simplecommand(SET_BAY, s, s->val[OPT_BAY]+1,s->val[OPT_BAY]+1)) != SANE_STATUS_GOOD) {
  2448.         DBG (1, "sane_start: set_bay failed: %s\n", sane_strstatus(status));
  2449.         return status;
  2450.     }
  2451.  
  2452.     
  2453. /* START SCAN */
  2454.     DBG(2, "sane_start:\n");
  2455.     send (s, "\033G", 2, &status);
  2456.     if (status != SANE_STATUS_GOOD) {
  2457.         DBG (1, "sane_start: start failed: %s\n", sane_strstatus (status));
  2458.         return status;
  2459.     }
  2460.  
  2461.     /*
  2462.      *    Set up the buffers ready to grab the data. The actual data will
  2463.      *    be read in a series of calls from the frontend to sane_read()..
  2464.      */
  2465.     s->eof = SANE_FALSE;
  2466.     s->buf = realloc (s->buf, lcount * s->params.bytes_per_line);
  2467.     s->ptr = s->end = s->buf;
  2468.     s->canceling = SANE_FALSE;
  2469.     return SANE_STATUS_GOOD;
  2470. }
  2471.  
  2472. /*
  2473.  *    S A N E _ R E A D
  2474.  *
  2475.  */
  2476. SANE_Status
  2477. sane_read (SANE_Handle handle, SANE_Byte * data,
  2478.        SANE_Int max_length, SANE_Int * length)
  2479. {
  2480.     Epson_Scanner *s = (Epson_Scanner *) handle;
  2481.     SANE_Status status;
  2482.     SANE_Byte    *dptr;
  2483.     unsigned char result[6];
  2484. /* *ptr; */
  2485.     size_t len, buf_len;
  2486.       int totalread, i;
  2487.  
  2488.     DBG (25, "sane_read: beginn\n");
  2489.  
  2490.     /*
  2491.      * Check to see if there is data stashed in our buffers that the app
  2492.      * hasn't had yet. If not read in another buffer load.
  2493.      */
  2494.     if (s->ptr == s->end) {
  2495.         /*
  2496.          *    Seen end.. clean up buffers and close the device
  2497.          */
  2498.         if (s->eof) {
  2499.             free (s->buf);
  2500.             s->buf = NULL;
  2501.             DBG(25, "sane_read: scan complete\n");
  2502.             if ((s->hw->type == 'F') && (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE)) {
  2503.                 reset(s);
  2504.                 s->needinit = 0;
  2505.             }
  2506.             epsonclose (s);
  2507.             *length = 0;
  2508.             return SANE_STATUS_EOF;
  2509.         }
  2510.  
  2511.         /*
  2512.          *    Otherwise there is more to do!
  2513.          */
  2514.         DBG (25, "sane_read: begin scan\n");
  2515.  
  2516.         /*
  2517.          * Work out how much data is coming in this transfer
  2518.          */
  2519.         len = s->block ? 6 : 4;
  2520.         receive (s, result, len, &status);
  2521.  
  2522.         buf_len = result[3] << 8 | result[2];
  2523.  
  2524.         if (s->block)
  2525.             buf_len *= (result[5] << 8 | result[4]);
  2526.  
  2527.         DBG(25,"sane_read: %d %d len: %d\n",result[0],result[1],buf_len);
  2528.  
  2529.         /*
  2530.          *    Length of zero means there is no more to come
  2531.          *    Ack it and return an INVAL error
  2532.          */
  2533.         if (buf_len == 0) {
  2534.             if (!(result[1] && 0x20))    /* Area end flag - don't send ack.. */
  2535.                 send (s, "\006", 1, &status);
  2536.             DBG(2, "sane_read: zero buffer, ack status: %s, block mode %d, flags 0x%x\n",sane_strstatus(status), s->block, (unsigned)result[1]);
  2537.  
  2538.             {
  2539.                 EpsonHdr scanner_status;
  2540.                 scanner_status = (EpsonHdr)  inputcommand (s, "\033F", 2, &status);
  2541.                 if (status == SANE_STATUS_GOOD) {
  2542.                     int i; unsigned char *ptr;
  2543.                     DBG(4, "esc-F status: %x %d\n", scanner_status->status, scanner_status->count);
  2544.                     for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  2545.                         DBG(4," %02x",*ptr);
  2546.                         if (i%10 == 0) DBG(4,"\n");
  2547.                     }
  2548.                     DBG(4,"\n");
  2549.                 }
  2550.                 free(scanner_status);
  2551.             
  2552.                 scanner_status = (EpsonHdr)  inputcommand (s, "\033f", 2, &status);
  2553.                 if (status == SANE_STATUS_GOOD) {
  2554.                     int i; unsigned char *ptr;
  2555.                     DBG(4, "esc-f status: %x %d\n", scanner_status->status, scanner_status->count);
  2556.                     for (ptr = (char *) scanner_status, i=4+scanner_status->count; i; i--, ptr++) {
  2557.                         DBG(4," %02x",*ptr);
  2558.                         if (i%10 == 0) DBG(4,"\n");
  2559.                     }
  2560.                     DBG(4,"\n");
  2561.                 }
  2562.                 free(scanner_status);
  2563.         
  2564.             }
  2565.             return SANE_STATUS_INVAL;
  2566.         }
  2567.         /*
  2568.          *    If no 'block' mode and in RGB mode we will need to grab 3 separate blocks of data
  2569.          *    and send an ACK for each
  2570.          */
  2571.         if (!s->block && SANE_FRAME_RGB == s->params.format) {
  2572.             receive (s, s->buf + s->params.pixels_per_line, buf_len, &status);
  2573.             send (s, "\006", 1, &status);
  2574.             len = s->block ? 6 : 4;
  2575.             receive (s, result, len, &status);
  2576.             buf_len = result[3] << 8 | result[2];
  2577.             if (s->block)
  2578.                 buf_len *= (result[5] << 8 | result[4]);
  2579.  
  2580.             DBG (25, "sane_read: buf len2 = %lu\n", (u_long) buf_len);
  2581.  
  2582.             receive (s, s->buf, buf_len, &status);
  2583.             send (s, "\006", 1, &status);
  2584.  
  2585.             len = s->block ? 6 : 4;
  2586.             receive (s, result, len, &status);
  2587.             buf_len = result[3] << 8 | result[2];
  2588.             if (s->block)
  2589.                 buf_len *= (result[5] << 8 | result[4]);
  2590.             DBG (25, "sane_read: buf len3 = %lu\n", (u_long) buf_len);
  2591.  
  2592.             receive (s, s->buf + 2 * s->params.pixels_per_line, buf_len, &status);
  2593.             totalread = 3 * s->params.pixels_per_line;
  2594.         } else {
  2595.             /* Otherwise its easy.. just grab one lot.. */
  2596.             receive (s, s->buf, buf_len, &status);
  2597.             totalread = buf_len;;
  2598.         }
  2599. #if 0 /* No longer needed - don in gamma correction 24/2/2000 */
  2600.  
  2601.         /*
  2602.          *    If we are working with a film scanner and have a
  2603.          *    negative image we need to invert it..
  2604.          */
  2605.         if ((status == SANE_STATUS_GOOD) && (s->hw->type == 'F') && (filmtype_values[s->val[OPT_FILMTYPE]] & OPT_FILMTYPE_NEGATIVE)) {
  2606.             ptr = s->buf;
  2607.  
  2608.             if (s->params.depth == 8) {
  2609.                 DBG(3, "Inverting grey/colour image (%d bytes)\n", totalread);
  2610.                 for (i=0; i<totalread; i++) {
  2611.                     *ptr = 255 - *ptr;
  2612.                     ptr++;
  2613.                 }
  2614.             } else if (s->params.depth == 1) {
  2615.                 DBG(2, "Inverting binary image\n");
  2616.                 for (i=0; i<totalread; i++) {
  2617.                     *ptr = ~*ptr;
  2618.                     ptr++;
  2619.                 }
  2620.             }
  2621.         }
  2622. #endif
  2623.     
  2624.         if (result[1] & 0x20) {
  2625.             s->eof = SANE_TRUE;
  2626.             DBG (25, "sane_read: scan complete\n");
  2627.         } else {
  2628.             if (s->canceling) {
  2629.                 send (s, "\030", 1, &status);        /* Send 'CAN' */
  2630.                 expect_ack (s);
  2631.                 free (s->buf);
  2632.                 s->buf = NULL;
  2633.                 DBG (25, "sane_read: scan cancel\n");
  2634.                 epsonclose (s);
  2635.                 *length = 0;
  2636.                 return SANE_STATUS_CANCELLED;
  2637.             } else {
  2638.                 send (s, "\006", 1, &status);
  2639.                 DBG (25, "sane_read: scan more\n");
  2640.             }
  2641.         }
  2642.         s->end = s->buf + buf_len;
  2643.         s->ptr = s->buf;
  2644.     } else
  2645.         DBG(25, "sane_read: data left in old buffer\n");
  2646.  
  2647.     /*
  2648.      *    Copy the read data to the user buffer, making any rearrangements
  2649.      *    necessary. Copy up to the amount asked for (max_length) but no more..
  2650.      *    Leave any remnamts in our buffer for next time.
  2651.      */
  2652.     if (!s->block && s->params.format == SANE_FRAME_RGB) {
  2653.         max_length /= 3;
  2654.         if (max_length > s->end - s->ptr)
  2655.             max_length = s->end - s->ptr;
  2656.         *length = 3 * max_length;
  2657.         while (max_length-- != 0) {
  2658.                     if (*data > red_max) red_max = *data;
  2659.                     if (*data < red_min) red_min = *data;
  2660.             *data++ = s->ptr[0];
  2661.             *data++ = s->ptr[s->params.pixels_per_line];
  2662.             *data++ = s->ptr[2 * s->params.pixels_per_line];
  2663.             ++s->ptr;
  2664.         }
  2665.     } else {
  2666.         if (max_length > (s->end - s->ptr))
  2667.             max_length = s->end - s->ptr;
  2668.         *length = max_length;                /* The amount we actually will copy */
  2669.  
  2670.     /* One bit deep image */
  2671.  
  2672.         if (s->params.depth == 1) {
  2673.             while (max_length-- != 0)
  2674.                 *data++ = ~*s->ptr++;
  2675.         } else {
  2676.  
  2677.     /* Eight bit deep image */
  2678.  
  2679. #ifdef LINEMODE
  2680.             int i, j;
  2681.             DBG(1,"COPYING.. %d %d %d\n", max_length, max_length / (3 * s->params.pixels_per_line), s->params.pixels_per_line);
  2682.             *length = (max_length / (3 * s->params.pixels_per_line)) * (3 * s->params.pixels_per_line);
  2683.             for (j=0; j< max_length / (3 * s->params.pixels_per_line); j++) {
  2684.                 for (i=0; i<s->params.pixels_per_line; i++) {
  2685.                     *data++ = s->ptr[0];
  2686.                     *data++ = s->ptr[s->params.pixels_per_line];
  2687.                     *data++ = s->ptr[2 * s->params.pixels_per_line];
  2688.                     ++s->ptr;
  2689.                 }
  2690.                 s->ptr += 2 * s->params.pixels_per_line;
  2691.             }
  2692. #else
  2693.             memcpy (data, s->ptr, max_length);
  2694.  
  2695.         /* Stash range of values coming from scanner */
  2696.  
  2697.             if (mode_params[s->val[OPT_MODE]].color) {
  2698.                 for (i=0, dptr = data; i<max_length; i+=3) {
  2699.                     if (*dptr > red_max) red_max = *dptr;
  2700.                     if (*dptr < red_min) red_min = *dptr;
  2701.                     dptr++;
  2702.                     if (*dptr > green_max) green_max = *dptr;
  2703.                     if (*dptr < green_min) green_min = *dptr;
  2704.                     dptr++;
  2705.                     if (*dptr > blue_max) blue_max = *dptr;
  2706.                     if (*dptr < blue_min) blue_min = *dptr;
  2707.                     dptr++;
  2708.                 }
  2709.             }
  2710.             s->ptr += max_length;
  2711. #endif
  2712.         }
  2713.     }
  2714.  
  2715.     DBG (25, "sane_read: end\n");
  2716.     if (s->eof) {
  2717.         printf("SCAN END: RED %3d %3d\n", red_min, red_max);
  2718.         printf("SCAN END: GRN %3d %3d\n", green_min, green_max);
  2719.         printf("SCAN END: BLU %3d %3d\n", blue_min, blue_max);
  2720.     }
  2721.     return SANE_STATUS_GOOD;
  2722. }
  2723.  
  2724. void
  2725. sane_cancel (SANE_Handle handle)
  2726. {
  2727.   Epson_Scanner *s = (Epson_Scanner *) handle;
  2728.  
  2729.   if (s->buf != NULL)
  2730.     s->canceling = SANE_TRUE;
  2731. }
  2732.  
  2733. SANE_Status
  2734. sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
  2735. {
  2736.   return SANE_STATUS_UNSUPPORTED;
  2737. }
  2738.  
  2739. SANE_Status
  2740. sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
  2741. {
  2742.   return SANE_STATUS_UNSUPPORTED;
  2743. }
  2744.  
  2745. /**********************************************************************
  2746.  *         LOW LEVEL INTERNAL STUFF
  2747.  */
  2748.  
  2749. /*
  2750.  *    N S T R I N G  --  Extract 'N' chars from a string and terminate
  2751.  *
  2752.  *    Result left in internal static buffer
  2753.  */
  2754. static char *
  2755. nstring(char *str, int len)
  2756. {
  2757.     static char buf[100];
  2758.     if (len >= sizeof(buf)) len = sizeof(buf) - 1;
  2759.     strncpy(buf, str, len);
  2760.     *(buf+len) = '\0';
  2761.     return(buf);
  2762. }
  2763.  
  2764. /*
  2765.  *    S E T G A M M A T A B L E  --
  2766.  *
  2767.  */
  2768. static void
  2769. setgammatable(unsigned char *gammatable, int min, int max, float gammaval)
  2770. {
  2771.     int        i, rev;
  2772.     unsigned char *gammaptr;
  2773.  
  2774.     rev = 0;
  2775.     if (gammaval < 0.0) {
  2776.         rev = 1;
  2777.         gammaval = -gammaval;
  2778.     }
  2779.  
  2780.     gammaptr = gammatable;
  2781.     for (i=0; i<256; i++) {
  2782.         if (i < min)
  2783.             *gammaptr = 0;
  2784.         else if (i > max)
  2785.             *gammaptr = 255;
  2786.         else {
  2787.             *gammaptr = (int) (pow( (float)(i-min) / (float)(max + 1 - min), gammaval) * 256);
  2788.         }
  2789.         if (rev)
  2790.             *gammaptr = 255 - *gammaptr;
  2791.         gammaptr++;
  2792.     }
  2793.  
  2794. #if 0
  2795.     int        i, inc;
  2796.     unsigned char *gammaptr;
  2797.  
  2798.     if (gammaval < 0.0) {
  2799.         inc = -1;
  2800.         gammaval = -gammaval;
  2801.         gammaptr = gammatable+255;
  2802.     } else {
  2803.         inc = 1;
  2804.         gammaptr = gammatable;
  2805.     }
  2806.  
  2807.     for (i=0; i<256; i++) {
  2808.         if (i < min)
  2809.             *gammaptr = 0;
  2810.         else if (i > max)
  2811.             *gammaptr = 255;
  2812.         else {
  2813.             *gammaptr = (int) (pow( (float)(i-min) / (float)(max + 1 - min), gammaval) * 256);
  2814.         }
  2815.         gammaptr += inc;
  2816.     }
  2817. #endif
  2818. #if 1
  2819.     { int t;
  2820.     printf("GAMMA: ");
  2821.     for (t=0; t<=255; t++)
  2822.         printf("%03d, ",gammatable[t]);
  2823.     printf("\n");
  2824.     }
  2825. #endif
  2826. }
  2827.  
  2828.  
  2829. static int 
  2830. scsi_write (int fd, const void *buf, size_t buf_size, SANE_Status * status)
  2831. {
  2832.   unsigned char *cmd;
  2833.  
  2834.   cmd = alloca (6 + buf_size);
  2835.   memset (cmd, 0, 6);
  2836.   cmd[0] = WRITE_6_COMMAND;
  2837.   cmd[2] = buf_size >> 16;
  2838.   cmd[3] = buf_size >> 8;
  2839.   cmd[4] = buf_size;
  2840.   memcpy (cmd + 6, buf, buf_size);
  2841.  
  2842.   if (SANE_STATUS_GOOD == (*status = sanei_scsi_cmd (fd, cmd, 6 + buf_size, NULL, NULL)))
  2843.     return buf_size;
  2844.  
  2845.   return 0;
  2846. }
  2847.  
  2848. static int 
  2849. send (Epson_Scanner * s, const void *buf, size_t buf_size, SANE_Status * status)
  2850. {
  2851.  
  2852.     DBG(28, "send buf, size = %lu\n", (u_long) buf_size);
  2853. /*
  2854. {
  2855.     size_t k;
  2856.     const char * s = buf;
  2857.  
  2858.     for( k = 0; k < buf_size; k++) {
  2859.         DBG(28, "buf[%u] %02x %c\n", k, s[ k], isprint( s[ k]) ? s[ k] : '.');
  2860.     }
  2861. }
  2862. */
  2863.   if (s->hw->is_scsi)
  2864.     {
  2865.       return scsi_write (s->fd, buf, buf_size, status);
  2866.     }
  2867.   else
  2868.     {
  2869.       int n;
  2870.  
  2871.       if (buf_size == (n = sanei_pio_write (s->fd, buf, buf_size)))
  2872.     *status = SANE_STATUS_GOOD;
  2873.       else
  2874.     *status = SANE_STATUS_INVAL;
  2875.  
  2876.       return n;
  2877.     }
  2878.  
  2879.   /* never reached */
  2880. }
  2881.  
  2882. static int 
  2883. scsi_read (int fd, void *buf, size_t buf_size, SANE_Status * status)
  2884. {
  2885.   unsigned char cmd[6];
  2886.  
  2887.   memset (cmd, 0, 6);
  2888.   cmd[0] = READ_6_COMMAND;
  2889.   cmd[2] = buf_size >> 16;
  2890.   cmd[3] = buf_size >> 8;
  2891.   cmd[4] = buf_size;
  2892.  
  2893.   DBG(31, "scsi_read: requesting %d bytes\n", buf_size);
  2894.  
  2895.   assert(buf_size > 0);
  2896.  
  2897.   
  2898.   if (SANE_STATUS_GOOD == (*status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, &buf_size)))
  2899.     return buf_size;
  2900.  
  2901.   return 0;
  2902. }
  2903.  
  2904.  
  2905. static int 
  2906. receive (Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
  2907. {
  2908.   int n;
  2909.  
  2910.   if (s->hw->is_scsi)
  2911.     {
  2912.         n = scsi_read (s->fd, buf, buf_size, status);
  2913.         if ((n == 0) && (*status == SANE_STATUS_NO_MEM)) {
  2914.                DBG(10, "receive: no mem error\n");
  2915.     } else if (n==0)
  2916.            DBG(28, "receive: status %d\n", *status);
  2917.     }
  2918.   else
  2919.     {
  2920.  
  2921.       if (buf_size == (n = sanei_pio_read (s->fd, buf, buf_size)))
  2922.     *status = SANE_STATUS_GOOD;
  2923.       else
  2924.     *status = SANE_STATUS_INVAL;
  2925.  
  2926.     }
  2927.  
  2928.   DBG(28, "receive buf, expected = %lu, got = %d\n", (u_long) buf_size, n);
  2929. /*
  2930. {
  2931.     int k;
  2932.     const char * s = buf;
  2933.  
  2934. z    for( k = 0; k < n; k++) {
  2935.         DBG(28, "buf[%u] %02x %c\n", k, s[ k], isprint( s[ k]) ? s[ k] : '.');
  2936.      }
  2937. }
  2938. */
  2939.       return n;
  2940. }
  2941.  
  2942.  
  2943. static SANE_Status
  2944. inquiry (int fd, int page_code, void *buf, size_t * buf_size)
  2945. {
  2946.   unsigned char cmd[6];
  2947.   int status;
  2948.  
  2949.   memset (cmd, 0, 6);
  2950.   cmd[0] = INQUIRY_COMMAND;
  2951.   cmd[2] = page_code;
  2952.   cmd[4] = *buf_size > 255 ? 255 : *buf_size;
  2953.   status = sanei_scsi_cmd (fd, cmd, sizeof cmd, buf, buf_size);
  2954.   return status;
  2955. }
  2956.  
  2957. static SANE_Status
  2958. expect_ack (Epson_Scanner * s)
  2959. {
  2960.   unsigned char result[1];
  2961.   size_t len;
  2962.   SANE_Status status;
  2963.  
  2964.   len = sizeof result;
  2965.  
  2966.   receive (s, result, len, &status);
  2967.  
  2968.   if (status != SANE_STATUS_GOOD)
  2969.     return status;
  2970.  
  2971.   if (result[0] != ACK) {
  2972. /*      DBG(8, "Expect ack got %d\n",result[0]); */
  2973.     return SANE_STATUS_INVAL;
  2974.   }
  2975.  
  2976.   return SANE_STATUS_GOOD;
  2977. }
  2978.  
  2979.  
  2980.