kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			719 wiersze
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			719 wiersze
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
| /* sane - Scanner Access Now Easy.
 | |
|    Copyright (C) 1997 BYTEC GmbH Germany
 | |
|    Written by Helmut Koeberle, Email: helmut.koeberle@bytec.de
 | |
|    Modified by Manuel Panea <Manuel.Panea@rzg.mpg.de>
 | |
|    and Markus Mertinat <Markus.Mertinat@Physik.Uni-Augsburg.DE>
 | |
| 
 | |
|    This file is part of the SANE package.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License as
 | |
|    published by the Free Software Foundation; either version 2 of the
 | |
|    License, or (at your option) any later version.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful, but
 | |
|    WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|    General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 | |
|    MA 02111-1307, USA.
 | |
| 
 | |
|    As a special exception, the authors of SANE give permission for
 | |
|    additional uses of the libraries contained in this release of SANE.
 | |
| 
 | |
|    The exception is that, if you link a SANE library with other files
 | |
|    to produce an executable, this does not by itself cause the
 | |
|    resulting executable to be covered by the GNU General Public
 | |
|    License.  Your use of that executable is in no way restricted on
 | |
|    account of linking the SANE library code into it.
 | |
| 
 | |
|    This exception does not, however, invalidate any other reasons why
 | |
|    the executable file might be covered by the GNU General Public
 | |
|    License.
 | |
| 
 | |
|    If you submit changes to SANE to the maintainers to be included in
 | |
|    a subsequent release, you agree by submitting the changes that
 | |
|    those changes may be distributed with this exception intact.
 | |
| 
 | |
|    If you write modifications of your own for SANE, it is your choice
 | |
|    whether to permit this exception to apply to your modifications.
 | |
|    If you do not wish that, delete this exception notice. */
 | |
| 
 | |
| /* This file implements the low-level scsi-commands.  */
 | |
| 
 | |
| static SANE_Status
 | |
| test_unit_ready (int fd)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> test_unit_ready\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< test_unit_ready\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS
 | |
| static SANE_Status
 | |
