1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
/*
* SANE backend for Xerox Phaser 3200MFP et al.
* Copyright 2008-2016 ABC <abc@telekom.ru>
*
* Network Scanners Support
* Copyright 2010 Alexander Kuznetsov <acca(at)cpan.org>
*
* Color scanning on Samsung M2870 model and Xerox Cognac 3215 & 3225
* models by Laxmeesh Onkar Markod <m.laxmeesh@samsung.com>
*
* This program is licensed under GPL + SANE exception.
* More info at http://www.sane-project.org/license.html
*/
#ifndef xerox_mfp_h
#define xerox_mfp_h
#ifdef __GNUC__
#define UNUSED(x) x __attribute__((unused))
#else
#define UNUSED(x) x
#endif
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define UNCONST(ptr) ((void *)(long)(ptr))
#define PNT_PER_MM (1200. / MM_PER_INCH)
#define PADDING_SIZE 16
#define SWAP_Word(x, y) { SANE_Word z = x; x = y; y = z; }
enum options {
OPT_NUMOPTIONS,
OPT_GROUP_STD,
OPT_RESOLUTION, /* dpi*/
OPT_MODE, /* color */
OPT_THRESHOLD, /* brightness */
OPT_SOURCE, /* affects max window size */
OPT_JPEG,
OPT_GROUP_GEO,
OPT_SCAN_TL_X, /* for (OPT_SCAN_TL_X to OPT_SCAN_BR_Y) */
OPT_SCAN_TL_Y,
OPT_SCAN_BR_X,
OPT_SCAN_BR_Y,
NUM_OPTIONS
};
typedef struct transport transport;
struct device {
struct device *next;
SANE_Device sane;
int dn; /* usb file descriptor */
SANE_Byte res[1024]; /* buffer for responses */
size_t reslen; /* response len */
SANE_Option_Descriptor opt[NUM_OPTIONS];
Option_Value val[NUM_OPTIONS];
SANE_Parameters para;
SANE_Bool non_blocking;
int scanning; /* scanning is started */
int cancel; /* cancel flag */
int state; /* current state */
int reserved; /* CMD_RESERVE_UNIT */
int reading; /* READ_IMAGE is sent */
SANE_Byte *data; /* postprocessing cyclic buffer 64k */
int datalen; /* how data in buffer */
int dataoff; /* offset of data */
int dataindex; /* sequental number */
#define DATAMASK 0xffff /* mask of data buffer */
#define DATASIZE (DATAMASK + 1) /* size of data buffer */
/* 64K will be enough to hold whole line of 2400 dpi of 23cm */
#define DATATAIL(dev) ((dev->dataoff + dev->datalen) & DATAMASK)
#define DATAROOM(dev) dataroom(dev)
#define POST_DATASIZE 0xFFFFFF /* 16777215 bytes */
SANE_Byte *decData; /* static buffer of POST_DATASIZE bytes */
int decDataSize;
int currentDecDataIndex;
/* data from CMD_INQUIRY: */
int resolutions; /* supported resolution bitmask */
int compositions; /* supported image compositions bitmask */
int max_len; /* effective max len for current doc source */
int max_win_width;
int max_win_len;
int max_len_adf;
int max_len_fb;
int line_order; /* if need post processing */
SANE_Word dpi_list[30]; /* allowed resolutions */
int doc_loaded;
SANE_Range win_x_range;
SANE_Range win_y_range;
/* CMD_SET_WINDOW parameters we set: */
int win_width; /* in 1200dpi points */
int win_len;
double win_off_x; /* in inches (byte.byte) */
double win_off_y;
int resolution; /* dpi indexed values */
int composition; /* MODE_ */
int doc_source; /* document source */
int threshold; /* brightness */
int compressionTypes;
SANE_Bool compressionEnabled;
/* CMD_READ data. It is per block only, image could be in many blocks */
int blocklen; /* image data block len (padding incl.) */
int vertical; /* lines in block (padded) */
int horizontal; /* b/w: bytes, gray/color: pixels (padded) */
int final_block;
int pixels_per_line;
int bytes_per_line;
int ulines; /* up to this block including */
int y_off; /* up to this block excluding*/
int blocks;
/* stat */
int total_img_size; /* predicted image size */
int total_out_size; /* total we sent to user */
int total_data_size; /* total of what scanner sent us */
/* transport to use */
transport *io;
};
/* Transport abstract layer */
struct transport {
char *ttype;
int (*dev_request)(struct device *dev,
SANE_Byte *cmd, size_t cmdlen,
SANE_Byte *resp, size_t *resplen);
SANE_Status(*dev_open)(struct device *dev);
void (*dev_close)(struct device *dev);
SANE_Status(*configure_device)(const char *devname, SANE_Status(*cb)(SANE_String_Const devname));
};
/* USB transport */
int usb_dev_request(struct device *dev, SANE_Byte *cmd, size_t cmdlen, SANE_Byte *resp, size_t *resplen);
SANE_Status usb_dev_open(struct device *dev);
void usb_dev_close(struct device *dev);
SANE_Status usb_configure_device(const char *devname, SANE_Status(*cb)(SANE_String_Const devname));
/* TCP unicast */
int tcp_dev_request(struct device *dev, SANE_Byte *cmd, size_t cmdlen, SANE_Byte *resp, size_t *resplen);
SANE_Status tcp_dev_open(struct device *dev);
void tcp_dev_close(struct device *dev);
SANE_Status tcp_configure_device(const char *devname, SANE_Status(*cb)(SANE_String_Const devname));
/* device wants transfer buffer to be multiple of 512 */
#define USB_BLOCK_SIZE 512
#define USB_BLOCK_MASK ~(USB_BLOCK_SIZE - 1)
static inline int dataroom(struct device *dev)
{
int tail = DATATAIL(dev);
if (tail < dev->dataoff)
return dev->dataoff - tail;
else if (dev->datalen == DATASIZE) {
return 0;
} else
return DATASIZE - tail;
}
/* Functions from original xerox_mfp.c, used in -usb.c and -tcp.c */
SANE_Status ret_cancel(struct device *dev, SANE_Status ret);
/* a la SCSI commands. */ /* request len, response len, exception */
#define CMD_ABORT 0x06 /* 4, 32 */
#define CMD_INQUIRY 0x12 /* 4, 70 */
#define CMD_RESERVE_UNIT 0x16 /* 4, 32 */
#define CMD_RELEASE_UNIT 0x17 /* 4, 32 */
#define CMD_SET_WINDOW 0x24 /* 25, 32, specified req len is 22 */
#define CMD_READ 0x28 /* 4, 32 */
#define CMD_READ_IMAGE 0x29 /* 4, var + padding[16] */
#define CMD_OBJECT_POSITION 0x31 /* 4, 32 */
/* Packet Headers */
#define REQ_CODE_A 0x1b
#define REQ_CODE_B 0xa8
#define RES_CODE 0xa8
/* Status Codes, going into dev->state */
#define STATUS_GOOD 0x00
#define STATUS_CHECK 0x02 /* MSG_SCANNER_STATE */
#define STATUS_CANCEL 0x04
#define STATUS_BUSY 0x08
/* Message Code */
#define MSG_NO_MESSAGE 0x00
#define MSG_PRODUCT_INFO 0x10 /* CMD_INQUIRY */
#define MSG_SCANNER_STATE 0x20 /* CMD_RESERVE_UNIT, and
CMD_READ, CMD_SET_WINDOW, CMD_OBJECT_POSITION */
#define MSG_SCANNING_PARAM 0x30 /* CMD_SET_WINDOW */
#define MSG_PREVIEW_PARAM 0x31 /* CMD_SET_WINDOW */
#define MSG_LINK_BLOCK 0x80 /* CMD_READ */
#define MSG_END_BLOCK 0x81 /* CMD_READ */
/* Scanner State Bits (if MSG_SCANNER_STATE if STATUS_CHECK) */
#define STATE_NO_ERROR 0x001
#define STATE_COMMAND_ERROR 0x002
#define STATE_UNSUPPORTED 0x004
#define STATE_RESET 0x008
#define STATE_NO_DOCUMENT 0x010
#define STATE_DOCUMENT_JAM 0x020
#define STATE_COVER_OPEN 0x040
#define STATE_WARMING 0x080
#define STATE_LOCKING 0x100
#define STATE_INVALID_AREA 0x200
#define STATE_RESOURCE_BUSY 0x400
/* Image Composition */
#define MODE_LINEART 0x00
#define MODE_HALFTONE 0x01
#define MODE_GRAY8 0x03
#define MODE_RGB24 0x05
/* Document Source */
#define DOC_ADF 0x20
#define DOC_FLATBED 0x40
#define DOC_AUTO 0x80
#endif /* xerox_mfp_h */
|