Porównaj commity

...

8 Commity

Autor SHA1 Wiadomość Data
tly000 be5ccdb392 Merge branch 'cs3200f' into 'master'
Experimental cs3200f backend

See merge request sane-project/backends!765
2024-04-17 08:10:20 +00:00
ThierryFR 728ca40272 Merge branch 'escl-force-idle-status' into 'master'
Escl force idle status

See merge request sane-project/backends!835
2024-04-16 20:45:49 +00:00
ThierryFR 113be50f6b Escl force idle status 2024-04-16 20:45:49 +00:00
tly 7296238e5f cs3200f-drv.c set firmware buffer alignment to 512 bytes 2022-11-16 00:08:53 +01:00
tly 098ec069f3 Add experimental cs3200f backend to dll.conf 2022-11-14 22:49:39 +01:00
tly 94bd3f980a cs3200f update u_state_q to read 2 bytes instead of 1 byte 2022-11-14 22:29:06 +01:00
tly 4ff97ac86a genesys/scanner_interface_usb.cpp include fix 2022-11-14 22:28:41 +01:00
tly 67b85b021e Add experimental cs3200f backend 2022-11-14 22:05:00 +01:00
22 zmienionych plików z 7054 dodań i 11 usunięć

Wyświetl plik

@ -187,7 +187,7 @@ be_convenience_libs = libabaton.la libagfafocus.la \
libtamarack.la libtest.la libteco1.la \
libteco2.la libteco3.la libu12.la libumax.la \
libumax1220u.la libumax_pp.la libv4l.la \
libxerox_mfp.la
libxerox_mfp.la libcs3200f.la
# Each stand-alone backend that's possible to be built should be listed
# here. There are the libraries that are installed under $(libdir)/sane.
@ -222,7 +222,7 @@ be_dlopen_libs = libsane-abaton.la libsane-agfafocus.la \
libsane-tamarack.la libsane-test.la libsane-teco1.la \
libsane-teco2.la libsane-teco3.la libsane-u12.la libsane-umax.la \
libsane-umax1220u.la libsane-umax_pp.la libsane-v4l.la \
libsane-xerox_mfp.la
libsane-xerox_mfp.la libsane-cs3200f.la
EXTRA_LTLIBRARIES = $(be_convenience_libs) $(be_dlopen_libs)
@ -1179,6 +1179,24 @@ libsane_ma1509_la_LIBADD = $(COMMON_LIBS) \
$(USB_LIBS) $(RESMGR_LIBS)
EXTRA_DIST += ma1509.conf.in
libcs3200f_la_SOURCES = cs3200f.c
libcs3200f_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=cs3200f
nodist_libsane_cs3200f_la_SOURCES = cs3200f-s.c
libsane_cs3200f_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=cs3200f
libsane_cs3200f_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
libsane_cs3200f_la_LIBADD = $(COMMON_LIBS) \
libcs3200f.la \
../sanei/sanei_init_debug.lo \
../sanei/sanei_constrain_value.lo \
../sanei/sanei_config.lo \
sane_strstatus.lo \
../sanei/sanei_usb.lo \
../sanei/sanei_access.lo \
../sanei/sanei_thread.lo \
$(USB_LIBS) $(RESMGR_LIBS)
# EXTRA_DIST += cs3200f.conf.in
libmagicolor_la_SOURCES = magicolor.c magicolor.h
libmagicolor_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=magicolor $(SNMP_CFLAGS)

