Fujitsu backend v97 image processing functions

use sanei_magic to provide software deskew, autocrop and despeckle
merge-requests/1/head
m. allan noah 2009-09-14 13:11:37 -04:00
rodzic 3a26db083f
commit 4c4ecb3bab
4 zmienionych plików z 289 dodań i 31 usunięć

Wyświetl plik

@ -471,7 +471,7 @@ libfujitsu_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=fujitsu
nodist_libsane_fujitsu_la_SOURCES = fujitsu-s.c
libsane_fujitsu_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=fujitsu
libsane_fujitsu_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS)
libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_magic.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS)
EXTRA_DIST += fujitsu.conf.in
libgenesys_la_SOURCES = genesys.c genesys.h genesys_gl646.c genesys_gl841.c genesys_low.h

Wyświetl plik

@ -382,7 +382,8 @@ libsane_canon_dr_la_DEPENDENCIES = $(COMMON_LIBS) libcanon_dr.la \
../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \
../sanei/sanei_config.lo ../sanei/sanei_config2.lo \
sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
nodist_libsane_canon_dr_la_OBJECTS = \
libsane_canon_dr_la-canon_dr-s.lo
libsane_canon_dr_la_OBJECTS = $(nodist_libsane_canon_dr_la_OBJECTS)
@ -541,8 +542,8 @@ libsane_fujitsu_la_DEPENDENCIES = $(COMMON_LIBS) libfujitsu.la \
../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \
../sanei/sanei_config.lo ../sanei/sanei_config2.lo \
sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
../sanei/sanei_magic.lo $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
nodist_libsane_fujitsu_la_OBJECTS = libsane_fujitsu_la-fujitsu-s.lo
libsane_fujitsu_la_OBJECTS = $(nodist_libsane_fujitsu_la_OBJECTS)
libsane_fujitsu_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@ -1896,7 +1897,7 @@ libfujitsu_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=fujitsu
nodist_libsane_fujitsu_la_SOURCES = fujitsu-s.c
libsane_fujitsu_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=fujitsu
libsane_fujitsu_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS)
libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_magic.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS)
libgenesys_la_SOURCES = genesys.c genesys.h genesys_gl646.c genesys_gl841.c genesys_low.h
libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys
nodist_libsane_genesys_la_SOURCES = genesys-s.c
@ -3164,11 +3165,11 @@ libepson2_la-epson2-ops.lo: epson2-ops.c
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libepson2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libepson2_la-epson2-ops.lo `test -f 'epson2-ops.c' || echo '$(srcdir)/'`epson2-ops.c
libepson2_la-epson2-cct.lo: epson2-cct.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libepson2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libepson2_la-epson2-cct.lo -MD -MP -MF $(DEPDIR)/libepson2_la-epson2-cct.Tpo -c -o libepson2_la-epson2-cct.lo `test -f 'epson2-cct.c' || echo '$(srcdir)/'`epson2-cct.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libepson2_la-epson2-cct.Tpo $(DEPDIR)/libepson2_la-epson2-cct.Plo
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libepson2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libepson2_la-epson2-cct.lo -MD -MP -MF $(DEPDIR)/libepson2_la-epson2-cct.Tpo -c -o libepson2_la-epson2-cct.lo `test -f 'epson2-cct.c' || echo '$(srcdir)/'`epson2-cct.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libepson2_la-epson2-cct.Tpo $(DEPDIR)/libepson2_la-epson2-cct.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='epson2-cct.c' object='libepson2_la-epson2-cct.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libepson2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libepson2_la-epson2-cct.lo `test -f 'epson2-cct.c' || echo '$(srcdir)/'`epson2-cct.c
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libepson2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libepson2_la-epson2-cct.lo `test -f 'epson2-cct.c' || echo '$(srcdir)/'`epson2-cct.c
libfujitsu_la-fujitsu.lo: fujitsu.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfujitsu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libfujitsu_la-fujitsu.lo -MD -MP -MF $(DEPDIR)/libfujitsu_la-fujitsu.Tpo -c -o libfujitsu_la-fujitsu.lo `test -f 'fujitsu.c' || echo '$(srcdir)/'`fujitsu.c

