This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

CSE going loopy (1.1.1pre2, i386)



The following test case makes 1.1.1 prerelease 2 on i386--netbsd suck
up a huge amount of resources and (on my machine) eventually run out
of memory and exit.

It's a rather simple case, but contains a lot of duplicate address
calculations.  It's extracted from sane 0.74 (a free scanner package).

-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----
typedef long long int64_t;
typedef int64_t quad_t;
typedef quad_t  off_t;
typedef int     pid_t;
typedef unsigned int size_t;
typedef off_t   fpos_t;
struct __sbuf {
	unsigned char  *_base;
	int             _size;
};
typedef struct __sFILE {
	unsigned char  *_p;
	int             _r;
	int             _w;
	short           _flags;
	short           _file;
	struct __sbuf   _bf;
	int             _lbfsize;
	void           *_cookie;
	int             (*_close) (void *);
	int             (*_read) (void *, char *, int);
	                fpos_t(*_seek) (void *, fpos_t, int);
	int             (*_write) (void *, const char *, int);
	struct __sbuf   _ub;
	unsigned char  *_up;
	int             _ur;
	unsigned char   _ubuf[3];
	unsigned char   _nbuf[1];
	struct __sbuf   _lb;
	int             _blksize;
	fpos_t          _offset;
}               FILE;
extern FILE     __sF[];
int             fprintf(FILE *, const char *,...);
size_t
strlen(const char *);
char           *
                strdup(const char *);