1485
backend/cs3200f-dat.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,382 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_DAT_H
#define CS3200F_DAT_H
#include "../include/sane/sane.h"
/***********************************************************************
* Options
***********************************************************************/
/** Option identifiers */
typedef enum
{
OPT_NUM_OPTS = 0,
OPT_RESOLUTION, /* 1 */
OPT_SOURCE, /* 2 */
OPT_MODE_GROUP, /* 3 */
OPT_MODE, /* 4 */
OPT_DEPTH, /* 5 */
OPT_GRAY_COLOR, /* 6 */
OPT_PREVIEW, /* 7 */
OPT_GAMMA_GROUP, /* 8 */
OPT_RGB_BIND, /* 9 */
OPT_GAMMA, /* 10 */
OPT_GAMMA_R, /* 11 */
OPT_GAMMA_G, /* 12 */
OPT_GAMMA_B, /* 13 */
OPT_THRESHOLD, /* 14 */
OPT_GEOMETRY_GROUP, /* 15 */
OPT_TL_X, /* 16 */
OPT_TL_Y, /* 17 */
OPT_BR_X, /* 18 */
OPT_BR_Y, /* 19 */
OPT_CALIBRATE_GROUP, /* 20 */
OPT_CALIBRATE, /* 21 */
OPT_CALIBRATE_BEFORE_SCAN, /* 22 */
NUM_OPTIONS /* 23 */
} OPT_E;
/************************************************************************
* Option constraints
************************************************************************/
/** Sources */
typedef enum
{
OPT_SOURCE_PAPER,
OPT_SOURCE_FILM
} OPT_SOURCE_E;
/** Modes */
typedef enum
{
OPT_MODE_COLOR,
OPT_MODE_GRAY,
OPT_MODE_LINEART
} OPT_MODE_E;
/** RGB Color */
typedef enum
{
OPT_RGB_COLOR_RED,
OPT_RGB_COLOR_GREEN,
OPT_RGB_COLOR_BLUE
} OPT_RGB_COLOR_E;
/** Geometry limits in mm */
#define OPT_X_MAX 219.0
#define OPT_X_MAX_TA 38.0
#define OPT_Y_MAX 299.0
#define OPT_Y_MAX_TA 25.0
/** Resolutions */
extern const SANE_Word opt_const_resolutions[];
/** Sources */
extern const SANE_String_Const opt_const_sources[];
#define OPT_CONST_SOURCES_MAX_LEN (sizeof(SANE_I18N("Paper")))
/** Modes */
extern const SANE_String_Const opt_const_modes[];
#define OPT_CONST_MODES_MAX_LEN (sizeof(SANE_VALUE_SCAN_MODE_LINEART))
/** Sample depths */
extern const SANE_Word opt_const_depths[];
/** RGB Color */
extern const SANE_String_Const opt_const_rgb_colors[];
#define OPT_CONST_RGB_COLORS_MAX_LEN (sizeof(SANE_I18N("Green")))
/** Gamma */
extern const SANE_Range opt_gamma_range;
/** Threshold */
extern const SANE_Range opt_threshold_range;
/** X range in mm */
extern const SANE_Range opt_x_range;
/** X range in mm */
extern const SANE_Range opt_x_range_ta;
/** Y range in mm */
extern const SANE_Range opt_y_range;
/** Y range in mm */
extern const SANE_Range opt_y_range_ta;
/** Device specific options */
typedef struct
{
SANE_Int resolution;
OPT_SOURCE_E source;
OPT_MODE_E mode;
SANE_Int depth;
OPT_RGB_COLOR_E gray_color;
SANE_Bool preview;
SANE_Bool rgb_bind;
SANE_Fixed gamma;
SANE_Fixed gamma_r;
SANE_Fixed gamma_g;
SANE_Fixed gamma_b;
SANE_Fixed threshold;
SANE_Fixed tl_x;
SANE_Fixed tl_y;
SANE_Fixed br_x;
SANE_Fixed br_y;
SANE_Fixed tl_x_ta;
SANE_Fixed tl_y_ta;
SANE_Fixed br_x_ta;
SANE_Fixed br_y_ta;
SANE_Bool calibrate_before_scan;
} OPT_T;
/************************************************************************
* HW control
************************************************************************/
/** RGB triplet */
typedef struct
{
char r;
char g;
char b;
} RGB_T;
/** AFE settings */
typedef struct {
RGB_T offs;
RGB_T gain;
} AFE_SET_T;
/************************************************************************
* Calibration data
************************************************************************/
typedef struct
{
SANE_Int res; /*< resolution */
SANE_Int offs_x; /*< imaging area offset in 1200 dpi pixels */
SANE_Int offs_y; /*< imaging area offset in 2400 dpi lines */
AFE_SET_T afe_set; /*< AFE settings */
SANE_Int width; /*< width of the imaging area in pixels */
double *bshd; /*< averaged black shading data */
double *wshd; /*< averaged white shading data */
} CAL_T;
/************************************************************************
* Line FIFO
************************************************************************/
typedef struct
{
int width;
int length;
int length2;
int write_idx;
int read_idx;
SANE_Byte *data;
} LINE_FIFO_T;
typedef struct
{
SANE_Int n_lines;
SANE_Int current_line;
SANE_Int line_width;
SANE_Int line_pos;
SANE_Byte *line;
LINE_FIFO_T *r;
LINE_FIFO_T *g;
LINE_FIFO_T *b;
} SCAN_T;
/************************************************************************
* Device data
************************************************************************/
typedef struct DEVICE DEVICE_T;
typedef DEVICE_T *DEVICE_H;
struct DEVICE
{
DEVICE_T *next;
DEVICE_T *prev;
SANE_String name;
SANE_Int dn;
SANE_Bool open;
SANE_Bool hs;
SANE_Bool scanning;
SANE_Pid scan_thread;
int scan_pipe[2];
int scan_bytes_left;
OPT_T opt;
CAL_T cal_300;
CAL_T cal_600;
CAL_T cal_1200;
CAL_T cal_300_ta;
CAL_T cal_600_ta;
CAL_T cal_1200_ta;
SCAN_T scan;
};
/** Initialize device data
*/
void
a_init_data( void );
/** Create new device data
* @return handle to the device
*/
SANE_Handle
a_new_dev( void );
/** Check if the give handle is valid
* @param h handle of the device
* @return SANE_STATUS_GOOD if OK, SANE_STATUS_INVAL if invalid
*/
SANE_Status
a_handle_valid( SANE_Handle h );
/** Delete device data
* @param d handle to the device
*/
void
a_delete_dev( SANE_Handle d );
/** Option getters */
SANE_Int a_get_resolution( SANE_Handle d );
SANE_String_Const a_get_source( SANE_Handle d );
OPT_SOURCE_E a_get_source_e( SANE_Handle d );
SANE_String_Const a_get_mode( SANE_Handle d );
OPT_MODE_E a_get_mode_e( SANE_Handle d );
SANE_Int a_get_depth( SANE_Handle d );
SANE_String_Const a_get_gray_color( SANE_Handle d );
OPT_RGB_COLOR_E a_get_gray_color_e( SANE_Handle d );
SANE_Bool a_get_preview( SANE_Handle d );
SANE_Bool a_get_rgb_bind( SANE_Handle d );
SANE_Fixed a_get_gamma( SANE_Handle d );
SANE_Fixed a_get_gamma_r( SANE_Handle d );
SANE_Fixed a_get_gamma_g( SANE_Handle d );
SANE_Fixed a_get_gamma_b( SANE_Handle d );
SANE_Fixed a_get_threshold( SANE_Handle d );
SANE_Fixed a_get_tl_x( SANE_Handle d );
SANE_Fixed a_get_tl_y( SANE_Handle d );
SANE_Fixed a_get_br_x( SANE_Handle d );
SANE_Fixed a_get_br_y( SANE_Handle d );
SANE_Int a_get_tl_x_pix( SANE_Handle d );
SANE_Int a_get_tl_y_pix( SANE_Handle d );
SANE_Int a_get_br_x_pix( SANE_Handle d );
SANE_Int a_get_br_y_pix( SANE_Handle d );
SANE_Bool a_get_calibrate_before_scan( SANE_Handle d );
/** Option setters */
SANE_Int a_set_resolution( SANE_Handle d, SANE_Int resolution );
SANE_Int a_set_source( SANE_Handle d, SANE_String_Const source );
SANE_Int a_set_mode( SANE_Handle d, SANE_String_Const mode );
SANE_Int a_set_depth( SANE_Handle d, SANE_Int depth );
SANE_Int a_set_gray_color( SANE_Handle d, SANE_String_Const gray_color );
SANE_Int a_set_preview( SANE_Handle d, SANE_Bool preview );
SANE_Int a_set_rgb_bind( SANE_Handle d, SANE_Bool rgb_bind );
SANE_Int a_set_gamma( SANE_Handle d, SANE_Fixed gamma );
SANE_Int a_set_gamma_r( SANE_Handle d, SANE_Fixed gamma_r );
SANE_Int a_set_gamma_g( SANE_Handle d, SANE_Fixed gamma_g );
SANE_Int a_set_gamma_b( SANE_Handle d, SANE_Fixed gamma_b );
SANE_Int a_set_threshold( SANE_Handle d, SANE_Fixed threshold );
SANE_Int a_set_tl_x( SANE_Handle d, SANE_Fixed tl_x );
SANE_Int a_set_tl_y( SANE_Handle d, SANE_Fixed tl_y );
SANE_Int a_set_br_x( SANE_Handle d, SANE_Fixed br_x );
SANE_Int a_set_br_y( SANE_Handle d, SANE_Fixed br_y );
SANE_Int a_set_calibrate_before_scan( SANE_Handle d, SANE_Bool cbs );
/** Scan parameters */
SANE_Frame a_format( SANE_Handle handle );
SANE_Int a_depth( SANE_Handle handle );
SANE_Int a_lines( SANE_Handle handle );
SANE_Int a_pixels_per_line( SANE_Handle handle );
SANE_Int a_bytes_per_line( SANE_Handle handle );
void a_scan_init( SANE_Handle handle );
void a_scan_finish( SANE_Handle handle );
/** Line FIFO */
LINE_FIFO_T *a_new_fifo( int width, int length, int length2 );
void a_delete_fifo( LINE_FIFO_T *fifo );
int a_write_idx( LINE_FIFO_T *fifo );
int a_read_idx( LINE_FIFO_T *fifo );
int a_read_idx2( LINE_FIFO_T *fifo );
void a_write_idx_inc( LINE_FIFO_T *fifo );
void a_read_idx_inc( LINE_FIFO_T *fifo );
int a_space_in_fifo( LINE_FIFO_T *fifo );
SANE_Byte *a_fifo_write_ptr( LINE_FIFO_T *fifo );
SANE_Byte *a_fifo_read_ptr( LINE_FIFO_T *fifo );
SANE_Byte *a_fifo_read_ptr2( LINE_FIFO_T *fifo );
int a_fifo_width( LINE_FIFO_T *fifo );
int a_write_to_fifo( LINE_FIFO_T *fifo, int in_pipe );
void a_read_from_fifo_g( SCAN_T *scan );
void a_read_from_fifo_g_2( SCAN_T *scan );
void a_read_from_fifos_c( SCAN_T *scan );
void a_read_from_fifos_c_2( SCAN_T *scan );
SANE_Int a_read_from_scan( SCAN_T *scan, SANE_Byte *data, SANE_Int max );
SANE_Bool a_lines_left( SCAN_T *scan );
SANE_Bool a_line_empty( SCAN_T *scan );
#endif /* ndef CS3200F_DAT_H */
/************************************************************************
* $Id: cs3200f-dat.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,374 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#include <stdlib.h>
#include <string.h>
#include "cs3200f-dev.h"
#include "cs3200f-dat.h"
#include "cs3200f-drv.h"
#include "cs3200f-usb.h"
#include "../include/sane/sanei_access.h"
/***********************************************************************
* Local types
***********************************************************************/
typedef struct DEVICE_NODE DEVICE_NODE_T;
struct DEVICE_NODE
{
SANE_Device dev;
SANE_String name;
DEVICE_NODE_T *next;
};
/***********************************************************************
* Local prototypes
***********************************************************************/
static void build_device_list( void );
static SANE_Status tell_device( SANE_String_Const name );
static void get_first_device( void );
static SANE_Status first_device( SANE_String_Const name );
/***********************************************************************
* Local data
***********************************************************************/
static SANE_String_Const str_c_vendor_canon =
SANE_I18N( "CANON" );
static SANE_String_Const str_c_model_cs3200f =
SANE_I18N( "CS3200F" );
static SANE_String_Const str_c_type_flatbed_scanner =
SANE_I18N( "flatbed scanner" );
static const SANE_Int usb_vendor_canon = 0x04A9;
static const SANE_Int usb_device_cs3200f = 0x2216;
static DEVICE_NODE_T *current_device_list;
static const SANE_Device **current_device_table;
static SANE_String first_device_name;
/***********************************************************************
* Interface
***********************************************************************/
void d_init_devices( void )
{
DBG( D_CALL, "d_init_devices()\n" );
current_device_list = 0;
current_device_table = 0;
first_device_name = 0;
a_init_data();
}
const SANE_Device **
d_get_devices( void )
{
const SANE_Device **dt;
DBG( D_CALL, "d_get_devices()\n" );
build_device_list();
dt = current_device_table;
DBG( D_RES, "return device table %08X\n", (unsigned int)dt );
return dt;
}
SANE_Status
d_open_device( SANE_String_Const devicename, SANE_Handle *handle )
{
DEVICE_T *dh;
SANE_String_Const the_name;
DBG( D_CALL, "d_open_device( devicename = %s, handle = %08X )\n",
devicename, (unsigned int)handle );
if ( handle )
{
*handle = a_new_dev();
}
else
{
return SANE_STATUS_INVAL;
}
if ( ! *handle )
{
DBG( D_ERR, "Can't allocate memory for the device\n" );
return SANE_STATUS_NO_MEM;
}
dh = *handle;
if ( strcmp( devicename, "dummy" ) == 0 )
{
DBG( D_RES, "Dummy device handle %08X\n", (unsigned int)*handle );
return SANE_STATUS_GOOD;
}
if ( devicename[0] == 0 )
{
get_first_device();
if ( first_device_name == 0 )
{
DBG( D_INFO, "No CS3200F found\n" );
a_delete_dev( *handle );
*handle = 0;
return SANE_STATUS_IO_ERROR;
}
else
{
DBG( D_INFO, "CS3200F found at [%s]\n", first_device_name );
the_name = first_device_name;
}
}
else
{
the_name = devicename;
}
dh->name = malloc( strlen( the_name ) + 1 );
strcpy( dh->name, the_name );
/* check is there is already device with that name open */
DBG( D_INFO, "Trying to lock %s\n", the_name );
if ( sanei_access_lock( the_name, 5 ) )
{
DBG( D_INFO, "Device already open by someone else\n" );
a_delete_dev( *handle );
*handle = 0;
return SANE_STATUS_DEVICE_BUSY;
}
DBG( D_INFO, "Lock obtained\n" );
if ( u_open( dh ) != SANE_STATUS_GOOD )
{
sane_close( *handle );
*handle = 0;
return SANE_STATUS_DEVICE_BUSY;
}
if ( r_boot( dh->dn ) != SANE_STATUS_GOOD )
{
sane_close( *handle );
*handle = 0;
return SANE_STATUS_IO_ERROR;
}
DBG( D_RES, "Device handle %08X\n", (unsigned int)*handle );
return SANE_STATUS_GOOD;
}
void
d_close_device( SANE_Handle handle )
{
DEVICE_T *dh = handle;
DBG( D_CALL, "d_close_device( handle = %08X )\n",
(unsigned int)handle );
if ( a_handle_valid( handle ) != SANE_STATUS_GOOD )
{
return;
}
u_close( dh );
if ( dh->name )
{
DBG( D_INFO, "Unlocking %s\n", dh->name );
(void)sanei_access_unlock( dh->name );
}
a_delete_dev( handle );
}
/***********************************************************************
* Local code
***********************************************************************/
static void build_device_list( void )
{
DEVICE_NODE_T *dn;
int n_devices;
int i;
DBG( D_CALL, "build_device_list()\n" );
/* kill old device list */
while( current_device_list )
{
dn = current_device_list;
current_device_list = current_device_list->next;
if ( dn->name )
{
free( dn->name );
}
free( dn );
}
/* kill old device table */
if ( current_device_table )
{
free( current_device_table );
current_device_table = 0;
}
/* build new name list */
sanei_usb_find_devices( usb_vendor_canon,
usb_device_cs3200f,
tell_device );
/* add dummy device if the list is empty */
if ( ! current_device_list )
{
(void)tell_device( "dummy" );
}
/* build new device table & device list*/
n_devices = 0;
dn = current_device_list;
while ( dn )
{
++n_devices;
dn = dn->next;
}
current_device_table =
malloc( ( n_devices + 1 ) * sizeof( SANE_Device * ) );
dn = current_device_list;
for ( i = 0; i < n_devices; i++ )
{
current_device_table[i] = &(dn->dev);
dn = dn->next;
}
current_device_table[i] = 0;
}
static SANE_Status tell_device( SANE_String_Const name )
{
DEVICE_NODE_T *dn;
DBG( D_CALL, "tell_device_name( name = %s )\n", name );
if ( ! name )
{
/* got null string pointer */
return SANE_STATUS_INVAL;
}
DBG( D_INFO, "Found device %s\n", name );
dn = current_device_list;
while ( dn && dn->next )
{
dn = dn->next;
}
if ( dn )
{
dn = dn->next = malloc( sizeof( DEVICE_NODE_T ) );
}
else
{
dn = current_device_list = malloc( sizeof( DEVICE_NODE_T ) );
}
dn->name = malloc( strlen( name ) + 1 );
strcpy( dn->name, name );
dn->dev.name = dn->name;
dn->dev.vendor = str_c_vendor_canon;
dn->dev.model = str_c_model_cs3200f;
dn->dev.type = str_c_type_flatbed_scanner;
dn->next = 0;
return SANE_STATUS_GOOD;
}
static void get_first_device( void )
{
DBG( D_CALL, "get_first_device()\n" );
if ( first_device_name )
{
free( first_device_name );
first_device_name = 0;
}
sanei_usb_find_devices( usb_vendor_canon,
usb_device_cs3200f,
first_device );
}
static SANE_Status first_device( SANE_String_Const name )
{
DBG( D_CALL, "first_device( name = %s )\n", name );
if ( ! first_device_name )
{
first_device_name = malloc( strlen( name ) + 1 );
strcpy( first_device_name, name );
}
return SANE_STATUS_GOOD;
}
/************************************************************************
* $Id: cs3200f-dev.c,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,84 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_DEV_H
#define CS3200F_DEV_H
#include "../include/sane/sane.h"
/***********************************************************************
* Interface
***********************************************************************/
/** Initialize devices
*/
void d_init_devices( void );
/** Get list of available devices
* @return null terminated list of pointers to SANE_Device structures
*/
const SANE_Device **
d_get_devices( void );
/** Open a device
* @param devicename name of the device to be opened
* @param handle pointer to place where the handle will be put
* @return status of the opening
* @note If the device name is empty string, the first device will be
* opened.
*/
SANE_Status
d_open_device( SANE_String_Const devicename, SANE_Handle *handle );
/** Close a device
* @param handle handle to the device
*/
void
d_close_device( SANE_Handle handle );
#endif /* ndef CS3200F_DEV_H */
/************************************************************************
* $Id: cs3200f-dev.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************/