Wyświetl plik

@ -55,12 +55,13 @@
The source code is divided in sections which you can easily find by
searching for the tag "@@".
Section 1 - Init & static stuff
Section 2 - sane_init, _get_devices, _open & friends
Section 3 - sane_*_option functions
Section 4 - sane_start, _get_param, _read & friends
Section 5 - sane_close functions
Section 6 - misc functions
Section 1 - Boilerplate: Init & static stuff
Section 2 - Init: sane_init, _get_devices, _open ...
Section 3 - Options: sane_*_option functions
Section 4 - Scanning: sane_start, _get_param, _read ...
Section 5 - Cleanup: sane_cancel, ...
Section 6 - Misc: sense_handler, hexdump, ...
Section 7 - Image processing: deskew, crop, despeck
Changes:
v1, 2002-05-05, OS
@ -443,6 +444,8 @@
- split sane_get_parameters into two functions
- remove unused code from get_pixelsize
- support hardware based auto length detection
v97 2009-09-14, MAN
- use sanei_magic to provide software deskew, autocrop and despeckle
SANE FLOW DIAGRAM
@ -471,7 +474,7 @@
*/
/*
* @@ Section 1 - Init
* @@ Section 1 - Boilerplate
*/
#include "../include/sane/config.h"
@ -498,12 +501,13 @@
#include "../include/sane/sanei_usb.h"
#include "../include/sane/saneopts.h"
#include "../include/sane/sanei_config.h"
#include "../include/sane/sanei_magic.h"
#include "fujitsu-scsi.h"
#include "fujitsu.h"
#define DEBUG 1
#define BUILD 96
#define BUILD 97
/* values for SANE_DEBUG_FUJITSU env var:
- errors 5
@ -606,6 +610,8 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
DBG (5, "sane_init: fujitsu backend %d.%d.%d, from %s\n",
SANE_CURRENT_MAJOR, V_MINOR, BUILD, PACKAGE_STRING);
sanei_magic_init();
DBG (10, "sane_init: finish\n");
return SANE_STATUS_GOOD;
@ -3613,6 +3619,51 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
opt->constraint_type = SANE_CONSTRAINT_NONE;
}
/*deskew by software*/
if(option==OPT_SWDESKEW){
opt->name = "swdeskew";
opt->title = "Software deskew";
opt->desc = "Request driver to rotate skewed pages digitally";
opt->type = SANE_TYPE_BOOL;
if (1)
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
else
opt->cap = SANE_CAP_INACTIVE;
}
/*software despeckle radius*/
if(option==OPT_SWDESPECK){
opt->name = "swdespeck";
opt->title = "Software despeckle diameter";
opt->desc = "Maximum diameter of lone dots to remove from scan";
opt->type = SANE_TYPE_INT;
opt->unit = SANE_UNIT_NONE;
opt->constraint_type = SANE_CONSTRAINT_RANGE;
opt->constraint.range = &s->swdespeck_range;
s->swdespeck_range.quant=1;
if(1){
s->swdespeck_range.min=0;
s->swdespeck_range.max=9;
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
}
else
opt->cap = SANE_CAP_INACTIVE;
}
/*crop by software*/
if(option==OPT_SWCROP){
opt->name = "swcrop";
opt->title = "Software crop";
opt->desc = "Request driver to remove border from pages digitally";
opt->type = SANE_TYPE_BOOL;
if (1)
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
else
opt->cap = SANE_CAP_INACTIVE;
}
/* "Endorser" group ------------------------------------------------------ */
if(option==OPT_ENDORSER_GROUP){
opt->name = "endorser-options";
@ -4502,6 +4553,18 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
*val_p = s->side;
return SANE_STATUS_GOOD;
case OPT_SWDESKEW:
*val_p = s->swdeskew;
return SANE_STATUS_GOOD;
case OPT_SWDESPECK:
*val_p = s->swdespeck;
return SANE_STATUS_GOOD;
case OPT_SWCROP:
*val_p = s->swcrop;
return SANE_STATUS_GOOD;
/* Endorser Group */
case OPT_ENDORSER:
*val_p = s->u_endorser;
@ -5101,6 +5164,18 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
s->low_mem = val_c;
return SANE_STATUS_GOOD;
case OPT_SWDESKEW:
s->swdeskew = val_c;
return SANE_STATUS_GOOD;
case OPT_SWDESPECK:
s->swdespeck = val_c;
return SANE_STATUS_GOOD;
case OPT_SWCROP:
s->swcrop = val_c;
return SANE_STATUS_GOOD;
/* Endorser Group */
case OPT_ENDORSER:
s->u_endorser = val_c;
@ -6078,7 +6153,14 @@ sane_start (SANE_Handle handle)
/* the front buffer is normally very small, but some scanners or
* option combinations can't handle it, so we make a big one */
if(s->mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091)
if(
(s->mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091)
|| (s->swcrop || s->swdeskew || s->swdespeck
#ifdef SANE_FRAME_JPEG
&& s->s.format != SANE_FRAME_JPEG
#endif
)
)
s->buff_tot[SIDE_FRONT] = s->bytes_tot[SIDE_FRONT];
}
else{
@ -6132,6 +6214,44 @@ sane_start (SANE_Handle handle)
DBG (15, "started=%d, side=%d, source=%d\n", s->started, s->side, s->source);
/* certain options require the entire image to
* be collected from the scanner before we can
* tell the user the size of the image. the sane
* API has no way to inform the frontend of this,
* so we block and buffer. yuck */
if( (s->swdeskew || s->swdespeck || s->swcrop)
#ifdef SANE_FRAME_JPEG
&& s->s.format != SANE_FRAME_JPEG
#endif
){
/* get image */
while(!s->eof_rx[s->side] && !ret){
SANE_Int len = 0;
ret = sane_read((SANE_Handle)s, NULL, 0, &len);
}
/* check for errors */
if (ret != SANE_STATUS_GOOD) {
DBG (5, "sane_start: ERROR: cannot buffer image\n");
goto errors;
}
DBG (5, "sane_start: OK: done buffering\n");
/* finished buffering, adjust image as required */
if(s->swdeskew){
buffer_deskew(s,s->side);
}
if(s->swcrop){
buffer_crop(s,s->side);
}
if(s->swdespeck){
buffer_despeck(s,s->side);
}
}
/* check if user cancelled during this start */
ret = check_for_cancel(s);
@ -6139,8 +6259,14 @@ sane_start (SANE_Handle handle)
s->reading=0;
DBG (10, "sane_start: finish %d\n", ret);
return ret;
errors:
DBG (10, "sane_start: error %d\n", ret);
s->started = 0;
s->cancelled = 0;
s->reading = 0;
return ret;
}
static SANE_Status
@ -6845,8 +6971,8 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
/* protect this block from sane_cancel */
s->reading = 1;
/* no bytes to send to caller, but no eof from scanner yet? get some */
if(s->buff_rx[s->side] == s->buff_tx[s->side]){
/* no eof from scanner yet, try to get some bytes */
if(!s->eof_rx[s->side]){
/* 3091/2 are on crack, get their own duplex reader function */
if(s->source == SOURCE_ADF_DUPLEX
@ -6927,6 +7053,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
return ret;
}
#ifdef SANE_FRAME_JPEG
static SANE_Status
read_from_JPEGduplex(struct fujitsu *s)
{
@ -7174,6 +7301,7 @@ read_from_JPEGduplex(struct fujitsu *s)
return ret;
}
#endif
static SANE_Status
read_from_3091duplex(struct fujitsu *s)
@ -7311,6 +7439,7 @@ read_from_scanner(struct fujitsu *s, int side)
int bytes = s->buffer_size;
int remain = s->bytes_tot[side] - s->bytes_rx[side];
int space = s->buff_tot[side] - s->buff_rx[side];
DBG (10, "read_from_scanner: start\n");
@ -7318,6 +7447,9 @@ read_from_scanner(struct fujitsu *s, int side)
if(bytes > remain){
bytes = remain;
}
if(bytes > space){
bytes = space;
}
/* all requests must end on line boundary */
bytes -= (bytes % s->params.bytes_per_line);
@ -7327,12 +7459,6 @@ read_from_scanner(struct fujitsu *s, int side)
bytes -= s->params.bytes_per_line;
}
/* this should never happen */
if(bytes < 1){
DBG(5, "read_from_scanner: ERROR: no bytes this pass\n");
ret = SANE_STATUS_INVAL;
}
DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d\n",
side, remain, s->buffer_size, bytes);
@ -7342,8 +7468,10 @@ read_from_scanner(struct fujitsu *s, int side)
DBG(15, "read_from_scanner: buf to:%d rx:%d tx:%d\n",
s->buff_tot[side], s->buff_rx[side], s->buff_tx[side]);
if(ret){
return ret;
/* this will happen if buffer is not drained yet */
if(bytes < 1){
DBG(5, "read_from_scanner: no bytes this pass\n");
return ret;
}
/* fi-6770A gets mad if you 'read' too soon on usb, see if it is ready */
@ -7612,7 +7740,7 @@ read_from_buffer(struct fujitsu *s, SANE_Byte * buf,
/*
* @@ Section 4 - SANE cleanup functions
* @@ Section 5 - SANE cleanup functions
*/
/*
* Cancels a scan.
@ -7745,9 +7873,8 @@ sane_exit (void)
DBG (10, "sane_exit: finish\n");
}
/*
* @@ Section 5 - misc helper functions
* @@ Section 6 - misc helper functions
*/
/*
* Called by the SANE SCSI core and our usb code on device errors
@ -8486,3 +8613,120 @@ sane_get_select_fd (SANE_Handle h, SANE_Int *fdp)
DBG (15, "%p %d\n", h, *fdp);
return SANE_STATUS_UNSUPPORTED;
}
/*
* @@ Section 7 - Image processing functions
*/
/* Look in image for likely upper and left paper edges, then rotate
* image so that upper left corner of paper is upper left of image.
* FIXME: should we do this before we binarize instead of after? */
static SANE_Status
buffer_deskew(struct fujitsu *s, int side)
{
SANE_Status ret = SANE_STATUS_GOOD;
int x = 0, y = 0;
double slope = 0;
int bg_color = 0xdd;
DBG (10, "buffer_deskew: start\n");
ret = sanei_magic_findSkew(&s->params,s->buffers[side],
s->resolution_x,s->resolution_y,&x,&y,&slope);
if(ret){
DBG (5, "buffer_despeck: bad findSkew, bailing\n");
ret = SANE_STATUS_GOOD;
goto cleanup;
}
/* tweak the bg color based on scanner settings */
if(s->mode == MODE_HALFTONE || s->mode == MODE_GRAYSCALE){
if(s->bg_color == COLOR_BLACK)
bg_color = 0xff;
else
bg_color = 0;
}
else if(s->bg_color == COLOR_BLACK)
bg_color = 0;
ret = sanei_magic_rotate(&s->params,s->buffers[side], x, y, slope, bg_color);
if(ret){
DBG(5,"buffer_deskew: rotate error: %d",ret);
ret = SANE_STATUS_GOOD;
goto cleanup;
}
cleanup:
DBG (10, "buffer_deskew: finish\n");
return ret;
}
/* Look in image for likely left/right/bottom paper edges, then crop image.
* Does not attempt to rotate the image, that should be done first.
* FIXME: should we do this before we binarize instead of after? */
static SANE_Status
buffer_crop(struct fujitsu *s, int side)
{
SANE_Status ret = SANE_STATUS_GOOD;
int top = 0;
int bot = 0;
int left = 0;
int right = 0;
DBG (10, "buffer_crop: start\n");
ret = sanei_magic_findEdges(&s->params,s->buffers[side],
s->resolution_x,s->resolution_y,&top,&bot,&left,&right);
if(ret){
DBG (5, "buffer_crop: bad edges, bailing\n");
ret = SANE_STATUS_GOOD;
goto cleanup;
}
DBG (15, "buffer_crop: t:%d b:%d l:%d r:%d\n",top,bot,left,right);
/* we dont listen to the 'top' value, since fujitsu does not pad the top */
top = 0;
/* now crop the image */
/*FIXME: crop duplex backside at same time?*/
ret = sanei_magic_crop(&s->params,s->buffers[side],top,bot,left,right);
if(ret){
DBG (5, "buffer_crop: bad crop, bailing\n");
ret = SANE_STATUS_GOOD;
goto cleanup;
}
/* update image size counter to new, smaller size */
s->bytes_rx[side] = s->params.lines * s->params.bytes_per_line;
s->buff_rx[side] = s->bytes_rx[side];
cleanup:
DBG (10, "buffer_crop: finish\n");
return ret;
}
/* Look in image for disconnected 'spots' of the requested size.
* Replace the spots with the average color of the surrounding pixels.
* FIXME: should we do this before we binarize instead of after? */
static SANE_Status
buffer_despeck(struct fujitsu *s, int side)
{
SANE_Status ret = SANE_STATUS_GOOD;
DBG (10, "buffer_despeck: start\n");
ret = sanei_magic_despeck(&s->params,s->buffers[side],s->swdespeck);
if(ret){
DBG (5, "buffer_despeck: bad despeck, bailing\n");
ret = SANE_STATUS_GOOD;
goto cleanup;
}
cleanup:
DBG (10, "buffer_despeck: finish\n");
return ret;
}

Wyświetl plik

@ -81,6 +81,9 @@ enum fujitsu_Option
OPT_BLUE_OFFSET,
OPT_LOW_MEM,
OPT_SIDE,
OPT_SWDESKEW,
OPT_SWDESPECK,
OPT_SWCROP,
OPT_ENDORSER_GROUP,
OPT_ENDORSER,
@ -389,6 +392,7 @@ struct fujitsu
SANE_Range duplex_offset_range;
SANE_Range green_offset_range;
SANE_Range blue_offset_range;
SANE_Range swdespeck_range;
/*endorser group*/
SANE_Range endorser_bits_range;
@ -469,6 +473,9 @@ struct fujitsu
int green_offset;
int blue_offset;
int low_mem;
int swdeskew;
int swdespeck;
int swcrop;
/*endorser group*/
int u_endorser;
@ -772,7 +779,9 @@ static SANE_Status start_scan (struct fujitsu *s);
static SANE_Status check_for_cancel(struct fujitsu *s);
#ifdef SANE_FRAME_JPEG
static SANE_Status read_from_JPEGduplex(struct fujitsu *s);
#endif
static SANE_Status read_from_3091duplex(struct fujitsu *s);
static SANE_Status read_from_scanner(struct fujitsu *s, int side);
@ -785,6 +794,10 @@ static SANE_Status setup_buffers (struct fujitsu *s);
static SANE_Status get_hardware_status (struct fujitsu *s, SANE_Int option);
static SANE_Status buffer_deskew(struct fujitsu *s, int side);
static SANE_Status buffer_crop(struct fujitsu *s, int side);
static SANE_Status buffer_despeck(struct fujitsu *s, int side);
static void hexdump (int level, char *comment, unsigned char *p, int l);
static size_t maxStringSize (const SANE_String_Const strings[]);