typedef unsigned char SANE_Byte;
typedef int     SANE_Word;
typedef SANE_Word SANE_Bool;
typedef SANE_Word SANE_Int;
typedef char    SANE_Char;
typedef SANE_Char *SANE_String;
typedef const SANE_Char *SANE_String_Const;
typedef void   *SANE_Handle;
typedef SANE_Word SANE_Fixed;
typedef enum {
	SANE_STATUS_GOOD = 0,
	SANE_STATUS_UNSUPPORTED,
	SANE_STATUS_CANCELLED,
	SANE_STATUS_DEVICE_BUSY,
	SANE_STATUS_INVAL,
	SANE_STATUS_EOF,
	SANE_STATUS_JAMMED,
	SANE_STATUS_NO_DOCS,
	SANE_STATUS_COVER_OPEN,
	SANE_STATUS_IO_ERROR,
	SANE_STATUS_NO_MEM,
	SANE_STATUS_ACCESS_DENIED
}               SANE_Status;
typedef enum {
	SANE_TYPE_BOOL = 0,
	SANE_TYPE_INT,
	SANE_TYPE_FIXED,
	SANE_TYPE_STRING,
	SANE_TYPE_BUTTON,
	SANE_TYPE_GROUP
}               SANE_Value_Type;
typedef enum {
	SANE_UNIT_NONE = 0,
	SANE_UNIT_PIXEL,
	SANE_UNIT_BIT,
	SANE_UNIT_MM,
	SANE_UNIT_DPI,
	SANE_UNIT_PERCENT,
	SANE_UNIT_MICROSECOND
}               SANE_Unit;
typedef struct {
	SANE_String_Const name;
	SANE_String_Const vendor;
	SANE_String_Const model;
	SANE_String_Const type;
}               SANE_Device;
typedef enum {
	SANE_CONSTRAINT_NONE = 0,
	SANE_CONSTRAINT_RANGE,
	SANE_CONSTRAINT_WORD_LIST,
	SANE_CONSTRAINT_STRING_LIST
}               SANE_Constraint_Type;
typedef struct {
	SANE_Word       min;
	SANE_Word       max;
	SANE_Word       quant;
}               SANE_Range;
typedef struct {
	SANE_String_Const name;
	SANE_String_Const title;
	SANE_String_Const desc;
	SANE_Value_Type type;
	SANE_Unit       unit;
	SANE_Int        size;
	SANE_Int        cap;
	SANE_Constraint_Type constraint_type;
	union {
		const SANE_String_Const *string_list;
		const SANE_Word *word_list;
		const SANE_Range *range;
	}               constraint;
}               SANE_Option_Descriptor;
typedef enum {
	SANE_ACTION_GET_VALUE = 0,
	SANE_ACTION_SET_VALUE,
	SANE_ACTION_SET_AUTO
}               SANE_Action;
typedef enum {
	SANE_FRAME_GRAY,
	SANE_FRAME_RGB,
	SANE_FRAME_RED,
	SANE_FRAME_GREEN,
	SANE_FRAME_BLUE
}               SANE_Frame;
typedef struct {
	SANE_Frame      format;
	SANE_Bool       last_frame;
	SANE_Int        bytes_per_line;
	SANE_Int        pixels_per_line;
	SANE_Int        lines;
	SANE_Int        depth;
}               SANE_Parameters;
enum Umax_Option {
	OPT_NUM_OPTS = 0,
	OPT_MODE_GROUP,
	OPT_MODE,
	OPT_SOURCE,
	OPT_X_RESOLUTION,
	OPT_Y_RESOLUTION,
	OPT_RESOLUTION_BIND,
	OPT_NEGATIVE,
	OPT_GEOMETRY_GROUP,
	OPT_TL_X,
	OPT_TL_Y,
	OPT_BR_X,
	OPT_BR_Y,
	OPT_ENHANCEMENT_GROUP,
	OPT_TEN_BIT_MODE,
	OPT_TWELVE_BIT_MODE,
	OPT_QUALITY,
	OPT_WARMUP,
	OPT_RGB_BIND,
	OPT_BRIGHTNESS,
	OPT_CONTRAST,
	OPT_THRESHOLD,
	OPT_HIGHLIGHT,
	OPT_HIGHLIGHT_R,
	OPT_HIGHLIGHT_G,
	OPT_HIGHLIGHT_B,
	OPT_SHADOW,
	OPT_SHADOW_R,
	OPT_SHADOW_G,
	OPT_SHADOW_B,
	OPT_ANALOG_GAMMA,
	OPT_ANALOG_GAMMA_R,
	OPT_ANALOG_GAMMA_G,
	OPT_ANALOG_GAMMA_B,
	OPT_CUSTOM_GAMMA,
	OPT_GAMMA_VECTOR,
	OPT_GAMMA_VECTOR_R,
	OPT_GAMMA_VECTOR_G,
	OPT_GAMMA_VECTOR_B,
	OPT_HALFTONE_DIMENSION,
	OPT_HALFTONE_PATTERN,
	OPT_ADVANCED_GROUP,
	OPT_CAL_EXPOS_TIME,
	OPT_CAL_EXPOS_TIME_R,
	OPT_CAL_EXPOS_TIME_G,
	OPT_CAL_EXPOS_TIME_B,
	OPT_SCAN_EXPOS_TIME,
	OPT_SCAN_EXPOS_TIME_R,
	OPT_SCAN_EXPOS_TIME_G,
	OPT_SCAN_EXPOS_TIME_B,
	OPT_CAL_LAMP_DEN,
	OPT_SCAN_LAMP_DEN,
	OPT_SELECT_EXPOSURE_TIME,
	OPT_SELECT_LAMP_DENSITY,
	OPT_SLOW,
	OPT_SMEAR,
	OPT_CALIB_MODE,
	OPT_SHADING_TYPE,
	OPT_PREVIEW,
	NUM_OPTIONS
};
typedef union {
	SANE_Word       w;
	SANE_Word      *wa;
	SANE_String     s;
}               Option_Value;
typedef struct Umax_Device {
	struct Umax_Device *next;
	SANE_Device     sane;
	SANE_Range      x_dpi_range;
	SANE_Range      y_dpi_range;
	SANE_Range      x_range;
	SANE_Range      y_range;
	SANE_Range      analog_gamma_range;
	unsigned        flags;
	unsigned char  *buffer;
	unsigned int    bufsize;
	unsigned int    row_bufsize;
	unsigned char  *pixelbuffer;
	unsigned int    pixelline_max;
	unsigned int    pixelline_ready[3];
	unsigned int    pixelline_next[3];
	unsigned int    pixelline_del[3];
	unsigned int    pixelline_optic[3];
	unsigned int    pixelline_opt_res;
	unsigned int    pixelline_read;
	unsigned int    pixelline_written;
	unsigned int    CCD_distance;
	unsigned int    CCD_color[9];
	char           *devicename;
	int             sfd;
	char            vendor[9];
	char            product[17];
	char            version[5];
	int             three_pass;
	int             three_pass_color;
	int             row_len;
	unsigned int    max_value;
	int             inquiry_len;
	int             inquiry_wdb_len;
	int             inquiry_optical_res;
	int             inquiry_x_res;
	int             inquiry_y_res;
	double          inquiry_fb_width;
	double          inquiry_fb_length;
	double          inquiry_uta_width;
	double          inquiry_uta_length;
	double          inquiry_dor_width;
	double          inquiry_dor_length;
	int             inquiry_exposure_adj;
	int             inquiry_exposure_time_step_unit;
	int             inquiry_exposure_time_max;
	int             inquiry_exposure_time_l_min;
	int             inquiry_exposure_time_l_fb_def;
	int             inquiry_exposure_time_l_uta_def;
	int             inquiry_exposure_time_h_min;
	int             inquiry_exposure_time_h_fb_def;
	int             inquiry_exposure_time_h_uta_def;
	int             inquiry_exposure_time_g_min;
	int             inquiry_exposure_time_g_fb_def;
	int             inquiry_exposure_time_g_uta_def;
	int             inquiry_exposure_time_c_min;
	int             inquiry_exposure_time_c_fb_def_r;
	int             inquiry_exposure_time_c_fb_def_g;
	int             inquiry_exposure_time_c_fb_def_b;
	int             inquiry_exposure_time_c_uta_def_r;
	int             inquiry_exposure_time_c_uta_def_g;
	int             inquiry_exposure_time_c_uta_def_b;
	int             inquiry_max_warmup_time;
	int             inquiry_cbhs;
	int             inquiry_cbhs_min;
	int             inquiry_cbhs_max;
	int             inquiry_quality_ctrl;
	int             inquiry_preview;
	int             inquiry_lamp_ctrl;
	int             inquiry_transavail;
	int             inquiry_adfmode;
	int             inquiry_uta;
	int             inquiry_adf;
	int             inquiry_dor;
	int             inquiry_reverse;
	int             inquiry_reverse_multi;
	int             inquiry_analog_gamma;
	int             inquiry_gamma_dwload;
	int             inquiry_gamma_DCF;
	int             inquiry_one_pass_color;
	int             inquiry_three_pass_color;
	int             inquiry_color;
	int             inquiry_grey;
	int             inquiry_halftone;
	int             inquiry_lineart;
	int             inquiry_calibration;
	int             inquiry_highlight;
	int             inquiry_shadow;
	int             inquiry_GIB;
	int             inquiry_GOB;
	int             inquiry_max_calib_lines;
	int             inquiry_color_order;
	int             inquiry_CCD_line_distance;
	int             inquiry_fb_uta_color_arrangement;
	int             inquiry_adf_color_arrangement;
	int             use_exposure_time_min;
	int             use_exposure_time_def_r;
	int             use_exposure_time_def_g;
	int             use_exposure_time_def_b;
	int             wdb_len;
	double          width;
	double          length;
	int             width_in_pixels;
	int             height_in_pixels;
	int             phys_width;
	int             phys_height;
	int             x_resolution;
	int             y_resolution;
	double          scale_x;
	double          scale_y;
	int             upper_left_x;
	int             upper_left_y;
	int             x_coordinate_base;
	int             y_coordinate_base;
	int             bits_per_pixel;
	int             gamma_input_bits;
	int             set_auto;
	int             preview;
	int             quality;
	int             shading_type;
	int             reverse;
	int             reverse_multi;
	int             WD_speed;
	int             slow;
	int             smear;
	int             dor;
	int             cbhs_range;
	int             warmup;
	int             module;
	int             adf;
	int             uta;
	int             calibration;
	int             low_byte_first;
	int             colormode;
	int             exposure_time_calibration_r;
	int             exposure_time_calibration_g;
	int             exposure_time_calibration_b;
	int             exposure_time_scan_r;
	int             exposure_time_scan_g;
	int             exposure_time_scan_b;
	int             c_density;
	int             s_density;
	int             threshold;
	int             brightness;
	int             contrast;
	int             highlight_r;
	int             highlight_g;
	int             highlight_b;
	int             shadow_r;
	int             shadow_g;
	int             shadow_b;
	int             halftone;
	int             digital_gamma_r;
	int             digital_gamma_g;
	int             digital_gamma_b;
	int             analog_gamma_r;
	int             analog_gamma_g;
	int             analog_gamma_b;
	int             calib_lines;
	int             do_calibration;
	int             do_color_ordering;
	int             button_pressed;
	int             RGB_PREVIEW_FIX;
}               Umax_Device;
typedef struct Umax_Scanner {
	struct Umax_Scanner *next;
	Umax_Device    *device;
	SANE_Option_Descriptor opt[NUM_OPTIONS];
	Option_Value    val[NUM_OPTIONS];
	SANE_Int        gamma_table[4][1024];
	SANE_Int        halftone_pattern[64];
	SANE_Range      gamma_range;
	int             gamma_length;
	int             output_bytes;
	SANE_Range      exposure_time_range;
	int             scanning;
	SANE_Parameters params;
	pid_t           reader_pid;
	int             pipe;
}               Umax_Scanner;
int             sanei_debug_umax;
extern SANE_Status sane_umax_control_option(SANE_Handle, SANE_Int, SANE_Action, void *, SANE_Word *);
static SANE_String_Const scan_mode_list[7];
static SANE_String_Const source_list[4];
static SANE_String_Const calibration_list[] = {
	"Calibration ignored",
	"Calibration by image-type",
	"Calibration driver-selected",
	0
};
static SANE_String_Const shading_list[] = {
	"use one shading line",
	"calculate average",
	0
};
static const SANE_Int pattern_dim_list[] = {
	8,
	0, 2, 3, 4, 5, 6, 7, 8
};
static const SANE_Range u8_range = {
	0,
	255,
	0
};
static const SANE_Range percentage_range = {
	-100 << 16,
	100 << 16,
	1 << 16
};
static const SANE_Range percentage_range_100 = {
	0 << 16,
	100 << 16,
	0 << 16
};
static int      num_devices;
static Umax_Device *first_dev;
static Umax_Scanner *first_handle;
static          size_t
max_string_size(SANE_String_Const strings[])
{
	size_t          size, max_size = 0;
	int             i;
	for (i = 0; strings[i]; ++i) {
		size = strlen(strings[i]) + 1;
		if (size > max_size) {
			max_size = size;
		}
	}
	return max_size;
}
static          SANE_Status
init_options(Umax_Scanner * scanner)
{
	int             i;
	int             scan_modes;
	do {
		if (sanei_debug_umax >= (11))
			fprintf((&__sF[2]), "[umax] init_options\n");
	} while (0);
	memset(scanner->opt, 0, sizeof(scanner->opt));
	memset(scanner->val, 0, sizeof(scanner->val));
	for (i = 0; i < NUM_OPTIONS; ++i) {
		scanner->opt[i].size = sizeof(SANE_Word);
		scanner->opt[i].cap = (1 << 0) | (1 << 2);
	}
	scanner->opt[OPT_NUM_OPTS].title = "Number of options";
	scanner->opt[OPT_NUM_OPTS].desc = "Read-only option that specifies how many options a specific devices supports.";
	scanner->opt[OPT_NUM_OPTS].cap = (1 << 2);
	scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
	scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
	scanner->opt[OPT_MODE_GROUP].desc = "";
	scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
	scanner->opt[OPT_MODE_GROUP].cap = 0;
	scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
	scan_modes = -1;
	if (scanner->device->inquiry_lineart) {
		scan_mode_list[++scan_modes] = "Lineart";
	}
	if (scanner->device->inquiry_halftone) {
		scan_mode_list[++scan_modes] = "Halftone";
	}
	if (scanner->device->inquiry_grey) {
		scan_mode_list[++scan_modes] = "Grey";
	}
	if (scanner->device->inquiry_color) {
		scan_mode_list[++scan_modes] = "Color";
	} {
		int             i = 0;
		{
			source_list[i++] = "Flatbed";
		}
		if (scanner->device->inquiry_adfmode) {
			source_list[i++] = "Automatic Document Feeder";
		}
		if (scanner->device->inquiry_transavail) {
			source_list[i++] = "Transparency Adapter";
		}
	}
	scanner->opt[OPT_MODE].name = "mode";
	scanner->opt[OPT_MODE].title = "Scan mode";
	scanner->opt[OPT_MODE].desc = "Selects the scan mode (e.g., lineart,monochrome, or color).";
	scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
	scanner->opt[OPT_MODE].size = max_string_size(scan_mode_list);
	scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
	scanner->opt[OPT_MODE].constraint.string_list = scan_mode_list;
	scanner->val[OPT_MODE].s = (SANE_Char *) strdup(scan_mode_list[0]);
	scanner->opt[OPT_SOURCE].name = "source";
	scanner->opt[OPT_SOURCE].title = "Scan source";
	scanner->opt[OPT_SOURCE].desc = "Selects the scan source (such as a document-feeder).";
	scanner->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
	scanner->opt[OPT_SOURCE].size = max_string_size(source_list);
	scanner->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
	scanner->opt[OPT_SOURCE].constraint.string_list = source_list;
	scanner->val[OPT_SOURCE].s = (SANE_Char *) strdup(source_list[0]);
	scanner->opt[OPT_X_RESOLUTION].name = "resolution";
	scanner->opt[OPT_X_RESOLUTION].title = "Scan resolution";
	scanner->opt[OPT_X_RESOLUTION].desc = "Sets the resolution of the scanned image.";
	scanner->opt[OPT_X_RESOLUTION].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI;
	scanner->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_X_RESOLUTION].constraint.range = &scanner->device->x_dpi_range;
	scanner->val[OPT_X_RESOLUTION].w = 100 << 16;
	scanner->opt[OPT_Y_RESOLUTION].name = "y-resolution";
	scanner->opt[OPT_Y_RESOLUTION].title = "Y-resolution";
	scanner->opt[OPT_Y_RESOLUTION].desc = "Sets the vertical resolution of the scanned image.";
	scanner->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI;
	scanner->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_Y_RESOLUTION].constraint.range = &scanner->device->y_dpi_range;
	scanner->val[OPT_Y_RESOLUTION].w = 100 << 16;
	scanner->opt[OPT_Y_RESOLUTION].cap |= (1 << 5);
	scanner->opt[OPT_RESOLUTION_BIND].name = "resolution-bind";
	scanner->opt[OPT_RESOLUTION_BIND].title = "Bind X and Y resolution";
	scanner->opt[OPT_RESOLUTION_BIND].desc = "Use same values for X and Y resolution";
	scanner->opt[OPT_RESOLUTION_BIND].type = SANE_TYPE_BOOL;
	scanner->val[OPT_RESOLUTION_BIND].w = 1;
	scanner->opt[OPT_NEGATIVE].name = "negative";
	scanner->opt[OPT_NEGATIVE].title = "Negative";
	scanner->opt[OPT_NEGATIVE].desc = "Swap black and white";
	scanner->opt[OPT_NEGATIVE].type = SANE_TYPE_BOOL;
	scanner->val[OPT_NEGATIVE].w = 0;
	if (scanner->device->inquiry_reverse_multi == 0) {
		scanner->opt[OPT_NEGATIVE].cap |= (1 << 5);
	}
	scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
	scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
	scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
	scanner->opt[OPT_GEOMETRY_GROUP].cap = (1 << 6);
	scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
	scanner->opt[OPT_TL_X].name = "tl-x";
	scanner->opt[OPT_TL_X].title = "Top-left x";
	scanner->opt[OPT_TL_X].desc = "Top-left x position of scan area.";
	scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
	scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range);
	scanner->val[OPT_TL_X].w = 0;
	scanner->opt[OPT_TL_Y].name = "tl-y";
	scanner->opt[OPT_TL_Y].title = "Top-left y";
	scanner->opt[OPT_TL_Y].desc = "Top-left y position of scan area.";
	scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
	scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range);
	scanner->val[OPT_TL_Y].w = 0;
	scanner->opt[OPT_BR_X].name = "br-x";
	scanner->opt[OPT_BR_X].title = "Bottom-right x";
	scanner->opt[OPT_BR_X].desc = "Bottom-right x position of scan area.";
	scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
	scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range);
	scanner->val[OPT_BR_X].w = scanner->device->x_range.max;
	scanner->opt[OPT_BR_Y].name = "br-y";
	scanner->opt[OPT_BR_Y].title = "Bottom-right y";
	scanner->opt[OPT_BR_Y].desc = "Bottom-right y position of scan area.";
	scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
	scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range);
	scanner->val[OPT_BR_Y].w = scanner->device->y_range.max;
	scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
	scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
	scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
	scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
	scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
	scanner->opt[OPT_TEN_BIT_MODE].name = "ten-bit-mode";
	scanner->opt[OPT_TEN_BIT_MODE].title = "10 bit-mode";
	scanner->opt[OPT_TEN_BIT_MODE].desc = "Output with 10 bits instead of 8 bits";
	scanner->opt[OPT_TEN_BIT_MODE].type = SANE_TYPE_BOOL;
	scanner->val[OPT_TEN_BIT_MODE].w = 0;
	if ((scanner->device->inquiry_GOB & 4) == 0) {
		scanner->opt[OPT_TEN_BIT_MODE].cap |= (1 << 5);
	}
	scanner->opt[OPT_TWELVE_BIT_MODE].name = "twelve-bit-mode";
	scanner->opt[OPT_TWELVE_BIT_MODE].title = "12 bit-mode";
	scanner->opt[OPT_TWELVE_BIT_MODE].desc = "Output with 12 bits instead of 8 bits";
	scanner->opt[OPT_TWELVE_BIT_MODE].type = SANE_TYPE_BOOL;
	scanner->val[OPT_TWELVE_BIT_MODE].w = 0;
	if ((scanner->device->inquiry_GOB & 8) == 0) {
		scanner->opt[OPT_TWELVE_BIT_MODE].cap |= (1 << 5);
	}
	scanner->opt[OPT_QUALITY].name = "quality-cal";
	scanner->opt[OPT_QUALITY].title = "Quality calibration";
	scanner->opt[OPT_QUALITY].desc = "Do a quality white-calibration";
	scanner->opt[OPT_QUALITY].type = SANE_TYPE_BOOL;
	scanner->val[OPT_QUALITY].w = 0;
	if (scanner->device->inquiry_quality_ctrl == 0) {
		scanner->opt[OPT_QUALITY].cap |= (1 << 5);
	}
	scanner->opt[OPT_WARMUP].name = "warmup";
	scanner->opt[OPT_WARMUP].title = "Warmup lamp";
	scanner->opt[OPT_WARMUP].desc = "Warmup lamp before scanning";
	scanner->opt[OPT_WARMUP].type = SANE_TYPE_BOOL;
	scanner->val[OPT_WARMUP].w = 0;
	if (scanner->device->inquiry_max_warmup_time == 0) {
		scanner->opt[OPT_WARMUP].cap |= (1 << 5);
	}
	scanner->opt[OPT_RGB_BIND].name = "rgb-bind";
	scanner->opt[OPT_RGB_BIND].title = "Bind RGB";
	scanner->opt[OPT_RGB_BIND].desc = "In RGB-mode use same values for each color";
	scanner->opt[OPT_RGB_BIND].type = SANE_TYPE_BOOL;
	scanner->val[OPT_RGB_BIND].w = 1;
	scanner->opt[OPT_BRIGHTNESS].name = "brightness";
	scanner->opt[OPT_BRIGHTNESS].title = "Brightness";
	scanner->opt[OPT_BRIGHTNESS].desc = "Controls the brightness of the acquired image.";
	scanner->opt[OPT_BRIGHTNESS].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_BRIGHTNESS].constraint.range = &percentage_range;
	scanner->val[OPT_BRIGHTNESS].w = 0;
	scanner->opt[OPT_CONTRAST].name = "contrast";
	scanner->opt[OPT_CONTRAST].title = "Contrast";
	scanner->opt[OPT_CONTRAST].desc = "Controls the contrast of the acquired image.";
	scanner->opt[OPT_CONTRAST].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CONTRAST].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CONTRAST].constraint.range = &percentage_range;
	scanner->val[OPT_CONTRAST].w = 0;
	scanner->opt[OPT_THRESHOLD].name = "threshold";
	scanner->opt[OPT_THRESHOLD].title = "Threshold";
	scanner->opt[OPT_THRESHOLD].desc = "Select minimum-brightness to get a white point";
	scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100;
	scanner->val[OPT_THRESHOLD].w = ((SANE_Word) ((50) * (1 << 16)));
	scanner->opt[OPT_HIGHLIGHT].name = "highlight";
	scanner->opt[OPT_HIGHLIGHT].title = "Highlight";
	scanner->opt[OPT_HIGHLIGHT].desc = "Selects what radiance level should be considered \"white\".";
	scanner->opt[OPT_HIGHLIGHT].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_HIGHLIGHT].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_HIGHLIGHT].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_HIGHLIGHT].constraint.range = &percentage_range_100;
	scanner->val[OPT_HIGHLIGHT].w = ((SANE_Word) ((100) * (1 << 16)));
	scanner->opt[OPT_HIGHLIGHT_R].name = "highlight-r";
	scanner->opt[OPT_HIGHLIGHT_R].title = "Highlight for red";
	scanner->opt[OPT_HIGHLIGHT_R].desc = "Selects what red radiance level should be considered \"full red\".";
	scanner->opt[OPT_HIGHLIGHT_R].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_HIGHLIGHT_R].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_HIGHLIGHT_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_HIGHLIGHT_R].constraint.range = &percentage_range_100;
	scanner->val[OPT_HIGHLIGHT_R].w = ((SANE_Word) ((100) * (1 << 16)));
	scanner->opt[OPT_HIGHLIGHT_G].name = "highlight-g";
	scanner->opt[OPT_HIGHLIGHT_G].title = "Highlight for green";
	scanner->opt[OPT_HIGHLIGHT_G].desc = "Selects what green radiance level should be considered \"full green\".";
	scanner->opt[OPT_HIGHLIGHT_G].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_HIGHLIGHT_G].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_HIGHLIGHT_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_HIGHLIGHT_G].constraint.range = &percentage_range_100;
	scanner->val[OPT_HIGHLIGHT_G].w = ((SANE_Word) ((100) * (1 << 16)));
	scanner->opt[OPT_HIGHLIGHT_B].name = "highlight-b";
	scanner->opt[OPT_HIGHLIGHT_B].title = "Highlight for blue";
	scanner->opt[OPT_HIGHLIGHT_B].desc = "Selects what blue radiance level should be considered \"full blue\".";
	scanner->opt[OPT_HIGHLIGHT_B].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_HIGHLIGHT_B].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_HIGHLIGHT_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_HIGHLIGHT_B].constraint.range = &percentage_range_100;
	scanner->val[OPT_HIGHLIGHT_B].w = ((SANE_Word) ((100) * (1 << 16)));
	scanner->opt[OPT_SHADOW].name = "shadow";
	scanner->opt[OPT_SHADOW].title = "Shadow";
	scanner->opt[OPT_SHADOW].desc = "Selects what radiance level should be considered \"black\".";
	scanner->opt[OPT_SHADOW].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SHADOW].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_SHADOW].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SHADOW].constraint.range = &percentage_range_100;
	scanner->val[OPT_SHADOW].w = 0;
	scanner->opt[OPT_SHADOW_R].name = "shadow-r";
	scanner->opt[OPT_SHADOW_R].title = "Shadow for red";
	scanner->opt[OPT_SHADOW_R].desc = "Selects what red radiance level should be considered \"black\".";
	scanner->opt[OPT_SHADOW_R].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SHADOW_R].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_SHADOW_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SHADOW_R].constraint.range = &percentage_range_100;
	scanner->val[OPT_SHADOW_R].w = 0;
	scanner->opt[OPT_SHADOW_G].name = "shadow-g";
	scanner->opt[OPT_SHADOW_G].title = "Shadow for green";
	scanner->opt[OPT_SHADOW_G].desc = "Selects what green radiance level should be considered \"black\".";
	scanner->opt[OPT_SHADOW_G].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SHADOW_G].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_SHADOW_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SHADOW_G].constraint.range = &percentage_range_100;
	scanner->val[OPT_SHADOW_G].w = 0;
	scanner->opt[OPT_SHADOW_B].name = "shadow-b";
	scanner->opt[OPT_SHADOW_B].title = "Shadow for blue";
	scanner->opt[OPT_SHADOW_B].desc = "Selects what blue radiance level should be considered \"black\".";
	scanner->opt[OPT_SHADOW_B].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SHADOW_B].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_SHADOW_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SHADOW_B].constraint.range = &percentage_range_100;
	scanner->val[OPT_SHADOW_B].w = 0;
	scanner->opt[OPT_ANALOG_GAMMA].name = "analog-gamma";
	scanner->opt[OPT_ANALOG_GAMMA].title = "Analog gamma correction";
	scanner->opt[OPT_ANALOG_GAMMA].desc = "Analog gamma-correction";
	scanner->opt[OPT_ANALOG_GAMMA].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_ANALOG_GAMMA].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_ANALOG_GAMMA].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_ANALOG_GAMMA].constraint.range = &(scanner->device->analog_gamma_range);
	scanner->val[OPT_ANALOG_GAMMA].w = 1 << 16;
	scanner->opt[OPT_ANALOG_GAMMA_R].name = "analog-gamma-r";
	scanner->opt[OPT_ANALOG_GAMMA_R].title = "Analog gamma red";
	scanner->opt[OPT_ANALOG_GAMMA_R].desc = "Analog gamma-correction for red";
	scanner->opt[OPT_ANALOG_GAMMA_R].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_ANALOG_GAMMA_R].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_ANALOG_GAMMA_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_ANALOG_GAMMA_R].constraint.range = &(scanner->device->analog_gamma_range);
	scanner->val[OPT_ANALOG_GAMMA_R].w = 1 << 16;
	scanner->opt[OPT_ANALOG_GAMMA_G].name = "analog-gamma-g";
	scanner->opt[OPT_ANALOG_GAMMA_G].title = "Analog gamma green";
	scanner->opt[OPT_ANALOG_GAMMA_G].desc = "Analog gamma-correction for green";
	scanner->opt[OPT_ANALOG_GAMMA_G].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_ANALOG_GAMMA_G].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_ANALOG_GAMMA_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_ANALOG_GAMMA_G].constraint.range = &(scanner->device->analog_gamma_range);
	scanner->val[OPT_ANALOG_GAMMA_G].w = 1 << 16;
	scanner->opt[OPT_ANALOG_GAMMA_B].name = "analog-gamma-b";
	scanner->opt[OPT_ANALOG_GAMMA_B].title = "Analog gamma blue";
	scanner->opt[OPT_ANALOG_GAMMA_B].desc = "Analog gamma-correction for blue";
	scanner->opt[OPT_ANALOG_GAMMA_B].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_ANALOG_GAMMA_B].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_ANALOG_GAMMA_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_ANALOG_GAMMA_B].constraint.range = &(scanner->device->analog_gamma_range);
	scanner->val[OPT_ANALOG_GAMMA_B].w = 1 << 16;
	scanner->opt[OPT_CUSTOM_GAMMA].name = "custom-gamma";
	scanner->opt[OPT_CUSTOM_GAMMA].title = "Use custom gamma table";
	scanner->opt[OPT_CUSTOM_GAMMA].desc = "Determines whether a builtin or a custom gamma-table should be used.";
	scanner->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
	scanner->val[OPT_CUSTOM_GAMMA].w = 0;
	scanner->opt[OPT_GAMMA_VECTOR].name = "gamma-table";
	scanner->opt[OPT_GAMMA_VECTOR].title = "Image intensity";
	scanner->opt[OPT_GAMMA_VECTOR].desc = "Gamma-correction table.  In color mode this option equally affects the red, green, and blue channels simultaneously (i.e., it is an intensity gamma table).";
	scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
	scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->val[OPT_GAMMA_VECTOR].wa = &(scanner->gamma_table[0][0]);
	scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
	scanner->opt[OPT_GAMMA_VECTOR].size = scanner->gamma_length * sizeof(SANE_Word);
	scanner->opt[OPT_GAMMA_VECTOR_R].name = "red-gamma-table";
	scanner->opt[OPT_GAMMA_VECTOR_R].title = "Red intensity";
	scanner->opt[OPT_GAMMA_VECTOR_R].desc = "Gamma-correction table for the red band.";
	scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
	scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->val[OPT_GAMMA_VECTOR_R].wa = &(scanner->gamma_table[1][0]);
	scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range);
	scanner->opt[OPT_GAMMA_VECTOR_R].size = scanner->gamma_length * sizeof(SANE_Word);
	scanner->opt[OPT_GAMMA_VECTOR_G].name = "green-gamma-table";
	scanner->opt[OPT_GAMMA_VECTOR_G].title = "Green intensity";
	scanner->opt[OPT_GAMMA_VECTOR_G].desc = "Gamma-correction table for the green band.";
	scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
	scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->val[OPT_GAMMA_VECTOR_G].wa = &(scanner->gamma_table[2][0]);
	scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range);
	scanner->opt[OPT_GAMMA_VECTOR_G].size = scanner->gamma_length * sizeof(SANE_Word);
	scanner->opt[OPT_GAMMA_VECTOR_B].name = "blue-gamma-table";
	scanner->opt[OPT_GAMMA_VECTOR_B].title = "Blue intensity";
	scanner->opt[OPT_GAMMA_VECTOR_B].desc = "Gamma-correction table for the blue band.";
	scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
	scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
	scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->val[OPT_GAMMA_VECTOR_B].wa = &(scanner->gamma_table[3][0]);
	scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range);
	scanner->opt[OPT_GAMMA_VECTOR_B].size = scanner->gamma_length * sizeof(SANE_Word);
	scanner->opt[OPT_HALFTONE_DIMENSION].name = "halftone-size";
	scanner->opt[OPT_HALFTONE_DIMENSION].title = "Halftone pattern size";
	scanner->opt[OPT_HALFTONE_DIMENSION].desc = "Sets the size of the halftoning (dithering) pattern used when scanning halftoned images.";
	scanner->opt[OPT_HALFTONE_DIMENSION].type = SANE_TYPE_INT;
	scanner->opt[OPT_HALFTONE_DIMENSION].unit = SANE_UNIT_PIXEL;
	scanner->opt[OPT_HALFTONE_DIMENSION].constraint_type =
		SANE_CONSTRAINT_WORD_LIST;
	scanner->opt[OPT_HALFTONE_DIMENSION].constraint.word_list = pattern_dim_list;
	scanner->val[OPT_HALFTONE_DIMENSION].w = 0;
	scanner->opt[OPT_HALFTONE_PATTERN].name = "halftone-pattern";
	scanner->opt[OPT_HALFTONE_PATTERN].title = "Halftone pattern";
	scanner->opt[OPT_HALFTONE_PATTERN].desc = "Defines the halftoning (dithering) pattern for scanning halftoned images.";
	scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_INT;
	scanner->opt[OPT_HALFTONE_PATTERN].size = 0;
	scanner->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_HALFTONE_PATTERN].constraint.range = &u8_range;
	scanner->val[OPT_HALFTONE_PATTERN].wa = scanner->halftone_pattern;
	scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
	scanner->opt[OPT_ADVANCED_GROUP].desc = "";
	scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
	scanner->opt[OPT_ADVANCED_GROUP].cap = (1 << 6);
	scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
	scanner->opt[OPT_SELECT_EXPOSURE_TIME].name = "select-exposure-time";
	scanner->opt[OPT_SELECT_EXPOSURE_TIME].title = "Set exposure-time";
	scanner->opt[OPT_SELECT_EXPOSURE_TIME].desc = "Enable selection of exposure-time";
	scanner->opt[OPT_SELECT_EXPOSURE_TIME].type = SANE_TYPE_BOOL;
	scanner->val[OPT_SELECT_EXPOSURE_TIME].w = 0;
	scanner->opt[OPT_CAL_EXPOS_TIME].name = "cal-exposure-time";
	scanner->opt[OPT_CAL_EXPOS_TIME].title = "Cal. exposure-time";
	scanner->opt[OPT_CAL_EXPOS_TIME].desc = "Define exposure-time for calibration";
	scanner->opt[OPT_CAL_EXPOS_TIME].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CAL_EXPOS_TIME].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_CAL_EXPOS_TIME].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CAL_EXPOS_TIME].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_CAL_EXPOS_TIME].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_g_fb_def *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_CAL_EXPOS_TIME].cap |= (1 << 5);
	scanner->opt[OPT_CAL_EXPOS_TIME_R].name = "cal-exposure-time-r";
	scanner->opt[OPT_CAL_EXPOS_TIME_R].title = "Cal. exposure-time for red";
	scanner->opt[OPT_CAL_EXPOS_TIME_R].desc = "Define exposure-time for red calibration";
	scanner->opt[OPT_CAL_EXPOS_TIME_R].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CAL_EXPOS_TIME_R].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_CAL_EXPOS_TIME_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CAL_EXPOS_TIME_R].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_CAL_EXPOS_TIME_R].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_r *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_CAL_EXPOS_TIME_R].cap |= (1 << 5);
	scanner->opt[OPT_CAL_EXPOS_TIME_G].name = "cal-exposure-time-g";
	scanner->opt[OPT_CAL_EXPOS_TIME_G].title = "Cal. exposure-time for green";
	scanner->opt[OPT_CAL_EXPOS_TIME_G].desc = "Define exposure-time for green calibration";
	scanner->opt[OPT_CAL_EXPOS_TIME_G].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CAL_EXPOS_TIME_G].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_CAL_EXPOS_TIME_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CAL_EXPOS_TIME_G].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_CAL_EXPOS_TIME_G].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_g *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_CAL_EXPOS_TIME_G].cap |= (1 << 5);
	scanner->opt[OPT_CAL_EXPOS_TIME_B].name = "cal-exposure-time-b";
	scanner->opt[OPT_CAL_EXPOS_TIME_B].title = "Cal. exposure-time for blue";
	scanner->opt[OPT_CAL_EXPOS_TIME_B].desc = "Define exposure-time for blue calibration";
	scanner->opt[OPT_CAL_EXPOS_TIME_B].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CAL_EXPOS_TIME_B].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_CAL_EXPOS_TIME_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CAL_EXPOS_TIME_B].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_CAL_EXPOS_TIME_B].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_b *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_CAL_EXPOS_TIME_B].cap |= (1 << 5);
	scanner->opt[OPT_SCAN_EXPOS_TIME].name = "scan-exposure-time";
	scanner->opt[OPT_SCAN_EXPOS_TIME].title = "Scan exposure-time";
	scanner->opt[OPT_SCAN_EXPOS_TIME].desc = "Define exposure-time for scan";
	scanner->opt[OPT_SCAN_EXPOS_TIME].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SCAN_EXPOS_TIME].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_SCAN_EXPOS_TIME].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SCAN_EXPOS_TIME].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_SCAN_EXPOS_TIME].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_g_fb_def *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_SCAN_EXPOS_TIME].cap |= (1 << 5);
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].name = "scan-exposure-time-r";
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].title = "Scan exposure-time for red";
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].desc = "Define exposure-time for red scan";
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_SCAN_EXPOS_TIME_R].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_r *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap |= (1 << 5);
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].name = "scan-exposure-time-g";
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].title = "Scan exposure-time for green";
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].desc = "Define exposure-time for green scan";
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_SCAN_EXPOS_TIME_G].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_g *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap |= (1 << 5);
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].name = "scan-exposure-time-b";
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].title = "Scan exposure-time for blue";
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].desc = "Define exposure-time for blue scan";
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].unit = SANE_UNIT_MICROSECOND;
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].constraint.range = &(scanner->exposure_time_range);
	scanner->val[OPT_SCAN_EXPOS_TIME_B].w = ((SANE_Word) ((scanner->device->inquiry_exposure_time_c_fb_def_b *
	    scanner->device->inquiry_exposure_time_step_unit) * (1 << 16)));
	scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap |= (1 << 5);
	if (scanner->device->inquiry_exposure_adj == 0) {
		scanner->opt[OPT_SELECT_EXPOSURE_TIME].cap |= (1 << 5);
	}
	scanner->opt[OPT_SELECT_LAMP_DENSITY].name = "select-lamp-density";
	scanner->opt[OPT_SELECT_LAMP_DENSITY].title = "Set lamp density";
	scanner->opt[OPT_SELECT_LAMP_DENSITY].desc = "Enable selection of lamp density";
	scanner->opt[OPT_SELECT_LAMP_DENSITY].type = SANE_TYPE_BOOL;
	scanner->val[OPT_SELECT_LAMP_DENSITY].w = 0;
	scanner->opt[OPT_CAL_LAMP_DEN].name = "cal-lamp-density";
	scanner->opt[OPT_CAL_LAMP_DEN].title = "Cal. lamp density";
	scanner->opt[OPT_CAL_LAMP_DEN].desc = "Define lamp density for calibration";
	scanner->opt[OPT_CAL_LAMP_DEN].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_CAL_LAMP_DEN].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_CAL_LAMP_DEN].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_CAL_LAMP_DEN].constraint.range = &percentage_range_100;
	scanner->val[OPT_CAL_LAMP_DEN].w = ((SANE_Word) ((50) * (1 << 16)));
	scanner->opt[OPT_CAL_LAMP_DEN].cap |= (1 << 5);
	scanner->opt[OPT_SCAN_LAMP_DEN].name = "scan-lamp-density";
	scanner->opt[OPT_SCAN_LAMP_DEN].title = "Scan lamp density";
	scanner->opt[OPT_SCAN_LAMP_DEN].desc = "Define lamp density for scan";
	scanner->opt[OPT_SCAN_LAMP_DEN].type = SANE_TYPE_FIXED;
	scanner->opt[OPT_SCAN_LAMP_DEN].unit = SANE_UNIT_PERCENT;
	scanner->opt[OPT_SCAN_LAMP_DEN].constraint_type = SANE_CONSTRAINT_RANGE;
	scanner->opt[OPT_SCAN_LAMP_DEN].constraint.range = &percentage_range_100;
	scanner->val[OPT_SCAN_LAMP_DEN].w = ((SANE_Word) ((50) * (1 << 16)));
	scanner->opt[OPT_SCAN_LAMP_DEN].cap |= (1 << 5);
	if (scanner->device->inquiry_lamp_ctrl == 0) {
		scanner->opt[OPT_SELECT_LAMP_DENSITY].cap |= (1 << 5);
	}
	scanner->opt[OPT_SLOW].name = "slow";
	scanner->opt[OPT_SLOW].title = "Slow speed";
	scanner->opt[OPT_SLOW].desc = "Scan with slow speed";
	scanner->opt[OPT_SLOW].type = SANE_TYPE_BOOL;
	scanner->val[OPT_SLOW].w = 0;
	scanner->opt[OPT_SMEAR].name = "smear";
	scanner->opt[OPT_SMEAR].title = "Smear";
	scanner->opt[OPT_SMEAR].desc = "Don't care about image smearing problem";
	scanner->opt[OPT_SMEAR].type = SANE_TYPE_BOOL;
	scanner->val[OPT_SMEAR].w = 0;
	scanner->opt[OPT_CALIB_MODE].name = "calibrationmode";
	scanner->opt[OPT_CALIB_MODE].title = "Calibration mode";
	scanner->opt[OPT_CALIB_MODE].desc = "Define calibration mode";
	scanner->opt[OPT_CALIB_MODE].type = SANE_TYPE_STRING;
	scanner->opt[OPT_CALIB_MODE].size = max_string_size(calibration_list);
	scanner->opt[OPT_CALIB_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
	scanner->opt[OPT_CALIB_MODE].constraint.string_list = calibration_list;
	scanner->val[OPT_CALIB_MODE].s = (SANE_Char *) strdup(calibration_list[1]);
	if (scanner->device->inquiry_calibration == 0) {
		scanner->opt[OPT_CALIB_MODE].cap |= (1 << 5);
	}
	scanner->opt[OPT_SHADING_TYPE].name = "shadingtype";
	scanner->opt[OPT_SHADING_TYPE].title = "Shading type";
	scanner->opt[OPT_SHADING_TYPE].desc = "Define calculation of shading data";
	scanner->opt[OPT_SHADING_TYPE].type = SANE_TYPE_STRING;
	scanner->opt[OPT_SHADING_TYPE].size = max_string_size(shading_list);
	scanner->opt[OPT_SHADING_TYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
	scanner->opt[OPT_SHADING_TYPE].constraint.string_list = shading_list;
	scanner->val[OPT_SHADING_TYPE].s = (SANE_Char *) strdup(shading_list[1]);
	if (scanner->device->inquiry_quality_ctrl == 0) {
		scanner->opt[OPT_SHADING_TYPE].cap |= (1 << 5);
	}
	scanner->opt[OPT_PREVIEW].name = "preview";
	scanner->opt[OPT_PREVIEW].title = "Preview";
	scanner->opt[OPT_PREVIEW].desc = "Request a preview-quality scan.";
	scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
	scanner->opt[OPT_PREVIEW].cap = (1 << 2) | (1 << 0);
	scanner->val[OPT_PREVIEW].w = 0;
	sane_umax_control_option(scanner, OPT_MODE, SANE_ACTION_SET_VALUE, (SANE_String *) scan_mode_list[scan_modes], 0);
	return SANE_STATUS_GOOD;
}
-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]