2
Copyright (C) 2009, Panasonic Russia Ltd.
3
Copyright (C) 2010,2011, m. allan noah
6
Panasonic KV-S40xx USB-SCSI scanner driver.
9
#include "../include/sane/config.h"
12
#define DEBUG_DECLARE_ONLY
13
#define BACKEND_NAME kvs40xx
15
#include "../include/sane/sanei_backend.h"
16
#include "../include/sane/saneopts.h"
17
#include "../include/sane/sanei.h"
18
#include "../include/sane/sanei_config.h"
23
#include "../include/sane/sanei_debug.h"
26
static inline unsigned
27
mm2scanner_units (unsigned mm)
29
return (mm * 12000 / 254.0 + .5);
31
static inline unsigned
32
scanner_units2mm (unsigned u)
34
return (u * 254.0 / 12000 + .5);
38
unsigned ux, uy, ux_pix, uy_pix;
41
static struct restriction flatbad = { 14064, 20400, 7031, 63999 };
42
static struct restriction cw = { 14268, 128000, 7133, 63999 };
43
static struct restriction cl = { 10724, 128000, 5361, 63999 };
46
check_area (struct scanner *s, unsigned ux,
47
unsigned uy, unsigned bx, unsigned by)
49
int fb = !strcmp (s->val[SOURCE].s, SANE_I18N ("fb"));
50
struct restriction *r = fb ? &flatbad
51
: (s->id == KV_S4085CL || s->id == KV_S4065CL) ? &cl : &cw;
52
unsigned res = s->val[RESOLUTION].w;
55
unsigned c1 = mm2scanner_units (ux + w);
56
unsigned c2 = mm2scanner_units (uy + h);
57
int c = c1 <= r->ux && c1 >= 16 && c2 >= 1 && c2 <= r->uy ? 0 : -1;
60
if (mm2scanner_units (ux) > r->ux)
62
if (res * mm2scanner_units (ux) / 1200 > r->ux_pix)
65
if (res * mm2scanner_units (uy) / 1200 > r->uy_pix)
71
max_string_size (const SANE_String_Const strings[])
73
size_t size, max_size = 0;
76
for (i = 0; strings[i]; ++i)
78
size = strlen (strings[i]) + 1;
85
static SANE_String_Const mode_list[] = {
86
SANE_VALUE_SCAN_MODE_LINEART,
87
SANE_VALUE_SCAN_MODE_GRAY,
88
SANE_VALUE_SCAN_MODE_COLOR,
91
static const unsigned mode_val[] = { 0, 2, 5 };
92
static const unsigned bps_val[] = { 1, 8, 24 };
94
static const SANE_Range resolutions_range = {
98
/* List of feeder modes */
99
static SANE_String_Const feeder_mode_list[] = {
100
SANE_I18N ("single"),
101
SANE_I18N ("continuous"),
105
/* List of scan sources */
106
static SANE_String_Const source_list[] = {
112
/* List of manual feed mode */
113
static SANE_String_Const manual_feed_list[] = {
115
SANE_I18N ("wait_doc"),
116
SANE_I18N ("wait_doc_hopper_up"),
117
SANE_I18N ("wait_key"),
121
/* List of paper sizes */
122
static SANE_String_Const paper_list[] = {
123
SANE_I18N ("user_def"),
124
SANE_I18N ("business_card"),
130
SANE_I18N ("Letter"),
131
SANE_I18N ("Double letter 11x17 in"),
139
static SANE_String_Const paper_list_woA3[] = {
140
SANE_I18N ("user_def"),
141
SANE_I18N ("business_card"),
143
/*SANE_I18N ("A3"), */
147
SANE_I18N ("Letter"),
148
/*SANE_I18N ("Double letter 11x17 in"), */
149
/*SANE_I18N ("B4"), */
156
static const unsigned paper_val[] = { 0, 1, 2, 3, 4, 5, 6, 7,
165
static const struct paper_size paper_sizes[] = {
166
{210, 297}, /* User defined, default=A4 */
167
{54, 90}, /* Business card */
168
{80, 170}, /* Check (China business) */
173
{215, 280}, /* US Letter 8.5 x 11 in */
174
{280, 432}, /* Double Letter 11 x 17 in */
178
{215, 355} /* US Legal */
182
#define MIN_LENGTH 70
183
#define MAX_WIDTH 297
184
#define MAX_LENGTH 432
186
#define MAX_WIDTH_A4 227
187
#define MAX_LENGTH_A4 432
189
static SANE_Range tl_x_range = { 0, MAX_WIDTH - MIN_WIDTH, 0 };
190
static SANE_Range tl_y_range = { 0, MAX_LENGTH - MIN_LENGTH, 0 };
191
static SANE_Range br_x_range = { MIN_WIDTH, MAX_WIDTH, 0 };
192
static SANE_Range br_y_range = { MIN_LENGTH, MAX_LENGTH, 0 };
194
static SANE_Range tl_x_range_A4 = { 0, MAX_WIDTH_A4 - MIN_WIDTH, 0 };
195
static SANE_Range tl_y_range_A4 = { 0, MAX_LENGTH_A4 - MIN_LENGTH, 0 };
196
static SANE_Range br_x_range_A4 = { MIN_WIDTH, MAX_WIDTH_A4, 0 };
197
static SANE_Range br_y_range_A4 = { MIN_LENGTH, MAX_LENGTH_A4, 0 };
199
static SANE_Range byte_value_range = { 0, 255, 0 };
200
static SANE_Range compression_value_range = { 1, 0x64, 0 };
202
/* List of image emphasis options, 5 steps */
203
static SANE_String_Const image_emphasis_list[] = {
206
SANE_I18N ("medium"),
208
SANE_I18N ("smooth"),
213
static SANE_String_Const gamma_list[] = {
214
SANE_I18N ("normal"),
218
static unsigned gamma_val[] = { 0, 1 };
220
/* List of lamp color dropout */
221
static SANE_String_Const lamp_list[] = {
222
SANE_I18N ("normal"),
228
static SANE_String_Const dfeed_sence_list[] = {
229
SANE_I18N ("Normal"),
230
SANE_I18N ("High sensivity"),
231
SANE_I18N ("Low sensivity"),
235
/* Lists of supported halftone. They are only valid with
236
* for the Black&White mode. */
237
static SANE_String_Const halftone_pattern[] = {
238
SANE_I18N ("bayer_64"),
239
SANE_I18N ("bayer_16"),
240
SANE_I18N ("halftone_32"),
241
SANE_I18N ("halftone_64"),
242
SANE_I18N ("err_diffusion"),
246
/* Stapled document */
247
static SANE_String_Const stapeled_list[] = {
248
SANE_I18N ("No detection"),
249
SANE_I18N ("Normal mode"),
250
SANE_I18N ("Enhanced mode"),
255
/* List of automatic threshold options */
256
static SANE_String_Const automatic_threshold_list[] = {
257
SANE_I18N ("normal"),
262
static const int automatic_threshold_val[] = {
268
/* List of white level base. */
269
static SANE_String_Const white_level_list[] = {
270
SANE_I18N ("From scanner"),
271
SANE_I18N ("From paper"),
272
SANE_I18N ("Automatic"),
275
static const int white_level_val[] = {
281
/* List of noise reduction options. */
282
static SANE_String_Const noise_reduction_list[] = {
283
SANE_I18N ("default"),
292
/* Reset the options for that scanner. */
294
kvs40xx_init_options (struct scanner *s)
297
SANE_Option_Descriptor *o;
298
/* Pre-initialize the options. */
299
memset (s->opt, 0, sizeof (s->opt));
300
memset (s->val, 0, sizeof (s->val));
302
for (i = 0; i < NUM_OPTIONS; i++)
304
s->opt[i].size = sizeof (SANE_Word);
305
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
308
/* Number of options. */
309
o = &s->opt[NUM_OPTS];
311
o->title = SANE_TITLE_NUM_OPTIONS;
312
o->desc = SANE_DESC_NUM_OPTIONS;
313
o->type = SANE_TYPE_INT;
314
o->cap = SANE_CAP_SOFT_DETECT;
315
s->val[NUM_OPTS].w = NUM_OPTIONS;
318
o = &s->opt[MODE_GROUP];
319
o->title = SANE_I18N ("Scan Mode");
320
o->desc = ""; /* not valid for a group */
321
o->type = SANE_TYPE_GROUP;
324
o->constraint_type = SANE_CONSTRAINT_NONE;
326
/* Scanner supported modes */
328
o->name = SANE_NAME_SCAN_MODE;
329
o->title = SANE_TITLE_SCAN_MODE;
330
o->desc = SANE_DESC_SCAN_MODE;
331
o->type = SANE_TYPE_STRING;
332
o->size = max_string_size (mode_list);
333
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
334
o->constraint.string_list = mode_list;
335
s->val[MODE].s = malloc (o->size);
336
strcpy (s->val[MODE].s, mode_list[2]);
338
/* X and Y resolution */
339
o = &s->opt[RESOLUTION];
340
o->name = SANE_NAME_SCAN_RESOLUTION;
341
o->title = SANE_TITLE_SCAN_RESOLUTION;
342
o->desc = SANE_DESC_SCAN_RESOLUTION;
343
o->type = SANE_TYPE_INT;
344
o->unit = SANE_UNIT_DPI;
345
o->constraint_type = SANE_CONSTRAINT_RANGE;
346
o->constraint.range = &resolutions_range;
347
s->val[RESOLUTION].w = 100;
352
o->title = SANE_I18N ("Duplex");
353
o->desc = SANE_I18N ("Enable Duplex (Dual-Sided) Scanning");
354
o->type = SANE_TYPE_BOOL;
355
o->unit = SANE_UNIT_NONE;
356
s->val[DUPLEX].w = SANE_FALSE;
359
if (!s->support_info.support_duplex)
360
o->cap |= SANE_CAP_INACTIVE;
364
o = &s->opt[FEEDER_MODE];
365
o->name = "feeder-mode";
366
o->title = SANE_I18N ("Feeder mode");
367
o->desc = SANE_I18N ("Sets the feeding mode");
368
o->type = SANE_TYPE_STRING;
369
o->size = max_string_size (feeder_mode_list);
370
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
371
o->constraint.string_list = feeder_mode_list;
372
s->val[FEEDER_MODE].s = malloc (o->size);
373
strcpy (s->val[FEEDER_MODE].s, feeder_mode_list[0]);
377
o->name = SANE_NAME_SCAN_SOURCE;
378
o->title = SANE_TITLE_SCAN_SOURCE;
379
o->desc = SANE_DESC_SCAN_SOURCE;
380
o->type = SANE_TYPE_STRING;
381
o->size = max_string_size (source_list);
382
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
383
o->constraint.string_list = source_list;
384
s->val[SOURCE].s = malloc (o->size);
385
strcpy (s->val[SOURCE].s, source_list[0]);
386
if (s->id != KV_S7075C)
387
o->cap |= SANE_CAP_INACTIVE;
390
o = &s->opt[LENGTHCTL];
391
o->name = "length-control";
392
o->title = SANE_I18N ("Length control mode");
395
("Length Control Mode is a mode that the scanner reads up to the shorter length of actual"
396
" paper or logical document length.");
397
o->type = SANE_TYPE_BOOL;
398
o->unit = SANE_UNIT_NONE;
399
s->val[LENGTHCTL].w = SANE_FALSE;
401
o = &s->opt[LONG_PAPER];
402
o->name = "long-paper";
403
o->title = SANE_I18N ("Long paper mode");
404
o->desc = SANE_I18N ("Long Paper Mode is a mode that the scanner "
405
"reads the image after it divides long paper "
406
"by the length which is set in Document Size option.");
407
o->type = SANE_TYPE_BOOL;
408
o->unit = SANE_UNIT_NONE;
409
s->val[LONG_PAPER].w = SANE_FALSE;
410
o->cap |= SANE_CAP_INACTIVE;
413
o = &s->opt[MANUALFEED];
414
o->name = "manual-feed";
415
o->title = SANE_I18N ("Manual feed mode");
416
o->desc = SANE_I18N ("Sets the manual feed mode");
417
o->type = SANE_TYPE_STRING;
418
o->size = max_string_size (manual_feed_list);
419
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
420
o->constraint.string_list = manual_feed_list;
421
s->val[MANUALFEED].s = malloc (o->size);
422
strcpy (s->val[MANUALFEED].s, manual_feed_list[0]);
424
/*Manual feed timeout */
425
o = &s->opt[FEED_TIMEOUT];
426
o->name = "feed-timeout";
427
o->title = SANE_I18N ("Manual feed timeout");
428
o->desc = SANE_I18N ("Sets the manual feed timeout in seconds");
429
o->type = SANE_TYPE_INT;
430
o->unit = SANE_UNIT_NONE;
431
o->size = sizeof (SANE_Int);
432
o->constraint_type = SANE_CONSTRAINT_RANGE;
433
o->constraint.range = &(byte_value_range);
434
o->cap |= SANE_CAP_INACTIVE;
435
s->val[FEED_TIMEOUT].w = 30;
438
o = &s->opt[DBLFEED];
440
o->title = SANE_I18N ("Double feed detection");
441
o->desc = SANE_I18N ("Enable/Disable double feed detection");
442
o->type = SANE_TYPE_BOOL;
443
o->unit = SANE_UNIT_NONE;
444
s->val[DBLFEED].w = SANE_FALSE;
446
o = &s->opt[DFEED_SENCE];
447
o->name = "dfeed-sense";
448
o->title = SANE_I18N ("Double feed detector sensitivity");
449
o->desc = SANE_I18N ("Set the double feed detector sensitivity");
450
o->type = SANE_TYPE_STRING;
451
o->size = max_string_size (dfeed_sence_list);
452
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
453
o->constraint.string_list = dfeed_sence_list;
454
s->val[DFEED_SENCE].s = malloc (o->size);
455
strcpy (s->val[DFEED_SENCE].s, dfeed_sence_list[0]);
456
o->cap |= SANE_CAP_INACTIVE;
460
o->title = SANE_I18N ("Do not stop after double feed detection");
461
o->desc = SANE_I18N ("Do not stop after double feed detection");
462
o->type = SANE_TYPE_BOOL;
463
o->unit = SANE_UNIT_NONE;
464
s->val[DFSTOP].w = SANE_FALSE;
465
o->cap |= SANE_CAP_INACTIVE;
467
o = &s->opt[DFEED_L];
469
o->title = SANE_I18N ("Ignore left double feed sensor");
470
o->desc = SANE_I18N ("Ignore left double feed sensor");
471
o->type = SANE_TYPE_BOOL;
472
o->unit = SANE_UNIT_NONE;
473
s->val[DFEED_L].w = SANE_FALSE;
474
o->cap |= SANE_CAP_INACTIVE;
476
o = &s->opt[DFEED_C];
478
o->title = SANE_I18N ("Ignore center double feed sensor");
479
o->desc = SANE_I18N ("Ignore center double feed sensor");
480
o->type = SANE_TYPE_BOOL;
481
o->unit = SANE_UNIT_NONE;
482
s->val[DFEED_C].w = SANE_FALSE;
483
o->cap |= SANE_CAP_INACTIVE;
485
o = &s->opt[DFEED_R];
487
o->title = SANE_I18N ("Ignore right double feed sensor");
488
o->desc = SANE_I18N ("Ignore right double feed sensor");
489
o->type = SANE_TYPE_BOOL;
490
o->unit = SANE_UNIT_NONE;
491
s->val[DFEED_R].w = SANE_FALSE;
492
o->cap |= SANE_CAP_INACTIVE;
495
o = &s->opt[FIT_TO_PAGE];
496
o->name = SANE_I18N ("fit-to-page");
497
o->title = SANE_I18N ("Fit to page");
498
o->desc = SANE_I18N ("Scanner shrinks image to fit scanned page");
499
o->type = SANE_TYPE_BOOL;
500
o->unit = SANE_UNIT_NONE;
501
s->val[FIT_TO_PAGE].w = SANE_FALSE;
504
o = &s->opt[GEOMETRY_GROUP];
505
o->title = SANE_I18N ("Geometry");
506
o->desc = ""; /* not valid for a group */
507
o->type = SANE_TYPE_GROUP;
510
o->constraint_type = SANE_CONSTRAINT_NONE;
512
/* Paper sizes list */
513
o = &s->opt[PAPER_SIZE];
514
o->name = "paper-size";
515
o->title = SANE_I18N ("Paper size");
516
o->desc = SANE_I18N ("Physical size of the paper in the ADF");
517
o->type = SANE_TYPE_STRING;
518
o->constraint.string_list =
519
s->id == KV_S4085CL || s->id == KV_S4065CL ? paper_list_woA3 : paper_list;
522
o->size = max_string_size (o->constraint.string_list);
523
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
524
s->val[PAPER_SIZE].s = malloc (o->size);
525
strcpy (s->val[PAPER_SIZE].s, SANE_I18N ("A4"));
528
o = &s->opt[LANDSCAPE];
529
o->name = "landscape";
530
o->title = SANE_I18N ("Landscape");
532
SANE_I18N ("Set paper position : "
533
"true for landscape, false for portrait");
534
o->type = SANE_TYPE_BOOL;
535
o->unit = SANE_UNIT_NONE;
536
s->val[LANDSCAPE].w = SANE_FALSE;
540
o->name = SANE_NAME_SCAN_TL_X;
541
o->title = SANE_TITLE_SCAN_TL_X;
542
o->desc = SANE_DESC_SCAN_TL_X;
543
o->type = SANE_TYPE_INT;
544
o->unit = SANE_UNIT_MM;
545
o->constraint_type = SANE_CONSTRAINT_RANGE;
546
o->constraint.range =
547
(s->id == KV_S4085CL || s->id == KV_S4065CL)
548
? &tl_x_range_A4 : &tl_x_range;
549
o->cap |= SANE_CAP_INACTIVE;
554
o->name = SANE_NAME_SCAN_TL_Y;
555
o->title = SANE_TITLE_SCAN_TL_Y;
556
o->desc = SANE_DESC_SCAN_TL_Y;
557
o->type = SANE_TYPE_INT;
558
o->unit = SANE_UNIT_MM;
559
o->constraint_type = SANE_CONSTRAINT_RANGE;
560
o->constraint.range =
561
(s->id == KV_S4085CL || s->id == KV_S4065CL)
562
? &tl_y_range_A4 : &tl_y_range;
563
o->cap |= SANE_CAP_INACTIVE;
568
o->name = SANE_NAME_SCAN_BR_X;
569
o->title = SANE_TITLE_SCAN_BR_X;
570
o->desc = SANE_DESC_SCAN_BR_X;
571
o->type = SANE_TYPE_INT;
572
o->unit = SANE_UNIT_MM;
573
o->constraint_type = SANE_CONSTRAINT_RANGE;
574
o->constraint.range =
575
(s->id == KV_S4085CL || s->id == KV_S4065CL)
576
? &br_x_range_A4 : &br_x_range;
577
o->cap |= SANE_CAP_INACTIVE;
578
s->val[BR_X].w = 210;
582
o->name = SANE_NAME_SCAN_BR_Y;
583
o->title = SANE_TITLE_SCAN_BR_Y;
584
o->desc = SANE_DESC_SCAN_BR_Y;
585
o->type = SANE_TYPE_INT;
586
o->unit = SANE_UNIT_MM;
587
o->constraint_type = SANE_CONSTRAINT_RANGE;
588
o->constraint.range =
589
(s->id == KV_S4085CL || s->id == KV_S4065CL)
590
? &br_y_range_A4 : &br_y_range;
591
o->cap |= SANE_CAP_INACTIVE;
592
s->val[BR_Y].w = 297;
594
/* Enhancement group */
595
o = &s->opt[ADVANCED_GROUP];
596
o->title = SANE_I18N ("Advanced");
597
o->desc = ""; /* not valid for a group */
598
o->type = SANE_TYPE_GROUP;
599
o->cap = SANE_CAP_ADVANCED;
601
o->constraint_type = SANE_CONSTRAINT_NONE;
604
o = &s->opt[BRIGHTNESS];
605
o->name = SANE_NAME_BRIGHTNESS;
606
o->title = SANE_TITLE_BRIGHTNESS;
607
o->desc = SANE_DESC_BRIGHTNESS;
608
o->type = SANE_TYPE_INT;
609
o->unit = SANE_UNIT_NONE;
610
o->size = sizeof (SANE_Int);
611
o->constraint_type = SANE_CONSTRAINT_RANGE;
612
o->constraint.range = &(byte_value_range);
613
s->val[BRIGHTNESS].w = 128;
616
o = &s->opt[CONTRAST];
617
o->name = SANE_NAME_CONTRAST;
618
o->title = SANE_TITLE_CONTRAST;
619
o->desc = SANE_DESC_CONTRAST;
620
o->type = SANE_TYPE_INT;
621
o->unit = SANE_UNIT_NONE;
622
o->size = sizeof (SANE_Int);
623
o->constraint_type = SANE_CONSTRAINT_RANGE;
624
o->constraint.range = &(byte_value_range);
625
s->val[CONTRAST].w = 128;
628
o = &s->opt[THRESHOLD];
629
o->name = SANE_NAME_THRESHOLD;
630
o->title = SANE_TITLE_THRESHOLD;
631
o->desc = SANE_DESC_THRESHOLD;
632
o->type = SANE_TYPE_INT;
633
o->size = sizeof (SANE_Int);
634
o->constraint_type = SANE_CONSTRAINT_RANGE;
635
o->constraint.range = &(byte_value_range);
636
s->val[THRESHOLD].w = 128;
637
o->cap |= SANE_CAP_INACTIVE;
639
o = &s->opt[AUTOMATIC_THRESHOLD];
640
o->name = "athreshold";
641
o->title = SANE_I18N ("Automatic threshold mode");
642
o->desc = SANE_I18N ("Sets the automatic threshold mode");
643
o->type = SANE_TYPE_STRING;
644
o->size = max_string_size (automatic_threshold_list);
645
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
646
o->constraint.string_list = automatic_threshold_list;
647
s->val[AUTOMATIC_THRESHOLD].s = malloc (o->size);
648
strcpy (s->val[AUTOMATIC_THRESHOLD].s, automatic_threshold_list[0]);
649
o->cap |= SANE_CAP_INACTIVE;
652
o = &s->opt[IMAGE_EMPHASIS];
653
o->name = "image-emphasis";
654
o->title = SANE_I18N ("Image emphasis");
655
o->desc = SANE_I18N ("Sets the image emphasis");
656
o->type = SANE_TYPE_STRING;
657
o->size = max_string_size (image_emphasis_list);
658
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
659
o->constraint.string_list = image_emphasis_list;
660
s->val[IMAGE_EMPHASIS].s = malloc (o->size);
661
strcpy (s->val[IMAGE_EMPHASIS].s, image_emphasis_list[0]);;
662
o->cap |= SANE_CAP_INACTIVE;
665
o = &s->opt[GAMMA_CORRECTION];
666
o->name = "gamma-cor";
667
o->title = SANE_I18N ("Gamma correction");
668
o->desc = SANE_I18N ("Gamma correction");
669
o->type = SANE_TYPE_STRING;
670
o->size = max_string_size (gamma_list);
671
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
672
o->constraint.string_list = gamma_list;
673
s->val[GAMMA_CORRECTION].s = malloc (o->size);
674
strcpy (s->val[GAMMA_CORRECTION].s, gamma_list[0]);
675
o->cap |= SANE_CAP_INACTIVE;
677
/* Lamp color dropout */
679
o->name = "lamp-color";
680
o->title = SANE_I18N ("Lamp color");
681
o->desc = SANE_I18N ("Sets the lamp color (color dropout)");
682
o->type = SANE_TYPE_STRING;
683
o->size = max_string_size (lamp_list);
684
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
685
o->constraint.string_list = lamp_list;
686
s->val[LAMP].s = malloc (o->size);
687
strcpy (s->val[LAMP].s, lamp_list[0]);
690
o = &s->opt[INVERSE];
692
o->title = SANE_I18N ("Inverse Image");
693
o->desc = SANE_I18N ("Inverse image in B/W mode");
694
o->type = SANE_TYPE_BOOL;
695
o->unit = SANE_UNIT_NONE;
696
o->cap |= SANE_CAP_INACTIVE;
698
/* Halftone pattern */
699
o = &s->opt[HALFTONE_PATTERN];
700
o->name = SANE_NAME_HALFTONE_PATTERN;
701
o->title = SANE_TITLE_HALFTONE_PATTERN;
702
o->desc = SANE_DESC_HALFTONE_PATTERN;
703
o->type = SANE_TYPE_STRING;
704
o->size = max_string_size (halftone_pattern);
705
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
706
o->constraint.string_list = halftone_pattern;
707
s->val[HALFTONE_PATTERN].s = malloc (o->size);
708
strcpy (s->val[HALFTONE_PATTERN].s, halftone_pattern[0]);
709
o->cap |= SANE_CAP_INACTIVE;
711
/* JPEG Compression */
712
o = &s->opt[COMPRESSION];
714
o->title = SANE_I18N ("JPEG compression");
717
("JPEG compression (yours application must be able to uncompress)");
718
o->type = SANE_TYPE_BOOL;
719
o->unit = SANE_UNIT_NONE;
721
/* Compression parameter */
722
o = &s->opt[COMPRESSION_PAR];
723
o->name = "comp_arg";
724
o->title = "Compression Argument";
725
o->desc = "Compression Argument (Q parameter for JPEG)";
726
o->type = SANE_TYPE_INT;
727
o->size = sizeof (SANE_Int);
728
o->constraint_type = SANE_CONSTRAINT_RANGE;
729
o->constraint.range = &(compression_value_range);
730
s->val[COMPRESSION_PAR].w = 0x4b;
731
o->cap |= SANE_CAP_INACTIVE;
733
/* Stapled document */
734
o = &s->opt[STAPELED_DOC];
735
o->name = "stapeled_doc";
736
o->title = SANE_I18N ("Detect stapled document");
737
o->desc = SANE_I18N ("Detect stapled document");
738
o->type = SANE_TYPE_STRING;
739
o->size = max_string_size (stapeled_list);
740
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
741
o->constraint.string_list = stapeled_list;
742
s->val[STAPELED_DOC].s = malloc (o->size);
743
strcpy (s->val[STAPELED_DOC].s, stapeled_list[0]);
744
if (s->id == KV_S7075C)
745
o->cap |= SANE_CAP_INACTIVE;
747
/* White level base */
748
o = &s->opt[WHITE_LEVEL];
749
o->name = SANE_NAME_WHITE_LEVEL;
750
o->title = SANE_TITLE_WHITE_LEVEL;
751
o->desc = SANE_DESC_WHITE_LEVEL;
752
o->type = SANE_TYPE_STRING;
753
o->size = max_string_size (white_level_list);
754
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
755
o->constraint.string_list = white_level_list;
756
s->val[WHITE_LEVEL].s = malloc (o->size);
757
strcpy (s->val[WHITE_LEVEL].s, white_level_list[0]);
758
o->cap |= SANE_CAP_INACTIVE;
760
/* Noise reduction */
761
o = &s->opt[NOISE_REDUCTION];
762
o->name = "noise-reduction";
763
o->title = SANE_I18N ("Noise reduction");
764
o->desc = SANE_I18N ("Reduce the isolated dot noise");
765
o->type = SANE_TYPE_STRING;
766
o->size = max_string_size (noise_reduction_list);
767
o->constraint_type = SANE_CONSTRAINT_STRING_LIST;
768
o->constraint.string_list = noise_reduction_list;
769
s->val[NOISE_REDUCTION].s = malloc (o->size);
770
strcpy (s->val[NOISE_REDUCTION].s, noise_reduction_list[0]);
771
o->cap |= SANE_CAP_INACTIVE;
773
o = &s->opt[RED_CHROMA];
774
o->name = "red-chroma";
775
o->title = SANE_I18N ("chroma of red");
776
o->desc = SANE_I18N ("Set chroma of red");
777
o->type = SANE_TYPE_INT;
778
o->unit = SANE_UNIT_NONE;
779
o->size = sizeof (SANE_Int);
780
o->constraint_type = SANE_CONSTRAINT_RANGE;
781
o->constraint.range = &(byte_value_range);
782
s->val[RED_CHROMA].w = 0;
784
o = &s->opt[BLUE_CHROMA];
785
o->name = "blue chroma";
786
o->title = SANE_I18N ("chroma of blue");
787
o->desc = SANE_I18N ("Set chroma of blue");
788
o->type = SANE_TYPE_INT;
789
o->unit = SANE_UNIT_NONE;
790
o->size = sizeof (SANE_Int);
791
o->constraint_type = SANE_CONSTRAINT_RANGE;
792
o->constraint.range = &(byte_value_range);
793
s->val[BLUE_CHROMA].w = 0;
797
o->title = SANE_I18N ("Skew adjustment");
798
o->desc = SANE_I18N ("Skew adjustment");
799
o->type = SANE_TYPE_BOOL;
800
o->unit = SANE_UNIT_NONE;
801
s->val[DESKEW].w = SANE_FALSE;
802
if (s->id != KV_S4085CL && s->id != KV_S4085CW)
803
o->cap |= SANE_CAP_INACTIVE;
805
o = &s->opt[STOP_SKEW];
806
o->name = "stop-skew";
807
o->title = SANE_I18N ("Stop scanner when a paper have been skewed");
808
o->desc = SANE_I18N ("Scanner will be stop when a paper have been skewed");
809
o->type = SANE_TYPE_BOOL;
810
o->unit = SANE_UNIT_NONE;
811
s->val[STOP_SKEW].w = SANE_FALSE;
815
o->title = SANE_I18N ("Crop actual image area");
816
o->desc = SANE_I18N ("Scanner automatically detect image area and crop it");
817
o->type = SANE_TYPE_BOOL;
818
o->unit = SANE_UNIT_NONE;
819
s->val[CROP].w = SANE_FALSE;
820
if (s->id != KV_S4085CL && s->id != KV_S4085CW)
821
o->cap |= SANE_CAP_INACTIVE;
825
o->title = SANE_I18N ("Mirror image");
826
o->desc = SANE_I18N ("It is right and left reversing");
827
o->type = SANE_TYPE_BOOL;
828
o->unit = SANE_UNIT_NONE;
829
s->val[MIRROR].w = SANE_FALSE;
833
o->title = SANE_I18N ("Addition of space in top position");
834
o->desc = SANE_I18N ("Addition of space in top position");
835
o->type = SANE_TYPE_BOOL;
836
o->unit = SANE_UNIT_NONE;
837
s->val[TOPPOS].w = SANE_FALSE;
841
o->title = SANE_I18N ("Addition of space in bottom position");
842
o->desc = SANE_I18N ("Addition of space in bottom position");
843
o->type = SANE_TYPE_BOOL;
844
o->unit = SANE_UNIT_NONE;
845
s->val[BTMPOS].w = SANE_FALSE;
849
/* Lookup a string list from one array and return its index. */
851
str_index (const SANE_String_Const * list, SANE_String_Const name)
857
if (!strcmp (list[index], name))
861
return (-1); /* not found */
866
sane_control_option (SANE_Handle handle, SANE_Int option,
867
SANE_Action action, void *val, SANE_Int * info)
872
struct scanner *s = (struct scanner *) handle;
877
if (option < 0 || option >= NUM_OPTIONS)
878
return SANE_STATUS_UNSUPPORTED;
880
cap = s->opt[option].cap;
881
if (!SANE_OPTION_IS_ACTIVE (cap))
882
return SANE_STATUS_UNSUPPORTED;
884
if (action == SANE_ACTION_GET_VALUE)
886
if (s->opt[option].type == SANE_TYPE_STRING)
889
"sane_control_option: reading opt[%d] = %s\n",
890
option, s->val[option].s);
891
strcpy (val, s->val[option].s);
895
*(SANE_Word *) val = s->val[option].w;
897
"sane_control_option: reading opt[%d] = %d\n",
898
option, s->val[option].w);
900
return SANE_STATUS_GOOD;
903
else if (action == SANE_ACTION_SET_VALUE)
905
if (!SANE_OPTION_IS_SETTABLE (cap))
906
return SANE_STATUS_INVAL;
908
status = sanei_constrain_value (s->opt + option, val, info);
909
if (status != SANE_STATUS_GOOD)
912
if (s->opt[option].type == SANE_TYPE_STRING)
914
if (!strcmp (val, s->val[option].s))
915
return SANE_STATUS_GOOD;
917
"sane_control_option: writing opt[%d] = %s\n",
918
option, (SANE_String_Const) val);
922
if (*(SANE_Word *) val == s->val[option].w)
923
return SANE_STATUS_GOOD;
925
"sane_control_option: writing opt[%d] = %d\n",
926
option, *(SANE_Word *) val);
931
/* Side-effect options */
933
s->val[option].w = *(SANE_Word *) val;
935
*info |= SANE_INFO_RELOAD_PARAMS;
936
return SANE_STATUS_GOOD;
939
if ((*(SANE_Word *) val) + MIN_LENGTH <=
941
!check_area (s, s->val[TL_X].w, *(SANE_Word *) val,
942
s->val[BR_X].w, s->val[BR_Y].w))
944
s->val[option].w = *(SANE_Word *) val;
946
*info |= SANE_INFO_RELOAD_PARAMS;
949
*info |= SANE_INFO_INEXACT |
950
SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
951
return SANE_STATUS_GOOD;
953
if ((*(SANE_Word *) val) >=
954
s->val[TL_Y].w + MIN_LENGTH
955
&& !check_area (s, s->val[TL_X].w, s->val[TL_Y].w,
956
s->val[BR_X].w, *(SANE_Word *) val))
958
s->val[option].w = *(SANE_Word *) val;
960
*info |= SANE_INFO_RELOAD_PARAMS;
963
*info |= SANE_INFO_INEXACT |
964
SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
965
return SANE_STATUS_GOOD;
968
if ((*(SANE_Word *) val) + MIN_WIDTH <=
970
!check_area (s, *(SANE_Word *) val, s->val[TL_Y].w,
971
s->val[BR_X].w, s->val[BR_Y].w))
973
s->val[option].w = *(SANE_Word *) val;
975
*info |= SANE_INFO_RELOAD_PARAMS;
978
*info |= SANE_INFO_INEXACT |
979
SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
980
return SANE_STATUS_GOOD;
983
if (*(SANE_Word *) val >=
984
s->val[TL_X].w + MIN_WIDTH
985
&& !check_area (s, s->val[TL_X].w, s->val[TL_Y].w,
986
*(SANE_Word *) val, s->val[BR_Y].w))
988
s->val[option].w = *(SANE_Word *) val;
990
*info |= SANE_INFO_RELOAD_PARAMS;
993
*info |= SANE_INFO_INEXACT |
994
SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
995
return SANE_STATUS_GOOD;
998
s->val[option].w = *(SANE_Word *) val;
1000
*info |= SANE_INFO_RELOAD_PARAMS;
1001
return SANE_STATUS_GOOD;
1003
/* Side-effect free options */
1012
case COMPRESSION_PAR:
1025
s->val[option].w = *(SANE_Word *) val;
1026
return SANE_STATUS_GOOD;
1029
s->val[option].w = *(SANE_Word *) val;
1030
return kvs40xx_set_timeout (s, s->val[option].w);
1033
case IMAGE_EMPHASIS:
1034
case GAMMA_CORRECTION:
1036
case HALFTONE_PATTERN:
1038
case AUTOMATIC_THRESHOLD:
1040
case NOISE_REDUCTION:
1041
strcpy (s->val[option].s, val);
1042
return SANE_STATUS_GOOD;
1045
strcpy (s->val[option].s, val);
1046
if (strcmp (s->val[option].s, SANE_I18N ("adf")))
1048
strcpy (s->val[FEEDER_MODE].s, feeder_mode_list[0]);
1049
strcpy (s->val[MANUALFEED].s, manual_feed_list[0]);
1050
s->val[DUPLEX].w = SANE_FALSE;
1051
s->val[DBLFEED].w = SANE_FALSE;
1052
s->val[BTMPOS].w = SANE_FALSE;
1053
s->val[TOPPOS].w = SANE_FALSE;
1054
s->val[STOP_SKEW].w = SANE_FALSE;
1055
s->val[LENGTHCTL].w = SANE_FALSE;
1056
s->val[LONG_PAPER].w = SANE_FALSE;
1057
s->opt[FEEDER_MODE].cap |= SANE_CAP_INACTIVE;
1058
s->opt[MANUALFEED].cap |= SANE_CAP_INACTIVE;
1059
s->opt[DUPLEX].cap |= SANE_CAP_INACTIVE;
1060
s->opt[DBLFEED].cap |= SANE_CAP_INACTIVE;
1061
s->opt[BTMPOS].cap |= SANE_CAP_INACTIVE;
1062
s->opt[TOPPOS].cap |= SANE_CAP_INACTIVE;
1063
s->opt[STOP_SKEW].cap |= SANE_CAP_INACTIVE;
1064
s->opt[LENGTHCTL].cap |= SANE_CAP_INACTIVE;
1065
s->opt[LONG_PAPER].cap |= SANE_CAP_INACTIVE;
1069
s->opt[FEEDER_MODE].cap &= ~SANE_CAP_INACTIVE;
1070
s->opt[MANUALFEED].cap &= ~SANE_CAP_INACTIVE;
1071
s->opt[DUPLEX].cap &= ~SANE_CAP_INACTIVE;
1072
s->opt[DBLFEED].cap &= ~SANE_CAP_INACTIVE;
1073
s->opt[BTMPOS].cap &= ~SANE_CAP_INACTIVE;
1074
s->opt[TOPPOS].cap &= ~SANE_CAP_INACTIVE;
1075
s->opt[STOP_SKEW].cap &= ~SANE_CAP_INACTIVE;
1076
s->opt[LENGTHCTL].cap &= ~SANE_CAP_INACTIVE;
1077
s->opt[LONG_PAPER].cap &= ~SANE_CAP_INACTIVE;
1080
*info |= SANE_INFO_RELOAD_OPTIONS;
1082
return SANE_STATUS_GOOD;
1085
strcpy (s->val[option].s, val);
1086
if (strcmp (s->val[option].s, SANE_I18N ("continuous")))
1088
s->opt[LONG_PAPER].cap |= SANE_CAP_INACTIVE;
1092
s->opt[LONG_PAPER].cap &= ~SANE_CAP_INACTIVE;
1095
*info |= SANE_INFO_RELOAD_OPTIONS;
1097
return SANE_STATUS_GOOD;
1100
strcpy (s->val[option].s, val);
1101
if (!strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART))
1103
s->opt[GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
1104
s->opt[COMPRESSION].cap |= SANE_CAP_INACTIVE;
1105
s->opt[COMPRESSION_PAR].cap |= SANE_CAP_INACTIVE;
1106
s->opt[THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
1107
s->opt[HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
1109
s->opt[AUTOMATIC_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
1110
s->opt[WHITE_LEVEL].cap &= ~SANE_CAP_INACTIVE;
1111
s->opt[NOISE_REDUCTION].cap &= ~SANE_CAP_INACTIVE;
1112
s->opt[INVERSE].cap &= ~SANE_CAP_INACTIVE;
1113
s->opt[RED_CHROMA].cap |= SANE_CAP_INACTIVE;
1114
s->opt[BLUE_CHROMA].cap |= SANE_CAP_INACTIVE;
1118
s->opt[COMPRESSION].cap &= ~SANE_CAP_INACTIVE;
1119
s->opt[COMPRESSION_PAR].cap &= ~SANE_CAP_INACTIVE;
1121
s->opt[THRESHOLD].cap |= SANE_CAP_INACTIVE;
1122
s->opt[INVERSE].cap |= SANE_CAP_INACTIVE;
1123
s->opt[HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1125
s->opt[AUTOMATIC_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1126
s->opt[WHITE_LEVEL].cap |= SANE_CAP_INACTIVE;
1127
s->opt[NOISE_REDUCTION].cap |= SANE_CAP_INACTIVE;
1128
s->opt[RED_CHROMA].cap &= ~SANE_CAP_INACTIVE;
1129
s->opt[BLUE_CHROMA].cap &= ~SANE_CAP_INACTIVE;
1132
if (!strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY))
1134
s->opt[INVERSE].cap &= ~SANE_CAP_INACTIVE;
1136
s->opt[GAMMA_CORRECTION].cap &= ~SANE_CAP_INACTIVE;
1140
s->opt[GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
1144
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1146
return SANE_STATUS_GOOD;
1149
strcpy (s->val[option].s, val);
1150
if (strcmp (s->val[option].s, manual_feed_list[0]) == 0) /* off */
1151
s->opt[FEED_TIMEOUT].cap |= SANE_CAP_INACTIVE;
1153
s->opt[FEED_TIMEOUT].cap &= ~SANE_CAP_INACTIVE;
1155
*info |= SANE_INFO_RELOAD_OPTIONS;
1157
return SANE_STATUS_GOOD;
1160
strcpy (s->val[option].s, val);
1161
if (strcmp (s->val[option].s, stapeled_list[0]) == 0)
1163
s->opt[DBLFEED].cap &= ~SANE_CAP_INACTIVE;
1164
s->opt[DFSTOP].cap &= ~SANE_CAP_INACTIVE;
1165
s->opt[DFEED_L].cap &= ~SANE_CAP_INACTIVE;
1166
s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
1167
s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
1168
s->opt[DFEED_R].cap &= ~SANE_CAP_INACTIVE;
1169
s->opt[DFEED_SENCE].cap &= ~SANE_CAP_INACTIVE;
1173
s->opt[DBLFEED].cap |= SANE_CAP_INACTIVE;
1174
s->opt[DFSTOP].cap |= SANE_CAP_INACTIVE;
1175
s->opt[DFEED_L].cap |= SANE_CAP_INACTIVE;
1176
s->opt[DFEED_C].cap |= SANE_CAP_INACTIVE;
1177
s->opt[DFEED_R].cap |= SANE_CAP_INACTIVE;
1178
s->opt[DFEED_SENCE].cap |= SANE_CAP_INACTIVE;
1181
*info |= SANE_INFO_RELOAD_OPTIONS;
1183
return SANE_STATUS_GOOD;
1186
s->val[option].w = *(SANE_Word *) val;
1187
if (!s->val[option].b)
1189
s->opt[DFSTOP].cap |= SANE_CAP_INACTIVE;
1190
s->opt[DFEED_L].cap |= SANE_CAP_INACTIVE;
1191
s->opt[DFEED_C].cap |= SANE_CAP_INACTIVE;
1192
s->opt[DFEED_R].cap |= SANE_CAP_INACTIVE;
1193
s->opt[DFEED_SENCE].cap |= SANE_CAP_INACTIVE;
1197
s->opt[DFSTOP].cap &= ~SANE_CAP_INACTIVE;
1198
s->opt[DFEED_L].cap &= ~SANE_CAP_INACTIVE;
1199
s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
1200
s->opt[DFEED_C].cap &= ~SANE_CAP_INACTIVE;
1201
s->opt[DFEED_R].cap &= ~SANE_CAP_INACTIVE;
1202
s->opt[DFEED_SENCE].cap &= ~SANE_CAP_INACTIVE;
1205
*info |= SANE_INFO_RELOAD_OPTIONS;
1207
return SANE_STATUS_GOOD;
1210
strcpy (s->val[option].s, val);
1211
i = str_index (paper_list, s->val[option].s);
1216
s->opt[BR_X].cap &= s->opt[BR_Y].cap &= ~SANE_CAP_INACTIVE;
1217
s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
1218
s->val[LANDSCAPE].w = 0;
1224
s->opt[BR_X].cap |= s->opt[BR_Y].cap |= SANE_CAP_INACTIVE;
1225
if ( /*i == 4 || */ i == 5 || i == 6 /*XXX*/
1226
|| i == 10 || i == 11)
1227
{ /*A4, A5, A6, B5, B6 */
1228
if ((s->id == KV_S4085CL || s->id == KV_S4065CL)
1229
&& i == 4 && i == 10)
1231
s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
1232
s->val[LANDSCAPE].w = 0;
1235
s->opt[LANDSCAPE].cap &= ~SANE_CAP_INACTIVE;
1239
s->opt[LANDSCAPE].cap |= SANE_CAP_INACTIVE;
1240
s->val[LANDSCAPE].w = 0;
1244
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1246
return SANE_STATUS_GOOD;
1249
s->val[option].w = *(SANE_Word *) val;
1250
if (!s->val[option].b)
1252
s->opt[COMPRESSION_PAR].cap |= SANE_CAP_INACTIVE;
1256
s->opt[COMPRESSION_PAR].cap &= ~SANE_CAP_INACTIVE;
1259
*info |= SANE_INFO_RELOAD_OPTIONS;
1261
return SANE_STATUS_GOOD;
1266
return SANE_STATUS_UNSUPPORTED;
1270
kvs40xx_init_window (struct scanner *s, struct window *wnd, int wnd_id)
1272
int paper = str_index (paper_list, s->val[PAPER_SIZE].s), i;
1273
memset (wnd, 0, sizeof (struct window));
1274
*(u16 *) wnd->window_descriptor_block_length = cpu2be16 (66);
1276
wnd->window_identifier = wnd_id;
1277
*(u16 *) wnd->x_resolution = cpu2be16 (s->val[RESOLUTION].w);
1278
*(u16 *) wnd->y_resolution = cpu2be16 (s->val[RESOLUTION].w);
1281
*(u32 *) wnd->upper_left_x =
1282
cpu2be32 (mm2scanner_units (s->val[TL_X].w));
1283
*(u32 *) wnd->upper_left_y =
1284
cpu2be32 (mm2scanner_units (s->val[TL_Y].w));
1285
*(u32 *) wnd->document_width =
1286
cpu2be32 (mm2scanner_units (s->val[BR_X].w));
1287
*(u32 *) wnd->width =
1288
cpu2be32 (mm2scanner_units (s->val[BR_X].w - s->val[TL_X].w));
1289
*(u32 *) wnd->document_length = cpu2be32 (mm2scanner_units
1291
*(u32 *) wnd->length =
1292
cpu2be32 (mm2scanner_units (s->val[BR_Y].w - s->val[TL_Y].w));
1296
u32 w = cpu2be32 (mm2scanner_units (paper_sizes[paper].width));
1297
u32 h = cpu2be32 (mm2scanner_units (paper_sizes[paper].height));
1298
*(u32 *) wnd->upper_left_x = cpu2be32 (mm2scanner_units (0));
1299
*(u32 *) wnd->upper_left_y = cpu2be32 (mm2scanner_units (0));
1300
if (!s->val[LANDSCAPE].b)
1302
*(u32 *) wnd->document_width = *(u32 *) wnd->width = w;
1303
*(u32 *) wnd->document_length = *(u32 *) wnd->length = h;
1307
*(u32 *) wnd->document_width = *(u32 *) wnd->width = h;
1308
*(u32 *) wnd->document_length = *(u32 *) wnd->length = w;
1311
wnd->brightness = s->val[BRIGHTNESS].w;
1312
wnd->threshold = s->val[THRESHOLD].w;
1313
wnd->contrast = s->val[CONTRAST].w;
1314
wnd->image_composition = mode_val[str_index (mode_list, s->val[MODE].s)];
1315
wnd->bit_per_pixel = bps_val[str_index (mode_list, s->val[MODE].s)];
1317
*(u16 *) wnd->halftone_pattern =
1318
cpu2be16 (str_index (halftone_pattern, s->val[HALFTONE_PATTERN].s));
1320
wnd->rif_padding = s->val[INVERSE].b << 7;
1321
*(u16 *) wnd->bit_ordering = cpu2be16 (BIT_ORDERING);
1322
wnd->compression_type = s->val[COMPRESSION].b ? 0x81 : 0;
1323
wnd->compression_argument = s->val[COMPRESSION_PAR].w;
1325
wnd->vendor_unique_identifier = 0;
1326
wnd->nobuf_fstspeed_dfstop = str_index (source_list,
1327
s->val[SOURCE].s) << 7 |
1328
str_index (stapeled_list,
1329
s->val[STAPELED_DOC].s) << 5 |
1330
s->val[STOP_SKEW].b << 4 | s->val[CROP].b << 3 | s->val[DFSTOP].b << 0;
1332
wnd->mirror_image = s->val[MIRROR].b << 7 |
1333
s->val[DFEED_L].b << 2 | s->val[DFEED_C].b << 1 | s->val[DFEED_R].b << 0;
1334
wnd->image_emphasis = str_index (image_emphasis_list,
1335
s->val[IMAGE_EMPHASIS].s);
1336
wnd->gamma_correction = gamma_val[str_index (gamma_list,
1337
s->val[GAMMA_CORRECTION].s)];
1338
wnd->mcd_lamp_dfeed_sens =
1339
str_index (lamp_list, s->val[LAMP].s) << 4 |
1340
str_index (dfeed_sence_list, s->val[DFEED_SENCE].s);
1342
wnd->document_size = (paper != 0) << 7
1343
| s->val[LENGTHCTL].b << 6
1344
| s->val[LONG_PAPER].b << 5 | s->val[LANDSCAPE].b << 4 | paper_val[paper];
1346
wnd->ahead_deskew_dfeed_scan_area_fspeed_rshad =
1347
(s->val[DESKEW].b || s->val[CROP].b ? 2 : 0) << 5 | /*XXX*/
1348
s->val[DBLFEED].b << 4 | s->val[FIT_TO_PAGE].b << 2;
1349
wnd->continuous_scanning_pages =
1350
str_index (feeder_mode_list, s->val[FEEDER_MODE].s) ? 0xff : 0;
1351
wnd->automatic_threshold_mode = automatic_threshold_val
1352
[str_index (automatic_threshold_list, s->val[AUTOMATIC_THRESHOLD].s)];
1353
wnd->automatic_separation_mode = 0; /*Does not supported */
1354
wnd->standard_white_level_mode =
1355
white_level_val[str_index (white_level_list, s->val[WHITE_LEVEL].s)];
1356
wnd->b_wnr_noise_reduction =
1357
str_index (noise_reduction_list, s->val[NOISE_REDUCTION].s);
1359
i = str_index (manual_feed_list, s->val[MANUALFEED].s);
1360
wnd->mfeed_toppos_btmpos_dsepa_hsepa_dcont_rstkr = i << 6 |
1361
s->val[TOPPOS].b << 5 | s->val[BTMPOS].b << 4;
1363
wnd->red_chroma = s->val[RED_CHROMA].w;
1364
wnd->blue_chroma = s->val[BLUE_CHROMA].w;
1367
/* Get scan parameters */
1369
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1371
struct scanner *s = (struct scanner *) handle;
1372
SANE_Parameters *p = &s->params;
1376
unsigned w, h, res = s->val[RESOLUTION].w;
1377
unsigned i = str_index (paper_list,
1378
s->val[PAPER_SIZE].s);
1381
if (s->val[LANDSCAPE].b)
1383
w = paper_sizes[i].height;
1384
h = paper_sizes[i].width;
1388
w = paper_sizes[i].width;
1389
h = paper_sizes[i].height;
1394
w = s->val[BR_X].w - s->val[TL_X].w;
1395
h = s->val[BR_Y].w - s->val[TL_Y].w;
1397
p->pixels_per_line = w * res / 25.4 + .5;
1398
p->lines = h * res / 25.4 + .5;
1401
p->format = !strcmp (s->val[MODE].s,
1402
SANE_VALUE_SCAN_MODE_COLOR) ? SANE_FRAME_RGB :
1404
p->last_frame = SANE_TRUE;
1405
p->depth = bps_val[str_index (mode_list, s->val[MODE].s)];
1406
p->bytes_per_line = p->depth * p->pixels_per_line / 8;
1410
memcpy (params, p, sizeof (SANE_Parameters));
1411
s->side_size = p->bytes_per_line * p->lines;
1413
return SANE_STATUS_GOOD;