2
Copyright (C) 2008, Panasonic Russia Ltd.
3
Copyright (C) 2010, m. allan noah
6
Panasonic KV-S20xx USB-SCSI scanners.
9
#include "../include/sane/config.h"
13
#define DEBUG_DECLARE_ONLY
14
#define BACKEND_NAME kvs20xx
16
#include "../include/sane/sane.h"
17
#include "../include/sane/saneopts.h"
18
#include "../include/sane/sanei.h"
19
#include "../include/sane/sanei_backend.h"
20
#include "../include/sane/sanei_config.h"
21
#include "../include/lassert.h"
24
#include "kvs20xx_cmd.h"
28
max_string_size (SANE_String_Const strings[])
30
size_t size, max_size = 0;
33
for (i = 0; strings[i]; ++i)
35
size = strlen (strings[i]) + 1;
41
static SANE_String_Const mode_list[] = {
42
SANE_VALUE_SCAN_MODE_LINEART,
43
SANE_VALUE_SCAN_MODE_GRAY,
44
SANE_VALUE_SCAN_MODE_COLOR,
47
static const unsigned mode_val[] = { 0, 2, 5 };
48
static const unsigned bps_val[] = { 1, 8, 24 };
50
static const SANE_Range resolutions_range = {100,600,10};
52
/* List of feeder modes */
53
static SANE_String_Const feeder_mode_list[] = {
55
SANE_I18N ("continuous"),
59
/* List of manual feed mode */
60
static SANE_String_Const manual_feed_list[] = {
62
SANE_I18N ("wait_doc"),
63
SANE_I18N ("wait_key"),
67
/* List of paper sizes */
68
static SANE_String_Const paper_list[] = {
69
SANE_I18N ("user_def"),
70
SANE_I18N ("business_card"),
71
/*SANE_I18N("Check"), */
72
/*SANE_I18N ("A3"), */
77
/*SANE_I18N ("Double letter 11x17 in"),
84
static const unsigned paper_val[] = { 0, 1, 4, 5, 6, 7, 13, 14, 15 };
90
static const struct paper_size paper_sizes[] = {
91
{210, 297}, /* User defined, default=A4 */
92
{54, 90}, /* Business card */
93
/*{80, 170}, *//* Check (China business) */
94
/*{297, 420}, *//* A3 */
98
{215, 280}, /* US Letter 8.5 x 11 in */
99
/*{280, 432}, *//* Double Letter 11 x 17 in */
100
/*{250, 353}, *//* B4 */
103
{215, 355} /* US Legal */
107
#define MAX_WIDTH 215
108
#define MIN_LENGTH 70
109
#define MAX_LENGTH 355
110
static SANE_Range tl_x_range = { 0, MAX_WIDTH - MIN_WIDTH, 0 };
111
static SANE_Range tl_y_range = { 0, MAX_LENGTH - MIN_LENGTH, 0 };
112
static SANE_Range br_x_range = { MIN_WIDTH, MAX_WIDTH, 0 };
113
static SANE_Range br_y_range = { MIN_LENGTH, MAX_LENGTH, 0 };
114
static SANE_Range byte_value_range = { 0, 255, 0 };
116
/* List of image emphasis options, 5 steps */
117
static SANE_String_Const image_emphasis_list[] = {
120
SANE_I18N ("medium"),
122
SANE_I18N ("smooth"),
127
static SANE_String_Const gamma_list[] = {
128
SANE_I18N ("normal"),
132
static unsigned gamma_val[] = { 0, 1 };
134
/* List of lamp color dropout */
135
static SANE_String_Const lamp_list[] = {
136
SANE_I18N ("normal"),
143
/* Reset the options for that scanner. */
145
init_options (struct scanner *s)
148
SANE_Option_Descriptor *o;
149
/* Pre-initialize the options. */
150
memset (s->opt, 0, sizeof (s->opt));
151
memset (s->val, 0, sizeof (s->val));
153
for (i = 0; i < NUM_OPTIONS; i++)
155
s->opt[i].size = sizeof (SANE_Word);
156
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
159
/* Number of options. */
160
o = &s->opt[NUM_OPTS];
162
o->title = SANE_TITLE_NUM_OPTIONS;
163
o->desc = SANE_DESC_NUM_OPTIONS;
164
o->type = SANE_TYPE_INT;
165
o->cap = SANE_CAP_SOFT_DETECT;
166
s->val[NUM_OPTS].w = NUM_OPTIONS;
169
o = &s->opt[MODE_GROUP];
170
o->title = SANE_I18N ("Scan Mode");
171
o->desc = ""; /* not valid for a group */
172
o->type = SANE_TYPE_GROUP;
175
o->constraint_type = SANE_CONSTRAINT_NONE;
177
/* Scanner supported modes */
179
o->name = SANE_NAME_SCAN_MODE;
180
o->title = SANE_TITLE_SCAN_MODE;
181
o->desc = SANE_DESC_SCAN_MODE;
182
o->type = SANE_TYPE_STRING;
183
o->size = max_string_size (mode_list);
184
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
185
o->constraint.string_list = mode_list;
186
s->val[MODE].s = malloc (o->size);
187
strcpy (s->val[MODE].s, mode_list[0]);
189
/* X and Y resolution */
190
o = &s->opt[RESOLUTION];
191
o->name = SANE_NAME_SCAN_RESOLUTION;
192
o->title = SANE_TITLE_SCAN_RESOLUTION;
193
o->desc = SANE_DESC_SCAN_RESOLUTION;
194
o->type = SANE_TYPE_INT;
195
o->unit = SANE_UNIT_DPI;
196
o->constraint_type = SANE_CONSTRAINT_RANGE;
197
o->constraint.range = &resolutions_range;
198
s->val[RESOLUTION].w = 100;
203
o->title = SANE_I18N ("Duplex");
204
o->desc = SANE_I18N ("Enable Duplex (Dual-Sided) Scanning");
205
o->type = SANE_TYPE_BOOL;
206
o->unit = SANE_UNIT_NONE;
207
s->val[DUPLEX].w = SANE_FALSE;
210
if (!s->support_info.support_duplex)
211
o->cap |= SANE_CAP_INACTIVE;
215
o = &s->opt[FEEDER_MODE];
216
o->name = "feeder-mode";
217
o->title = SANE_I18N ("Feeder mode");
218
o->desc = SANE_I18N ("Sets the feeding mode");
219
o->type = SANE_TYPE_STRING;
220
o->size = max_string_size (feeder_mode_list);
221
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
222
o->constraint.string_list = feeder_mode_list;
223
s->val[FEEDER_MODE].s = malloc (o->size);
224
strcpy (s->val[FEEDER_MODE].s, feeder_mode_list[0]);
227
o = &s->opt[LENGTHCTL];
228
o->name = "length-control";
229
o->title = SANE_I18N ("Length control mode");
232
("Length Control Mode is a mode that the scanner reads up to the shorter length of actual"
233
" paper or logical document length.");
234
o->type = SANE_TYPE_BOOL;
235
o->unit = SANE_UNIT_NONE;
236
s->val[LENGTHCTL].w = SANE_FALSE;
239
o = &s->opt[MANUALFEED];
240
o->name = "manual-feed";
241
o->title = SANE_I18N ("Manual feed mode");
242
o->desc = SANE_I18N ("Sets the manual feed mode");
243
o->type = SANE_TYPE_STRING;
244
o->size = max_string_size (manual_feed_list);
245
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
246
o->constraint.string_list = manual_feed_list;
247
s->val[MANUALFEED].s = malloc (o->size);
248
strcpy (s->val[MANUALFEED].s, manual_feed_list[0]);
250
/*Manual feed timeout */
251
o = &s->opt[FEED_TIMEOUT];
252
o->name = "feed-timeout";
253
o->title = SANE_I18N ("Manual feed timeout");
254
o->desc = SANE_I18N ("Sets the manual feed timeout in seconds");
255
o->type = SANE_TYPE_INT;
256
o->unit = SANE_UNIT_NONE;
257
o->size = sizeof (SANE_Int);
258
o->constraint_type = SANE_CONSTRAINT_RANGE;
259
o->constraint.range = &(byte_value_range);
260
o->cap |= SANE_CAP_INACTIVE;
261
s->val[FEED_TIMEOUT].w = 30;
264
o = &s->opt[DBLFEED];
265
o->name = "double-feed";
266
o->title = SANE_I18N ("Double feed detection");
267
o->desc = SANE_I18N ("Enable/Disable double feed detection");
268
o->type = SANE_TYPE_BOOL;
269
o->unit = SANE_UNIT_NONE;
270
s->val[DBLFEED].w = SANE_FALSE;
274
o = &s->opt[FIT_TO_PAGE];
275
o->name = SANE_I18N ("fit-to-page");
276
o->title = SANE_I18N ("Fit to page");
277
o->desc = SANE_I18N ("Scanner shrinks image to fit scanned page");
278
o->type = SANE_TYPE_BOOL;
279
o->unit = SANE_UNIT_NONE;
280
s->val[FIT_TO_PAGE].w = SANE_FALSE;
283
o = &s->opt[GEOMETRY_GROUP];
284
o->title = SANE_I18N ("Geometry");
285
o->desc = ""; /* not valid for a group */
286
o->type = SANE_TYPE_GROUP;
289
o->constraint_type = SANE_CONSTRAINT_NONE;
291
/* Paper sizes list */
292
o = &s->opt[PAPER_SIZE];
293
o->name = "paper-size";
294
o->title = SANE_I18N ("Paper size");
295
o->desc = SANE_I18N ("Physical size of the paper in the ADF");
296
o->type = SANE_TYPE_STRING;
297
o->size = max_string_size (paper_list);
298
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
299
o->constraint.string_list = paper_list;
300
s->val[PAPER_SIZE].s = malloc (o->size);
301
strcpy (s->val[PAPER_SIZE].s, SANE_I18N ("A4"));
304
o = &s->opt[LANDSCAPE];
305
o->name = "landscape";
306
o->title = SANE_I18N ("Landscape");
308
SANE_I18N ("Set paper position : "
309
"true for landscape, false for portrait");
310
o->type = SANE_TYPE_BOOL;
311
o->unit = SANE_UNIT_NONE;
312
s->val[LANDSCAPE].w = SANE_FALSE;
313
o->cap |= SANE_CAP_INACTIVE;
317
o->name = SANE_NAME_SCAN_TL_X;
318
o->title = SANE_TITLE_SCAN_TL_X;
319
o->desc = SANE_DESC_SCAN_TL_X;
320
o->type = SANE_TYPE_INT;
321
o->unit = SANE_UNIT_MM;
322
o->constraint_type = SANE_CONSTRAINT_RANGE;
323
o->constraint.range = &tl_x_range;
324
o->cap |= SANE_CAP_INACTIVE;
329
o->name = SANE_NAME_SCAN_TL_Y;
330
o->title = SANE_TITLE_SCAN_TL_Y;
331
o->desc = SANE_DESC_SCAN_TL_Y;
332
o->type = SANE_TYPE_INT;
333
o->unit = SANE_UNIT_MM;
334
o->constraint_type = SANE_CONSTRAINT_RANGE;
335
o->constraint.range = &tl_y_range;
336
o->cap |= SANE_CAP_INACTIVE;
341
o->name = SANE_NAME_SCAN_BR_X;
342
o->title = SANE_TITLE_SCAN_BR_X;
343
o->desc = SANE_DESC_SCAN_BR_X;
344
o->type = SANE_TYPE_INT;
345
o->unit = SANE_UNIT_MM;
346
o->constraint_type = SANE_CONSTRAINT_RANGE;
347
o->constraint.range = &br_x_range;
348
o->cap |= SANE_CAP_INACTIVE;
349
s->val[BR_X].w = 210;
353
o->name = SANE_NAME_SCAN_BR_Y;
354
o->title = SANE_TITLE_SCAN_BR_Y;
355
o->desc = SANE_DESC_SCAN_BR_Y;
356
o->type = SANE_TYPE_INT;
357
o->unit = SANE_UNIT_MM;
358
o->constraint_type = SANE_CONSTRAINT_RANGE;
359
o->constraint.range = &br_y_range;
360
o->cap |= SANE_CAP_INACTIVE;
361
s->val[BR_Y].w = 297;
363
/* Enhancement group */
364
o = &s->opt[ADVANCED_GROUP];
365
o->title = SANE_I18N ("Advanced");
366
o->desc = ""; /* not valid for a group */
367
o->type = SANE_TYPE_GROUP;
368
o->cap = SANE_CAP_ADVANCED;
370
o->constraint_type = SANE_CONSTRAINT_NONE;
373
o = &s->opt[BRIGHTNESS];
374
o->name = SANE_NAME_BRIGHTNESS;
375
o->title = SANE_TITLE_BRIGHTNESS;
376
o->desc = SANE_DESC_BRIGHTNESS;
377
o->type = SANE_TYPE_INT;
378
o->unit = SANE_UNIT_NONE;
379
o->size = sizeof (SANE_Int);
380
o->constraint_type = SANE_CONSTRAINT_RANGE;
381
o->constraint.range = &(byte_value_range);
382
s->val[BRIGHTNESS].w = 128;
385
o = &s->opt[CONTRAST];
386
o->name = SANE_NAME_CONTRAST;
387
o->title = SANE_TITLE_CONTRAST;
388
o->desc = SANE_DESC_CONTRAST;
389
o->type = SANE_TYPE_INT;
390
o->unit = SANE_UNIT_NONE;
391
o->size = sizeof (SANE_Int);
392
o->constraint_type = SANE_CONSTRAINT_RANGE;
393
o->constraint.range = &(byte_value_range);
394
s->val[CONTRAST].w = 128;
397
o = &s->opt[THRESHOLD];
398
o->name = SANE_NAME_THRESHOLD;
399
o->title = SANE_TITLE_THRESHOLD;
400
o->desc = SANE_DESC_THRESHOLD;
401
o->type = SANE_TYPE_INT;
402
o->size = sizeof (SANE_Int);
403
o->constraint_type = SANE_CONSTRAINT_RANGE;
404
o->constraint.range = &(byte_value_range);
405
s->val[THRESHOLD].w = 128;
409
o = &s->opt[IMAGE_EMPHASIS];
410
o->name = "image-emphasis";
411
o->title = SANE_I18N ("Image emphasis");
412
o->desc = SANE_I18N ("Sets the image emphasis");
413
o->type = SANE_TYPE_STRING;
414
o->size = max_string_size (image_emphasis_list);
415
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
416
o->constraint.string_list = image_emphasis_list;
417
s->val[IMAGE_EMPHASIS].s = malloc (o->size);
418
strcpy (s->val[IMAGE_EMPHASIS].s, image_emphasis_list[0]);
421
o = &s->opt[GAMMA_CORRECTION];
422
o->name = "gamma-cor";
423
o->title = SANE_I18N ("Gamma correction");
424
o->desc = SANE_I18N ("Gamma correction");
425
o->type = SANE_TYPE_STRING;
426
o->size = max_string_size (gamma_list);
427
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
428
o->constraint.string_list = gamma_list;
429
s->val[GAMMA_CORRECTION].s = malloc (o->size);
430
strcpy (s->val[GAMMA_CORRECTION].s, gamma_list[0]);
432
/* Lamp color dropout */
434
o->name = "lamp-color";
435
o->title = SANE_I18N ("Lamp color");
436
o->desc = SANE_I18N ("Sets the lamp color (color dropout)");
437
o->type = SANE_TYPE_STRING;
438
o->size = max_string_size (lamp_list);
439
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
440
o->constraint.string_list = lamp_list;
441
s->val[LAMP].s = malloc (o->size);
442
strcpy (s->val[LAMP].s, lamp_list[0]);
446
/* Lookup a string list from one array and return its index. */
448
str_index (const SANE_String_Const * list, SANE_String_Const name)
454
if (!strcmp (list[index], name))
458
return (-1); /* not found */
463
sane_control_option (SANE_Handle handle, SANE_Int option,
464
SANE_Action action, void *val, SANE_Int * info)
469
struct scanner *s = (struct scanner *) handle;
474
if (option < 0 || option >= NUM_OPTIONS)
475
return SANE_STATUS_UNSUPPORTED;
477
cap = s->opt[option].cap;
478
if (!SANE_OPTION_IS_ACTIVE (cap))
479
return SANE_STATUS_UNSUPPORTED;
481
if (action == SANE_ACTION_GET_VALUE)
483
if (s->opt[option].type == SANE_TYPE_STRING)
485
DBG (DBG_INFO, "sane_control_option: reading opt[%d] = %s\n",
486
option, s->val[option].s);
487
strcpy (val, s->val[option].s);
491
*(SANE_Word *) val = s->val[option].w;
492
DBG (DBG_INFO, "sane_control_option: reading opt[%d] = %d\n",
493
option, s->val[option].w);
495
return SANE_STATUS_GOOD;
498
else if (action == SANE_ACTION_SET_VALUE)
500
if (!SANE_OPTION_IS_SETTABLE (cap))
501
return SANE_STATUS_INVAL;
503
status = sanei_constrain_value (s->opt + option, val, info);
504
if (status != SANE_STATUS_GOOD)
507
if (s->opt[option].type == SANE_TYPE_STRING)
509
if (!strcmp (val, s->val[option].s))
510
return SANE_STATUS_GOOD;
511
DBG (DBG_INFO, "sane_control_option: writing opt[%d] = %s\n",
512
option, (SANE_String_Const) val);
516
if (*(SANE_Word *) val == s->val[option].w)
517
return SANE_STATUS_GOOD;
518
DBG (DBG_INFO, "sane_control_option: writing opt[%d] = %d\n",
519
option, *(SANE_Word *) val);
524
/* Side-effect options */
526
s->val[option].w = *(SANE_Word *) val;
528
*info |= SANE_INFO_RELOAD_PARAMS;
529
return SANE_STATUS_GOOD;
532
if ((*(SANE_Word *) val) + MIN_LENGTH <= s->val[BR_Y].w)
534
s->val[option].w = *(SANE_Word *) val;
536
*info |= SANE_INFO_RELOAD_PARAMS;
539
*info |= SANE_INFO_INEXACT;
540
return SANE_STATUS_GOOD;
542
if ((*(SANE_Word *) val) >= s->val[TL_Y].w + MIN_LENGTH)
544
s->val[option].w = *(SANE_Word *) val;
546
*info |= SANE_INFO_RELOAD_PARAMS;
549
*info |= SANE_INFO_INEXACT;
550
return SANE_STATUS_GOOD;
553
if ((*(SANE_Word *) val) + MIN_WIDTH <= s->val[BR_X].w)
555
s->val[option].w = *(SANE_Word *) val;
557
*info |= SANE_INFO_RELOAD_PARAMS;
560
*info |= SANE_INFO_INEXACT;
561
return SANE_STATUS_GOOD;
564
if (*(SANE_Word *) val >= s->val[TL_X].w + MIN_WIDTH)
566
s->val[option].w = *(SANE_Word *) val;
568
*info |= SANE_INFO_RELOAD_PARAMS;
571
*info |= SANE_INFO_INEXACT;
572
return SANE_STATUS_GOOD;
575
s->val[option].w = *(SANE_Word *) val;
577
*info |= SANE_INFO_RELOAD_PARAMS;
578
return SANE_STATUS_GOOD;
580
/* Side-effect free options */
588
s->val[option].w = *(SANE_Word *) val;
589
return SANE_STATUS_GOOD;
592
s->val[option].w = *(SANE_Word *) val;
593
return set_timeout (s, s->val[option].w);
597
case GAMMA_CORRECTION:
600
strcpy (s->val[option].s, val);
601
return SANE_STATUS_GOOD;
604
strcpy (s->val[MODE].s, val);
605
if (!strcmp (s->val[MODE].s, SANE_VALUE_SCAN_MODE_LINEART))
607
s->opt[THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
608
s->opt[GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
609
s->opt[BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
613
s->opt[THRESHOLD].cap |= SANE_CAP_INACTIVE;
614
s->opt[GAMMA_CORRECTION].cap &= ~SANE_CAP_INACTIVE;
615
s->opt[BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
618
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
620
return SANE_STATUS_GOOD;
623
strcpy (s->val[option].s, val);
624
if (strcmp (s->val[option].s, manual_feed_list[0]) == 0) /* off */
625
s->opt[FEED_TIMEOUT].cap |= SANE_CAP_INACTIVE;
627
s->opt[FEED_TIMEOUT].cap &= ~SANE_CAP_INACTIVE;
629
*info |= SANE_INFO_RELOAD_OPTIONS;
631
return SANE_STATUS_GOOD;
634
strcpy (s->val[PAPER_SIZE].s, val);
635
i = str_index (paper_list, s->val[PAPER_SIZE].s);
640
s->opt[BR_X].cap &= s->opt[BR_Y].cap &= ~SANE_CAP_INACTIVE;
641
s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
642
s->val[LANDSCAPE].w = 0;
648
s->opt[BR_X].cap |= s->opt[BR_Y].cap |= SANE_CAP_INACTIVE;
649
if (i == 3 || i == 4 || i == 7)
651
s->opt[LANDSCAPE].cap &= ~SANE_CAP_INACTIVE;
655
s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
656
s->val[LANDSCAPE].w = 0;
660
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
662
return SANE_STATUS_GOOD;
667
return SANE_STATUS_UNSUPPORTED;
670
static inline unsigned
671
mm2scanner_units (unsigned mm)
673
return mm * 12000 / 254;
675
static inline unsigned
676
scanner_units2mm (unsigned u)
678
return u * 254 / 12000;
682
init_window (struct scanner *s, struct window *wnd, int wnd_id)
684
int paper = str_index (paper_list, s->val[PAPER_SIZE].s);
685
memset (wnd, 0, sizeof (struct window));
686
wnd->window_descriptor_block_length = cpu2be16 (64);
688
wnd->window_identifier = wnd_id;
689
wnd->x_resolution = cpu2be16 (s->val[RESOLUTION].w);
690
wnd->y_resolution = cpu2be16 (s->val[RESOLUTION].w);
694
cpu2be32 (mm2scanner_units (s->val[TL_X].w));
696
cpu2be32 (mm2scanner_units (s->val[TL_Y].w));
698
cpu2be32 (mm2scanner_units (s->val[BR_X].w - s->val[TL_X].w));
700
cpu2be32 (mm2scanner_units (s->val[BR_Y].w - s->val[TL_Y].w));
704
u32 w = cpu2be32 (mm2scanner_units (paper_sizes[paper].width));
705
u32 h = cpu2be32 (mm2scanner_units (paper_sizes[paper].height));
706
wnd->upper_left_x = cpu2be32 (mm2scanner_units (0));
707
wnd->upper_left_y = cpu2be32 (mm2scanner_units (0));
708
if (!s->val[LANDSCAPE].b)
710
wnd->document_width = wnd->width = w;
711
wnd->document_length = wnd->length = h;
715
wnd->document_width = wnd->width = h;
716
wnd->document_length = wnd->length = w;
719
wnd->brightness = s->val[BRIGHTNESS].w;
720
wnd->threshold = s->val[THRESHOLD].w;
721
wnd->contrast = s->val[CONTRAST].w;
722
wnd->image_composition = mode_val[str_index (mode_list, s->val[MODE].s)];
723
wnd->bit_per_pixel = bps_val[str_index (mode_list, s->val[MODE].s)];
724
wnd->halftone_pattern = 0; /*Does not supported */
725
wnd->bit_ordering = cpu2be16 (BIT_ORDERING);
726
wnd->compression_type = 0; /*Does not supported */
727
wnd->compression_argument = 0; /*Does not supported */
729
wnd->vendor_unique_identifier = 0;
730
wnd->nobuf_fstspeed_dfstop = 0;
731
wnd->mirror_image = 0;
732
wnd->image_emphasis = str_index (image_emphasis_list,
733
s->val[IMAGE_EMPHASIS].s);
734
wnd->gamma_correction = gamma_val[str_index (gamma_list,
735
s->val[GAMMA_CORRECTION].s)];
736
wnd->mcd_lamp_dfeed_sens = str_index (lamp_list, s->val[LAMP].s) << 4 | 2;
738
wnd->document_size = (paper != 0) << 7
739
| s->val[LENGTHCTL].b << 6 | s->val[LANDSCAPE].b << 4 | paper_val[paper];
741
wnd->ahead_deskew_dfeed_scan_area_fspeed_rshad = s->val[DBLFEED].b << 4
742
| s->val[FIT_TO_PAGE].b << 2;
743
wnd->continuous_scanning_pages = str_index (feeder_mode_list,
746
wnd->automatic_threshold_mode = 0; /*Does not supported */
747
wnd->automatic_separation_mode = 0; /*Does not supported */
748
wnd->standard_white_level_mode = 0; /*Does not supported */
749
wnd->b_wnr_noise_reduction = 0; /*Does not supported */
750
if (str_index (manual_feed_list, s->val[MANUALFEED].s) == 2)
751
wnd->mfeed_toppos_btmpos_dsepa_hsepa_dcont_rstkr = 2 << 6;
757
/* Get scan parameters */
759
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
761
struct scanner *s = (struct scanner *) handle;
762
SANE_Parameters *p = &s->params;
766
unsigned w, h, res = s->val[RESOLUTION].w;
767
unsigned i = str_index (paper_list,
768
s->val[PAPER_SIZE].s);
771
if (s->val[LANDSCAPE].b)
773
w = paper_sizes[i].height;
774
h = paper_sizes[i].width;
778
w = paper_sizes[i].width;
779
h = paper_sizes[i].height;
784
w = s->val[BR_X].w - s->val[TL_X].w;
785
h = s->val[BR_Y].w - s->val[TL_Y].w;
787
p->pixels_per_line = w * res / 25.4;
788
p->lines = h * res / 25.4;
791
p->format = (!strcmp(s->val[MODE].s,SANE_VALUE_SCAN_MODE_COLOR)) ?
792
SANE_FRAME_RGB : SANE_FRAME_GRAY;
793
p->last_frame = SANE_TRUE;
794
p->depth = bps_val[str_index (mode_list, s->val[MODE].s)];
795
p->bytes_per_line = p->depth * p->pixels_per_line / 8;
799
memcpy (params, p, sizeof (SANE_Parameters));
800
return SANE_STATUS_GOOD;