1462
backend/cs3200f-drv.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,222 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_DRV_H
#define CS3200F_DRV_H
#include "../include/sane/sane.h"
/***********************************************************************
* Interface constants
***********************************************************************/
/** Lamp control */
typedef enum
{
LAMP_MAIN_LOW,
LAMP_MAIN_HIGH,
LAMP_TA
} LAMP_E;
/** Color line of the scan */
typedef enum
{
COLOR_RED = 0,
COLOR_GREEN,
COLOR_BLUE,
COLOR_ALL
} COLOR_E;
/***********************************************************************
* The device interface
***********************************************************************/
/** Boot the scanner
* @param dn device number of the scanner
* @return status of the boot
*/
SANE_Status
r_boot( SANE_Int dn );
/** Set lamp watchdog counts
* @param dn device number of the scanner
* @param c1 zero state count
* @param c2 one state count
* @return status of the boot
* @note Unit of the counts is such that there are 31+13/15 counts
* in one second. Typically c1 = 4000 and c2 = 20000 making
* the lamp tun-off time 24000/(31+13/15) = 753 s or about
* 12.5 min.
*/
SANE_Status
r_wd_set( SANE_Int dn, SANE_Int c1, SANE_Int c2 );
/** Turn a lamp on
* @param dn device number of the scanner
* @param lamp which lamp to turn on
* @return status of the command
*/
SANE_Status
r_lamp_on( SANE_Int dn, LAMP_E lamp );
/** Turn lamps off
* @param dn device number of the scanner
*/
void
r_lamp_off( SANE_Int dn );
/** Set AFE
* @param dn device number of the scanner
* @param as the AFE settings
*/
void
r_afe_set( SANE_Int dn, AFE_SET_T *as );
/** Move scan head home
* @param dn device number of the scanner
*/
void r_home( SANE_Int dn );
/** Move scan head to the given line
* @param dn device number of the scanner
* @param line line to move to
*/
void r_move( SANE_Int dn, SANE_Int line );
/** Wait until the lamp intensity settles
* @param dn device number of the scanner
* @param ta tells if transparency adapter is being used
* @param nmax maximum number of trials (also approximately max
* waiting time is 5*nmax seconds)
* @return SANE_STATUS_GOOD if settled, else SANE_STATUS_CANCELLED
*/
SANE_Status
r_lamp_settle( SANE_Int dn, SANE_Bool ta, SANE_Int nmax );
/** Calibrate AFE to given targets
* @param dn device number of the scanner
* @param res scan head resolution (300/600/1200)
* @param ta tells if transparency adapter is being used
* @param afe_set pointer to initial AFE settings or null if
* offset 0 gain 1 should be used
* @param target_swing target swing of the signal (0..255, typ 250)
* @param target_offset target offset of the signal (0..255, typ 2 )
* @return pointer to a AFE setting structure which is afe_set or
* a newly allocated block if afe_set is null
*/
AFE_SET_T *
r_afe_calibrate( SANE_Int dn,
SANE_Int res,
SANE_Bool ta,
AFE_SET_T *afe_set,
SANE_Int target_swing,
SANE_Int target_offset );
/** Set scanning offsets
* @param dn device number of the scanner
* @param col horizontal offset in 1200 dpi pixels
* @param row vertical offset in 2400 dpi lines
*/
void r_offset( SANE_Int dn, SANE_Int col, SANE_Int row );
/** Reset scan
* @param dn device number of the scanner
*/
void r_reset( SANE_Int dn );
/** Set gamma
* @param dn device number of the scanner
* @param t linear threshold (typ 0.05, rane 0-1)
* @param rg red gamma
* @param gg green gamma
* @param bg blue gamma
*/
void r_gamma( SANE_Int dn,
SANE_Fixed t,
SANE_Fixed rg,
SANE_Fixed gg,
SANE_Fixed bg );
/** Set null shading
* @param dn device number of the scanner
*/
SANE_Status
r_null_shading( SANE_Int dn );
/** Start color scan
* @param dn device number of the scanner
* @param res resolution
* @param x column offset in pixels of current resolution
* @param w scan width in pixels of currebt resolution
* @param y starting line in current resoloution
* @param l number of lines in current resolution
* @param c color line of the scan
*/
SANE_Status
r_scan( SANE_Int dn,
SANE_Int res,
SANE_Int x,
SANE_Int w,
SANE_Int y,
SANE_Int l,
COLOR_E c );
/** Find the top left corner of the scanning area
* @param dn device number of the scanner
* @param res resolution
* @param top pointer to var to receive the x coordinate of
* the top left corner in 1200 lpi lines
* @param left pointer to var to receive the y coordinate of
* the top left corner in 1200 dpi pixels
*/
void r_find_top_left( SANE_Int dn,
SANE_Int res,
SANE_Int *top,
SANE_Int *left );
#endif /* ndef CS3200F_DRV_H */
/************************************************************************
* $Id: cs3200f-drv.h,v 1.2 2006/03/31 18:55:51 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,852 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#include <string.h>
#include "cs3200f-opt.h"
/* temporarily for testing only */
#include "cs3200f-drv.h"
/************************************************************************
* Option descriptors
************************************************************************/
static const SANE_Option_Descriptor o_od_num_opts =
{
/* name = */ "",
/* title = */ SANE_TITLE_NUM_OPTIONS,
/* desc = */ SANE_DESC_NUM_OPTIONS,
/* type = */ SANE_TYPE_INT,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_resolution =
{
/* name = */ SANE_NAME_SCAN_RESOLUTION,
/* title = */ SANE_TITLE_SCAN_RESOLUTION,
/* desc = */ SANE_DESC_SCAN_RESOLUTION,
/* type = */ SANE_TYPE_INT,
/* unit = */ SANE_UNIT_DPI,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
/* constraint.word_list = */ { (const void *)opt_const_resolutions }
};
static const SANE_Option_Descriptor o_od_source =
{
/* name = */ "source",
/* title = */ SANE_I18N( "Source" ),
/* desc = */ SANE_I18N( "Source for the scan." ),
/* type = */ SANE_TYPE_STRING,
/* unit = */ SANE_UNIT_NONE,
/* size = */ OPT_CONST_SOURCES_MAX_LEN,
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
/* constraint.string_list = */ { opt_const_sources }
};
static const SANE_Option_Descriptor o_od_mode_group =
{
/* name = */ "",
/* title = */ SANE_I18N( "Mode settings" ),
/* desc = */ "",
/* type = */ SANE_TYPE_GROUP,
/* unit = */ SANE_UNIT_NONE,
/* size = */ 0,
/* cap = */ 0,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_mode =
{
/* name = */ SANE_NAME_SCAN_MODE,
/* title = */ SANE_TITLE_SCAN_MODE,
/* desc = */ SANE_DESC_SCAN_MODE,
/* type = */ SANE_TYPE_STRING,
/* unit = */ SANE_UNIT_NONE,
/* size = */ OPT_CONST_MODES_MAX_LEN,
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
/* constraint.range = */ { opt_const_modes }
};
static const SANE_Option_Descriptor o_od_depth =
{
/* name = */ SANE_NAME_BIT_DEPTH,
/* title = */ SANE_TITLE_BIT_DEPTH,
/* desc = */ SANE_DESC_BIT_DEPTH,
/* type = */ SANE_TYPE_INT,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof( SANE_Word ),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
/* constraint.range = */ { (const void *)opt_const_depths }
};
static const SANE_Option_Descriptor o_od_depth_ia =
{
/* name = */ SANE_NAME_BIT_DEPTH,
/* title = */ SANE_TITLE_BIT_DEPTH,
/* desc = */ SANE_DESC_BIT_DEPTH,
/* type = */ SANE_TYPE_INT,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof( SANE_Word ),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
/* constraint.range = */ { (const void *)opt_const_depths }
};
static const SANE_Option_Descriptor o_od_gray_color =
{
/* name = */ SANE_I18N( "graycolor" ),
/* title = */ SANE_I18N( "Gray color" ),
/* desc = */ SANE_I18N( "The color that will be used for the gray scale scanning." ),
/* type = */ SANE_TYPE_STRING,
/* unit = */ SANE_UNIT_NONE,
/* size = */ OPT_CONST_RGB_COLORS_MAX_LEN,
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
/* constraint.range = */ { opt_const_rgb_colors }
};
static const SANE_Option_Descriptor o_od_gray_color_ia =
{
/* name = */ SANE_I18N( "graycolor" ),
/* title = */ SANE_I18N( "Gray color" ),
/* desc = */ SANE_I18N( "The color that will be used for the gray scale scanning." ),
/* type = */ SANE_TYPE_STRING,
/* unit = */ SANE_UNIT_NONE,
/* size = */ OPT_CONST_RGB_COLORS_MAX_LEN,
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
/* constraint.range = */ { opt_const_rgb_colors }
};
static const SANE_Option_Descriptor o_od_gamma_group =
{
/* name = */ "",
/* title = */ SANE_I18N( "Gamma settings") ,
/* desc = */ "",
/* type = */ SANE_TYPE_GROUP,
/* unit = */ SANE_UNIT_NONE,
/* size = */ 0,
/* cap = */ 0,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_preview =
{
/* name = */ SANE_NAME_PREVIEW,
/* title = */ SANE_TITLE_PREVIEW,
/* desc = */ SANE_DESC_PREVIEW,
/* type = */ SANE_TYPE_BOOL,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_rgb_bind =
{
/* name = */ SANE_NAME_RGB_BIND,
/* title = */ SANE_TITLE_RGB_BIND,
/* desc = */ SANE_DESC_RGB_BIND,
/* type = */ SANE_TYPE_BOOL,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_rgb_bind_ia =
{
/* name = */ SANE_NAME_RGB_BIND,
/* title = */ SANE_TITLE_RGB_BIND,
/* desc = */ SANE_DESC_RGB_BIND,
/* type = */ SANE_TYPE_BOOL,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_gamma =
{
/* name = */ "gamma",
/* title = */ SANE_I18N( "Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_ia =
{
/* name = */ "gamma",
/* title = */ SANE_I18N( "Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_r =
{
/* name = */ "gammar",
/* title = */ SANE_I18N( "Red Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning red." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_r_ia =
{
/* name = */ "gammar",
/* title = */ SANE_I18N( "Red Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning red." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_g =
{
/* name = */ "gammag",
/* title = */ SANE_I18N( "Green Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning green." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_g_ia =
{
/* name = */ "gammag",
/* title = */ SANE_I18N( "Green Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning green." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_b =
{
/* name = */ "gammab",
/* title = */ SANE_I18N( "Blue Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning blue." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_gamma_b_ia =
{
/* name = */ "gammab",
/* title = */ SANE_I18N( "Blue Gamma" ),
/* desc = */ SANE_I18N( "Gamma correction for scanning blue." ),
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_gamma_range }
};
static const SANE_Option_Descriptor o_od_threshold =
{
/* name = */ SANE_NAME_THRESHOLD,
/* title = */ SANE_TITLE_THRESHOLD,
/* desc = */ SANE_DESC_THRESHOLD,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_PERCENT,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_threshold_range }
};
static const SANE_Option_Descriptor o_od_threshold_ia =
{
/* name = */ SANE_NAME_THRESHOLD,
/* title = */ SANE_TITLE_THRESHOLD,
/* desc = */ SANE_DESC_THRESHOLD,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_PERCENT,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_INACTIVE,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_threshold_range }
};
static const SANE_Option_Descriptor o_od_geometry_group =
{
/* name = */ "",
/* title = */ SANE_I18N( "Geometry" ),
/* desc = */ "",
/* type = */ SANE_TYPE_GROUP,
/* unit = */ SANE_UNIT_NONE,
/* size = */ 0,
/* cap = */ 0,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_tl_x =
{
/* name = */ SANE_NAME_SCAN_TL_X,
/* title = */ SANE_TITLE_SCAN_TL_X,
/* desc = */ SANE_DESC_SCAN_TL_X,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_x_range }
};
static const SANE_Option_Descriptor o_od_tl_y =
{
/* name = */ SANE_NAME_SCAN_TL_Y,
/* title = */ SANE_TITLE_SCAN_TL_Y,
/* desc = */ SANE_DESC_SCAN_TL_Y,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_y_range }
};
static const SANE_Option_Descriptor o_od_br_x =
{
/* name = */ SANE_NAME_SCAN_BR_X,
/* title = */ SANE_TITLE_SCAN_BR_X,
/* desc = */ SANE_DESC_SCAN_BR_X,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_x_range }
};
static const SANE_Option_Descriptor o_od_br_x_ta =
{
/* name = */ SANE_NAME_SCAN_BR_X,
/* title = */ SANE_TITLE_SCAN_BR_X,
/* desc = */ SANE_DESC_SCAN_BR_X,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_x_range_ta }
};
static const SANE_Option_Descriptor o_od_br_y =
{
/* name = */ SANE_NAME_SCAN_BR_Y,
/* title = */ SANE_TITLE_SCAN_BR_Y,
/* desc = */ SANE_DESC_SCAN_BR_Y,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_y_range }
};
static const SANE_Option_Descriptor o_od_br_y_ta =
{
/* name = */ SANE_NAME_SCAN_BR_Y,
/* title = */ SANE_TITLE_SCAN_BR_Y,
/* desc = */ SANE_DESC_SCAN_BR_Y,
/* type = */ SANE_TYPE_FIXED,
/* unit = */ SANE_UNIT_MM,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
/* constraint.range = */ { (const void *)&opt_y_range_ta }
};
static const SANE_Option_Descriptor o_od_calibrate_group =
{
/* name = */ "",
/* title = */ SANE_I18N( "Calibration") ,
/* desc = */ "",
/* type = */ SANE_TYPE_GROUP,
/* unit = */ SANE_UNIT_NONE,
/* size = */ 0,
/* cap = */ 0,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_calibrate =
{
/* name = */ "calibrate",
/* title = */ SANE_I18N( "Calibrate now" ),
/* desc = */ SANE_I18N( "Calibrates the current source" ),
/* type = */ SANE_TYPE_BUTTON,
/* unit = */ SANE_UNIT_NONE,
/* size = */ 0,
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
static const SANE_Option_Descriptor o_od_calibrate_before_scan =
{
/* name = */ "calibratebs",
/* title = */ SANE_I18N( "Calibrate before every scan" ),
/* desc = */ SANE_I18N( "If this is selected the chosen mode and source will"
"be calibrated before each scan" ),
/* type = */ SANE_TYPE_BOOL,
/* unit = */ SANE_UNIT_NONE,
/* size = */ sizeof(SANE_Word),
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
/* constraint_type = */ SANE_CONSTRAINT_NONE,
/* constraint.range = */ { 0 }
};
/************************************************************************
* Option descriptor get
************************************************************************/
const SANE_Option_Descriptor *
o_opt_desc( SANE_Handle handle,
SANE_Int option )
{
DEVICE_H dh = handle;
switch ( option )
{
case OPT_NUM_OPTS:
return &o_od_num_opts;
break;
case OPT_RESOLUTION:
return &o_od_resolution;
break;
case OPT_SOURCE:
return &o_od_source;
break;
case OPT_MODE_GROUP:
return &o_od_mode_group;
break;
case OPT_MODE:
return &o_od_mode;
break;
case OPT_DEPTH:
if ( dh->opt.mode == OPT_MODE_LINEART )
{
return &o_od_depth_ia;
}
else
{
return &o_od_depth;
}
break;
case OPT_GRAY_COLOR:
if ( dh->opt.mode == OPT_MODE_COLOR )
{
return &o_od_gray_color_ia;
}
else
{
return &o_od_gray_color;
}
break;
case OPT_PREVIEW:
return &o_od_preview;
break;
case OPT_GAMMA_GROUP:
return &o_od_gamma_group;
break;
case OPT_RGB_BIND:
if ( dh->opt.mode == OPT_MODE_COLOR )
{
return &o_od_rgb_bind;
}
else
{
return &o_od_rgb_bind_ia;
}
break;
case OPT_GAMMA:
if ( dh->opt.mode == OPT_MODE_LINEART ||
( dh->opt.rgb_bind == SANE_FALSE &&
dh->opt.mode == OPT_MODE_COLOR ) )
{
return &o_od_gamma_ia;
}
else
{
return &o_od_gamma;
}
break;
case OPT_GAMMA_R:
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
dh->opt.mode == OPT_MODE_COLOR ) ||
dh->opt.mode != OPT_MODE_COLOR )
{
return &o_od_gamma_r_ia;
}
else
{
return &o_od_gamma_r;
}
break;
case OPT_GAMMA_G:
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
dh->opt.mode == OPT_MODE_COLOR ) ||
dh->opt.mode != OPT_MODE_COLOR )
{
return &o_od_gamma_g_ia;
}
else
{
return &o_od_gamma_g;
}
break;
case OPT_GAMMA_B:
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
dh->opt.mode == OPT_MODE_COLOR ) ||
dh->opt.mode != OPT_MODE_COLOR )
{
return &o_od_gamma_b_ia;
}
else
{
return &o_od_gamma_b;
}
break;
case OPT_THRESHOLD:
if ( dh->opt.mode == OPT_MODE_LINEART )
{
return &o_od_threshold;
}
else
{
return &o_od_threshold_ia;
}
break;
case OPT_GEOMETRY_GROUP:
return &o_od_geometry_group;
break;
case OPT_TL_X:
return &o_od_tl_x;
break;
case OPT_TL_Y:
return &o_od_tl_y;
break;
case OPT_BR_X:
if ( dh->opt.source == OPT_SOURCE_PAPER )
{
return &o_od_br_x;
}
else
{
return &o_od_br_x_ta;
}
break;
case OPT_BR_Y:
if ( dh->opt.source == OPT_SOURCE_PAPER )
{
return &o_od_br_y;
}
else
{
return &o_od_br_y_ta;
}
break;
case OPT_CALIBRATE_GROUP:
return &o_od_calibrate_group;
break;
case OPT_CALIBRATE:
return &o_od_calibrate;
break;
case OPT_CALIBRATE_BEFORE_SCAN:
return &o_od_calibrate_before_scan;
break;
default:
return 0;
break;
}
}
/************************************************************************
* Option manipulation
************************************************************************/
SANE_Status
o_opt_get( SANE_Handle handle,
SANE_Int option,
void *value )
{
DBG( D_CALL, "o_opt_get( handle = %08X, option = %d, value = %08X )\n",
(unsigned int)handle, option, (unsigned int)value );
if ( ( ( ! value ) && option != OPT_CALIBRATE ) ||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
{
return SANE_STATUS_INVAL;
}
switch ( option )
{
case OPT_NUM_OPTS:
*(SANE_Int *)value = NUM_OPTIONS;
DBG( D_RES, "return number of options: %d\n", NUM_OPTIONS );
break;
case OPT_RESOLUTION:
*(SANE_Int *)value = a_get_resolution( handle );
break;
case OPT_SOURCE:
strcpy( (SANE_String)value, a_get_source( handle ) );
break;
case OPT_MODE:
strcpy( (SANE_String)value, a_get_mode( handle ) );
break;
case OPT_DEPTH:
*(SANE_Int *)value = a_get_depth( handle );
break;
case OPT_GRAY_COLOR:
strcpy( (SANE_String)value, a_get_gray_color( handle ) );
break;
case OPT_PREVIEW:
*(SANE_Bool *)value = a_get_preview( handle );
break;
case OPT_RGB_BIND:
*(SANE_Bool *)value = a_get_rgb_bind( handle );
break;
case OPT_GAMMA:
*(SANE_Fixed *)value = a_get_gamma( handle );
break;
case OPT_GAMMA_R:
*(SANE_Fixed *)value = a_get_gamma_r( handle );
break;
case OPT_GAMMA_G:
*(SANE_Fixed *)value = a_get_gamma_g( handle );
break;
case OPT_GAMMA_B:
*(SANE_Fixed *)value = a_get_gamma_b( handle );
break;
case OPT_THRESHOLD:
*(SANE_Fixed *)value = a_get_threshold( handle );
break;
case OPT_TL_X:
*(SANE_Fixed *)value = a_get_tl_x( handle );
break;
case OPT_TL_Y:
*(SANE_Fixed *)value = a_get_tl_y( handle );
break;
case OPT_BR_X:
*(SANE_Fixed *)value = a_get_br_x( handle );
break;
case OPT_BR_Y:
*(SANE_Fixed *)value = a_get_br_y( handle );
break;
case OPT_CALIBRATE:
break;
case OPT_CALIBRATE_BEFORE_SCAN:
*(SANE_Bool *)value = a_get_calibrate_before_scan( handle );
break;
default:
return SANE_STATUS_INVAL;
break;
}
return SANE_STATUS_GOOD;
}
SANE_Status
o_opt_set( SANE_Handle handle,
SANE_Int option,
void *value,
SANE_Int * info)
{
SANE_Int no_info;
DBG( D_CALL, "o_opt_set( handle = %08X, option = %d,"
" value = %08X, info =%08X )\n",
(unsigned int)handle, option,
(unsigned int)value, (unsigned int)info );
if ( ( ( ! value ) && option != OPT_CALIBRATE ) ||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
{
return SANE_STATUS_INVAL;
}
if ( !info )
{
info = &no_info;
}
switch ( option )
{
case OPT_RESOLUTION:
*info = a_set_resolution( handle, *(SANE_Int *)value );
break;
case OPT_SOURCE:
*info = a_set_source( handle, (SANE_String_Const)value );
break;
case OPT_MODE:
*info = a_set_mode( handle, (SANE_String_Const)value );
break;
case OPT_DEPTH:
*info = a_set_depth( handle, *(SANE_Int *)value );
break;
case OPT_GRAY_COLOR:
*info = a_set_gray_color( handle, (SANE_String_Const)value );
break;
case OPT_PREVIEW:
*info = a_set_preview( handle, *(SANE_Bool *)value );
break;
case OPT_RGB_BIND:
*info = a_set_rgb_bind( handle, *(SANE_Bool *)value );
break;
case OPT_GAMMA:
*info = a_set_gamma( handle, *(SANE_Fixed *)value );
break;
case OPT_GAMMA_R:
*info = a_set_gamma_r( handle, *(SANE_Fixed *)value );
break;
case OPT_GAMMA_G:
*info = a_set_gamma_g( handle, *(SANE_Fixed *)value );
break;
case OPT_GAMMA_B:
*info = a_set_gamma_b( handle, *(SANE_Fixed *)value );
break;
case OPT_THRESHOLD:
*info = a_set_threshold( handle, *(SANE_Fixed *)value );
break;
case OPT_TL_X:
*info = a_set_tl_x( handle, *(SANE_Fixed *)value );
break;
case OPT_TL_Y:
*info = a_set_tl_y( handle, *(SANE_Fixed *)value );
if ( 0 )
{
SANE_Int line;
DEVICE_H dh = handle;
line = SANE_UNFIX( a_get_tl_y( handle ) ) * 2400. / 25.4;
DBG( D_INFO, "Moving to line %d\n", line );
if ( dh->dn >= 0 )
{
r_move( dh->dn, line );
}
}
break;
case OPT_BR_X:
*info = a_set_br_x( handle, *(SANE_Fixed *)value );
break;
case OPT_BR_Y:
*info = a_set_br_y( handle, *(SANE_Fixed *)value );
break;
case OPT_CALIBRATE:
DBG( D_INFO, "Calibrating now!\n" );
{
DEVICE_H dh = handle;
AFE_SET_T *afe_set = 0;
r_lamp_on( dh->dn, LAMP_MAIN_HIGH );
r_lamp_settle( dh->dn, SANE_FALSE, 120 );
r_afe_calibrate( dh->dn, 600, SANE_FALSE, afe_set, 250, 2 );
free( afe_set );
}
*info = 0;
break;
case OPT_CALIBRATE_BEFORE_SCAN:
*info = a_set_calibrate_before_scan( handle, *(SANE_Bool *)value );
break;
default:
return SANE_STATUS_INVAL;
break;
}
DBG( D_RES, "info: %s, %s, %s\n",
*info & SANE_INFO_INEXACT ? "inexact" : "exact",
*info & SANE_INFO_RELOAD_OPTIONS ? "reload options" : "keep options",
*info & SANE_INFO_RELOAD_PARAMS ? "reload params" : "keep params" );
return SANE_STATUS_GOOD;
}
/************************************************************************
* $Id: cs3200f-opt.c,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,88 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_OPT_H
#define CS3200F_OPT_H
#include "../include/sane/sane.h"
#include "cs3200f-dat.h"
/** Get option decriptor
* @param handle the device for which the descriptor is queried
* @param option the option for which the descriptor is queried
* @return pointer to the descriptor
*/
const SANE_Option_Descriptor *
o_opt_desc( SANE_Handle handle,
SANE_Int option );
/** Get option
* @param handle the device for which the option is queried
* @param option the option which is being queried
* @param value pointer to the location where value is put
* @return status of the query
*/
SANE_Status
o_opt_get( SANE_Handle handle,
SANE_Int option,
void *value );
/** Set option
* @param handle the device for which the option is set
* @param option the option which is being set
* @param value pointer to the location where the new value is
* @param info tells about the side effects of setting
* @return status of the query
*/
SANE_Status
o_opt_set( SANE_Handle handle,
SANE_Int option,
void *value,
SANE_Int * info);
#endif /* ndef CS3200F_OPT_H */
/************************************************************************
* $Id: cs3200f-opt.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,539 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#include "../include/sane/sanei_thread.h"
#include <unistd.h>
#include "cs3200f-scan.h"
#include "cs3200f-dat.h"
#include "cs3200f-drv.h"
/***********************************************************************
* Local types
***********************************************************************/
typedef struct RAW_DATA
{
struct RAW_DATA *next;
SANE_Int n_lines;
SANE_Byte data[1];
} RAW_DATA_T;
/***********************************************************************
* Local prototypes
***********************************************************************/
static int s_scan_thread( void *handle );
void s_unstagger( SANE_Handle handle,
SANE_Byte * data,
SANE_Int max_length,
SANE_Int * length );
/***********************************************************************
* Interface
***********************************************************************/
SANE_Status s_get_params( SANE_Handle handle,
SANE_Parameters * params )
{
DBG( D_CALL, "s_get_params( handle = %08X, params = %08X)\n",
(unsigned int)handle, (unsigned int)params );
if ( ( ! params ) ||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
{
DBG( D_ERR, "Bad parameters\n" );
return SANE_STATUS_INVAL;
}
params->format = a_format( handle );
DBG( D_RES, "Format: %s\n",
(params->format == SANE_FRAME_RGB ) ? "RGB": "Gray" );
params->last_frame = SANE_TRUE;
DBG( D_RES, "Last frame: true\n" );
params->depth = a_depth( handle );
DBG( D_RES, "Depth: %d\n", params->depth );
params->lines = a_lines( handle );
DBG( D_RES, "Lines: %d\n", params->lines );
params->pixels_per_line = a_pixels_per_line( handle );
DBG( D_RES, "Pixels per line: %d\n", params->pixels_per_line );
params->bytes_per_line = a_bytes_per_line( handle );
DBG( D_RES, "Bytes per line: %d\n", params->bytes_per_line );
return SANE_STATUS_GOOD;
}
SANE_Status s_scan_start( SANE_Handle handle )
{
DEVICE_H dh = handle;
DBG( D_CALL, "s_scan_start( handle = %08X )\n",
(unsigned int)handle );
a_scan_finish( handle );
a_scan_init(handle );
if ( pipe( dh->scan_pipe ) == -1 )
{
DBG( D_ERR, "Pipe creation failed\n" );
return SANE_STATUS_IO_ERROR;
}
dh->scan_thread = sanei_thread_begin( s_scan_thread, dh );
if ( sanei_thread_is_forked() )
{
close( dh->scan_pipe[1] );
}
if ( dh->scan_thread == -1 )
{
DBG( D_ERR, "Scan thread spawning failed\n" );
return SANE_STATUS_IO_ERROR;
}
else
{
DBG( D_INFO, "Scan thread %d spawned\n", dh->scan_thread );
}
dh->scan_bytes_left = a_lines( handle ) * a_bytes_per_line( handle );
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR
|| a_get_resolution( handle ) == 1200 )
{
a_scan_init( handle );
}
return SANE_STATUS_GOOD;
}
SANE_Status
s_scan_read( SANE_Handle handle,
SANE_Byte * data,
SANE_Int max_length,
SANE_Int * length )
{
DEVICE_H dh = handle;
DBG( D_CALL, "s_scan_read( handle = %08X, data = %08X, "
"max_length = %d, length = %08X )\n",
(unsigned int)handle, (unsigned int)data,
max_length, (unsigned int)length );
if ( dh->dn < 0 )
{
*length = read( dh->scan_pipe[0], data, max_length );
}
else
{
s_unstagger( handle, data, max_length, length );
}
if ( *length <= 0 )
{
*length = 0;
DBG( D_INFO, "Read finished\n" );
DBG( D_INFO, "Killing scan thread %d\n", dh->scan_thread );
/* TODO: how to handle rbuf in scan thread? */
sanei_thread_kill( dh->scan_thread );
/* reset scanner */
r_reset( dh->dn );
r_home( dh->dn );
a_scan_finish( handle );
return SANE_STATUS_EOF;
}
dh->scan_bytes_left -= *length;
DBG( D_INFO, "Read %d bytes %d left\n", *length, dh->scan_bytes_left );
return SANE_STATUS_GOOD;
}
void
s_scan_cancel( SANE_Handle handle )
{
DEVICE_H dh = handle;
int info;
DBG( D_CALL, "s_scan_cancel( handle = %08X )\n",
(unsigned int)handle );
a_scan_finish( handle );
if ( dh->scan_thread != -1 )
{
#if 1
DBG( D_INFO, "Waiting scan thread %d\n", dh->scan_thread );
sanei_thread_waitpid( dh->scan_thread, &info );
#else
DBG( D_INFO, "Killing scan thread %d\n", dh->scan_thread );
sanei_thread_kill( dh->scan_thread );
#endif
}
dh->scan_thread = -1;
close( dh->scan_pipe[0] );
}
/***********************************************************************
* Local code
***********************************************************************/
static int s_scan_thread( void *handle )
{
DEVICE_H dh = handle;
int i;
DBG( D_INFO, "Scan thread starting\n" );
i = 0;
if ( sanei_thread_is_forked() )
{
close( dh->scan_pipe[0] );
}
if ( dh->dn < 0 ) /* dummy scanner */
{
int n_bytes = 0;
char buf1[3] = { '\377', '\000', '\000' };
char buf2[3] = { '\000', '\000', '\377' };
n_bytes = a_lines( handle ) * a_bytes_per_line( handle );
while ( n_bytes > 0 )
{
if ( i == 64 )
{
n_bytes -= write( dh->scan_pipe[1], buf1, 3 );
i = 0;
DBG( D_INFO, "bytes left in scan %d\n", n_bytes );
}
else
{
n_bytes -= write( dh->scan_pipe[1], buf2, 3 );
i++;
}
/* usleep(1); */
}
}
else /* real scanner */
{
AFE_SET_T *as;
SANE_Int ccd_res;
COLOR_E c;
SANE_Int m;
SANE_Fixed rg,gg,bg;
SANE_Status status;
SANE_Byte *rbuf;
size_t n_bytes;
size_t n_bytes_r;
size_t len;
SANE_Int res;
SANE_Int n_lines;
SANE_Int width;
/* turn lamp on */
r_lamp_on( dh->dn, LAMP_MAIN_HIGH );
r_lamp_settle( dh->dn, SANE_FALSE, 30 );
/* calibrate if not done or if every scan */
ccd_res = a_get_resolution( handle );
if ( ccd_res < 300 )
{
ccd_res = 300;
}
as = r_afe_calibrate( dh->dn,
ccd_res,
SANE_FALSE,
0,
250,
2 );
/* set AFE */
r_afe_set( dh->dn, as );
/* set gamma */
if ( a_get_rgb_bind( handle ) )
{
rg = gg = bg = a_get_gamma( handle );
}
else
{
rg = a_get_gamma_r( handle );
gg = a_get_gamma_g( handle );
bg = a_get_gamma_b( handle );
}
r_gamma( dh->dn, SANE_FIX( 0.05 ),
rg,gg,bg );
/* set shading */
r_null_shading( dh->dn );
/* set offset */
{
SANE_Int offs_x = 0;
SANE_Int offs_y = 0;
switch( ccd_res )
{
case 300:
offs_x = dh->cal_300.offs_x;
offs_y = dh->cal_300.offs_y;
break;
case 600:
offs_x = dh->cal_600.offs_x;
offs_y = dh->cal_600.offs_y;
break;
case 1200:
offs_x = dh->cal_1200.offs_x;
offs_y = dh->cal_1200.offs_y;
break;
default:
break;
}
r_offset( dh->dn, offs_x, offs_y );
}
/* start scan */
res = a_get_resolution( handle );
n_lines = a_lines( handle );
if ( a_get_resolution( handle ) == 75 )
{
n_lines += ( n_lines + 2 ) / 3 + 1;
}
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR )
{
c = 3;
m = 3;
n_lines += 48*res/1200;
if ( a_get_resolution( handle ) == 75 )
{
n_lines += ( n_lines + 2 ) / 3 + 1;
}
}
else
{
c = a_get_gray_color_e( handle );
m = 1;
}
if ( a_get_resolution( handle ) == 1200 )
{
n_lines += 4;
}
width = a_pixels_per_line( handle );
status = r_scan( dh->dn,
res,
a_get_tl_x_pix( handle ),
width,
a_get_tl_y_pix( handle ),
n_lines,
c
);
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "Can't start scan\n" );
close( dh->scan_pipe[1] );
return 0;
}
rbuf = malloc( 0x10000 );
/* in loop read all bytes */
n_bytes_r = n_lines * width * m;
while ( n_bytes_r > 0 )
{
n_bytes = n_bytes_r;
if ( n_bytes > 0x10000 )
{
n_bytes = 0x10000;
}
len = ( n_bytes + 511 ) & ~511;
DBG( D_INFO, ">>Bytes left %d now reading %d bytes\n",
n_bytes_r, n_bytes );
status = u_bulk_read( dh->dn, rbuf, &len );
n_bytes = len;
if ( status != SANE_STATUS_GOOD || len != n_bytes )
{
DBG( D_ERR, "Can't read scan data (status %d len %d of %d)\n",
status, len, n_bytes );
break;
}
write( dh->scan_pipe[1], rbuf, n_bytes );
if ( n_bytes > n_bytes_r )
{
n_bytes_r = 0;
}
else
{
n_bytes_r -= n_bytes;
}
}
/* reset scanner */
r_reset( dh->dn );
r_home( dh->dn );
free( rbuf );
}
close( dh->scan_pipe[1] );
DBG( D_INFO, "Scan thread exiting\n" );
return 0;
}
/************************************************************************
* Unstaggerer
************************************************************************/
void unstagger_gray( int width, int length );
void unstagger_color( int width, int length, int res );
void unstagger_color_2( int width, int length );
void s_unstagger( SANE_Handle handle,
SANE_Byte * data,
SANE_Int max_length,
SANE_Int * length )
{
int res;
int gray;
DEVICE_H dh = handle;
SCAN_T *scan;
int in_pipe;
scan = &(dh->scan);
in_pipe = dh->scan_pipe[0];
gray = 1;
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR )
{
gray = 0;
}
res = a_get_resolution( handle );
*length = 0;
while ( a_lines_left( scan ) && *length != max_length )
{
DBG( D_INFO, ">> line %d length %d\n", scan->current_line, *length );
*length += a_read_from_scan( scan,
&data[*length],
max_length - *length );
if ( a_line_empty( scan ) )
{
if ( gray )
{
while ( a_space_in_fifo( scan->r ) )
{
a_write_to_fifo( scan->r, in_pipe );
}
if ( res == 1200 )
{
a_read_from_fifo_g_2( scan );
}
else
{
a_read_from_fifo_g( scan );
}
}
else
{
if ( res == 75 && ( scan->current_line & 3 ) == 3 )
{
a_read_idx_inc( scan->r );
a_read_idx_inc( scan->g );
a_read_idx_inc( scan->b );
}
while ( a_space_in_fifo( scan->r ) ||
a_space_in_fifo( scan->g ) ||
a_space_in_fifo( scan->b ) )
{
if ( !a_space_in_fifo( scan->r ) )
{
a_read_idx_inc( scan->r );
}
if ( !a_space_in_fifo( scan->g ) )
{
a_read_idx_inc( scan->g );
}
a_write_to_fifo( scan->r, in_pipe );
a_write_to_fifo( scan->g, in_pipe );
a_write_to_fifo( scan->b, in_pipe );
}
if ( res == 1200 )
{
a_read_from_fifos_c_2( scan );
}
else
{
a_read_from_fifos_c( scan );
}
}
}
}
}

Wyświetl plik

@ -0,0 +1,84 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_SCAN_H
#define CS3200F_SCAN_H
#include "../include/sane/sane.h"
/***********************************************************************
* Interface
***********************************************************************/
/** Get scanning parameters
* @param handle handle of the device
* @param params pointer to the parameter structure
* @return status
*/
SANE_Status s_get_params( SANE_Handle handle,
SANE_Parameters * params );
/** Start scanning with the current options
* @param handle handle of the device
* @return status
*/
SANE_Status s_scan_start( SANE_Handle handle );
/** Read scan data
*/
SANE_Status
s_scan_read( SANE_Handle handle,
SANE_Byte * data,
SANE_Int max_length,
SANE_Int * length );
/** Cancel scanning
*/
void
s_scan_cancel( SANE_Handle handle );
#endif /* ndef CS3200F_SCAN_H */

Wyświetl plik

@ -0,0 +1,514 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#include "cs3200f-usb.h"
#include <stdlib.h>
#include <unistd.h>
#include "../include/sane/sanei.h"
#include "../include/sane/sanei_usb.h"
/***********************************************************************
* local prototypes
***********************************************************************/
/** Check if the device is connected via high speed USB
* @param dn usb device number
* @return SANE_TRUE if connected via USB HS, else SANE_FALSE
*/
static SANE_Bool
is_hs( SANE_Int dn );
/***********************************************************************
* Basic interface functions
***********************************************************************/
SANE_Status
u_open( DEVICE_T *dev )
{
SANE_Status status;
DBG( D_CALL, "u_open( dev = %08X )\n", (unsigned int)dev );
status = sanei_usb_open( dev->name, &(dev->dn) );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "sanei_usb_open() failed with status %d\n", status );
return status;
}
dev->open = SANE_TRUE;
dev->hs = is_hs( dev->dn );
return status;
}
void
u_close( DEVICE_T *dev )
{
DBG( D_CALL, "u_close( dev = %08X )\n", (unsigned int)dev );
if ( dev->open ) {
sanei_usb_close( dev->dn );
}
dev->open = SANE_FALSE;
}
SANE_Byte
u_byte_read( SANE_Int dn,
SANE_Int value,
SANE_Int index )
{
SANE_Byte data;
SANE_Status status;
DBG( D_CALL, "u_byte_read( dn = %d, value = %04X, index = %04X )\n",
dn, value, index );
status = sanei_usb_control_msg( dn,
USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE,
0x0c,
value,
index,
1,
&data );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_byte_read() failed\n" );
return 0;
}
DBG( D_RES, "return: %2X\n", (unsigned int) data );
return data;
}
void
u_byte_write( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte data )
{
SANE_Byte data_out[2] = { 0, 0 };
SANE_Status status;
DBG( D_CALL, "u_byte_write( dn = %d, value = %04X,"
" index = %04X, data = %02X )\n",
dn, value, index, data );
data_out[0] = data;
status = sanei_usb_control_msg( dn,
USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE,
0x04,
value,
index,
2,
data_out );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_byte_write() failed\n" );
}
}
SANE_Status
u_read( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte *data,
SANE_Int len )
{
SANE_Status status;
DBG( D_CALL, "u_read( dn = %d, value = %04X, index = %04X,"
" data = %08X, len = %d, len )\n",
dn, value, index, (unsigned int)data, len );
status = sanei_usb_control_msg( dn,
USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE,
0x04,
value,
index,
len,
data );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_read() failed\n" );
}
return status;
}
SANE_Status
u_write( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte *data,
SANE_Int len )
{
SANE_Status status;
DBG( D_CALL, "u_write( dn = %d, value = %04X, index = %04X,"
" data = %08X, len = %d )\n",
dn, value, index, (unsigned int)data, len);
if ( data[len-1] != 0 )
{
DBG( D_WARN, "The last byte of the control write should be \\0\n" );
}
status = sanei_usb_control_msg( dn,
USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE,
0x04,
value,
index,
len,
data );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_write() failed\n" );
}
return status;
}
SANE_Status
u_bulk_read( SANE_Int dn,
SANE_Byte *data,
size_t *len )
{
SANE_Status status;
int retry;
size_t len_read;
size_t len_remaining;
DBG( D_CALL, "u_bulk_read( dn = %d, data = %08X, len = %d )\n",
dn, (unsigned int)data, (int)(*len) );
#define RETRY_COUNT 60
len_read = 0;
for ( retry = 0; retry < RETRY_COUNT; retry++ )
{
len_remaining = *len - len_read;
status = sanei_usb_read_bulk( dn, data+len_read, &len_remaining );
len_read += len_remaining;
if ( status != SANE_STATUS_IO_ERROR )
{
break;
}
usleep( 10000 );
/* allow 10 ms for the device to catch up, then try again */
}
*len = len_read;
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_bulk_read() failed\n" );
}
return status;
}
SANE_Status
u_bulk_write( SANE_Int dn,
SANE_Byte *data,
size_t *len )
{
SANE_Status status;
DBG( D_CALL, "u_bulk_write( dn = %d, data = %08X, len = %d )\n",
dn, (unsigned int)data, *len );
status = sanei_usb_write_bulk( dn, data, len );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_bulk_write() failed\n" );
}
return status;
}
SANE_Status
u_mem_read( SANE_Int dn,
SANE_Int addr,
SANE_Byte *data,
size_t *len )
{
SANE_Status status;
SANE_Byte saddr[5];
SANE_Byte slen[4];
int i;
DBG( D_CALL, "u_mem_read( dn = %d, addr = %08X, data = %08X, len = %d )\n",
dn, addr, (unsigned int)data, (int)(*len));
if ( ( addr & 0xf ) != 0 )
{
DBG( D_ERR, "Error: address must be multiple of 16\n" );
return SANE_STATUS_INVAL;
}
if ( ( addr & 0x3f ) != 0 )
{
DBG( D_ERR, "Error: length must be multiple of 64\n" );
return SANE_STATUS_INVAL;
}
for ( i = 0; i < 4; i++ )
{
saddr[i] = ( addr >> (8*i+1) ) & 0xff;
}
saddr[4] = 0;
for ( i = 0; i < 3; i++ )
{
slen[i] = ( (SANE_Int)(*len) >> (8*i+1) ) & 0xff;
}
slen[3] = 0;
status = u_state_q( dn );
status = u_write( dn, 0x00f0, 0x0000, saddr, 5 );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "Can't set address\n" );
return status;
}
status = u_state_q( dn );
status = u_write( dn, 0x00f4, 0x0000, slen, 4 );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "Can't set length\n" );
return status;
}
status = u_bulk_read( dn, data, len );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_mem_read() failed\n" );
}
return status;
}
SANE_Status
u_mem_write( SANE_Int dn,
SANE_Int addr,
SANE_Byte *data,
size_t *len )
{
SANE_Status status;
SANE_Byte saddr[5];
SANE_Byte slen[4];
int i;
DBG( D_CALL, "u_mem_write( dn = %d, addr = %08X, data = %08X, len = %d )\n",
dn, addr, (unsigned int)data, (int)(*len) );
if ( ( addr & 0xf ) != 0 )
{
DBG( D_ERR, "Error: address must be multiple of 16\n" );
return SANE_STATUS_INVAL;
}
if ( ( addr & 0xf ) != 0 )
{
DBG( D_ERR, "Error: length must be multiple of 16\n" );
return SANE_STATUS_INVAL;
}
for ( i = 0; i < 4; i++ )
{
saddr[i] = ( addr >> (8*i+1) ) & 0xff;
}
saddr[4] = 0;
for ( i = 0; i < 3; i++ )
{
slen[i] = ( (SANE_Int)(*len) >> (8*i+1) ) & 0xff;
}
slen[3] = 0;
status = u_state_q( dn );
status = u_write( dn, 0x00f0, 0x0000, saddr, 5 );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "Can't set address\n" );
return status;
}
status = u_state_q( dn );
status = u_write( dn, 0x00f3, 0x0000, slen, 4 );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "Can't set length\n" );
return status;
}
status = u_bulk_write( dn, data, len );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "u_mem_write() failed\n" );
}
return status;
}
/***********************************************************************
* Applied interface functions
***********************************************************************/
SANE_Byte
u_b_r( SANE_Int dn, SANE_Int addr )
{
return u_byte_read( dn, 0x00e1, addr );
}
void
u_b_w( SANE_Int dn, SANE_Int addr, SANE_Byte data )
{
u_byte_write( dn, 0x00e0, addr, data );
}
SANE_Byte
u_state_q( SANE_Int dn )
{
/* TODO: the original driver sometimes queries 2 and sometimes 4 bytes. */
SANE_Byte status[2] = { 0 };
(void)u_read( dn, 0x0040, 0, status, sizeof(status) );
return status[0];
}
SANE_Bool
u_home_q( SANE_Int dn )
{
SANE_Byte status[2] = { 0, 0 };
(void)u_read( dn, 0x0040, 0, status, 2 );
return status[1]?SANE_FALSE:SANE_TRUE;
}
SANE_Int
u_line_q( SANE_Int dn )
{
SANE_Byte status[4] = { 0, 0, 0, 0 };
(void)u_read( dn, 0x0040, 0, status, 4 );
return ( ( (SANE_Int)status[2] & 0xFF ) << 8 ) +
( (SANE_Int)status[3] & 0xFF );
}
/***********************************************************************
* local utilities
***********************************************************************/
static SANE_Bool
is_hs( SANE_Int dn )
{
SANE_Byte device_descriptor[ USB_DT_DEVICE_SIZE ];
SANE_Status status;
DBG( D_CALL, "is_hs( dn = %d )\n", dn );
status = sanei_usb_control_msg( dn,
USB_DIR_IN
| USB_TYPE_STANDARD
| USB_RECIP_DEVICE,
USB_REQ_GET_DESCRIPTOR,
( USB_DT_DEVICE << 8 ),
0,
USB_DT_DEVICE_SIZE,
device_descriptor );
if ( status != SANE_STATUS_GOOD )
{
DBG( D_ERR, "xFailed to get device descriptor\n" );
return SANE_FALSE;
}
DBG( D_RES, "USB interface version %X.%02X\n",
device_descriptor[3], device_descriptor[2]);
if ( device_descriptor[3] == 2 )
{
return SANE_TRUE;
}
return SANE_FALSE;
}
/************************************************************************
* $Id: cs3200f-usb.c,v 1.4 2006/05/30 18:10:45 lapi-guest Exp $
************************************************************************/