| request_sense (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> request_sense\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x03;
 | |
|   cmd[4] = 14;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< request_sense\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| inquiry (int fd, int evpd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> inquiry\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x12;
 | |
|   cmd[1] = evpd;
 | |
|   cmd[2] = evpd ? 0xf0 : 0;
 | |
|   cmd[4] = evpd ? 74 : 36;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< inquiry\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| 
 | |
| #if 0
 | |
| static SANE_Status
 | |
| mode_select (int fd)
 | |
| {
 | |
| 
 | |
|   static u_char cmd[6 + 12];
 | |
|   int status;
 | |
|   DBG (31, ">> mode_select\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x15;
 | |
|   cmd[1] = 16;
 | |
|   cmd[4] = 12;
 | |
|   cmd[6 + 4] = 3;
 | |
|   cmd[6 + 5] = 6;
 | |
|   cmd[6 + 8] = 0x02;
 | |
|   cmd[6 + 9] = 0x58;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< mode_select\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| reserve_unit (int fd)
 | |
| {
 | |
| 
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> reserve_unit\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x16;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< reserve_unit\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS
 | |
| static SANE_Status
 | |
| release_unit (int fd)
 | |
| {
 | |
| 
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> release_unit\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x17;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< release_unit\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| mode_sense (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
| 
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> mode_sense\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x1a;
 | |
|   cmd[2] = 3;
 | |
|   cmd[4] = 12;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< mode_sense\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| scan (int fd)
 | |
| {
 | |
|   static u_char cmd[6 + 1];
 | |
|   int status;
 | |
|   DBG (31, ">> scan\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x1b;
 | |
|   cmd[4] = 1;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< scan\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| /* #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS */
 | |
| static SANE_Status
 | |
| send_diagnostic (int fd)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> send_diagnostic\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x1d;
 | |
|   cmd[1] = 4;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< send_diagnostic\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| /* #endif */
 | |
| 
 | |
| static SANE_Status
 | |
| set_window (int fd, void *data)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> set_window\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x24;
 | |
|   cmd[8] = 72;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), data, 72, NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< set_window\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| get_window (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get_window\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x25;
 | |
|   cmd[1] = 1;
 | |
|   cmd[8] = 72;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_window\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| read_data (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> read_data\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x28;
 | |
|   cmd[6] = *buf_size >> 16;
 | |
|   cmd[7] = *buf_size >> 8;
 | |
|   cmd[8] = *buf_size;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< read_data\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| medium_position (int fd)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> medium_position\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x31;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< medium_position\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS
 | |
| static SANE_Status
 | |
| execute_shading (int fd)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> execute shading\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xe2;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< execute shading\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| execute_auto_focus (int fd, int mode, int speed, int AE, int count)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (7, ">> execute auto focus\n");
 | |
|   DBG (7, ">> focus: mode='%d', speed='%d', AE='%d', count='%d'\n",
 | |
|        mode, speed, AE, count);
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xe0;
 | |
|   cmd[1] = mode;
 | |
|   cmd[2] = (speed << 6) | AE;
 | |
|   cmd[4] = count;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, NULL, NULL);
 | |
| 
 | |
|   DBG (7, "<< execute auto focus\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| set_adf_mode (int fd, u_char priority)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xd4;
 | |
|   cmd[4] = 0x01;
 | |
| 
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), &priority, 1, NULL, NULL);
 | |
| 
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| get_scan_mode (int fd, u_char page, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   int PageLen = 0x00;
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xd5;
 | |
|   cmd[2] = page;
 | |
| 
 | |
|   switch (page)
 | |
|     {
 | |
|     case AUTO_DOC_FEEDER_UNIT:
 | |
|     case TRANSPARENCY_UNIT:
 | |
|       cmd[4] = 0x0C + PageLen;
 | |
|       break;
 | |
| 
 | |
|     case SCAN_CONTROL_CONDITIONS:
 | |
|       cmd[4] = 0x14 + PageLen;
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       cmd[4] = 0x24 + PageLen;
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|   DBG (31, "get scan mode: cmd[4]='0x%0X'\n", cmd[4]);
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get scan mode\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| 
 | |
| static SANE_Status
 | |
| define_scan_mode (int fd, u_char page, void *data)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   u_char pdata[20];
 | |
|   size_t i;
 | |
|   int status, pdatalen;
 | |
|   DBG (31, ">> define scan mode\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   memset (pdata, 0, sizeof (data));
 | |
|   cmd[0] = 0xd6;
 | |
|   cmd[1] = 0x10;
 | |
|   cmd[4] = (page == TRANSPARENCY_UNIT) ? 0x0c :
 | |
|     (page == SCAN_CONTROL_CONDITIONS) ? 0x14 : 0x24;
 | |
| 
 | |
|   memcpy (pdata + 4, data, (page == TRANSPARENCY_UNIT) ? 8 :
 | |
| 	  (page == SCAN_CONTROL_CONDITIONS) ? 16 : 24);
 | |
| 
 | |
|   for (i = 0; i < sizeof (cmd); i++)
 | |
|     {
 | |
|       DBG (31, "define scan mode: cmd[%d]='0x%0X'\n", i, cmd[i]);
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < sizeof (pdata); i++)
 | |
|     {
 | |
|       DBG (31, "define scan mode: pdata[%d]='0x%0X'\n", i, pdata[i]);
 | |
|     }
 | |
| 
 | |
|   pdatalen = (page == TRANSPARENCY_UNIT) ? 12 :
 | |
|     (page == SCAN_CONTROL_CONDITIONS) ? 20 : 28;
 | |
| 
 | |
|   status =
 | |
|     sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), pdata, pdatalen, NULL, NULL);
 | |
|   DBG (31, "<< define scan mode\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| get_density_curve (int fd, int component, void *buf, size_t * buf_size,
 | |
| 		   int transfer_data_type)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get_density_curve\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x28;
 | |
|   cmd[2] = transfer_data_type;
 | |
|   cmd[4] = component;
 | |
|   cmd[5] = 0;
 | |
|   cmd[6] = ((*buf_size) >> 16) & 0xff;
 | |
|   cmd[7] = ((*buf_size) >> 8) & 0xff;
 | |
|   cmd[8] = (*buf_size) & 0xff;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_density_curve\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS
 | |
| static SANE_Status
 | |
| get_density_curve_data_format (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get_density_curve_data_format\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x28;
 | |
|   cmd[2] = 0x03;
 | |
|   cmd[4] = 0xff;
 | |
|   cmd[5] = 0;
 | |
|   cmd[6] = 0;
 | |
|   cmd[7] = 0;
 | |
|   cmd[8] = 14;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_density_curve_data_format\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| set_density_curve (int fd, int component, void *buf, size_t * buf_size,
 | |
| 		   int transfer_data_type)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> set_density_curve\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x2a;
 | |
|   cmd[2] = transfer_data_type;
 | |
|   cmd[4] = component;
 | |
|   cmd[5] = 0;
 | |
|   cmd[6] = ((*buf_size) >> 16) & 0xff;
 | |
|   cmd[7] = ((*buf_size) >> 8) & 0xff;
 | |
|   cmd[8] = (*buf_size) & 0xff;
 | |
| 
 | |
|   status =
 | |
|     sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), buf, *buf_size, NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< set_density_curve\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* static SANE_Status */
 | |
| /* set_density_curve_data_format (int fd, void *buf, size_t *buf_size) */
 | |
| /* { */
 | |
| /*   static u_char cmd[10]; */
 | |
| /*   int status, i; */
 | |
| /*   DBG (31, ">> set_density_curve_data_format\n"); */
 | |
| 
 | |
| /*   memset (cmd, 0, sizeof (cmd)); */
 | |
| /*   cmd[0] = 0x2a; */
 | |
| /*   cmd[2] = 0x03; */
 | |
| /*   cmd[4] = 0xff; */
 | |
| /*   cmd[5] = 0; */
 | |
| /*   cmd[6] = 0; */
 | |
| /*   cmd[7] = 0; */
 | |
| /*   cmd[8] = 14; */
 | |
| /*   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size); */
 | |
| 
 | |
| /*   DBG (31, "<< set_density_curve_data_format\n"); */
 | |
| /*   return (status); */
 | |
| /* } */
 | |
| 
 | |
| #ifdef IMPLEMENT_ALL_SCANNER_SCSI_COMMANDS
 | |
| static SANE_Status
 | |
| get_power_on_timer (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get power on timer\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xe3;
 | |
|   cmd[6] = 1;
 | |
|   cmd[7] = 0;
 | |
|   cmd[8] = 0;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get power on timer\n");
 | |
|   return (status);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static SANE_Status
 | |
| get_film_status (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get film status\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xe1;
 | |
|   cmd[6] = 0;
 | |
|   cmd[7] = 0;
 | |
|   cmd[8] = 4;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get film status\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| get_data_status (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[10];
 | |
|   int status;
 | |
|   DBG (31, ">> get_data_status\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0x34;
 | |
|   cmd[8] = 28;
 | |
|   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_data_status\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| /*************** modification for FB620S ***************/
 | |
| static SANE_Status
 | |
| reset_scanner (int fd)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> reset_scanner\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xc1;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< reset_scanner \n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| execute_calibration (int fd)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   u_char data[2];
 | |
|   int status;
 | |
|   DBG (31, ">> execute_calibration\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   memset (data, 0, sizeof (data));
 | |
|   cmd[0] = 0xc2;
 | |
|   cmd[4] = 2;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), data, sizeof (data),
 | |
| 			    NULL, NULL);
 | |
| 
 | |
|   DBG (31, "<< execute_calibration\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| get_calibration_status (int fd, void *buf, size_t * buf_size)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> get_calibration_status\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xc3;
 | |
|   cmd[4] = *buf_size;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_calibration_status\n");
 | |
|   return (status);
 | |
| }
 | |
| 
 | |
| /* static SANE_Status
 | |
| get_switch_status (int fd, void *buf, size_t *buf_size)
 | |
| {
 | |
|   static u_char cmd[6];
 | |
|   int status;
 | |
|   DBG (31, ">> get_switch_status\n");
 | |
| 
 | |
|   memset (cmd, 0, sizeof (cmd));
 | |
|   cmd[0] = 0xc4;
 | |
|   cmd[4] = 2;
 | |
|   status = sanei_scsi_cmd2 (fd, cmd, sizeof (cmd), NULL, 0, buf, buf_size);
 | |
| 
 | |
|   DBG (31, "<< get_switch_status\n");
 | |
|   return (status);
 | |
| } */
 | |
| 
 | |
| /* static SANE_Status
 | |
| wait_ready(int fd)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   int retry = 0;
 | |
| 
 | |
|   while ((status = test_unit_ready (fd)) != SANE_STATUS_GOOD)
 | |
|   {
 | |
|   DBG(5, "wait_ready failed (%d)\n", retry);
 | |
|   if(retry++ > 15) 
 | |
|     {
 | |
|        return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|     sleep(3);
 | |
|   }
 | |
|   return(status);
 | |
| } */
 | |
| 
 | |
| /**************************************************************************/
 | |
| /* As long as we do not know how this scanner stores its density curves,
 | |
|    we do the gamma correction with a 8 <--> 12 bit translation table
 | |
|    stored in the CANON_Scanner structure. */
 | |
| 
 | |
| static SANE_Status
 | |
| get_density_curve_fs2710 (SANE_Handle handle, int component, u_char * buf,
 | |
| 			  size_t * buf_size)
 | |
| {
 | |
|   CANON_Scanner *s = handle;
 | |
|   int i;
 | |
| 
 | |
|   for (i = 0; i < 256; i++)
 | |
|     *buf++ = s->gamma_map[component][i << 4];
 | |
|   *buf_size = 256;
 | |
|   return (SANE_STATUS_GOOD);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| set_density_curve_fs2710 (SANE_Handle handle, int component, u_char * buf)
 | |
| {
 | |
|   CANON_Scanner *s = handle;
 | |
|   int i, j, hi, lo;
 | |
|   u_char *p;
 | |
| 
 | |
|   for (i = 1, hi = *buf++, p = &s->gamma_map[component][0]; i <= 256; i++)
 | |
|     {
 | |
|       lo = hi;
 | |
|       hi = (i < 256) ? *buf++ : 2 * *(buf - 1) - *(buf - 2);
 | |
|       if (hi > 255)
 | |
| 	hi = 255;
 | |
|       for (j = 0; j < 16; j++)	/* do a linear interpolation */
 | |
| 	*p++ = (u_char) (lo + ((double) ((hi - lo) * j)) / 16.0 + 0.5);
 | |
|     }
 | |
|   return (SANE_STATUS_GOOD);
 | |
| }
 | |
| 
 | |
| static SANE_Status
 | |
| set_parameters_fs2710 (SANE_Handle handle)
 | |
| {
 | |
|   CANON_Scanner *s = handle;
 | |
|   int i, j, invert, shadow[4], hilite[4];
 | |
|   double x, b, c;
 | |
| 
 | |
|   shadow[1] = s->ShadowR << 4;
 | |
|   shadow[2] = s->ShadowG << 4;
 | |
|   shadow[3] = s->ShadowB << 4;
 | |
|   hilite[1] = s->HiliteR << 4;
 | |
|   hilite[2] = s->HiliteG << 4;
 | |
|   hilite[3] = s->HiliteB << 4;
 | |
|   c = ((double) s->contrast) / 128.0;
 | |
|   b = ((double) (s->brightness - 128)) / 128.0;
 | |
| 
 | |
|   invert = strcmp (filmtype_list[1], s->val[OPT_NEGATIVE].s);
 | |
| 
 | |
|   for (i = 1; i < 4; i++)
 | |
|     {
 | |
|       for (j = 0; j < 4096; j++)
 | |
| 	{
 | |
| 	  if (j <= shadow[i])
 | |
| 	    s->gamma_map[i][j] = (u_char) ((s->brightness >= 128) ?
 | |
| 					   2 * s->brightness - 256 : 0);
 | |
| 	  else if (j < hilite[i])
 | |
| 	    {
 | |
| 	      x =
 | |
| 		((double) (j - shadow[i])) /
 | |
| 		((double) (hilite[i] - shadow[i]));
 | |
| 	      /* first do the contrast correction */
 | |
| 	      x =
 | |
| 		(x <= 0.5) ? 0.5 * pow (2 * x,
 | |
| 					c) : 1.0 - 0.5 * pow (2 * (1.0 - x),
 | |
| 							      c);
 | |
| 	      x = pow (x, 0.4);	/* default gamma correction */
 | |
| 	      x += b;		/* brightness correction */
 | |
| 	      s->gamma_map[i][j] =
 | |
| 		(u_char) MAX (0, MIN (255, (int) (255.0 * x)));
 | |
| 	    }
 | |
| 	  else
 | |
| 	    s->gamma_map[i][j] = (u_char) ((s->brightness >= 128) ?
 | |
| 					   255 : 2 * s->brightness);
 | |
| 	  if (invert)
 | |
| 	    s->gamma_map[i][j] = 255 - s->gamma_map[i][j];
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   return (SANE_STATUS_GOOD);
 | |
| }
 | |
| 
 | |
| /**************************************************************************/
 |