2
* epson2.c - SANE library for Epson scanners.
4
* Based on Kazuhiro Sasayama previous
5
* Work on epson.[ch] file from the SANE package.
6
* Please see those files for additional copyrights.
8
* Copyright (C) 2006-10 Tower Technologies
9
* Author: Alessandro Zummo <a.zummo@towertech.it>
11
* This file is part of the SANE package.
13
* This program is free software; you can redistribute it and/or
14
* modify it under the terms of the GNU General Public License as
15
* published by the Free Software Foundation, version 2.
18
#define EPSON2_VERSION 1
19
#define EPSON2_REVISION 0
20
#define EPSON2_BUILD 124
26
* 32 more network progression
31
* 17 setvalue, getvalue, control_option
33
* 15 e2_send, e2_recv calls
34
* 13 e2_cmd_info_block
37
* 10 more debug in ESC/I commands
38
* 9 ESC x/FS x in e2_send
43
* 3 status information
44
* 1 scanner info and capabilities
48
#include "sane/config.h"
61
#include <sys/types.h>
62
#ifdef HAVE_SYS_SOCKET_H
63
#include <sys/socket.h>
66
#include "sane/saneopts.h"
67
#include "sane/sanei_scsi.h"
68
#include "sane/sanei_usb.h"
69
#include "sane/sanei_pio.h"
70
#include "sane/sanei_tcp.h"
71
#include "sane/sanei_udp.h"
72
#include "sane/sanei_backend.h"
73
#include "sane/sanei_config.h"
75
#include "epson2-io.h"
76
#include "epson2-commands.h"
77
#include "epson2-ops.h"
79
#include "epson2_scsi.h"
80
#include "epson_usb.h"
81
#include "epson2_net.h"
84
* Definition of the mode_param struct, that is used to
85
* specify the valid parameters for the different scan modes.
87
* The depth variable gets updated when the bit depth is modified.
90
struct mode_param mode_params[] = {
97
static SANE_String_Const mode_list[] = {
98
SANE_VALUE_SCAN_MODE_LINEART,
99
SANE_VALUE_SCAN_MODE_GRAY,
100
SANE_VALUE_SCAN_MODE_COLOR,
102
SANE_I18N("Infrared"),
107
static const SANE_String_Const adf_mode_list[] = {
108
SANE_I18N("Simplex"),
113
/* Define the different scan sources */
115
#define FBF_STR SANE_I18N("Flatbed")
116
#define TPU_STR SANE_I18N("Transparency Unit")
117
#define TPU_STR2 SANE_I18N("TPU8x10")
118
#define ADF_STR SANE_I18N("Automatic Document Feeder")
121
* source list need one dummy entry (save device settings is crashing).
122
* NOTE: no const - this list gets created while exploring the capabilities
126
SANE_String_Const source_list[] = {
133
static const SANE_String_Const film_list[] = {
134
SANE_I18N("Positive Film"),
135
SANE_I18N("Negative Film"),
136
SANE_I18N("Positive Slide"),
137
SANE_I18N("Negative Slide"),
141
static const SANE_String_Const focus_list[] = {
142
SANE_I18N("Focus on glass"),
143
SANE_I18N("Focus 2.5mm above glass"),
147
#define HALFTONE_NONE 0x01
148
#define HALFTONE_TET 0x03
150
const int halftone_params[] = {
164
static const SANE_String_Const halftone_list[] = {
166
SANE_I18N("Halftone A (Hard Tone)"),
167
SANE_I18N("Halftone B (Soft Tone)"),
168
SANE_I18N("Halftone C (Net Screen)"),
172
static const SANE_String_Const halftone_list_4[] = {
174
SANE_I18N("Halftone A (Hard Tone)"),
175
SANE_I18N("Halftone B (Soft Tone)"),
176
SANE_I18N("Halftone C (Net Screen)"),
177
SANE_I18N("Dither A (4x4 Bayer)"),
178
SANE_I18N("Dither B (4x4 Spiral)"),
179
SANE_I18N("Dither C (4x4 Net Screen)"),
180
SANE_I18N("Dither D (8x4 Net Screen)"),
184
static const SANE_String_Const halftone_list_7[] = {
186
SANE_I18N("Halftone A (Hard Tone)"),
187
SANE_I18N("Halftone B (Soft Tone)"),
188
SANE_I18N("Halftone C (Net Screen)"),
189
SANE_I18N("Dither A (4x4 Bayer)"),
190
SANE_I18N("Dither B (4x4 Spiral)"),
191
SANE_I18N("Dither C (4x4 Net Screen)"),
192
SANE_I18N("Dither D (8x4 Net Screen)"),
193
SANE_I18N("Text Enhanced Technology"),
194
SANE_I18N("Download pattern A"),
195
SANE_I18N("Download pattern B"),
199
static const SANE_String_Const dropout_list[] = {
207
static const SANE_Bool correction_userdefined[] = {
213
static const SANE_String_Const correction_list[] = {
215
SANE_I18N("Built in CCT profile"),
216
SANE_I18N("User defined CCT profile"),
221
CORR_NONE, CORR_AUTO, CORR_USER
224
static const SANE_String_Const cct_mode_list[] = {
228
"Monochrome negatives",
234
CCT_AUTO, CCT_REFLECTIVE, CCT_COLORNEG, CCT_MONONEG,
240
* The A and B level scanners work differently than the D level scanners,
241
* therefore I define two different sets of arrays, plus one set of
242
* variables that get set to the actally used params and list arrays at runtime.
245
static int gamma_params_ab[] = {
253
static const SANE_String_Const gamma_list_ab[] = {
254
SANE_I18N("Default"),
255
SANE_I18N("User defined"),
256
SANE_I18N("High density printing"),
257
SANE_I18N("Low density printing"),
258
SANE_I18N("High contrast printing"),
262
static SANE_Bool gamma_userdefined_ab[] = {
270
static int gamma_params_d[] = {
275
static const SANE_String_Const gamma_list_d[] = {
276
SANE_I18N("User defined (Gamma=1.0)"),
277
SANE_I18N("User defined (Gamma=1.8)"),
281
static SANE_Bool gamma_userdefined_d[] = {
286
static SANE_Bool *gamma_userdefined;
290
* this is used for the FilmScan
291
* XXX Add APS loader support
294
static const SANE_String_Const bay_list[] = {
304
/* minimum, maximum, quantization */
305
static const SANE_Range u8_range = { 0, 255, 0 };
306
static const SANE_Range s8_range = { -127, 127, 0 };
307
static const SANE_Range fx_range = { SANE_FIX(-2.0), SANE_FIX(2.0), 0 };
309
static const SANE_Range outline_emphasis_range = { -2, 2, 0 };
313
* List of pointers to devices - will be dynamically allocated depending
314
* on the number of devices found.
316
static const SANE_Device **devlist;
319
/* Some utility functions */
322
max_string_size(const SANE_String_Const strings[])
324
size_t size, max_size = 0;
327
for (i = 0; strings[i]; i++) {
328
size = strlen(strings[i]) + 1;
335
static SANE_Status attach_one_usb(SANE_String_Const devname);
336
static SANE_Status attach_one_net(SANE_String_Const devname);
339
print_params(const SANE_Parameters params)
341
DBG(6, "params.format = %d\n", params.format);
342
DBG(6, "params.last_frame = %d\n", params.last_frame);
343
DBG(6, "params.bytes_per_line = %d\n", params.bytes_per_line);
344
DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
345
DBG(6, "params.lines = %d\n", params.lines);
346
DBG(6, "params.depth = %d\n", params.depth);
352
* Close the open scanner. Depending on the connection method, a different
353
* close function is called.
357
close_scanner(Epson_Scanner *s)
361
DBG(7, "%s: fd = %d\n", __func__, s->fd);
366
/* send a request_status. This toggles w_cmd_count and r_cmd_count */
368
esci_request_status(s, NULL);
370
/* request extended status. This toggles w_cmd_count only */
372
esci_request_extended_status(s, NULL, NULL);
374
if (s->hw->connection == SANE_EPSON_NET) {
375
sanei_epson_net_unlock(s);
376
sanei_tcp_close(s->fd);
377
} else if (s->hw->connection == SANE_EPSON_SCSI) {
378
sanei_scsi_close(s->fd);
379
} else if (s->hw->connection == SANE_EPSON_PIO) {
380
sanei_pio_close(s->fd);
381
} else if (s->hw->connection == SANE_EPSON_USB) {
382
sanei_usb_close(s->fd);
388
for (i = 0; i < LINES_SHUFFLE_MAX; i++) {
389
if (s->line_buffer[i] != NULL)
390
free(s->line_buffer[i]);
397
e2_network_discovery(void)
403
char *ip, *query = "EPSONP\x00\xff\x00\x00\x00\x00\x00\x00\x00";
404
unsigned char buf[76];
408
status = sanei_udp_open_broadcast(&fd);
409
if (status != SANE_STATUS_GOOD)
412
sanei_udp_write_broadcast(fd, 3289, (unsigned char *) query, 15);
414
DBG(5, "%s, sent discovery packet\n", __func__);
422
sanei_udp_set_nonblock(fd, SANE_TRUE);
423
while (select(fd + 1, &rfds, NULL, NULL, &to) > 0) {
424
if ((len = sanei_udp_recvfrom(fd, buf, 76, &ip)) == 76) {
425
DBG(5, " response from %s\n", ip);
427
/* minimal check, protocol unknown */
428
if (strncmp((char *) buf, "EPSON", 5) == 0)
433
DBG(5, "%s, end\n", __func__);
441
* Open the scanner device. Depending on the connection method,
442
* different open functions are called.
446
open_scanner(Epson_Scanner *s)
448
SANE_Status status = 0;
450
DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
453
DBG(5, "scanner is already open: fd = %d\n", s->fd);
454
return SANE_STATUS_GOOD; /* no need to open the scanner */
457
if (s->hw->connection == SANE_EPSON_NET) {
458
unsigned char buf[5];
460
/* device name has the form net:ipaddr */
461
status = sanei_tcp_open(&s->hw->sane.name[4], 1865, &s->fd);
462
if (status == SANE_STATUS_GOOD) {
470
setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
474
DBG(32, "awaiting welcome message\n");
476
/* the scanner sends a kind of welcome msg */
477
read = e2_recv(s, buf, 5, &status);
479
sanei_tcp_close(s->fd);
481
return SANE_STATUS_IO_ERROR;
484
DBG(32, "welcome message received, locking the scanner...\n");
486
/* lock the scanner for use by sane */
487
status = sanei_epson_net_lock(s);
488
if (status != SANE_STATUS_GOOD) {
489
DBG(1, "%s cannot lock scanner: %s\n", s->hw->sane.name,
490
sane_strstatus(status));
492
sanei_tcp_close(s->fd);
498
DBG(32, "scanner locked\n");
501
} else if (s->hw->connection == SANE_EPSON_SCSI)
502
status = sanei_scsi_open(s->hw->sane.name, &s->fd,
503
sanei_epson2_scsi_sense_handler,
505
else if (s->hw->connection == SANE_EPSON_PIO)
506
/* device name has the form pio:0xnnn */
507
status = sanei_pio_open(&s->hw->sane.name[4], &s->fd);
509
else if (s->hw->connection == SANE_EPSON_USB)
510
status = sanei_usb_open(s->hw->sane.name, &s->fd);
512
if (status == SANE_STATUS_ACCESS_DENIED) {
513
DBG(1, "please check that you have permissions on the device.\n");
514
DBG(1, "if this is a multi-function device with a printer,\n");
515
DBG(1, "disable any conflicting driver (like usblp).\n");
518
if (status != SANE_STATUS_GOOD)
519
DBG(1, "%s open failed: %s\n", s->hw->sane.name,
520
sane_strstatus(status));
522
DBG(5, "scanner opened\n");
527
static SANE_Status detect_scsi(struct Epson_Scanner *s)
530
struct Epson_Device *dev = s->hw;
532
char buf[INQUIRY_BUF_SIZE + 1];
533
size_t buf_size = INQUIRY_BUF_SIZE;
535
char *vendor = buf + 8;
536
char *model = buf + 16;
537
char *rev = buf + 32;
539
status = sanei_epson2_scsi_inquiry(s->fd, buf, &buf_size);
540
if (status != SANE_STATUS_GOOD) {
541
DBG(1, "%s: inquiry failed: %s\n", __func__,
542
sane_strstatus(status));
546
buf[INQUIRY_BUF_SIZE] = 0;
547
DBG(1, "inquiry data:\n");
548
DBG(1, " vendor : %.8s\n", vendor);
549
DBG(1, " model : %.16s\n", model);
550
DBG(1, " revision: %.4s\n", rev);
552
if (buf[0] != TYPE_PROCESSOR) {
553
DBG(1, "%s: device is not of processor type (%d)\n",
555
return SANE_STATUS_INVAL;
558
if (strncmp(vendor, "EPSON", 5) != 0) {
560
"%s: device doesn't look like an EPSON scanner\n",
562
return SANE_STATUS_INVAL;
565
if (strncmp(model, "SCANNER ", 8) != 0
566
&& strncmp(model, "FilmScan 200", 12) != 0
567
&& strncmp(model, "Perfection", 10) != 0
568
&& strncmp(model, "Expression", 10) != 0
569
&& strncmp(model, "GT", 2) != 0) {
570
DBG(1, "%s: this EPSON scanner is not supported\n",
572
return SANE_STATUS_INVAL;
575
if (strncmp(model, "FilmScan 200", 12) == 0) {
576
dev->sane.type = "film scanner";
577
e2_set_model(s, (unsigned char *) model, 12);
580
/* Issue a test unit ready SCSI command. The FilmScan 200
581
* requires it for a sort of "wake up". We might eventually
582
* get the return code and reissue it in case of failure.
584
sanei_epson2_scsi_test_unit_ready(s->fd);
586
return SANE_STATUS_GOOD;
590
detect_usb(struct Epson_Scanner *s, SANE_Bool assume_valid)
595
SANE_Bool is_valid = assume_valid;
597
/* if the sanei_usb_get_vendor_product call is not supported,
598
* then we just ignore this and rely on the user to config
599
* the correct device.
602
status = sanei_usb_get_vendor_product(s->fd, &vendor, &product);
603
if (status != SANE_STATUS_GOOD) {
604
DBG(1, "the device cannot be verified - will continue\n");
605
return SANE_STATUS_GOOD;
608
/* check the vendor ID to see if we are dealing with an EPSON device */
609
if (vendor != SANE_EPSON_VENDOR_ID) {
610
/* this is not a supported vendor ID */
611
DBG(1, "not an Epson device at %s (vendor id=0x%x)\n",
612
s->hw->sane.name, vendor);
613
return SANE_STATUS_INVAL;
616
numIds = sanei_epson_getNumberOfUSBProductIds();
619
/* check all known product IDs to verify that we know
621
while (i != numIds) {
622
if (product == sanei_epson_usb_product_ids[i]) {
623
is_valid = SANE_TRUE;
629
if (is_valid == SANE_FALSE) {
630
DBG(1, "the device at %s is not supported (product id=0x%x)\n",
631
s->hw->sane.name, product);
632
return SANE_STATUS_INVAL;
635
DBG(1, "found valid Epson scanner: 0x%x/0x%x (vendorID/productID)\n",
638
return SANE_STATUS_GOOD;
641
static int num_devices; /* number of scanners attached to backend */
642
static Epson_Device *first_dev; /* first EPSON scanner in list */
644
static struct Epson_Scanner *
645
scanner_create(struct Epson_Device *dev, SANE_Status *status)
647
struct Epson_Scanner *s;
649
s = malloc(sizeof(struct Epson_Scanner));
651
*status = SANE_STATUS_NO_MEM;
655
memset(s, 0x00, sizeof(struct Epson_Scanner));
663
static struct Epson_Scanner *
664
device_detect(const char *name, int type, SANE_Bool assume_valid, SANE_Status *status)
666
struct Epson_Scanner *s;
667
struct Epson_Device *dev;
669
/* try to find the device in our list */
670
for (dev = first_dev; dev; dev = dev->next) {
671
if (strcmp(dev->sane.name, name) == 0) {
673
/* the device might have been just probed,
676
if (dev->connection == SANE_EPSON_NET)
679
return scanner_create(dev, status);
683
if (type == SANE_EPSON_NODEV) {
684
*status = SANE_STATUS_INVAL;
688
/* alloc and clear our device structure */
689
dev = malloc(sizeof(*dev));
691
*status = SANE_STATUS_NO_MEM;
694
memset(dev, 0x00, sizeof(struct Epson_Device));
696
s = scanner_create(dev, status);
700
e2_dev_init(dev, name, type);
702
*status = open_scanner(s);
703
if (*status != SANE_STATUS_GOOD) {
708
/* from now on, close_scanner() must be called */
710
/* SCSI and USB requires special care */
711
if (dev->connection == SANE_EPSON_SCSI) {
713
*status = detect_scsi(s);
715
} else if (dev->connection == SANE_EPSON_USB) {
717
*status = detect_usb(s, assume_valid);
720
if (*status != SANE_STATUS_GOOD)
723
/* set name and model (if not already set) */
724
if (dev->model == NULL)
725
e2_set_model(s, (unsigned char *) "generic", 7);
727
dev->name = strdup(name);
728
dev->sane.name = dev->name;
731
*status = esci_reset(s);
732
if (*status != SANE_STATUS_GOOD)
735
*status = e2_discover_capabilities(s);
736
if (*status != SANE_STATUS_GOOD)
739
if (source_list[0] == NULL || dev->dpi_range.min == 0) {
740
DBG(1, "something is wrong in the discovery process, aborting.\n");
741
*status = SANE_STATUS_IO_ERROR;
745
e2_dev_post_init(dev);
747
*status = esci_reset(s);
748
if (*status != SANE_STATUS_GOOD)
751
DBG(1, "scanner model: %s\n", dev->model);
753
/* add this scanner to the device list */
756
dev->next = first_dev;
768
attach(const char *name, int type)
773
DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
775
s = device_detect(name, type, 0, &status);
784
attach_one_scsi(const char *dev)
786
DBG(7, "%s: dev = %s\n", __func__, dev);
787
return attach(dev, SANE_EPSON_SCSI);
791
attach_one_usb(const char *dev)
793
DBG(7, "%s: dev = %s\n", __func__, dev);
794
return attach(dev, SANE_EPSON_USB);
798
attach_one_net(const char *dev)
802
DBG(7, "%s: dev = %s\n", __func__, dev);
804
strcpy(name, "net:");
806
return attach(name, SANE_EPSON_NET);
810
attach_one_pio(const char *dev)
812
DBG(7, "%s: dev = %s\n", __func__, dev);
813
return attach(dev, SANE_EPSON_PIO);
817
attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
821
int len = strlen(line);
823
DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
825
if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
827
/* add the vendor and product IDs to the list of
828
known devices before we call the attach function */
830
int numIds = sanei_epson_getNumberOfUSBProductIds();
833
return SANE_STATUS_INVAL; /* this is not an EPSON device */
835
sanei_epson_usb_product_ids[numIds - 1] = product;
836
sanei_usb_attach_matching_devices(line, attach_one_usb);
838
} else if (strncmp(line, "usb", 3) == 0 && len == 3) {
842
numIds = sanei_epson_getNumberOfUSBProductIds();
844
for (i = 0; i < numIds; i++) {
845
sanei_usb_find_devices(0x4b8,
846
sanei_epson_usb_product_ids[i], attach_one_usb);
849
} else if (strncmp(line, "net", 3) == 0) {
851
/* remove the "net" sub string */
852
const char *name = sanei_config_skip_whitespace(line + 3);
854
if (strncmp(name, "autodiscovery", 13) == 0)
855
e2_network_discovery();
857
attach_one_net(name);
859
} else if (strncmp(line, "pio", 3) == 0) {
861
/* remove the "pio" sub string */
862
const char *name = sanei_config_skip_whitespace(line + 3);
864
attach_one_pio(name);
867
sanei_config_attach_matching_devices(line, attach_one_scsi);
870
return SANE_STATUS_GOOD;
876
Epson_Device *dev, *next;
878
DBG(5, "%s\n", __func__);
880
for (dev = first_dev; dev; dev = next) {
895
DBG(5, "%s\n", __func__);
899
sanei_configure_attach(EPSON2_CONFIG_FILE, NULL,
904
sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
907
DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
909
DBG(1, "epson2 backend, version %i.%i.%i\n",
910
EPSON2_VERSION, EPSON2_REVISION, EPSON2_BUILD);
912
if (version_code != NULL)
913
*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR,
918
return SANE_STATUS_GOOD;
921
/* Clean up the list of attached scanners. */
925
DBG(5, "%s\n", __func__);
930
sane_get_devices(const SANE_Device ***device_list, SANE_Bool __sane_unused__ local_only)
935
DBG(5, "%s\n", __func__);
939
devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
941
DBG(1, "out of memory (line %d)\n", __LINE__);
942
return SANE_STATUS_NO_MEM;
945
DBG(5, "%s - results:\n", __func__);
947
for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
948
DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
949
devlist[i] = &dev->sane;
954
*device_list = devlist;
956
return SANE_STATUS_GOOD;
960
init_options(Epson_Scanner *s)
964
for (i = 0; i < NUM_OPTIONS; i++) {
965
s->opt[i].size = sizeof(SANE_Word);
966
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
969
s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
970
s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
971
s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
972
s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
973
s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
975
/* "Scan Mode" group: */
977
s->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan Mode");
978
s->opt[OPT_MODE_GROUP].desc = "";
979
s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
980
s->opt[OPT_MODE_GROUP].cap = 0;
983
s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
984
s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
985
s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
986
s->opt[OPT_MODE].type = SANE_TYPE_STRING;
987
s->opt[OPT_MODE].size = max_string_size(mode_list);
988
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
989
s->opt[OPT_MODE].constraint.string_list = mode_list;
990
s->val[OPT_MODE].w = 0; /* Lineart */
992
/* disable infrared on unsupported scanners */
993
if (!e2_model(s, "GT-X800") && !e2_model(s, "GT-X700") && !e2_model(s, "GT-X900"))
994
mode_list[MODE_INFRARED] = NULL;
997
s->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
998
s->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
999
s->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
1000
s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
1001
s->opt[OPT_BIT_DEPTH].unit = SANE_UNIT_BIT;
1002
s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1003
s->opt[OPT_BIT_DEPTH].constraint.word_list = s->hw->depth_list;
1004
s->val[OPT_BIT_DEPTH].w = 8; /* default to 8 bit */
1006
/* default is Lineart, disable depth selection */
1007
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
1010
s->opt[OPT_HALFTONE].name = SANE_NAME_HALFTONE;
1011
s->opt[OPT_HALFTONE].title = SANE_TITLE_HALFTONE;
1012
s->opt[OPT_HALFTONE].desc = SANE_I18N("Selects the halftone.");
1014
s->opt[OPT_HALFTONE].type = SANE_TYPE_STRING;
1015
s->opt[OPT_HALFTONE].size = max_string_size(halftone_list_7);
1016
s->opt[OPT_HALFTONE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1018
/* XXX use defines */
1019
if (s->hw->level >= 7)
1020
s->opt[OPT_HALFTONE].constraint.string_list = halftone_list_7;
1021
else if (s->hw->level >= 4)
1022
s->opt[OPT_HALFTONE].constraint.string_list = halftone_list_4;
1024
s->opt[OPT_HALFTONE].constraint.string_list = halftone_list;
1026
s->val[OPT_HALFTONE].w = 1; /* Halftone A */
1028
if (!s->hw->cmd->set_halftoning)
1029
s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
1032
s->opt[OPT_DROPOUT].name = "dropout";
1033
s->opt[OPT_DROPOUT].title = SANE_I18N("Dropout");
1034
s->opt[OPT_DROPOUT].desc = SANE_I18N("Selects the dropout.");
1036
s->opt[OPT_DROPOUT].type = SANE_TYPE_STRING;
1037
s->opt[OPT_DROPOUT].size = max_string_size(dropout_list);
1038
s->opt[OPT_DROPOUT].cap |= SANE_CAP_ADVANCED;
1039
s->opt[OPT_DROPOUT].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1040
s->opt[OPT_DROPOUT].constraint.string_list = dropout_list;
1041
s->val[OPT_DROPOUT].w = 0; /* None */
1044
s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
1045
s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
1046
s->opt[OPT_BRIGHTNESS].desc = SANE_I18N("Selects the brightness.");
1048
s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
1049
s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
1050
s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
1051
s->opt[OPT_BRIGHTNESS].constraint.range = &s->hw->cmd->bright_range;
1052
s->val[OPT_BRIGHTNESS].w = 0; /* Normal */
1054
if (!s->hw->cmd->set_bright)
1055
s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
1058
s->opt[OPT_SHARPNESS].name = "sharpness";
1059
s->opt[OPT_SHARPNESS].title = SANE_I18N("Sharpness");
1060
s->opt[OPT_SHARPNESS].desc = "";
1062
s->opt[OPT_SHARPNESS].type = SANE_TYPE_INT;
1063
s->opt[OPT_SHARPNESS].unit = SANE_UNIT_NONE;
1064
s->opt[OPT_SHARPNESS].constraint_type = SANE_CONSTRAINT_RANGE;
1065
s->opt[OPT_SHARPNESS].constraint.range = &outline_emphasis_range;
1066
s->val[OPT_SHARPNESS].w = 0; /* Normal */
1068
if (!s->hw->cmd->set_outline_emphasis)
1069
s->opt[OPT_SHARPNESS].cap |= SANE_CAP_INACTIVE;
1072
s->opt[OPT_GAMMA_CORRECTION].name = SANE_NAME_GAMMA_CORRECTION;
1073
s->opt[OPT_GAMMA_CORRECTION].title = SANE_TITLE_GAMMA_CORRECTION;
1074
s->opt[OPT_GAMMA_CORRECTION].desc = SANE_DESC_GAMMA_CORRECTION;
1076
s->opt[OPT_GAMMA_CORRECTION].type = SANE_TYPE_STRING;
1077
s->opt[OPT_GAMMA_CORRECTION].constraint_type =
1078
SANE_CONSTRAINT_STRING_LIST;
1081
* special handling for D1 function level - at this time I'm not
1082
* testing for D1, I'm just assuming that all D level scanners will
1083
* behave the same way. This has to be confirmed with the next D-level
1086
if (s->hw->cmd->level[0] == 'D') {
1087
s->opt[OPT_GAMMA_CORRECTION].size =
1088
max_string_size(gamma_list_d);
1089
s->opt[OPT_GAMMA_CORRECTION].constraint.string_list =
1091
s->val[OPT_GAMMA_CORRECTION].w = 1; /* Default */
1092
gamma_userdefined = gamma_userdefined_d;
1093
gamma_params = gamma_params_d;
1095
s->opt[OPT_GAMMA_CORRECTION].size =
1096
max_string_size(gamma_list_ab);
1097
s->opt[OPT_GAMMA_CORRECTION].constraint.string_list =
1099
s->val[OPT_GAMMA_CORRECTION].w = 0; /* Default */
1100
gamma_userdefined = gamma_userdefined_ab;
1101
gamma_params = gamma_params_ab;
1104
if (!s->hw->cmd->set_gamma)
1105
s->opt[OPT_GAMMA_CORRECTION].cap |= SANE_CAP_INACTIVE;
1107
/* red gamma vector */
1108
s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1109
s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1110
s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1112
s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1113
s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1114
s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof(SANE_Word);
1115
s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1116
s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
1117
s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[0][0];
1119
/* green gamma vector */
1120
s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1121
s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1122
s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1124
s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1125
s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1126
s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof(SANE_Word);
1127
s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1128
s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
1129
s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[1][0];
1132
/* red gamma vector */
1133
s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1134
s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1135
s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1137
s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1138
s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1139
s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof(SANE_Word);
1140
s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1141
s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
1142
s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[2][0];
1144
if (s->hw->cmd->set_gamma_table
1145
&& gamma_userdefined[s->val[OPT_GAMMA_CORRECTION].w] ==
1148
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1149
s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1150
s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1153
s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1154
s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1155
s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1158
/* initialize the Gamma tables */
1159
memset(&s->gamma_table[0], 0, 256 * sizeof(SANE_Word));
1160
memset(&s->gamma_table[1], 0, 256 * sizeof(SANE_Word));
1161
memset(&s->gamma_table[2], 0, 256 * sizeof(SANE_Word));
1163
/* memset(&s->gamma_table[3], 0, 256 * sizeof(SANE_Word)); */
1164
for (i = 0; i < 256; i++) {
1165
s->gamma_table[0][i] = i;
1166
s->gamma_table[1][i] = i;
1167
s->gamma_table[2][i] = i;
1169
/* s->gamma_table[3][i] = i; */
1173
/* color correction */
1174
s->opt[OPT_COLOR_CORRECTION].name = "color-correction";
1175
s->opt[OPT_COLOR_CORRECTION].title = SANE_I18N("Color correction");
1176
s->opt[OPT_COLOR_CORRECTION].desc =
1177
SANE_I18N("Sets the color correction table for the selected output device.");
1179
s->opt[OPT_COLOR_CORRECTION].type = SANE_TYPE_STRING;
1180
s->opt[OPT_COLOR_CORRECTION].size = max_string_size(correction_list);
1181
s->opt[OPT_COLOR_CORRECTION].cap |= SANE_CAP_ADVANCED;
1182
s->opt[OPT_COLOR_CORRECTION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1183
s->opt[OPT_COLOR_CORRECTION].constraint.string_list = correction_list;
1184
s->val[OPT_COLOR_CORRECTION].w = CORR_AUTO;
1186
if (!s->hw->cmd->set_color_correction)
1187
s->opt[OPT_COLOR_CORRECTION].cap |= SANE_CAP_INACTIVE;
1190
s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1191
s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1192
s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1194
s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1195
s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1196
s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1197
s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->resolution_list;
1198
s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
1201
s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1202
s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1203
s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1205
s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
1206
s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
1207
s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1208
s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
1209
s->val[OPT_THRESHOLD].w = 0x80;
1211
if (!s->hw->cmd->set_threshold)
1212
s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1215
/* "Advanced" group: */
1216
s->opt[OPT_ADVANCED_GROUP].title = SANE_I18N("Advanced");
1217
s->opt[OPT_ADVANCED_GROUP].desc = "";
1218
s->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
1219
s->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED;
1221
/* "Color correction" group: */
1222
s->opt[OPT_CCT_GROUP].title = SANE_I18N("Color correction");
1223
s->opt[OPT_CCT_GROUP].desc = "";
1224
s->opt[OPT_CCT_GROUP].type = SANE_TYPE_GROUP;
1225
s->opt[OPT_CCT_GROUP].cap = SANE_CAP_ADVANCED;
1227
/* XXX disabled for now */
1228
s->opt[OPT_CCT_MODE].name = "cct-type";
1229
s->opt[OPT_CCT_MODE].title = "CCT Profile Type";
1230
s->opt[OPT_CCT_MODE].desc = "Color correction profile type";
1231
s->opt[OPT_CCT_MODE].type = SANE_TYPE_STRING;
1232
s->opt[OPT_CCT_MODE].cap |= SANE_CAP_ADVANCED | SANE_CAP_INACTIVE;
1233
s->opt[OPT_CCT_MODE].size = max_string_size(cct_mode_list);
1234
s->opt[OPT_CCT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1235
s->opt[OPT_CCT_MODE].constraint.string_list = cct_mode_list;
1236
s->val[OPT_CCT_MODE].w = CCT_AUTO;
1238
s->opt[OPT_CCT_PROFILE].name = "cct-profile";
1239
s->opt[OPT_CCT_PROFILE].title = "CCT Profile";
1240
s->opt[OPT_CCT_PROFILE].desc = "Color correction profile data";
1241
s->opt[OPT_CCT_PROFILE].type = SANE_TYPE_FIXED;
1242
s->opt[OPT_CCT_PROFILE].cap |= SANE_CAP_ADVANCED;
1243
s->opt[OPT_CCT_PROFILE].unit = SANE_UNIT_NONE;
1244
s->opt[OPT_CCT_PROFILE].constraint_type = SANE_CONSTRAINT_RANGE;
1245
s->opt[OPT_CCT_PROFILE].constraint.range = &fx_range;
1246
s->opt[OPT_CCT_PROFILE].size = 9 * sizeof(SANE_Word);
1247
s->val[OPT_CCT_PROFILE].wa = s->cct_table;
1249
/* if (!s->hw->cmd->set_color_correction)
1250
s->opt[OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE;
1254
s->opt[OPT_MIRROR].name = "mirror";
1255
s->opt[OPT_MIRROR].title = SANE_I18N("Mirror image");
1256
s->opt[OPT_MIRROR].desc = SANE_I18N("Mirror the image.");
1258
s->opt[OPT_MIRROR].type = SANE_TYPE_BOOL;
1259
s->val[OPT_MIRROR].w = SANE_FALSE;
1261
if (!s->hw->cmd->mirror_image)
1262
s->opt[OPT_MIRROR].cap |= SANE_CAP_INACTIVE;
1264
/* auto area segmentation */
1265
s->opt[OPT_AAS].name = "auto-area-segmentation";
1266
s->opt[OPT_AAS].title = SANE_I18N("Auto area segmentation");
1267
s->opt[OPT_AAS].desc =
1268
"Enables different dithering modes in image and text areas";
1270
s->opt[OPT_AAS].type = SANE_TYPE_BOOL;
1271
s->val[OPT_AAS].w = SANE_TRUE;
1273
if (!s->hw->cmd->control_auto_area_segmentation)
1274
s->opt[OPT_AAS].cap |= SANE_CAP_INACTIVE;
1276
/* "Preview settings" group: */
1277
s->opt[OPT_PREVIEW_GROUP].title = SANE_TITLE_PREVIEW;
1278
s->opt[OPT_PREVIEW_GROUP].desc = "";
1279
s->opt[OPT_PREVIEW_GROUP].type = SANE_TYPE_GROUP;
1280
s->opt[OPT_PREVIEW_GROUP].cap = SANE_CAP_ADVANCED;
1283
s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1284
s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1285
s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1287
s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1288
s->val[OPT_PREVIEW].w = SANE_FALSE;
1290
/* "Geometry" group: */
1291
s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
1292
s->opt[OPT_GEOMETRY_GROUP].desc = "";
1293
s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1294
s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1297
s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1298
s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1299
s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1301
s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1302
s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1303
s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1304
s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
1305
s->val[OPT_TL_X].w = 0;
1308
s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1309
s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1310
s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1312
s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1313
s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1314
s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1315
s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
1316
s->val[OPT_TL_Y].w = 0;
1318
/* bottom-right x */
1319
s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1320
s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1321
s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1323
s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1324
s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1325
s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1326
s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
1327
s->val[OPT_BR_X].w = s->hw->x_range->max;
1329
/* bottom-right y */
1330
s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1331
s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1332
s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1334
s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1335
s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1336
s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1337
s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
1338
s->val[OPT_BR_Y].w = s->hw->y_range->max;
1340
/* "Optional equipment" group: */
1341
s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment");
1342
s->opt[OPT_EQU_GROUP].desc = "";
1343
s->opt[OPT_EQU_GROUP].type = SANE_TYPE_GROUP;
1344
s->opt[OPT_EQU_GROUP].cap = SANE_CAP_ADVANCED;
1347
s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
1348
s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
1349
s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
1351
s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
1352
s->opt[OPT_SOURCE].size = max_string_size(source_list);
1354
s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1355
s->opt[OPT_SOURCE].constraint.string_list = source_list;
1357
if (!s->hw->extension)
1358
s->opt[OPT_SOURCE].cap |= SANE_CAP_INACTIVE;
1360
s->val[OPT_SOURCE].w = 0; /* always use Flatbed as default */
1364
s->opt[OPT_FILM_TYPE].name = "film-type";
1365
s->opt[OPT_FILM_TYPE].title = SANE_I18N("Film type");
1366
s->opt[OPT_FILM_TYPE].desc = "";
1367
s->opt[OPT_FILM_TYPE].type = SANE_TYPE_STRING;
1368
s->opt[OPT_FILM_TYPE].size = max_string_size(film_list);
1369
s->opt[OPT_FILM_TYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1370
s->opt[OPT_FILM_TYPE].constraint.string_list = film_list;
1371
s->val[OPT_FILM_TYPE].w = 0;
1373
if (!s->hw->cmd->set_bay)
1374
s->opt[OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE;
1376
/* focus position */
1377
s->opt[OPT_FOCUS].name = SANE_EPSON_FOCUS_NAME;
1378
s->opt[OPT_FOCUS].title = SANE_EPSON_FOCUS_TITLE;
1379
s->opt[OPT_FOCUS].desc = SANE_EPSON_FOCUS_DESC;
1380
s->opt[OPT_FOCUS].type = SANE_TYPE_STRING;
1381
s->opt[OPT_FOCUS].size = max_string_size(focus_list);
1382
s->opt[OPT_FOCUS].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1383
s->opt[OPT_FOCUS].constraint.string_list = focus_list;
1384
s->val[OPT_FOCUS].w = 0;
1385
s->opt[OPT_FOCUS].cap |= SANE_CAP_ADVANCED;
1387
if (s->hw->focusSupport == SANE_TRUE)
1388
s->opt[OPT_FOCUS].cap &= ~SANE_CAP_INACTIVE;
1390
s->opt[OPT_FOCUS].cap |= SANE_CAP_INACTIVE;
1392
/* forward feed / eject */
1393
s->opt[OPT_EJECT].name = "eject";
1394
s->opt[OPT_EJECT].title = SANE_I18N("Eject");
1395
s->opt[OPT_EJECT].desc = SANE_I18N("Eject the sheet in the ADF");
1396
s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
1398
if ((!s->hw->ADF) && (!s->hw->cmd->set_bay)) { /* Hack: Using set_bay to indicate. */
1399
s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
1403
/* auto forward feed / eject */
1404
s->opt[OPT_AUTO_EJECT].name = "auto-eject";
1405
s->opt[OPT_AUTO_EJECT].title = SANE_I18N("Auto eject");
1406
s->opt[OPT_AUTO_EJECT].desc =
1407
SANE_I18N("Eject document after scanning");
1409
s->opt[OPT_AUTO_EJECT].type = SANE_TYPE_BOOL;
1410
s->val[OPT_AUTO_EJECT].w = SANE_FALSE;
1413
s->opt[OPT_AUTO_EJECT].cap |= SANE_CAP_INACTIVE;
1416
s->opt[OPT_ADF_MODE].name = "adf-mode";
1417
s->opt[OPT_ADF_MODE].title = SANE_I18N("ADF Mode");
1418
s->opt[OPT_ADF_MODE].desc =
1419
SANE_I18N("Selects the ADF mode (simplex/duplex)");
1420
s->opt[OPT_ADF_MODE].type = SANE_TYPE_STRING;
1421
s->opt[OPT_ADF_MODE].size = max_string_size(adf_mode_list);
1422
s->opt[OPT_ADF_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1423
s->opt[OPT_ADF_MODE].constraint.string_list = adf_mode_list;
1424
s->val[OPT_ADF_MODE].w = 0; /* simplex */
1426
if ((!s->hw->ADF) || (s->hw->duplex == SANE_FALSE))
1427
s->opt[OPT_ADF_MODE].cap |= SANE_CAP_INACTIVE;
1430
s->opt[OPT_BAY].name = "bay";
1431
s->opt[OPT_BAY].title = SANE_I18N("Bay");
1432
s->opt[OPT_BAY].desc = SANE_I18N("Select bay to scan");
1433
s->opt[OPT_BAY].type = SANE_TYPE_STRING;
1434
s->opt[OPT_BAY].size = max_string_size(bay_list);
1435
s->opt[OPT_BAY].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1436
s->opt[OPT_BAY].constraint.string_list = bay_list;
1437
s->val[OPT_BAY].w = 0; /* Bay 1 */
1439
if (!s->hw->cmd->set_bay)
1440
s->opt[OPT_BAY].cap |= SANE_CAP_INACTIVE;
1443
s->opt[OPT_WAIT_FOR_BUTTON].name = SANE_EPSON_WAIT_FOR_BUTTON_NAME;
1444
s->opt[OPT_WAIT_FOR_BUTTON].title = SANE_EPSON_WAIT_FOR_BUTTON_TITLE;
1445
s->opt[OPT_WAIT_FOR_BUTTON].desc = SANE_EPSON_WAIT_FOR_BUTTON_DESC;
1447
s->opt[OPT_WAIT_FOR_BUTTON].type = SANE_TYPE_BOOL;
1448
s->opt[OPT_WAIT_FOR_BUTTON].unit = SANE_UNIT_NONE;
1449
s->opt[OPT_WAIT_FOR_BUTTON].constraint_type = SANE_CONSTRAINT_NONE;
1450
s->opt[OPT_WAIT_FOR_BUTTON].constraint.range = NULL;
1451
s->opt[OPT_WAIT_FOR_BUTTON].cap |= SANE_CAP_ADVANCED;
1453
if (!s->hw->cmd->request_push_button_status)
1454
s->opt[OPT_WAIT_FOR_BUTTON].cap |= SANE_CAP_INACTIVE;
1456
return SANE_STATUS_GOOD;
1460
sane_open(SANE_String_Const name, SANE_Handle *handle)
1463
Epson_Scanner *s = NULL;
1465
int l = strlen(name);
1467
DBG(7, "%s: name = %s\n", __func__, name);
1471
/* probe if empty device name provided */
1476
if (first_dev == NULL) {
1477
DBG(1, "no device detected\n");
1478
return SANE_STATUS_INVAL;
1481
s = device_detect(first_dev->sane.name, first_dev->connection,
1484
DBG(1, "cannot open a perfectly valid device (%s),"
1485
" please report to the authors\n", name);
1486
return SANE_STATUS_INVAL;
1491
if (strncmp(name, "net:", 4) == 0) {
1492
s = device_detect(name, SANE_EPSON_NET, 0, &status);
1495
} else if (strncmp(name, "libusb:", 7) == 0) {
1496
s = device_detect(name, SANE_EPSON_USB, 1, &status);
1499
} else if (strncmp(name, "pio:", 4) == 0) {
1500
s = device_detect(name, SANE_EPSON_PIO, 0, &status);
1505
/* as a last resort, check for a match
1506
* in the device list. This should handle SCSI
1507
* devices and platforms without libusb.
1510
if (first_dev == NULL)
1513
s = device_detect(name, SANE_EPSON_NODEV, 0, &status);
1515
DBG(1, "invalid device name: %s\n", name);
1516
return SANE_STATUS_INVAL;
1522
/* s is always valid here */
1524
DBG(1, "handle obtained\n");
1528
status = open_scanner(s);
1529
if (status != SANE_STATUS_GOOD) {
1534
status = esci_reset(s);
1535
if (status != SANE_STATUS_GOOD) {
1540
*handle = (SANE_Handle)s;
1542
return SANE_STATUS_GOOD;
1546
sane_close(SANE_Handle handle)
1550
DBG(1, "* %s\n", __func__);
1553
* XXX Test if there is still data pending from
1554
* the scanner. If so, then do a cancel
1557
s = (Epson_Scanner *) handle;
1562
const SANE_Option_Descriptor *
1563
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
1565
Epson_Scanner *s = (Epson_Scanner *) handle;
1567
if (option < 0 || option >= NUM_OPTIONS)
1570
return s->opt + option;
1573
static const SANE_String_Const *
1574
search_string_list(const SANE_String_Const *list, SANE_String value)
1576
while (*list != NULL && strcmp(value, *list) != 0)
1579
return ((*list == NULL) ? NULL : list);
1583
Activate, deactivate an option. Subroutines so we can add
1584
debugging info if we want. The change flag is set to TRUE
1585
if we changed an option. If we did not change an option,
1586
then the value of the changed flag is not modified.
1590
activateOption(Epson_Scanner *s, SANE_Int option, SANE_Bool *change)
1592
if (!SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) {
1593
s->opt[option].cap &= ~SANE_CAP_INACTIVE;
1594
*change = SANE_TRUE;
1599
deactivateOption(Epson_Scanner *s, SANE_Int option, SANE_Bool *change)
1601
if (SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) {
1602
s->opt[option].cap |= SANE_CAP_INACTIVE;
1603
*change = SANE_TRUE;
1608
setOptionState(Epson_Scanner *s, SANE_Bool state, SANE_Int option,
1612
activateOption(s, option, change);
1614
deactivateOption(s, option, change);
1618
getvalue(SANE_Handle handle, SANE_Int option, void *value)
1620
Epson_Scanner *s = (Epson_Scanner *) handle;
1621
SANE_Option_Descriptor *sopt = &(s->opt[option]);
1622
Option_Value *sval = &(s->val[option]);
1624
DBG(17, "%s: option = %d\n", __func__, option);
1628
case OPT_GAMMA_VECTOR_R:
1629
case OPT_GAMMA_VECTOR_G:
1630
case OPT_GAMMA_VECTOR_B:
1631
case OPT_CCT_PROFILE:
1632
memcpy(value, sval->wa, sopt->size);
1636
case OPT_RESOLUTION:
1644
case OPT_BRIGHTNESS:
1646
case OPT_AUTO_EJECT:
1649
case OPT_WAIT_FOR_BUTTON:
1650
*((SANE_Word *) value) = sval->w;
1660
case OPT_GAMMA_CORRECTION:
1661
case OPT_COLOR_CORRECTION:
1664
strcpy((char *) value, sopt->constraint.string_list[sval->w]);
1668
return SANE_STATUS_INVAL;
1671
return SANE_STATUS_GOOD;
1675
* This routine handles common options between OPT_MODE and
1676
* OPT_HALFTONE. These options are TET (a HALFTONE mode), AAS
1677
* - auto area segmentation, and threshold. Apparently AAS
1678
* is some method to differentiate between text and photos.
1679
* Or something like that.
1681
* AAS is available when the scan color depth is 1 and the
1682
* halftone method is not TET.
1684
* Threshold is available when halftone is NONE, and depth is 1.
1687
handle_depth_halftone(Epson_Scanner *s, SANE_Bool *reload)
1689
int hti = s->val[OPT_HALFTONE].w;
1690
int mdi = s->val[OPT_MODE].w;
1691
SANE_Bool aas = SANE_FALSE;
1692
SANE_Bool thresh = SANE_FALSE;
1694
/* this defaults to false */
1695
setOptionState(s, thresh, OPT_THRESHOLD, reload);
1697
if (!s->hw->cmd->control_auto_area_segmentation)
1700
if (mode_params[mdi].depth == 1) {
1702
if (halftone_params[hti] != HALFTONE_TET)
1705
if (halftone_params[hti] == HALFTONE_NONE)
1708
setOptionState(s, aas, OPT_AAS, reload);
1709
setOptionState(s, thresh, OPT_THRESHOLD, reload);
1713
* Handles setting the source (flatbed, transparency adapter (TPU),
1714
* or auto document feeder (ADF)).
1716
* For newer scanners it also sets the focus according to the
1717
* glass / TPU settings.
1721
change_source(Epson_Scanner *s, SANE_Int optindex, char *value)
1723
int force_max = SANE_FALSE;
1726
DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
1729
/* reset the scanner when we are changing the source setting -
1730
this is necessary for the Perfection 1650 */
1731
if (s->hw->need_reset_on_source_change)
1734
s->focusOnGlass = SANE_TRUE; /* this is the default */
1736
if (s->val[OPT_SOURCE].w == optindex)
1739
s->val[OPT_SOURCE].w = optindex;
1741
if (s->val[OPT_TL_X].w == s->hw->x_range->min
1742
&& s->val[OPT_TL_Y].w == s->hw->y_range->min
1743
&& s->val[OPT_BR_X].w == s->hw->x_range->max
1744
&& s->val[OPT_BR_Y].w == s->hw->y_range->max) {
1745
force_max = SANE_TRUE;
1748
if (strcmp(ADF_STR, value) == 0) {
1749
s->hw->x_range = &s->hw->adf_x_range;
1750
s->hw->y_range = &s->hw->adf_y_range;
1751
s->hw->use_extension = SANE_TRUE;
1752
/* disable film type option */
1753
deactivateOption(s, OPT_FILM_TYPE, &dummy);
1754
s->val[OPT_FOCUS].w = 0;
1755
if (s->hw->duplex) {
1756
activateOption(s, OPT_ADF_MODE, &dummy);
1758
deactivateOption(s, OPT_ADF_MODE, &dummy);
1759
s->val[OPT_ADF_MODE].w = 0;
1762
DBG(1, "adf activated (ext: %d, duplex: %d)\n",
1763
s->hw->use_extension,
1766
} else if (strcmp(TPU_STR, value) == 0 || strcmp(TPU_STR2, value) == 0) {
1767
if (strcmp(TPU_STR, value) == 0) {
1768
s->hw->x_range = &s->hw->tpu_x_range;
1769
s->hw->y_range = &s->hw->tpu_y_range;
1770
s->hw->TPU2 = SANE_FALSE;
1772
if (strcmp(TPU_STR2, value) == 0) {
1773
s->hw->x_range = &s->hw->tpu2_x_range;
1774
s->hw->y_range = &s->hw->tpu2_y_range;
1775
s->hw->TPU2 = SANE_TRUE;
1777
s->hw->use_extension = SANE_TRUE;
1779
/* enable film type option only if the scanner supports it */
1780
if (s->hw->cmd->set_film_type != 0)
1781
activateOption(s, OPT_FILM_TYPE, &dummy);
1783
deactivateOption(s, OPT_FILM_TYPE, &dummy);
1785
/* enable focus position if the scanner supports it */
1786
if (s->hw->cmd->set_focus_position != 0) {
1787
s->val[OPT_FOCUS].w = 1;
1788
s->focusOnGlass = SANE_FALSE;
1791
deactivateOption(s, OPT_ADF_MODE, &dummy);
1792
deactivateOption(s, OPT_EJECT, &dummy);
1793
deactivateOption(s, OPT_AUTO_EJECT, &dummy);
1795
/* neither ADF nor TPU active */
1796
s->hw->x_range = &s->hw->fbf_x_range;
1797
s->hw->y_range = &s->hw->fbf_y_range;
1798
s->hw->use_extension = SANE_FALSE;
1800
/* disable film type option */
1801
deactivateOption(s, OPT_FILM_TYPE, &dummy);
1802
s->val[OPT_FOCUS].w = 0;
1803
deactivateOption(s, OPT_ADF_MODE, &dummy);
1806
/* special handling for FilmScan 200 */
1807
if (s->hw->cmd->level[0] == 'F')
1808
activateOption(s, OPT_FILM_TYPE, &dummy);
1810
s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
1811
s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
1813
if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
1814
s->val[OPT_TL_X].w = s->hw->x_range->min;
1816
if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
1817
s->val[OPT_TL_Y].w = s->hw->y_range->min;
1819
if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
1820
s->val[OPT_BR_X].w = s->hw->x_range->max;
1822
if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
1823
s->val[OPT_BR_Y].w = s->hw->y_range->max;
1825
setOptionState(s, s->hw->ADF
1826
&& s->hw->use_extension, OPT_AUTO_EJECT, &dummy);
1827
setOptionState(s, s->hw->ADF
1828
&& s->hw->use_extension, OPT_EJECT, &dummy);
1832
setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
1834
Epson_Scanner *s = (Epson_Scanner *) handle;
1835
SANE_Option_Descriptor *sopt = &(s->opt[option]);
1836
Option_Value *sval = &(s->val[option]);
1839
const SANE_String_Const *optval = NULL;
1841
SANE_Bool reload = SANE_FALSE;
1843
DBG(17, "%s: option = %d, value = %p\n", __func__, option, value);
1845
status = sanei_constrain_value(sopt, value, info);
1846
if (status != SANE_STATUS_GOOD)
1849
if (info && value && (*info & SANE_INFO_INEXACT)
1850
&& sopt->type == SANE_TYPE_INT)
1851
DBG(17, "%s: constrained val = %d\n", __func__,
1852
*(SANE_Word *) value);
1854
if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
1855
optval = search_string_list(sopt->constraint.string_list,
1858
return SANE_STATUS_INVAL;
1859
optindex = optval - sopt->constraint.string_list;
1864
case OPT_GAMMA_VECTOR_R:
1865
case OPT_GAMMA_VECTOR_G:
1866
case OPT_GAMMA_VECTOR_B:
1867
case OPT_CCT_PROFILE:
1868
memcpy(sval->wa, value, sopt->size); /* Word arrays */
1877
sval->w = optindex; /* Simple lists */
1881
/* XXX required? control_extension(s, 1); */
1885
case OPT_RESOLUTION:
1886
sval->w = *((SANE_Word *) value);
1887
DBG(17, "setting resolution to %d\n", sval->w);
1893
sval->w = *((SANE_Word *) value);
1894
if (SANE_UNFIX(sval->w) == 0) {
1895
DBG(17, "invalid br-x or br-y\n");
1896
return SANE_STATUS_INVAL;
1901
sval->w = *((SANE_Word *) value);
1902
DBG(17, "setting size to %f\n", SANE_UNFIX(sval->w));
1904
*info |= SANE_INFO_RELOAD_PARAMS;
1908
change_source(s, optindex, (char *) value);
1914
SANE_Bool isColor = mode_params[optindex].color;
1918
DBG(17, "%s: setting mode to %d\n", __func__, optindex);
1920
/* halftoning available only on bw scans */
1921
if (s->hw->cmd->set_halftoning != 0)
1922
setOptionState(s, mode_params[optindex].depth == 1,
1923
OPT_HALFTONE, &reload);
1925
/* disable dropout on non-color scans */
1926
setOptionState(s, !isColor, OPT_DROPOUT, &reload);
1928
if (s->hw->cmd->set_color_correction)
1929
setOptionState(s, isColor,
1930
OPT_COLOR_CORRECTION, &reload);
1932
/* if binary, then disable the bit depth selection */
1933
if (optindex == 0) {
1934
DBG(17, "%s: disabling bit depth selection\n", __func__);
1935
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
1937
if (s->hw->depth_list[0] == 1) {
1938
DBG(17, "%s: only one depth is available\n", __func__);
1939
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
1942
DBG(17, "%s: enabling bit depth selection\n", __func__);
1944
s->opt[OPT_BIT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
1945
s->val[OPT_BIT_DEPTH].w = mode_params[optindex].depth;
1949
handle_depth_halftone(s, &reload);
1956
sval->w = *((SANE_Word *) value);
1957
mode_params[s->val[OPT_MODE].w].depth = sval->w;
1963
handle_depth_halftone(s, &reload);
1966
case OPT_COLOR_CORRECTION:
1972
case OPT_GAMMA_CORRECTION:
1974
SANE_Bool f = gamma_userdefined[optindex];
1978
setOptionState(s, f, OPT_GAMMA_VECTOR_R, &reload);
1979
setOptionState(s, f, OPT_GAMMA_VECTOR_G, &reload);
1980
setOptionState(s, f, OPT_GAMMA_VECTOR_B, &reload);
1981
setOptionState(s, !f, OPT_BRIGHTNESS, &reload); /* Note... */
1988
case OPT_PREVIEW: /* needed? */
1989
case OPT_BRIGHTNESS:
1991
case OPT_AUTO_EJECT:
1993
case OPT_WAIT_FOR_BUTTON:
1994
sval->w = *((SANE_Word *) value);
1998
return SANE_STATUS_INVAL;
2001
if (reload && info != NULL)
2002
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2004
DBG(17, "%s: end\n", __func__);
2006
return SANE_STATUS_GOOD;
2010
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
2011
void *value, SANE_Int *info)
2013
DBG(17, "%s: action = %x, option = %d\n", __func__, action, option);
2015
if (option < 0 || option >= NUM_OPTIONS)
2016
return SANE_STATUS_INVAL;
2022
case SANE_ACTION_GET_VALUE:
2023
return getvalue(handle, option, value);
2025
case SANE_ACTION_SET_VALUE:
2026
return setvalue(handle, option, value, info);
2029
return SANE_STATUS_INVAL;
2032
return SANE_STATUS_INVAL;
2036
sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
2038
Epson_Scanner *s = (Epson_Scanner *) handle;
2040
DBG(5, "%s\n", __func__);
2043
DBG(1, "%s: params is NULL\n", __func__);
2046
* If sane_start was already called, then just retrieve the parameters
2047
* from the scanner data structure
2050
if (!s->eof && s->ptr != NULL) {
2051
DBG(5, "scan in progress, returning saved params structure\n");
2053
/* otherwise initialize the params structure and gather the data */
2054
e2_init_parameters(s);
2058
*params = s->params;
2060
print_params(s->params);
2062
return SANE_STATUS_GOOD;
2065
static void e2_load_cct_profile(struct Epson_Scanner *s, unsigned int index)
2067
s->cct_table[0] = SANE_FIX(s->hw->cct_profile->cct[index][0]);
2068
s->cct_table[1] = SANE_FIX(s->hw->cct_profile->cct[index][1]);
2069
s->cct_table[2] = SANE_FIX(s->hw->cct_profile->cct[index][2]);
2070
s->cct_table[3] = SANE_FIX(s->hw->cct_profile->cct[index][3]);
2071
s->cct_table[4] = SANE_FIX(s->hw->cct_profile->cct[index][4]);
2072
s->cct_table[5] = SANE_FIX(s->hw->cct_profile->cct[index][5]);
2073
s->cct_table[6] = SANE_FIX(s->hw->cct_profile->cct[index][6]);
2074
s->cct_table[7] = SANE_FIX(s->hw->cct_profile->cct[index][7]);
2075
s->cct_table[8] = SANE_FIX(s->hw->cct_profile->cct[index][8]);
2079
* This function is part of the SANE API and gets called from the front end to
2080
* start the scan process.
2084
sane_start(SANE_Handle handle)
2086
Epson_Scanner *s = (Epson_Scanner *) handle;
2087
Epson_Device *dev = s->hw;
2090
DBG(5, "* %s\n", __func__);
2092
s->eof = SANE_FALSE;
2093
s->canceling = SANE_FALSE;
2095
/* check if we just have finished working with the ADF */
2096
status = e2_check_adf(s);
2097
if (status != SANE_STATUS_GOOD)
2100
/* calc scanning parameters */
2101
status = e2_init_parameters(s);
2102
if (status != SANE_STATUS_GOOD)
2105
print_params(s->params);
2107
/* enable infrared */
2108
if (s->val[OPT_MODE].w == MODE_INFRARED)
2109
esci_enable_infrared(handle);
2112
if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_BAY].cap)) {
2113
status = esci_set_bay(s, s->val[OPT_BAY].w);
2114
if (status != SANE_STATUS_GOOD)
2118
/* set scanning parameters */
2119
if (dev->extended_commands)
2120
status = e2_set_extended_scanning_parameters(s);
2122
status = e2_set_scanning_parameters(s);
2124
if (status != SANE_STATUS_GOOD)
2127
/* ESC z, user defined gamma table */
2128
if (dev->cmd->set_gamma_table
2129
&& gamma_userdefined[s->val[OPT_GAMMA_CORRECTION].w]) {
2130
status = esci_set_gamma_table(s);
2131
if (status != SANE_STATUS_GOOD)
2136
if (s->val[OPT_COLOR_CORRECTION].w == CORR_AUTO) { /* Automatic */
2138
DBG(1, "using built in CCT profile\n");
2140
if (dev->model_id == 0)
2141
DBG(1, " specific profile not available, using default\n");
2144
if (0) { /* XXX TPU */
2146
/* XXX check this */
2147
if (s->val[OPT_FILM_TYPE].w == 0)
2148
e2_load_cct_profile(s, CCTP_COLORPOS);
2150
e2_load_cct_profile(s, CCTP_COLORNEG);
2153
e2_load_cct_profile(s, CCTP_REFLECTIVE);
2157
/* ESC m, user defined color correction */
2158
if (s->hw->cmd->set_color_correction_coefficients
2159
&& correction_userdefined[s->val[OPT_COLOR_CORRECTION].w]) {
2161
status = esci_set_color_correction_coefficients(s,
2163
if (status != SANE_STATUS_GOOD)
2167
/* check if we just have finished working with the ADF.
2168
* this seems to work only after the scanner has been
2169
* set up with scanning parameters
2171
status = e2_check_adf(s);
2172
if (status != SANE_STATUS_GOOD)
2176
* If WAIT_FOR_BUTTON is active, then do just that:
2177
* Wait until the button is pressed. If the button was already
2178
* pressed, then we will get the button pressed event right away.
2180
if (s->val[OPT_WAIT_FOR_BUTTON].w == SANE_TRUE)
2183
/* for debug, request command parameter */
2185
unsigned char buf[45];
2186
request_command_parameter(s, buf);
2189
/* set the retry count to 0 */
2192
/* allocate buffers for color shuffling */
2193
if (dev->color_shuffle == SANE_TRUE) {
2195
/* initialize the line buffers */
2196
for (i = 0; i < s->line_distance * 2 + 1; i++) {
2198
if (s->line_buffer[i] != NULL)
2199
free(s->line_buffer[i]);
2201
s->line_buffer[i] = malloc(s->params.bytes_per_line);
2202
if (s->line_buffer[i] == NULL) {
2203
DBG(1, "out of memory (line %d)\n", __LINE__);
2204
return SANE_STATUS_NO_MEM;
2209
/* prepare buffer here so that a memory allocation failure
2210
* will leave the scanner in a sane state.
2211
* the buffer will have to hold the image data plus
2212
* an error code in the extended handshaking mode.
2214
s->buf = realloc(s->buf, (s->lcount * s->params.bytes_per_line) + 1);
2216
return SANE_STATUS_NO_MEM;
2218
s->ptr = s->end = s->buf;
2220
/* feed the first sheet in the ADF */
2221
if (dev->ADF && dev->use_extension && dev->cmd->feed) {
2222
status = esci_feed(s);
2223
if (status != SANE_STATUS_GOOD)
2227
/* this seems to work only for some devices */
2228
status = e2_wait_warm_up(s);
2229
if (status != SANE_STATUS_GOOD)
2232
/* start scanning */
2233
DBG(1, "%s: scanning...\n", __func__);
2235
if (dev->extended_commands) {
2236
status = e2_start_ext_scan(s);
2238
/* sometimes the scanner gives an io error when
2241
if (status == SANE_STATUS_IO_ERROR) {
2242
status = e2_wait_warm_up(s);
2243
if (status == SANE_STATUS_GOOD)
2244
status = e2_start_ext_scan(s);
2247
status = e2_start_std_scan(s);
2249
if (status != SANE_STATUS_GOOD) {
2250
DBG(1, "%s: start failed: %s\n", __func__,
2251
sane_strstatus(status));
2256
/* this is a kind of read request */
2257
if (dev->connection == SANE_EPSON_NET) {
2258
sanei_epson_net_write(s, 0x2000, NULL, 0,
2259
s->ext_block_len + 1, &status);
2266
get_color(int status)
2268
switch ((status >> 2) & 0x03) {
2276
return 0; /* required to make the compiler happy */
2280
/* this moves data from our buffers to SANE */
2283
sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length,
2287
Epson_Scanner *s = (Epson_Scanner *) handle;
2289
DBG(18, "* %s: eof: %d, canceling: %d\n",
2290
__func__, s->eof, s->canceling);
2292
/* sane_read called before sane_start? */
2293
if (s->buf == NULL) {
2294
DBG(1, "%s: buffer is NULL", __func__);
2295
return SANE_STATUS_INVAL;
2300
if (s->hw->extended_commands)
2301
status = e2_ext_read(s);
2303
status = e2_block_read(s);
2305
/* The scanning operation might be canceled by the scanner itself
2306
* or the fronted program
2308
if (status == SANE_STATUS_CANCELLED || s->canceling) {
2310
return SANE_STATUS_CANCELLED;
2313
/* XXX if FS G and STATUS_IOERR, use e2_check_extended_status */
2315
DBG(18, "moving data %p %p, %d (%d lines)\n",
2317
max_length, max_length / s->params.bytes_per_line);
2319
e2_copy_image_data(s, data, max_length, length);
2321
DBG(18, "%d lines read, eof: %d, canceling: %d, status: %d\n",
2322
*length / s->params.bytes_per_line,
2323
s->canceling, s->eof, status);
2325
/* continue reading if appropriate */
2326
if (status == SANE_STATUS_GOOD)
2335
* void sane_cancel(SANE_Handle handle)
2337
* Set the cancel flag to true. The next time the backend requests data
2338
* from the scanner the CAN message will be sent.
2342
sane_cancel(SANE_Handle handle)
2344
Epson_Scanner *s = (Epson_Scanner *) handle;
2346
DBG(1, "* %s\n", __func__);
2348
s->canceling = SANE_TRUE;
2352
* SANE_Status sane_set_io_mode()
2354
* not supported - for asynchronous I/O
2358
sane_set_io_mode(SANE_Handle __sane_unused__ handle,
2359
SANE_Bool __sane_unused__ non_blocking)
2361
return SANE_STATUS_UNSUPPORTED;
2365
* SANE_Status sane_get_select_fd()
2367
* not supported - for asynchronous I/O
2371
sane_get_select_fd(SANE_Handle __sane_unused__ handle,
2372
SANE_Int __sane_unused__ *fd)
2374
return SANE_STATUS_UNSUPPORTED;