Wyświetl plik

@ -0,0 +1,215 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#ifndef CS3200F_USB_H
#define CS3200F_USB_H
#include "../include/sane/sane.h"
/***********************************************************************
* Basic interface functions
***********************************************************************/
/** Open the scanner
* @param dev the device to be opened
* @return status of the opening
*/
SANE_Status
u_open( DEVICE_T *dev );
/** Close the scanner
* @param dev the device to be close
*/
void
u_close( DEVICE_T *dev );
/** Read one byte from the scanner
* @param dn device number of the scanner
* @param value wValue of the control transfer
* @param index wIndex of the control transfer
* @return the byte read
*/
SANE_Byte
u_byte_read( SANE_Int dn,
SANE_Int value,
SANE_Int index );
/** Write one byte to the scanner
* @param dn device number of the scanner
* @param value wValue of the control transfer
* @param index wIndex of the control transfer
* @param data the byte to be written
*/
void
u_byte_write( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte data );
/** Read bytes from the scanner
* @param dn device number of the scanner
* @param value wValue of the control transfer
* @param index wIndex of the control transfer
* @param data pointer to the data buffer
* @param len number of bytes to read
* @return status of the read
*/
SANE_Status
u_read( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte *data,
SANE_Int len );
/** Write bytes to the scanner
* @param dn device number of the scanner
* @param value wValue of the control transfer
* @param index wIndex of the control transfer
* @param data the byte to be written
* @param len number of bytes to write
* @note The last byte of the data must be 0!
*/
SANE_Status
u_write( SANE_Int dn,
SANE_Int value,
SANE_Int index,
SANE_Byte *data,
SANE_Int len );
/** Bulk read bytes from the scanner
* @param dn device number of the scanner
* @param data pointer to the data buffer
* @param len pointer to the number of bytes to read;
* after return the number indicates bytes read
* @return status of the read
*/
SANE_Status
u_bulk_read( SANE_Int dn,
SANE_Byte *data,
size_t *len );
/** Bulk write bytes to the scanner
* @param dn device number of the scanner
* @param data pointer to the data buffer
* @param len pointer to the number of bytes to write
* after return the number indicates bytes written
* @return status of the write
*/
SANE_Status
u_bulk_write( SANE_Int dn,
SANE_Byte *data,
size_t *len );
/** Read bytes from the scanner memory
* @param dn device number of the scanner
* @param addr address to read from
* @param data pointer to the data buffer
* @param len pointer to the number of bytes to read;
* after return the number indicates bytes read
* @return status of the read
* @note Address must be multiple of 16 and length multiple of 64!
*/
SANE_Status
u_mem_read( SANE_Int dn,
SANE_Int addr,
SANE_Byte *data,
size_t *len );
/** Write bytes to the scanner memory
* @param dn device number of the scanner
* @param addr address to write to
* @param data pointer to the data buffer
* @param len poiter to the number of bytes to write;
* after return the number indicates bytes written
* @return status of the write
* @note Address and length must be multiples of 16!
*/
SANE_Status
u_mem_write( SANE_Int dn,
SANE_Int addr,
SANE_Byte *data,
size_t *len );
/***********************************************************************
* Applied interface functions
***********************************************************************/
/** Read a byte from the scanner memory
* @param dn the device number of the scanner
* @param addr address to read form
* @return the byte or 0 in failure
*/
SANE_Byte
u_b_r( SANE_Int dn, SANE_Int addr );
/** Write a byte from the scanner memory
* @param dn the device number of the scanner
* @param addr address to read form
* @param data the byte to write
*/
void
u_b_w( SANE_Int dn, SANE_Int addr, SANE_Byte data );
/** Query the scan engine state
* @param dn the device number of the scanner
* @return the state
*/
SANE_Byte
u_state_q( SANE_Int dn );
/** Query if the scanner cartridge is at home
* @param dn the device number of the scanner
* @return the home status
*/
SANE_Bool
u_home_q( SANE_Int dn );
/** Query the scanner cartridge position (in 1200 dpi lines)
* @param dn the device number of the scanner
* @return the line number
*/
SANE_Int
u_line_q( SANE_Int dn );
#endif /* ndef CS3200F_USB_H */

313
backend/cs3200f.c 100644
Wyświetl plik

@ -0,0 +1,313 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
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 backend is for CanoScan 3200F.
*/
#define BACKEND_NAME cs3200f
#include "../include/sane/config.h"
#include "../include/sane/sane.h"
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_debug.h"
#include "../include/sane/sanei_access.h"
#include "../include/sane/sanei_usb.h"
#include "../include/sane/sanei_thread.h"
#include "../include/sane/saneopts.h"
#include "cs3200f-dat.h"
#include "cs3200f-dev.h"
#include "cs3200f-opt.h"
#include "cs3200f-scan.h"
/***********************************************************************
* Debug info levels
***********************************************************************/
#define D_ERR 1
#define D_WARN 2
#define D_INFO 3
#define D_CALL 4
#define D_RES 5
/***********************************************************************
* Library
***********************************************************************/
#define CS_VERSION_MAJOR 1
#define CS_VERSION_MINOR 1
#define CS_VERSION_BUILD 1
static const SANE_Int
c_version = SANE_VERSION_CODE( CS_VERSION_MAJOR,
CS_VERSION_MINOR,
CS_VERSION_BUILD );
SANE_Status
sane_init( SANE_Int * version_code,
SANE_Auth_Callback authorize )
{
(void)authorize; /* we don't need authorizations */
DBG_INIT();
DBG( D_CALL, "sane_init( version_code = %08X, authorize = %08X )\n",
(unsigned int)version_code, (unsigned int)authorize );
sanei_access_init( STRINGIFY(BACKEND_NAME) );
sanei_usb_init();
sanei_thread_init();
d_init_devices();
if ( version_code )
{
*version_code = c_version;
DBG( D_RES, "return version %08X\n", c_version );
}
return SANE_STATUS_GOOD;
}
void
sane_exit( void )
{
DBG( D_CALL, "sane_exit()\n" );
}
/***********************************************************************
* Devices
***********************************************************************/
SANE_Status
sane_get_devices( const SANE_Device *** device_list,
SANE_Bool local_only )
{
(void)local_only; /* we don't look for remote devices anyway */
DBG( D_CALL, "sane_get_devices( device_list = %08X, local_only = %d )\n",
(unsigned int)device_list, local_only );
if ( device_list )
{
*device_list = d_get_devices();
}
return SANE_STATUS_GOOD;
}
SANE_Status
sane_open( SANE_String_Const devicename,
SANE_Handle * handle )
{
DBG( D_CALL, "sane_open( devicename = %s, handle = %08X )\n",
devicename, (unsigned int)handle );
return d_open_device( devicename, handle );
}
void
sane_close( SANE_Handle handle )
{
(void)handle;
DBG( D_CALL, "sane_close( handle = %08X )\n",
(unsigned int)handle );
d_close_device( handle );
}
/***********************************************************************
* Options
***********************************************************************/
const SANE_Option_Descriptor *
sane_get_option_descriptor( SANE_Handle handle,
SANE_Int option )
{
const SANE_Option_Descriptor * od;
(void)handle;
DBG( D_CALL, "sane_get_option_descriptor( handle = %08X, option = %d )\n",
(unsigned int)handle, option );
od = o_opt_desc( handle, option );
if ( od )
{
DBG( D_RES, "return option descriptor for %s\n", od->title );
}
else
{
DBG( D_ERR, "no option descriptor to return\n" );
}
return od;
}
SANE_Status
sane_control_option( SANE_Handle handle,
SANE_Int option,
SANE_Action action,
void *value,
SANE_Int * info )
{
(void)handle;
(void)option;
(void)info;
DBG( D_CALL, "sane_control_option( handle = %08X, option = %d, "
"action = %d, value = %08X, info = %08X)\n",
(unsigned int)handle, option, action,
(unsigned int)value, (unsigned int)info );
switch ( action )
{
case SANE_ACTION_GET_VALUE:
return o_opt_get( handle, option, value );
case SANE_ACTION_SET_VALUE:
return o_opt_set( handle, option, value, info );
case SANE_ACTION_SET_AUTO:
return SANE_STATUS_UNSUPPORTED;
default:
return SANE_STATUS_INVAL;
}
}
/***********************************************************************
* Scanning
***********************************************************************/
SANE_Status
sane_get_parameters( SANE_Handle handle,
SANE_Parameters * params )
{
DBG( D_CALL, "sane_get_parameters( handle = %08X, params = %08X )\n",
(unsigned int)handle, (unsigned int)params );
return s_get_params( handle, params );
}
SANE_Status
sane_start( SANE_Handle handle )
{
DBG( D_CALL, "sane_start( handle = %08X )\n",
(unsigned int)handle );
return s_scan_start( handle );
}
SANE_Status
sane_read( SANE_Handle handle,
SANE_Byte * data,
SANE_Int max_length,
SANE_Int * length )
{
DBG( D_CALL, "sane_read( handle = %08X, data = %08X, "
"max_length = %d, length = %08X )\n",
(unsigned int)handle, (unsigned int)data,
max_length, (unsigned int)length );
return s_scan_read( handle, data, max_length, length );
}
void
sane_cancel( SANE_Handle handle )
{
DBG( D_CALL, "sane_cancel( handle = %08X )\n",
(unsigned int)handle );
s_scan_cancel( handle );
}
SANE_Status
sane_set_io_mode( SANE_Handle handle,
SANE_Bool non_blocking )
{
(void)handle;
(void)non_blocking;
DBG( D_CALL, "sane_set_io_mode( handle = %08X, non_blocking = %d )\n",
(unsigned int)handle, non_blocking );
return SANE_STATUS_UNSUPPORTED;
}
SANE_Status
sane_get_select_fd( SANE_Handle handle,
SANE_Int * fd )
{
(void)handle;
(void)fd;
DBG( D_CALL, "sane_get_select_fd( handle = %08X, fd = %08X )\n",
(unsigned int)handle, (unsigned int)fd );
return SANE_STATUS_UNSUPPORTED;
}
/***********************************************************************
* Level 2
***********************************************************************/
#include "cs3200f-dev.c"
#include "cs3200f-opt.c"
#include "cs3200f-scan.c"
/***********************************************************************
* Level 3
***********************************************************************/
#include "cs3200f-drv.c"
/***********************************************************************
* Level 4
***********************************************************************/
#include "cs3200f-dat.c"
#include "cs3200f-usb.c"
/************************************************************************
* $Id: cs3200f.c,v 1.2 2006/05/27 18:47:49 lapi-guest Exp $
************************************************************************/

239
backend/cs3200f.txt 100644
Wyświetl plik

@ -0,0 +1,239 @@
************************************************************************
* NOTE!
************************************************************************
NOTE! The code in this directory is highly experimental, likely
to contain errors, crappy by outlook etc. etc.
Also note: because of this: IF YOU DO NOT KNOW WHAT
YOU ARE DOING, DON'T USE IT. At best it may give
some hint of where the development is going, at
worst IT MAY BURN YOUR SCANNER. So, you were warned!
************************************************************************
* Status
************************************************************************
What works in this version is basically the UI and uncalibrated
reflective scans at 150/300/600/1200 dpi, 8-bit gray and color.
Everything else is non-functional or buggy or someting else that
makes it useless in practice.
************************************************************************
* Design info
************************************************************************
Files
=====
First level
-----------
cs3200f.c
- identifier prefix c_
- contains the SANE interface functions that delegate
almost all workings to subsystems
- only the library initialization is done here
(sane_init implementation intializes trace, usb etc.)
- includes interfaces of second level subsystems
- includes sources of second level subsystems
Second level
------------
cs3200f-dev.[ch]
- identifier prefix d_
- device handling
cs3200f-opt.[ch]
- identifier prefix o_
- option and option descriptor handling
cs3200f-scan.[ch]
- identifier prefix s_
- scanning engine
Third level
-----------
cs3200f-drv.[ch]
- identifier prefix r_
- scanner driver
Fourth level
------------
cs3200f-dat.[ch]
- identifier prefix a_
- device specific data
cs3200f-usb.[ch]
- identifier prefix u_
- scanner specific USB interface
************************************************************************
* How to build
************************************************************************
Below some instructions of how to compile this in.
I do not provide this as a patch to SANE release
because of the pre-alpha experimental status.
Still, it can be compiled and run, with varying
success.
------------------------------------------------------
First, take the latest SANE back-ends from CVS, or any
1.0.17 release (I think any should work since cs3200f
does not depend on any recent patches).
I would recommend a directory structure
$SOMEDIR/sane-backends
$SOMEDIR/sandbox
if you have SANE already installed. The sandbox dir will
be used for installing the compiled backend instead of the
actual directories (like /usr/lib/sane etc.)
Then put the cs3200f files into
$SOMEDIR/sane-backends/backend
Put only c and h files. The links will be made automatically
in compilation phase.
In $SOMEDIR/sane-backends do
./configure --prefix=$SOMEDIR/sandbox BACKENDS="test cs3200f"
The test backend is not necessary but will show if your
compilation system works when you build it.
Now, in dir $SOMEDIR/sane-backends/backend you must add
to the Makefile the following lines
(e.g. before the line starting libsane-dc25.la: ...)
libsane-cs3200f.la: ../sanei/sanei_constrain_value.lo
libsane-cs3200f.la: ../sanei/sanei_thread.lo
libsane-cs3200f.la: ../sanei/sanei_usb.lo
libsane-cs3200f.la: ../sanei/sanei_access.lo
libsane-cs3200f.la: ../lib/md5.lo
Now in dir $SOMEDIR/sane-backends
do make and check that it works OK. E.g. in
$SOMEDIR/sane-backends do
make >make.log 2>&1
In make log there may be warnings but compilation
of cs3200f.c should give no warnings or errors. If
it does, drop me a note with log (compressed please :) ).
The make may end in error in makin sane.ps but that
do not worry about, that's just docs.
Then do make install and you should now have the
cs3200f libraries in $SOMEDIR/sandbox/lib/sane.
Now become a root and copy the cs3200f lib files
to /usr/lib/sane or where ever your xsane expects
the libs to be.
Then in /etc/sane.d (or wherever you find the dll.conf
for sane dll lib) add to the dll.conf line
cs3200f
and if you wish, uncomment test backend.
Now run xsane. You should have test backend and
cs3200f:dummy devices available (do not plugin the
scanner, if you plugin the scanner, the real one
instead of dummy you shall get). :)
Now, into directory $SOMEDIR/share/sane/cs3200f put
the firmware file cs3200f_v0054.fw you have
created. Instructions are given below.
Now, if you plug in the scanner and restart the xsane
you should actually be able to boot the sanner and
then moving the top left y cordinate will actually
move the scan head, and pressing the calibrate
now, will calibrate the AFE (that takes some time
if lamp is not warmed up). These are just for
testing the driver and thus do not reflect the
actual final functions of these controls.
Warning: if you hear strange noises from the scanner,
unplug the power adapter immediately. Then reset
the scanner with windows driver and check that it
still works OK. This "should" hot happen but
happened to me several times when figuring out the
command set.
If you suspect problems,
have the following env vars exported:
export SANE_DEBUG_CS3200F=255
export SANE_DEBUG_SANEI_USB=255
export SANE_DEBUG_SANEI_ACCESS=255
and start xsane from a command line like
xsane >xsane.log 2>&1
Send me the log, compressed, or try to figure out
where the problem is.
That should do it. If not, drop me a note.
************************************************************************
* On the firmware
************************************************************************
Now, there is one complication, that must be addressed
early. Like snapscan driver, this will also require
uploading the firmware to the scanner at the beginning.
While cross checking Windows logs (thanks to Mike
Evans) I found out that there are at least two versions
of the firmware out there. Some early CDs shipped with
the scanners contain firmware version 0052. The latest
(and presumably final one, since CanoScan 3200F is a
discontinued product) is version 0054 and that version
can be found in ScanGear version 8.5.1.1 which is available
from Canon www pages (either as 3200F8511WNEN.exe which
is a self extracting LHA package, for US and Japan, I guess,
or s3A0Benx.exe which is a self extracting ZIP file).
In the package there is a self extracting ZIP file
(installer) SetupSG.exe which contains the low level
DLL file CNQL1210.DLL. That file contains, as a binary file
resource, the needed firmware.
If you have CD version 1.03 or 1.04 that should contain
the correct version of the DLL, which is 1.0.3.0. Else
get your copy from the net.
In the first phase I will only support the version 0054
so anybody wanting to use the driver will need that
version of the firmware. To get it you have to get the
mentioned DLL and run the following perl script on it:
=====================================================
#!perl
use Digest::MD5 qw(md5_base64);
$start_address = 0x3a8c0;
$end_address = 0x44304;
$length = $end_address - $start_address;
$refmd5 = "/wyuQDxka5rgidwmcDedZA";
open FIN, "<CNQL1210.DLL";
binmode FIN;
sysseek FIN, 0x3a8c0, 0;
$res = sysread FIN, $fw, $length;
close FIN;
$md5 = md5_base64( $fw );
if ( $md5 ne $refmd5 ) {
print "Did not find CanoScan 3200F firmware v0054\n";
die;
}
open FOUT, ">cs3200f_v0054.fw";
binmode FOUT;
syswrite FOUT, $fw, $length;
close FOUT;
=====================================================
The resulting file cs3200f_v0054.fw will be needed
in order to the driver to work properly.
************************************************************************
* $Id: cs3200f.txt,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
************************************************************************

Wyświetl plik

@ -25,6 +25,7 @@ cardscan
coolscan
#coolscan2
coolscan3
cs3200f
#dc210
#dc240
#dc25

Wyświetl plik

@ -1345,7 +1345,7 @@ sane_cancel(SANE_Handle h)
}
handler->scanner->work = SANE_FALSE;
handler->cancel = SANE_TRUE;
escl_scanner(handler->device, handler->scanner->scanJob, handler->result);
escl_scanner(handler->device, handler->scanner->scanJob, handler->result, SANE_TRUE);
free(handler->result);
handler->result = NULL;
free(handler->scanner->scanJob);
@ -1566,6 +1566,7 @@ sane_start(SANE_Handle h)
handler->decompress_scan_data = SANE_FALSE;
handler->end_read = SANE_FALSE;
if (handler->scanner->work == SANE_FALSE) {
escl_reset_all_jobs(handler->device);
SANE_Status st = escl_status(handler->device,
handler->scanner->source,
NULL,

Wyświetl plik

@ -248,7 +248,11 @@ SANE_Status escl_scan(capabilities_t *scanner,
void escl_scanner(const ESCL_Device *device,
char *scanJob,
char *result);
char *result,
SANE_Bool status);
SANE_Status escl_reset_all_jobs(ESCL_Device *device);
typedef void CURL;

Wyświetl plik

@ -44,7 +44,32 @@ write_callback(void __sane_unused__*str,
* This function is called in the 'sane_cancel' function.
*/
void
escl_scanner(const ESCL_Device *device, char *scanJob, char *result)
escl_delete(const ESCL_Device *device, char *uri)
{
CURL *curl_handle = NULL;
long answer = 0;
if (uri == NULL)
return;
curl_handle = curl_easy_init();
if (curl_handle != NULL) {
escl_curl_url(curl_handle, device, uri);
curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
if (curl_easy_perform(curl_handle) == CURLE_OK) {
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);
return;
}
curl_easy_cleanup(curl_handle);
}
}
/**
* \fn void escl_scanner(const ESCL_Device *device, char *result)
* \brief Function that resets the scanner after each scan, using curl.
* This function is called in the 'sane_cancel' function.
*/
void
escl_scanner(const ESCL_Device *device, char *scanJob, char *result, SANE_Bool status)
{
CURL *curl_handle = NULL;
const char *scan_jobs = "/eSCL/";
@ -70,10 +95,15 @@ CURL_CALL:
if (i >= 15) return;
}
curl_easy_cleanup(curl_handle);
if (SANE_STATUS_GOOD != escl_status(device,
PLATEN,
NULL,
NULL))
goto CURL_CALL;
char* end = strrchr(scan_cmd, '/');
*end = 0;
escl_delete(device, scan_cmd);
if (status) {
if (SANE_STATUS_GOOD != escl_status(device,
PLATEN,
NULL,
NULL))
goto CURL_CALL;
}
}
}

Wyświetl plik

@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libxml/parser.h>
@ -270,3 +271,135 @@ clean_data:
}
return (status);
}
static void
print_xml_job_finish(xmlNode *node,
SANE_Status *job)
{
while (node) {
if (node->type == XML_ELEMENT_NODE) {
if (find_nodes_s(node)) {
if (strcmp((const char *)node->name, "JobState") == 0) {
const char *state = (const char *)xmlNodeGetContent(node);
if (!strcmp(state, "Canceled")) {
*job = SANE_STATUS_GOOD;
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
}
else if (!strcmp(state, "Aborted")) {
*job = SANE_STATUS_GOOD;
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
}
else if (!strcmp(state, "Completed")) {
*job = SANE_STATUS_GOOD;
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
}
}
}
}
print_xml_job_finish(node->children, job);
node = node->next;
}
}
static void
print_xml_reset_all_jobs (xmlNode *node,
ESCL_Device *device)
{
DBG(10, "print_xml_reset_all_jobs\n");
SANE_Status status = SANE_STATUS_DEVICE_BUSY;
while (node) {
if (node->type == XML_ELEMENT_NODE) {
if (find_nodes_s(node)) {
if (strcmp((const char *)node->name, "JobUri") == 0) {
DBG(10, "print_xml_reset_all_jobs: %s\n", node->name);
if (device != NULL) {
print_xml_job_finish (node, &status);
if (status == SANE_STATUS_DEVICE_BUSY) {
char *jobUri = (char *)xmlNodeGetContent(node);
char *job = strrchr((const char *)jobUri, '/');
char *scanj = NULL;
if (job != NULL) {
if (strstr(jobUri,"ScanJobs"))
scanj = strdup("ScanJobs");
else
scanj = strdup("ScanJob");
DBG(10, "print_xml_reset_all_jobs: %s/%s\n", scanj, job);
escl_scanner(device, scanj, job, SANE_FALSE);
free(scanj);
}
DBG(10, "print_xml_reset_all_jobs: sleep to finish the job\n");
}
}
}
}
}
print_xml_reset_all_jobs (node->children,
device);
node = node->next;
}
}
/**
* \fn SANE_Status escl_reset_all_jobs (ESCL_Device *device, , char *scanJob)
* \brief Function that forces the end of jobs, using curl.
* This function is called in the 'sane_start' function.
*
* \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)
*/
SANE_Status
escl_reset_all_jobs(ESCL_Device *device)
{
CURL *curl_handle = NULL;
xmlDoc *data = NULL;
xmlNode *node = NULL;
struct idle *var = NULL;
const char *scanner_status = "/eSCL/ScannerStatus";
SANE_Status status = SANE_STATUS_DEVICE_BUSY;
DBG(10, "escl_reset_all_jobs\n");
if (device == NULL)
return (SANE_STATUS_NO_MEM);
DBG(10, "1 - escl_reset_all_jobs\n");
var = (struct idle*)calloc(1, sizeof(struct idle));
if (var == NULL)
return (SANE_STATUS_NO_MEM);
DBG(10, "2 - escl_reset_all_jobs\n");
var->memory = malloc(1);
var->size = 0;
curl_handle = curl_easy_init();
escl_curl_url(curl_handle, device, scanner_status);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_s);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var);
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
CURLcode res = curl_easy_perform(curl_handle);
if (res != CURLE_OK) {
DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
status = SANE_STATUS_INVAL;
goto clean_data1;
}
DBG(10, "3 - escl_reset_all_jobs\n");
DBG( 10, "eSCL : Status : %s.\n", var->memory);
data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0);
if (data == NULL) {
status = SANE_STATUS_NO_MEM;
goto clean_data1;
}
node = xmlDocGetRootElement(data);
if (node == NULL) {
status = SANE_STATUS_NO_MEM;
goto clean1;
}
print_xml_reset_all_jobs (node, device);
status = SANE_STATUS_GOOD;
clean1:
xmlFreeDoc(data);
clean_data1:
xmlCleanupParser();
xmlMemoryDump();
curl_easy_cleanup(curl_handle);
free(var->memory);
free(var);
return status;
}

Wyświetl plik

@ -20,6 +20,9 @@
#define DEBUG_DECLARE_ONLY
#include "../include/sane/config.h"
#include <unistd.h>
#include "scanner_interface_usb.h"
#include "low.h"

Wyświetl plik

@ -668,7 +668,7 @@ AC_ARG_ENABLE(local-backends,
ALL_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e \
avision bh canon canon630u canon_dr canon_lide70 canon_pp cardscan \
coolscan coolscan2 coolscan3 dc25 dc210 dc240 \
coolscan coolscan2 coolscan3 cs3200f dc25 dc210 dc240 \
dell1600n_net dmc epjitsu epson epson2 epsonds escl fujitsu \
genesys gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \
hp5590 hpsj5s hpljm1005 hs2p ibm kodak kodakaio kvs1025 kvs20xx \