1 /*
2 * epsonds.c - Epson ESC/I-2 driver.
3 *
4 * Copyright (C) 2015 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This file is part of the SANE package.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
12 */
13
14 #define EPSONDS_VERSION 1
15 #define EPSONDS_REVISION 1
16 #define EPSONDS_BUILD 0
17
18 /* debugging levels:
19 *
20 * 32 eds_send
21 * 30 eds_recv
22 * 20 sane_read and related
23 * 18 sane_read and related
24 * 17 setvalue, getvalue, control_option
25 * 16
26 * 15 esci2_img
27 * 13 image_cb
28 * 12 eds_control
29 * 11 all received params
30 * 10 some received params
31 * 9
32 * 8 esci2_xxx
33 * 7 open/close/attach
34 * 6 print_params
35 * 5 basic functions
36 * 3 JPEG decompressor
37 * 1 scanner info and capabilities
38 * 0 errors
39 */
40
41 #include "sane/config.h"
42
43 #include <ctype.h>
44 #ifdef HAVE_SYS_SELECT_H
45 #include <sys/select.h>
46 #endif
47 #ifdef HAVE_SYS_TIME_H
48 # include <sys/time.h>
49 #endif
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <unistd.h>
53 #include <math.h>
54
55 #include "sane/saneopts.h"
56 #include "sane/sanei_config.h"
57 #include "sane/sanei_tcp.h"
58 #include "sane/sanei_udp.h"
59
60 #include "epsonds.h"
61 #include "epsonds-usb.h"
62 #include "epsonds-io.h"
63 #include "epsonds-cmd.h"
64 #include "epsonds-ops.h"
65 #include "epsonds-jpeg.h"
66 #include "epsonds-net.h"
67
68 static SANE_Status
69 setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info);
70 /*
71 * Definition of the mode_param struct, that is used to
72 * specify the valid parameters for the different scan modes.
73 *
74 * The depth variable gets updated when the bit depth is modified.
75 */
76
77
78 static unsigned char LUT[][256] =
79 {
80 {// 0
81 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
82 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
83 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
84 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
85 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
86 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
87 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
88 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
89 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
90 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
91 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
92 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
93 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
94 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
95 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
96 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
97 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
98 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
99 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
100 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
101 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
102 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
103 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
104 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
105 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
106 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
107 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
108 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
109 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
110 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
111 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
112 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
113 },
114 { // 1
115 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
119 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
120 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
121 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
122 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
123 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
124 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
125 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
126 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
127 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
128 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
129 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
130 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
131 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
132 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
133 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
134 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
135 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
136 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
137 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
138 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
139 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
140 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
141 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
142 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
143 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
144 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
145 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
146 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
147 },
148 { // 2
149 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
151 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
154 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
155 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
156 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
157 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
158 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
159 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
160 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
161 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
162 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
163 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
164 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
165 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
166 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
167 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
168 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
169 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
170 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
171 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
172 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
173 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
174 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
175 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
176 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
177 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
178 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
179 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
180 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
181 },
182 { // 3
183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
187 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
189 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07,
190 0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,
191 0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,
192 0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,
193 0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,
194 0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,
195 0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B,
196 0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67,
197 0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,
198 0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,
199 0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A,
200 0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,
201 0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,
202 0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,
203 0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,
204 0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,
205 0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,
206 0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,
207 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF,
208 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
209 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
210 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
211 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
212 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
213 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
214 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
215 },
216 { //4
217 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
218 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
219 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
220 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
221 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
223 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
224 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
225 0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,
226 0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,
227 0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A,
228 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,
229 0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,
230 0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,
231 0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A,
232 0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,
233 0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,
234 0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,
235 0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,
236 0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,
237 0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,
238 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,
239 0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,
240 0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,
241 0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5,
242 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
243 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
244 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
245 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
246 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
247 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
248 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
249 },
250 { // 5
251 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
252 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
253 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
254 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
255 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
256 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
257 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
258 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
259 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
260 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
261 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
262 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
263 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
264 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
265 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
266 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
267 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
268 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
269 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
270 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
271 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
272 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
273 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
274 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
275 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
276 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
277 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
278 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
279 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
280 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
281 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
282 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
283 },
284 { // 6
285 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
286 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
287 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
288 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
289 0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C,
290 0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B,
291 0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38,
292 0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44,
293 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
294 0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B,
295 0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65,
296 0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70,
297 0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A,
298 0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83,
299 0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D,
300 0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96,
301 0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
302 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
303 0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,
304 0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
305 0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4,
306 0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,
307 0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
308 0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,
309 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
310 0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,
311 0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
312 0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
313 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
314 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
315 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
316 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
317 },
318 { // 7
319 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
320 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
321 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
322 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
323 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
324 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
325 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
326 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
327 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
328 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
329 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
330 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
331 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
332 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
333 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
334 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
335 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
336 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
337 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
338 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
339 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
340 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
341 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
342 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
343 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
344 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
345 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
346 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
347 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
348 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
349 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
350 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
351 }
352 };
353
354 static unsigned char LUT_R[][256] =
355 {
356 { // 0
357 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
358 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
359 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
360 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
361 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
362 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
363 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
364 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
365 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
366 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
367 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
368 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
369 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
370 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
371 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
372 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
373 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
374 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
375 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
376 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
377 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
378 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
379 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
380 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
381 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
382 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
383 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
384 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
385 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
386 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
387 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
388 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
389 },
390 { // 1
391 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
393 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
394 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
395 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
396 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
397 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
398 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
399 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
400 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
401 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
402 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
403 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
404 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
405 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
406 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
407 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
408 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
409 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
410 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
411 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
412 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
413 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
414 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
415 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
416 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
417 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
418 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
419 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
420 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
421 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
422 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
423 },
424 { // 2
425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
426 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
427 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
428 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
429 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
430 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
431 0x10,0x12,0x14,0x16,0x19,0x1B,0x1D,0x1F,
432 0x21,0x23,0x25,0x27,0x28,0x2A,0x2C,0x2E,
433 0x30,0x32,0x33,0x35,0x37,0x39,0x3A,0x3C,
434 0x3E,0x40,0x41,0x43,0x45,0x46,0x48,0x4A,
435 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,
436 0x58,0x5A,0x5B,0x5D,0x5F,0x60,0x62,0x63,
437 0x65,0x66,0x68,0x69,0x6B,0x6C,0x6E,0x6F,
438 0x71,0x72,0x74,0x75,0x77,0x78,0x7A,0x7B,
439 0x7D,0x7E,0x80,0x81,0x83,0x84,0x86,0x87,
440 0x88,0x8A,0x8B,0x8D,0x8E,0x90,0x91,0x92,
441 0x94,0x95,0x97,0x98,0x99,0x9B,0x9C,0x9E,
442 0x9F,0xA0,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,
443 0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,0xB4,
444 0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,0xBE,
445 0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,0xC9,
446 0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,0xD4,
447 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,0xDE,
448 0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,
449 0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,
450 0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,
451 0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
452 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
453 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
454 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
455 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
456 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
457 },
458 {
459 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
461 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
462 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
463 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
464 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
466 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
467 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
468 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
469 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
470 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
471 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
472 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
473 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
474 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
475 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
476 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
477 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
478 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
479 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
480 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
481 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
482 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
483 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
484 0xE1,0xE3,0xE4,0xE5,0xE5,0xE6,0xE8,0xE9,
485 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
486 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
487 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
488 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
489 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
490 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
491 },
492 {
493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
494 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
498 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,
499 0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,
500 0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,
501 0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,
502 0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,
503 0x42,0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,
504 0x4F,0x50,0x52,0x53,0x55,0x56,0x58,0x59,
505 0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,
506 0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,
507 0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,
508 0x7E,0x80,0x81,0x83,0x84,0x85,0x87,0x88,
509 0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,
510 0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,
511 0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,
512 0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,
513 0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,
514 0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,
515 0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,
516 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,
517 0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,
518 0xE8,0xE9,0xEA,0xEB,0xEB,0xED,0xEE,0xEF,
519 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
520 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
521 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
522 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
523 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
524 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
525 },
526 {
527 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
528 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
529 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
531 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
532 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
533 0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,
534 0x20,0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,
535 0x2F,0x31,0x33,0x34,0x36,0x38,0x39,0x3B,
536 0x3D,0x3E,0x40,0x42,0x43,0x45,0x47,0x48,
537 0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,
538 0x56,0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,
539 0x63,0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,
540 0x6E,0x70,0x71,0x73,0x74,0x76,0x77,0x79,
541 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
542 0x85,0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,
543 0x90,0x92,0x93,0x95,0x96,0x97,0x99,0x9A,
544 0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,
545 0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,
546 0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,
547 0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
548 0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,
549 0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,
550 0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,
551 0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,0xED,
552 0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,
553 0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,
554 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
555 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
556 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
557 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
558 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
559 },
560 {
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
564 0x02,0x03,0x04,0x05,0x06,0x08,0x0A,0x0C,
565 0x0E,0x10,0x12,0x14,0x16,0x19,0x1B,0x1D,
566 0x1F,0x20,0x22,0x24,0x26,0x28,0x2A,0x2B,
567 0x2D,0x2F,0x31,0x32,0x34,0x35,0x37,0x39,
568 0x3A,0x3C,0x3D,0x3F,0x41,0x42,0x44,0x45,
569 0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x4F,0x51,
570 0x52,0x54,0x55,0x57,0x58,0x59,0x5B,0x5C,
571 0x5E,0x5F,0x60,0x62,0x63,0x64,0x66,0x67,
572 0x68,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x72,
573 0x73,0x74,0x75,0x77,0x78,0x79,0x7B,0x7C,
574 0x7D,0x7E,0x80,0x81,0x82,0x83,0x85,0x86,
575 0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,
576 0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,
577 0x9A,0x9B,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,
578 0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAB,0xAC,
579 0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,
580 0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,
581 0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,
582 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
583 0xD0,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,
584 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,
585 0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xEA,
586 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,
587 0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,
588 0xFB,0xFC,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
589 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
590 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
591 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
592 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
593 },
594 {
595 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
596 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
597 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
598 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
599 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
600 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
601 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
602 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
603 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
604 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
605 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
606 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
607 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
608 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
609 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
610 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
611 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
612 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
613 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
614 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
615 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
616 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
617 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
618 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
619 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
620 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
621 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
622 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
623 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
624 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
625 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
626 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
627 }
628 };
629
630 static unsigned char LUT_G[][256] =
631 {
632 {
633 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
634 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
635 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
636 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
637 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
638 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
639 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
640 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
641 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
642 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
643 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
644 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
645 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
646 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
647 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
648 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
649 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
650 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
651 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
652 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
653 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
654 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
655 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
656 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
657 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
658 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
659 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
660 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
661 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
662 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
663 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
664 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
665 },
666 {
667 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
668 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
669 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
670 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
671 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
672 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
673 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
674 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
675 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
676 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
677 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
678 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
679 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
680 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
681 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
682 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
683 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
684 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
685 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
686 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
687 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
688 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
689 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
690 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
691 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
692 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
693 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
694 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
695 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
696 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
697 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
698 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
699 },
700 {
701 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
702 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
703 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
704 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
705 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
706 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
707 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
708 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
709 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
710 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
711 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
712 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
713 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
714 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
715 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
716 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
717 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
718 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
719 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
720 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
721 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
722 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
723 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
724 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
725 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
726 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
727 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
728 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
729 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
730 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
731 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
732 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
733 },
734 {
735 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
736 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
737 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
738 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
739 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
740 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
741 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07,
742 0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,
743 0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,
744 0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,
745 0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,
746 0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,
747 0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B,
748 0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67,
749 0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,
750 0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,
751 0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A,
752 0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,
753 0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,
754 0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,
755 0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,
756 0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,
757 0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,
758 0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,
759 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF,
760 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
761 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
762 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
763 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
764 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
765 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
766 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
767 },
768 {
769 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
770 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
772 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
773 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
775 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
776 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
777 0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,
778 0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,
779 0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A,
780 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,
781 0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,
782 0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,
783 0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A,
784 0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,
785 0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,
786 0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,
787 0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,
788 0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,
789 0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,
790 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,
791 0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,
792 0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,
793 0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5,
794 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
795 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
796 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
797 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
798 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
799 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
800 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
801 },
802 {
803 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
804 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
805 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
806 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
807 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
808 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
809 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
810 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
811 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
812 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
813 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
814 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
815 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
816 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
817 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
818 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
819 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
820 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
821 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
822 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
823 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
824 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
825 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
826 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
827 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
828 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
829 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
830 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
831 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
832 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
833 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
834 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
835 },
836 {
837 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
838 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
839 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
840 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
841 0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C,
842 0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B,
843 0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38,
844 0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44,
845 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
846 0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B,
847 0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65,
848 0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70,
849 0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A,
850 0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83,
851 0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D,
852 0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96,
853 0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
854 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
855 0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,
856 0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
857 0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4,
858 0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,
859 0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
860 0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,
861 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
862 0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,
863 0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
864 0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
865 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
866 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
867 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
868 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
869 },
870 { // 7
871 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
872 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
874 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
876 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
877 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
878 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
879 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
880 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
881 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
882 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
883 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
884 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
885 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
886 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
887 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
888 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
889 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
890 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
891 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
892 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
893 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
894 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
895 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
896 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
897 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
898 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
899 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
900 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
901 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
902 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
903 }
904 };
905
906 static unsigned char LUT_B[][256] =
907 {
908 {
909 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
910 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
911 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
912 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
913 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
914 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
915 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
916 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
917 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
918 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
919 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
920 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
921 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
922 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
923 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
924 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
925 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
926 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
927 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
928 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
929 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
930 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
931 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
932 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
933 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
934 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
935 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
936 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
937 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
938 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
939 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
940 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
941 },
942 {
943 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
944 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
945 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
946 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
947 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
948 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
949 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
950 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
951 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
952 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
953 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
954 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
955 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
956 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
957 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
958 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
959 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
960 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
961 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
962 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
963 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
964 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
965 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
966 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
967 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
968 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
969 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
970 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
971 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
972 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
973 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
974 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
975 },
976 {
977 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
978 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
979 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
980 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
981 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
982 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
983 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
984 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
985 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
986 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
987 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
988 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
989 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
990 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
991 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
992 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
993 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
994 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
995 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
996 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
997 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
998 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
999 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
1000 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
1001 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
1002 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
1003 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1004 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1005 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1006 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1007 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1008 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1009 },
1010 {
1011 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1012 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1013 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1014 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1015 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1016 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1017 0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x08,
1018 0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,
1019 0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,
1020 0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,
1021 0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,
1022 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,
1023 0x52,0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,
1024 0x5E,0x60,0x61,0x63,0x64,0x66,0x67,0x69,
1025 0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,
1026 0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,
1027 0x81,0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,
1028 0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,
1029 0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,
1030 0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,
1031 0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,
1032 0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,
1033 0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,
1034 0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
1035 0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,
1036 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
1037 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
1038 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
1039 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1040 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1041 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1042 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1043 },
1044 {
1045 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1046 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1047 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1048 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1049 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1050 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
1051 0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12,
1052 0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,
1053 0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31,
1054 0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E,
1055 0x40,0x42,0x43,0x45,0x47,0x48,0x4A,0x4B,
1056 0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,0x58,
1057 0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
1058 0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70,
1059 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
1060 0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,0x87,
1061 0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92,
1062 0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D,
1063 0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,
1064 0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,
1065 0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,
1066 0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,
1067 0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,
1068 0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,
1069 0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,
1070 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
1071 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
1072 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
1073 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1074 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1075 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1076 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1077 },
1078 {
1079 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1080 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1081 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1082 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1083 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1084 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
1085 0x0E,0x10,0x12,0x14,0x16,0x16,0x18,0x1A,
1086 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
1087 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
1088 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
1089 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
1090 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
1091 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
1092 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
1093 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
1094 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
1095 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
1096 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA3,
1097 0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,
1098 0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,
1099 0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,
1100 0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,
1101 0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,
1102 0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,
1103 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
1104 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
1105 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
1106 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1107 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1108 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1109 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1110 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1111 },
1112 {
1113 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1114 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1115 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
1116 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
1117 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
1118 0x22,0x24,0x26,0x27,0x29,0x2B,0x2C,0x2E,
1119 0x30,0x31,0x33,0x35,0x36,0x38,0x39,0x3B,
1120 0x3C,0x3E,0x40,0x41,0x43,0x44,0x45,0x47,
1121 0x48,0x4B,0x4D,0x4E,0x50,0x51,0x52,0x54,
1122 0x55,0x56,0x58,0x59,0x5B,0x5C,0x5D,0x5F,
1123 0x60,0x61,0x63,0x64,0x65,0x67,0x68,0x69,
1124 0x6A,0x6C,0x6D,0x6E,0x70,0x71,0x72,0x73,
1125 0x75,0x76,0x77,0x78,0x7A,0x7B,0x7C,0x7D,
1126 0x7E,0x80,0x81,0x82,0x83,0x85,0x86,0x87,
1127 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x90,
1128 0x92,0x93,0x94,0x95,0x96,0x96,0x97,0x99,
1129 0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA1,0xA2,
1130 0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,
1131 0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,
1132 0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,
1133 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,
1134 0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,
1135 0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
1136 0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,
1137 0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,
1138 0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,
1139 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,
1140 0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,
1141 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1142 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1143 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1144 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1145 },
1146 {
1147 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1148 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1149 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1150 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1151 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
1152 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
1153 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
1154 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
1155 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
1156 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
1157 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
1158 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
1159 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
1160 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
1161 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
1162 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
1163 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
1164 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
1165 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
1166 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
1167 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
1168 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
1169 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
1170 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
1171 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
1172 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
1173 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
1174 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
1175 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1176 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1177 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1178 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1179 }
1180 };
1181 //// profile array ////
1182
1183 typedef struct
1184 {
1185 int productID; // USB PID
1186 char productName[50]; // ESCI/2 procduct name
1187 char deviceID[50]; // device ID (same as bonjour mdl name)
1188 int lutID; // look up table no
1189 }epsonds_profile_map;
1190
1191 const epsonds_profile_map epsonds_models_predefined[] = {
1192 {0x0145, "DS-5500","DS-5500", 7},
1193 {0x0145, "DS-6500","DS-6500", 7},
1194 {0x0145, "DS-7500","DS-7500", 7},
1195 {0x0146, "DS-50000","DS-50000", 7},
1196 {0x0146, "DS-60000","DS-60000", 7},
1197 {0x0146, "DS-70000","DS-70000", 7},
1198 {0x014C, "DS-510","DS-510", 7},
1199 {0x0150, "DS-560","DS-560", 7},
1200 {0x0152, "DS-40","DS-40", 7},
1201 {0x014D, "DS-760","DS-760", 7},
1202 {0x014D, "DS-860","DS-860", 7},
1203 {0x0154, "DS-520","DS-520", 7},
1204 {0x08BC, "PID 08BC","PX-M7050 Series", 7},
1205 {0x08BC, "PID 08BC","WF-8510 Series", 7},
1206 {0x08BC, "PID 08BC","WF-8590 Series", 7},
1207 {0x08CC, "PID 08CC","PX-M7050FX Series", 7},
1208 {0x08CC, "PID 08CC","WF-R8590 Series", 7},
1209 {0x0165, "DS-410","DS-410", 7},
1210 {0x016C, "ES-50","ES-50", 6},
1211 {0x0160, "DS-70","DS-70", 6},
1212 {0x016D, "ES-55R","ES-55R", 6},
1213 {0x018C, "RR-60","RR-60", 6},
1214 {0x016E, "ES-60W","ES-60W", 6},
1215 {0x0166, "DS-80W","DS-80W", 6},
1216 {0x016F, "ES-65WR","ES-65WR", 6},
1217 {0x018B, "RR-70W","RR-70W", 6},
1218 {0x016E, "ES-60WW","ES-60WW", 6},
1219 {0x016E, "ES-60WB","ES-60WB", 6},
1220 {0x015C, "DS-1630","DS-1630", 4},
1221 {0x015D, "DS-1610","DS-1610", 4},
1222 {0x015E, "DS-1660W","DS-1660W", 4},
1223 {0x0159, "DS-310","DS-310", 5},
1224 {0x0159, "ES-200","ES-200", 5},
1225 {0x0162, "DS-320","DS-320", 5},
1226 {0x015A, "DS-360W","DS-360W", 5},
1227 {0x015A, "ES-300W","ES-300W", 5},
1228 {0x0177, "ES-300WR","ES-300WR", 5},
1229 {0x0181, "ES-400II","ES-400II", 2},
1230 {0x0183, "DS-535II","DS-535II", 2},
1231 {0x0184, "DS-531","DS-531", 2},
1232 {0x0182, "DS-530II","DS-530II", 2},
1233 {0x0185, "ES-500WII","ES-500WII", 2},
1234 {0x0188, "DS-571W","DS-571W", 2},
1235 {0x0187, "DS-575WII","DS-575WII", 2},
1236 {0x0186, "DS-570WII","DS-570WII", 2},
1237 {0x017F, "ES-580W","ES-580W", 2},
1238 {0x0180, "RR-600W","RR-600W", 2},
1239 {0x0167, "DS-535","DS-535", 2},
1240 {0x017A, "DS-535H","DS-535H", 2},
1241 {0x0156, "ES-400","ES-400", 2},
1242 {0x0155, "DS-530","DS-530", 2},
1243 {0x016B, "FF-680W","FF-680W", 2},
1244 {0x0157, "DS-570W","DS-570W", 2},
1245 {0x0157, "ES-500W","ES-500W", 2},
1246 {0x0169, "DS-575W","DS-575W", 2},
1247 {0x0176, "ES-500WR","ES-500WR", 2},
1248 {0x114E, "PID 114E","EW-052A Series", 7},
1249 {0x114E, "PID 114E","XP-2100 Series", 7},
1250 {0x1135, "PID 1135","ET-2700 Series", 7},
1251 {0x1135, "PID 1135","L4150 Series", 7},
1252 {0x114A, "PID 114A","ET-M2140 Series", 7},
1253 {0x114A, "PID 114A","M2140 Series", 7},
1254 {0x114F, "PID 114F","ET-M3140 Series", 7},
1255 {0x114F, "PID 114F","M3140 Series", 7},
1256 {0x1143, "PID 1143","L3150 Series", 7},
1257 {0x1143, "PID 1143","ET-2710 Series", 7},
1258 {0x118A, "PID 118A","ET-2810 Series", 7},
1259 {0x118A, "PID 118A","L3250 Series", 7},
1260 {0x119B, "PID 119B","XP-2150 Series", 7},
1261 {0x11B1, "PID 11B1","XP-2200 Series", 7},
1262 {0x00, "","", 0x00 }
1263 };
1264
1265 typedef struct
1266 {
1267 epsonds_profile_map *array;
1268 int used;
1269 int size;
1270 }epsonds_profile_map_array;
1271
1272
1273 static epsonds_profile_map_array stProfileMapArray;
1274
1275 static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element);
1276
init_profile_maps(epsonds_profile_map_array *a, size_t initialSize)1277 static void init_profile_maps(epsonds_profile_map_array *a, size_t initialSize) {
1278 a->array = malloc(initialSize * sizeof(epsonds_profile_map));
1279 a->used = 0;
1280 a->size = initialSize;
1281
1282 for (int i = 0; epsonds_models_predefined[i].productID != 0; i++) {
1283
1284 //DBG(6, "epsonds_models_predefined[i].productID = %x\n", epsonds_models_predefined[i].productID );
1285
1286 insert_profile_map(a, epsonds_models_predefined[i]);
1287 }
1288 }
1289
insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element)1290 static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element) {
1291 if (a->used == a->size) {
1292 a->size *= 2;
1293 a->array = realloc(a->array, a->size * sizeof(epsonds_profile_map));
1294 }
1295 a->array[a->used++] = element;
1296 }
1297
free_profile_maps(epsonds_profile_map_array *a)1298 static void free_profile_maps(epsonds_profile_map_array *a) {
1299 free(a->array);
1300 a->array = NULL;
1301 a->used = a->size = 0;
1302 }
1303 /////////////////////////
1304
1305
1306 struct mode_param mode_params[] = {
1307 {0, 0x00, 0x30, 1},
1308 {0, 0x00, 0x30, 8},
1309 {1, 0x02, 0x00, 8},
1310 {0, 0x00, 0x30, 1}
1311 };
1312
1313 static SANE_String_Const mode_list[] = {
1314 SANE_VALUE_SCAN_MODE_LINEART,
1315 SANE_VALUE_SCAN_MODE_GRAY,
1316 SANE_VALUE_SCAN_MODE_COLOR,
1317 NULL
1318 };
1319
1320
1321 /* Define the different scan sources */
1322
1323 #define STRING_FLATBED SANE_I18N("Flatbed")
1324 #define STRING_ADFFRONT SANE_I18N("ADF Front")
1325 #define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
1326
1327 /* order will be fixed: fb, adf, tpu */
1328 SANE_String_Const source_list[] = {
1329 NULL,
1330 NULL,
1331 NULL,
1332 NULL
1333 };
1334
1335 /*
1336 * List of pointers to devices - will be dynamically allocated depending
1337 * on the number of devices found.
1338 */
1339 static const SANE_Device **devlist;
1340
1341 /* Some utility functions */
1342
1343 static size_t
max_string_size(const SANE_String_Const strings[])1344 max_string_size(const SANE_String_Const strings[])
1345 {
1346 size_t size, max_size = 0;
1347 int i;
1348
1349 for (i = 0; strings[i]; i++) {
1350 size = strlen(strings[i]) + 1;
1351 if (size > max_size)
1352 max_size = size;
1353 }
1354 return max_size;
1355 }
1356
1357 static SANE_Status attach_one_usb(SANE_String_Const devname);
1358 static SANE_Status attach_one_net(SANE_String_Const devname);
1359 static SANE_Status acquire_jpeg_data(epsonds_scanner* s);
1360 static SANE_Status acquire_and_decode_jpeg_data(epsonds_scanner* s);
1361 static SANE_Status acquire_raw_data(epsonds_scanner* s);
1362
1363 static void
print_params(const SANE_Parameters params)1364 print_params(const SANE_Parameters params)
1365 {
1366 DBG(6, "params.format = %d\n", params.format);
1367 DBG(6, "params.last_frame = %d\n", params.last_frame);
1368 DBG(6, "params.bytes_per_line = %d\n", params.bytes_per_line);
1369 DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
1370 DBG(6, "params.lines = %d\n", params.lines);
1371 DBG(6, "params.depth = %d\n", params.depth);
1372 }
1373
1374 static void
close_scanner(epsonds_scanner *s)1375 close_scanner(epsonds_scanner *s)
1376 {
1377 DBG(7, "%s: fd = %d\n", __func__, s->fd);
1378
1379 if (s->scanning)
1380 {
1381 sane_cancel(s);
1382 }
1383
1384 if (s->fd == -1)
1385 goto free;
1386
1387 if (s->locked) {
1388 DBG(7, " unlocking scanner\n");
1389 esci2_fin(s);
1390 }
1391
1392 if (s->hw->connection == SANE_EPSONDS_NET) {
1393 epsonds_net_unlock(s);
1394 sanei_tcp_close(s->fd);
1395 } else if (s->hw->connection == SANE_EPSONDS_USB) {
1396 sanei_usb_close(s->fd);
1397 }
1398
1399 free:
1400
1401 free(s->front.ring);
1402 free(s->back.ring);
1403 free(s->line_buffer);
1404 free(s);
1405
1406 DBG(7, "%s: ZZZ\n", __func__);
1407 }
1408
1409 static SANE_Status
open_scanner(epsonds_scanner *s)1410 open_scanner(epsonds_scanner *s)
1411 {
1412 SANE_Status status = SANE_STATUS_INVAL;
1413
1414 DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
1415
1416 if (s->fd != -1) {
1417 DBG(5, "scanner is already open: fd = %d\n", s->fd);
1418 return SANE_STATUS_GOOD; /* no need to open the scanner */
1419 }
1420
1421 if (s->hw->connection == SANE_EPSONDS_NET) {
1422 unsigned char buf[5];
1423
1424 /* device name has the form net:ipaddr */
1425 status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);
1426 if (status == SANE_STATUS_GOOD) {
1427
1428 ssize_t read;
1429 struct timeval tv;
1430
1431 tv.tv_sec = 5;
1432 tv.tv_usec = 0;
1433
1434 setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
1435
1436 s->netlen = 0;
1437
1438 DBG(32, "awaiting welcome message\n");
1439
1440 /* the scanner sends a kind of welcome msg */
1441 // XXX check command type, answer to connect is 0x80
1442 read = eds_recv(s, buf, 5, &status);
1443 if (read != 5) {
1444 sanei_tcp_close(s->fd);
1445 s->fd = -1;
1446 return SANE_STATUS_IO_ERROR;
1447 }
1448
1449 DBG(32, "welcome message received, locking the scanner...\n");
1450
1451 /* lock the scanner for use by sane */
1452 status = epsonds_net_lock(s);
1453 if (status != SANE_STATUS_GOOD) {
1454 DBG(1, "%s cannot lock scanner: %s\n", s->hw->sane.name,
1455 sane_strstatus(status));
1456
1457 sanei_tcp_close(s->fd);
1458 s->fd = -1;
1459
1460 return status;
1461 }
1462
1463 DBG(32, "scanner locked\n");
1464 }
1465
1466 } else if (s->hw->connection == SANE_EPSONDS_USB) {
1467 status = sanei_usb_open(s->hw->sane.name, &s->fd);
1468
1469 if (status == SANE_STATUS_GOOD) {
1470 sanei_usb_set_timeout(USB_TIMEOUT);
1471 }
1472
1473 } else {
1474 DBG(1, "unknown connection type: %d\n", s->hw->connection);
1475 }
1476
1477 if (status == SANE_STATUS_ACCESS_DENIED) {
1478 DBG(1, "please check that you have permissions on the device.\n");
1479 DBG(1, "if this is a multi-function device with a printer,\n");
1480 DBG(1, "disable any conflicting driver (like usblp).\n");
1481 }
1482
1483 if (status != SANE_STATUS_GOOD)
1484 DBG(1, "%s open failed: %s\n",
1485 s->hw->sane.name,
1486 sane_strstatus(status));
1487 else
1488 DBG(5, " opened correctly\n");
1489
1490 return status;
1491 }
1492
1493 static int num_devices; /* number of scanners attached to backend */
1494 static epsonds_device *first_dev; /* first EPSON scanner in list */
1495
1496 static struct epsonds_scanner *
scanner_create(struct epsonds_device *dev, SANE_Status *status)1497 scanner_create(struct epsonds_device *dev, SANE_Status *status)
1498 {
1499 struct epsonds_scanner *s;
1500 s = malloc(sizeof(struct epsonds_scanner));
1501 if (s == NULL) {
1502 *status = SANE_STATUS_NO_MEM;
1503 return NULL;
1504 }
1505
1506 /* clear verything */
1507 memset(s, 0x00, sizeof(struct epsonds_scanner));
1508
1509 s->fd = -1;
1510 s->hw = dev;
1511
1512 return s;
1513 }
1514
1515 static struct epsonds_scanner *
device_detect(const char *name, int type, SANE_Status *status)1516 device_detect(const char *name, int type, SANE_Status *status)
1517 {
1518 struct epsonds_scanner *s;
1519 struct epsonds_device *dev;
1520
1521 DBG(1, "%s, %s, type: %d\n", __func__, name, type);
1522
1523 /* try to find the device in our list */
1524 for (dev = first_dev; dev; dev = dev->next) {
1525
1526 if (strcmp(dev->sane.name, name) == 0) {
1527
1528 DBG(1, " found cached device\n");
1529
1530 // the device might have been just probed, sleep a bit.
1531 if (dev->connection == SANE_EPSONDS_NET) {
1532 sleep(1);
1533 }
1534
1535 return scanner_create(dev, status);
1536 }
1537 }
1538
1539 /* not found, create new if valid */
1540 if (type == SANE_EPSONDS_NODEV) {
1541 *status = SANE_STATUS_INVAL;
1542 return NULL;
1543 }
1544
1545 /* alloc and clear our device structure */
1546 dev = malloc(sizeof(*dev));
1547 if (!dev) {
1548 *status = SANE_STATUS_NO_MEM;
1549 return NULL;
1550 }
1551 memset(dev, 0x00, sizeof(struct epsonds_device));
1552
1553 s = scanner_create(dev, status);
1554 if (s == NULL)
1555 return NULL;
1556
1557 dev->connection = type;
1558 dev->model = strdup("(undetermined)");
1559 dev->name = strdup(name);
1560
1561 dev->sane.name = dev->name;
1562 dev->sane.vendor = "Epson";
1563 dev->sane.model = dev->model;
1564 dev->sane.type = "ESC/I-2";
1565
1566 *status = open_scanner(s);
1567 if (*status != SANE_STATUS_GOOD) {
1568 free(s);
1569 return NULL;
1570 }
1571
1572 eds_dev_init(dev);
1573
1574 /* lock scanner */
1575 *status = eds_lock(s);
1576 if (*status != SANE_STATUS_GOOD) {
1577 goto close;
1578 }
1579
1580 /* discover capabilities */
1581 *status = esci2_info(s);
1582 if (*status != SANE_STATUS_GOOD)
1583 goto close;
1584
1585 *status = esci2_capa(s);
1586 if (*status != SANE_STATUS_GOOD)
1587 goto close;
1588
1589 *status = esci2_resa(s);
1590 if (*status != SANE_STATUS_GOOD)
1591 goto close;
1592
1593 // assume 1 and 8 bit are always supported
1594 eds_add_depth(s->hw, 1);
1595 eds_add_depth(s->hw, 8);
1596
1597 // setup area according to available options
1598 if (s->hw->has_fb) {
1599
1600 dev->x_range = &dev->fbf_x_range;
1601 dev->y_range = &dev->fbf_y_range;
1602 dev->alignment = dev->fbf_alignment;
1603
1604 } else if (s->hw->has_adf) {
1605
1606 dev->x_range = &dev->adf_x_range;
1607 dev->y_range = &dev->adf_y_range;
1608 dev->alignment = dev->adf_alignment;
1609
1610 } else {
1611 DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n");
1612 }
1613
1614 *status = eds_dev_post_init(dev);
1615 if (*status != SANE_STATUS_GOOD)
1616 goto close;
1617
1618 DBG(1, "scanner model: %s\n", dev->model);
1619
1620
1621 s->hw->lut_id = 0;
1622
1623 for (int i = 0; i < stProfileMapArray.used; i++) {
1624
1625 epsonds_profile_map* map = &stProfileMapArray.array[i];
1626
1627
1628 if (strcmp(map->productName, dev->model) == 0) {
1629
1630 {//Convert to user friendly model name
1631 free(s->hw->model);
1632
1633 s->hw->model = strdup(map->deviceID);
1634 s->hw->sane.model = s->hw->model;
1635 }
1636 {// set lutid
1637 s->hw->lut_id = map->lutID;
1638 }
1639 break;
1640 }
1641 }
1642 DBG(1, "scanner lut_id: %d\n", s->hw->lut_id);
1643
1644 num_devices++;
1645 dev->next = first_dev;
1646 first_dev = dev;
1647
1648 return s;
1649
1650 close:
1651 DBG(1, " failed\n");
1652
1653 close_scanner(s);
1654 return NULL;
1655 }
1656
1657
1658 static SANE_Status
attach(const char *name, int type)1659 attach(const char *name, int type)
1660 {
1661 SANE_Status status;
1662 epsonds_scanner * s;
1663
1664 DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
1665
1666 s = device_detect(name, type, &status);
1667 if (s == NULL)
1668 return status;
1669
1670 close_scanner(s);
1671 return status;
1672 }
1673
1674 SANE_Status
attach_one_usb(const char *dev)1675 attach_one_usb(const char *dev)
1676 {
1677 DBG(7, "%s: dev = %s\n", __func__, dev);
1678 return attach(dev, SANE_EPSONDS_USB);
1679 }
1680
1681 static SANE_Status
attach_one_net(const char *dev)1682 attach_one_net(const char *dev)
1683 {
1684 char name[39 + 4];
1685
1686 DBG(7, "%s: dev = %s\n", __func__, dev);
1687
1688 strcpy(name, "net:");
1689 strcat(name, dev);
1690 return attach(name, SANE_EPSONDS_NET);
1691 }
1692
found_net_device(const char* device_name, const char* ip)1693 static void found_net_device(const char* device_name, const char* ip)
1694 {
1695 DBG(7, "Found %s: ip = %s\n", device_name, ip);
1696
1697 int foundSupportedDevice = 0;
1698
1699 // search models
1700 for (int i = 0; i < stProfileMapArray.used; i++) {
1701 if (strcmp(stProfileMapArray.array[i].deviceID, device_name) == 0) {
1702 foundSupportedDevice = 1;
1703 break;
1704 }
1705 }
1706
1707
1708 if (foundSupportedDevice)
1709 {
1710 char name[39 + 4];
1711
1712 strcpy(name, "net:");
1713 strncat(name, ip, 39);
1714
1715 int foundCache = 0;
1716 // search cache and prents duplicated model
1717 for (epsonds_device* dev = first_dev; dev; dev = dev->next) {
1718 if (strcmp(dev->sane.name, name) == 0) {
1719 foundCache = 1;
1720 }
1721 }
1722 if (foundCache == 0)
1723 {
1724 attach(name, SANE_EPSONDS_NET);
1725 }
1726 }
1727 }
1728
1729 static void
splitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID)1730 splitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID)
1731 {
1732 char target[1024];
1733 strncpy(target, input, 1023);
1734
1735 strtok(target, ":");//profile
1736
1737 //productID
1738 char* pid = strtok(NULL, ",");
1739 sscanf(pid, "%x", (unsigned int*)outProductID);
1740
1741 //productName
1742 char* productName = strtok(NULL, ",");
1743 strncpy(outProductName, productName, 49);
1744
1745 //deviceID
1746 char* deviceID = strtok(NULL, ",");
1747 strncpy(outDeviceID, deviceID, 49);
1748
1749 //lutID
1750 char* lutID = strtok(NULL, ",");
1751 sscanf(lutID, "%d", outLutID);
1752 }
1753
1754
1755 static SANE_Status
attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, void *data)1756 attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,
1757 void *data)
1758 {
1759 int vendor, product;
1760 SANE_Bool local_only = *(SANE_Bool*) data;
1761 int len = strlen(line);
1762
1763 DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
1764 if (strncmp(line, "profile", 7) == 0 ) {
1765 DBG(7, " found profile device profile\n");
1766
1767 epsonds_profile_map profle_map;
1768
1769 splitProfileName(line, &profle_map.productID, profle_map.productName, profle_map.deviceID, &profle_map.lutID);
1770
1771 DBG(7, "Found profile : %x %s %s %d\n", profle_map.productID, profle_map.productName, profle_map.deviceID, profle_map.lutID);
1772
1773 insert_profile_map(&stProfileMapArray, profle_map);
1774 }else if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
1775
1776 DBG(7, " user configured device\n");
1777
1778 if (vendor != SANE_EPSONDS_VENDOR_ID)
1779 return SANE_STATUS_INVAL; /* this is not an Epson device */
1780
1781 sanei_usb_attach_matching_devices(line, attach_one_usb);
1782
1783 } else if (strncmp(line, "usb", 3) == 0 && len == 3) {
1784
1785 DBG(7, " probing usb devices\n");
1786
1787 for (int i = 0; i < stProfileMapArray.used; i++) {
1788 int usbPid = stProfileMapArray.array[i].productID;
1789 sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, usbPid, attach_one_usb);
1790 }
1791
1792 } else if (strncmp(line, "net", 3) == 0) {
1793
1794 if (!local_only) {
1795 /* remove the "net" sub string */
1796 const char *name =
1797 sanei_config_skip_whitespace(line + 3);
1798
1799 if (strncmp(name, "autodiscovery", 13) == 0)
1800 {
1801 #if WITH_AVAHI
1802 epsonds_searchDevices(found_net_device);
1803 #else
1804 // currently does not support
1805 //e2_network_discovery();
1806 #endif
1807 }
1808 else
1809 attach_one_net(name);
1810 }
1811 } else {
1812 DBG(0, "unable to parse config line: %s\n", line);
1813 }
1814
1815 return SANE_STATUS_GOOD;
1816 }
1817
1818 static void
free_devices(void)1819 free_devices(void)
1820 {
1821 epsonds_device *dev, *next;
1822
1823 for (dev = first_dev; dev; dev = next) {
1824 next = dev->next;
1825 free(dev->name);
1826 free(dev->model);
1827 free(dev);
1828 }
1829
1830 free(devlist);
1831 first_dev = NULL;
1832 }
1833
1834 static void
probe_devices(SANE_Bool local_only)1835 probe_devices(SANE_Bool local_only)
1836 {
1837 DBG(5, "%s\n", __func__);
1838
1839 free_devices();
1840 sanei_configure_attach(EPSONDS_CONFIG_FILE, NULL,
1841 attach_one_config, &local_only);
1842 }
1843
1844 /**** SANE API ****/
1845
1846 SANE_Status
sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)1847 sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
1848 {
1849 DBG_INIT();
1850
1851 init_profile_maps(&stProfileMapArray, 100);
1852
1853 DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
1854
1855 DBG(1, "epsonds backend, version %i.%i.%i\n",
1856 EPSONDS_VERSION, EPSONDS_REVISION, EPSONDS_BUILD);
1857
1858 if (version_code != NULL)
1859 *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR,
1860 EPSONDS_BUILD);
1861
1862 sanei_usb_init();
1863
1864 return SANE_STATUS_GOOD;
1865 }
1866
1867 void
sane_exit(void)1868 sane_exit(void)
1869 {
1870 DBG(5, "** %s\n", __func__);
1871 free_profile_maps(&stProfileMapArray);
1872 free_devices();
1873 }
1874
1875 SANE_Status
sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)1876 sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
1877 {
1878 int i;
1879 epsonds_device *dev;
1880
1881 DBG(5, "** %s local_only = %d \n", __func__, local_only);
1882
1883
1884 probe_devices(local_only);
1885
1886 devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
1887 if (!devlist) {
1888 DBG(1, "out of memory (line %d)\n", __LINE__);
1889 return SANE_STATUS_NO_MEM;
1890 }
1891
1892 DBG(5, "%s - results:\n", __func__);
1893
1894 for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
1895 DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
1896 devlist[i] = &dev->sane;
1897 }
1898
1899 devlist[i] = NULL;
1900
1901 *device_list = devlist;
1902
1903
1904 return SANE_STATUS_GOOD;
1905 }
1906
1907 static SANE_Status
init_options(epsonds_scanner *s)1908 init_options(epsonds_scanner *s)
1909 {
1910 DBG(5, "init_options\n");
1911 int i;
1912
1913 for (i = 0; i < NUM_OPTIONS; i++) {
1914 s->opt[i].size = sizeof(SANE_Word);
1915 s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1916 }
1917
1918 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1919 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1920 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1921 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1922 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1923
1924 /* "Scan Mode" group: */
1925 s->opt[OPT_STANDARD_GROUP].name = SANE_NAME_STANDARD;
1926 s->opt[OPT_STANDARD_GROUP].title = SANE_TITLE_STANDARD;
1927 s->opt[OPT_STANDARD_GROUP].desc = SANE_DESC_STANDARD;
1928 s->opt[OPT_STANDARD_GROUP].type = SANE_TYPE_GROUP;
1929 s->opt[OPT_STANDARD_GROUP].cap = 0;
1930
1931 /* scan mode */
1932 s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1933 s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1934 s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1935 s->opt[OPT_MODE].type = SANE_TYPE_STRING;
1936 s->opt[OPT_MODE].size = max_string_size(mode_list);
1937 s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1938 s->opt[OPT_MODE].constraint.string_list = mode_list;
1939 s->val[OPT_MODE].w = 0; /* Lineart */
1940
1941 /* bit depth */
1942 s->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH;
1943 s->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
1944 s->opt[OPT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
1945 s->opt[OPT_DEPTH].type = SANE_TYPE_INT;
1946 s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT;
1947 s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1948 s->opt[OPT_DEPTH].constraint.word_list = s->hw->depth_list;
1949 s->val[OPT_DEPTH].w = s->hw->depth_list[1]; /* the first "real" element is the default */
1950
1951 /* default is Lineart, disable depth selection */
1952 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
1953
1954 /* resolution */
1955 s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1956 s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1957 s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1958
1959 s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1960 s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1961
1962 /* range */
1963 if (s->hw->dpi_range.quant) {
1964 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1965 s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
1966 s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
1967 } else { /* list */
1968 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1969 s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->res_list;
1970 s->val[OPT_RESOLUTION].w = s->hw->res_list[1];
1971 }
1972
1973 /* "Geometry" group: */
1974 s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
1975 s->opt[OPT_GEOMETRY_GROUP].desc = "";
1976 s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1977 s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1978
1979 /* top-left x */
1980 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1981 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1982 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1983 s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1984 s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1985 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1986 s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
1987 s->val[OPT_TL_X].w = 0;
1988
1989 /* top-left y */
1990 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1991 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1992 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1993
1994 s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1995 s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1996 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1997 s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
1998 s->val[OPT_TL_Y].w = 0;
1999
2000 /* bottom-right x */
2001 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2002 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2003 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2004
2005 s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2006 s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2007 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2008 s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2009 s->val[OPT_BR_X].w = s->hw->x_range->max;
2010
2011 /* bottom-right y */
2012 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2013 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2014 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2015
2016 s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2017 s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2018 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2019 s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2020 s->val[OPT_BR_Y].w = s->hw->y_range->max;
2021
2022 /* "Optional equipment" group: */
2023 s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment");
2024 s->opt[OPT_EQU_GROUP].desc = "";
2025 s->opt[OPT_EQU_GROUP].type = SANE_TYPE_GROUP;
2026 s->opt[OPT_EQU_GROUP].cap = SANE_CAP_ADVANCED;
2027
2028 /* source */
2029 s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
2030 s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
2031 s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
2032 s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
2033 s->opt[OPT_SOURCE].size = max_string_size(source_list);
2034 s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2035 s->opt[OPT_SOURCE].constraint.string_list = source_list;
2036 s->val[OPT_SOURCE].w = 0;
2037
2038 s->opt[OPT_EJECT].name = "eject";
2039 s->opt[OPT_EJECT].title = SANE_I18N("Eject");
2040 s->opt[OPT_EJECT].desc = SANE_I18N("Eject the sheet in the ADF");
2041 s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
2042
2043 if (!s->hw->adf_has_eject)
2044 s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
2045
2046 s->opt[OPT_LOAD].name = "load";
2047 s->opt[OPT_LOAD].title = SANE_I18N("Load");
2048 s->opt[OPT_LOAD].desc = SANE_I18N("Load a sheet in the ADF");
2049 s->opt[OPT_LOAD].type = SANE_TYPE_BUTTON;
2050
2051 if (!s->hw->adf_has_load)
2052 s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE;
2053
2054
2055 s->opt[OPT_ADF_SKEW].name = "adf-skew";
2056 s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction");
2057 s->opt[OPT_ADF_SKEW].desc =
2058 SANE_I18N("Enables ADF skew correction");
2059 s->opt[OPT_ADF_SKEW].type = SANE_TYPE_BOOL;
2060 s->val[OPT_ADF_SKEW].w = 0;
2061
2062
2063 s->opt[OPT_ADF_CRP].name = "adf-crp";
2064 s->opt[OPT_ADF_CRP].title = SANE_I18N("ADF CRP Correction");
2065 s->opt[OPT_ADF_CRP].desc =
2066 SANE_I18N("Enables ADF auto cropping"); //
2067 s->opt[OPT_ADF_CRP].type = SANE_TYPE_BOOL;
2068 s->val[OPT_ADF_CRP].w = 0;
2069
2070
2071 if (!s->hw->adf_has_skew)
2072 {
2073 s->val[OPT_ADF_SKEW].w = 0;
2074 s->opt[OPT_ADF_SKEW].cap |= SANE_CAP_INACTIVE;
2075 }
2076
2077 if(!s->hw->adf_has_crp)
2078 {
2079 s->val[OPT_ADF_CRP].w = 0;
2080 s->opt[OPT_ADF_CRP].cap |= SANE_CAP_INACTIVE;
2081 }
2082
2083 return SANE_STATUS_GOOD;
2084 }
2085
2086 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle *handle)2087 sane_open(SANE_String_Const name, SANE_Handle *handle)
2088 {
2089 SANE_Status status;
2090 epsonds_scanner *s = NULL;
2091
2092
2093
2094 DBG(7, "** %s: name = '%s'\n", __func__, name);
2095
2096 /* probe if empty device name provided */
2097 if (name[0] == '\0') {
2098
2099 probe_devices(SANE_FALSE);
2100
2101 if (first_dev == NULL) {
2102 DBG(1, "no devices detected\n");
2103 return SANE_STATUS_INVAL;
2104 }
2105
2106 s = device_detect(first_dev->sane.name, first_dev->connection,
2107 &status);
2108 if (s == NULL) {
2109 DBG(1, "cannot open a perfectly valid device (%s),"
2110 " please report to the authors\n", name);
2111 return SANE_STATUS_INVAL;
2112 }
2113
2114 } else {
2115
2116 if (strncmp(name, "net:", 4) == 0) {
2117 s = device_detect(name, SANE_EPSONDS_NET, &status);
2118 if (s == NULL)
2119 return status;
2120 } else if (strncmp(name, "libusb:", 7) == 0) {
2121 s = device_detect(name, SANE_EPSONDS_USB, &status);
2122 if (s == NULL)
2123 return status;
2124 } else {
2125 DBG(1, "invalid device name: %s\n", name);
2126 return SANE_STATUS_INVAL;
2127 }
2128 }
2129
2130 /* s is always valid here */
2131
2132 DBG(5, "%s: handle obtained\n", __func__);
2133
2134 init_options(s);
2135
2136 *handle = (SANE_Handle)s;
2137
2138 status = open_scanner(s);
2139 if (status != SANE_STATUS_GOOD) {
2140 free(s);
2141 return status;
2142 }
2143
2144 /* lock scanner if required */
2145 if (!s->locked) {
2146 status = eds_lock(s);
2147 }
2148
2149 setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL);
2150
2151 return status;
2152 }
2153
2154 void
sane_close(SANE_Handle handle)2155 sane_close(SANE_Handle handle)
2156 {
2157 epsonds_scanner *s = (epsonds_scanner *)handle;
2158
2159 DBG(1, "** %s\n", __func__);
2160
2161 close_scanner(s);
2162 }
2163
2164 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)2165 sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
2166 {
2167 epsonds_scanner *s = (epsonds_scanner *) handle;
2168
2169 if (option < 0 || option >= NUM_OPTIONS)
2170 return NULL;
2171
2172 return s->opt + option;
2173 }
2174
2175 static const SANE_String_Const *
search_string_list(const SANE_String_Const *list, SANE_String value)2176 search_string_list(const SANE_String_Const *list, SANE_String value)
2177 {
2178 while (*list != NULL && strcmp(value, *list) != 0)
2179 list++;
2180
2181 return ((*list == NULL) ? NULL : list);
2182 }
2183
2184 /*
2185 * Handles setting the source (flatbed, transparency adapter (TPU),
2186 * or auto document feeder (ADF)).
2187 *
2188 * For newer scanners it also sets the focus according to the
2189 * glass / TPU settings.
2190 */
2191
2192 static void
change_source(epsonds_scanner *s, SANE_Int optindex, char *value)2193 change_source(epsonds_scanner *s, SANE_Int optindex, char *value)
2194 {
2195 int force_max = SANE_FALSE;
2196
2197 DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
2198 value);
2199
2200 s->val[OPT_SOURCE].w = optindex;
2201
2202 /* if current selected area is the maximum available,
2203 * keep this setting on the new source.
2204 */
2205 if (s->val[OPT_TL_X].w == s->hw->x_range->min
2206 && s->val[OPT_TL_Y].w == s->hw->y_range->min
2207 && s->val[OPT_BR_X].w == s->hw->x_range->max
2208 && s->val[OPT_BR_Y].w == s->hw->y_range->max) {
2209 force_max = SANE_TRUE;
2210 }
2211
2212 if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) {
2213 s->hw->x_range = &s->hw->adf_x_range;
2214 s->hw->y_range = &s->hw->adf_y_range;
2215 s->hw->alignment = s->hw->adf_alignment;
2216
2217
2218 } else if (strcmp(TPU_STR, value) == 0) {
2219
2220 s->hw->x_range = &s->hw->tpu_x_range;
2221 s->hw->y_range = &s->hw->tpu_y_range;
2222
2223 } else {
2224
2225 /* neither ADF nor TPU active, assume FB */
2226 s->hw->x_range = &s->hw->fbf_x_range;
2227 s->hw->y_range = &s->hw->fbf_y_range;
2228 s->hw->alignment = s->hw->fbf_alignment;
2229 }
2230
2231 s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2232 s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2233
2234 if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
2235 s->val[OPT_TL_X].w = s->hw->x_range->min;
2236
2237 if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
2238 s->val[OPT_TL_Y].w = s->hw->y_range->min;
2239
2240 if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
2241 s->val[OPT_BR_X].w = s->hw->x_range->max;
2242
2243 if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
2244 s->val[OPT_BR_Y].w = s->hw->y_range->max;
2245 }
2246
2247 static SANE_Status
getvalue(SANE_Handle handle, SANE_Int option, void *value)2248 getvalue(SANE_Handle handle, SANE_Int option, void *value)
2249 {
2250 epsonds_scanner *s = (epsonds_scanner *)handle;
2251 SANE_Option_Descriptor *sopt = &(s->opt[option]);
2252 Option_Value *sval = &(s->val[option]);
2253
2254 DBG(17, "%s: option = %d\n", __func__, option);
2255
2256 switch (option) {
2257
2258 case OPT_NUM_OPTS:
2259 case OPT_RESOLUTION:
2260 case OPT_TL_X:
2261 case OPT_TL_Y:
2262 case OPT_BR_X:
2263 case OPT_BR_Y:
2264 case OPT_DEPTH:
2265 case OPT_ADF_SKEW:
2266 *((SANE_Word *) value) = sval->w;
2267 break;
2268
2269 case OPT_MODE:
2270 case OPT_SOURCE:
2271 strcpy((char *) value, sopt->constraint.string_list[sval->w]);
2272 break;
2273
2274 default:
2275 return SANE_STATUS_INVAL;
2276 }
2277
2278 return SANE_STATUS_GOOD;
2279 }
2280
2281 static SANE_Status
setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)2282 setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
2283 {
2284 epsonds_scanner *s = (epsonds_scanner *) handle;
2285 SANE_Option_Descriptor *sopt = &(s->opt[option]);
2286 Option_Value *sval = &(s->val[option]);
2287
2288 SANE_Status status;
2289 const SANE_String_Const *optval = NULL;
2290 int optindex = 0;
2291 SANE_Bool reload = SANE_FALSE;
2292
2293 DBG(17, "** %s: option = %d, value = %p\n", __func__, option, value);
2294
2295 status = sanei_constrain_value(sopt, value, info);
2296 if (status != SANE_STATUS_GOOD)
2297 return status;
2298
2299 if (info && value && (*info & SANE_INFO_INEXACT)
2300 && sopt->type == SANE_TYPE_INT)
2301 DBG(17, " constrained val = %d\n", *(SANE_Word *) value);
2302
2303 if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
2304 optval = search_string_list(sopt->constraint.string_list,
2305 (char *) value);
2306 if (optval == NULL)
2307 return SANE_STATUS_INVAL;
2308 optindex = optval - sopt->constraint.string_list;
2309 }
2310
2311 /* block faulty frontends */
2312 if (sopt->cap & SANE_CAP_INACTIVE) {
2313 DBG(1, " tried to modify a disabled parameter");
2314 return SANE_STATUS_INVAL;
2315 }
2316
2317 switch (option) {
2318
2319 case OPT_ADF_SKEW:
2320 case OPT_RESOLUTION:
2321 case OPT_ADF_CRP:
2322 sval->w = *((SANE_Word *) value);
2323 reload = SANE_TRUE;
2324 break;
2325
2326 case OPT_BR_X:
2327 case OPT_BR_Y:
2328 if (SANE_UNFIX(*((SANE_Word *) value)) == 0) {
2329 DBG(17, " invalid br-x or br-y\n");
2330 return SANE_STATUS_INVAL;
2331 }
2332 // fall through
2333 case OPT_TL_X:
2334 case OPT_TL_Y:
2335
2336 sval->w = *((SANE_Word *) value);
2337 if (NULL != info)
2338 *info |= SANE_INFO_RELOAD_PARAMS;
2339
2340 if (option == OPT_BR_X)
2341 {
2342 DBG(17, "OPT_BR_X = %d\n", sval->w);
2343 }
2344 if (option == OPT_BR_Y)
2345 {
2346 DBG(17, "OPT_BR_Y = %d\n", sval->w);
2347 }
2348 if (option == OPT_TL_X)
2349 {
2350 DBG(17, "OPT_TL_X = %d\n", sval->w);
2351 }
2352 if (option == OPT_TL_Y)
2353 {
2354 DBG(17, "OPT_TL_Y = %d\n", sval->w);
2355 }
2356 // adf crop set to off
2357 s->val[OPT_ADF_CRP].w = 0;
2358 break;
2359
2360 case OPT_SOURCE:
2361 change_source(s, optindex, (char *) value);
2362 reload = SANE_TRUE;
2363 break;
2364
2365 case OPT_MODE:
2366 {
2367 DBG(17, " OPT_MODE = index %d\n", optindex);
2368
2369 /* use JPEG mode if RAW is not available when bpp > 1 */
2370 if (optindex > 0 && !s->hw->has_raw) {
2371 s->mode_jpeg = 1;
2372 } else {
2373 s->mode_jpeg = 0;
2374 }
2375
2376 sval->w = optindex;
2377
2378 /* if binary, then disable the bit depth selection */
2379 if (optindex == 0) {
2380 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2381 } else {
2382 if (s->hw->depth_list[0] == 1)
2383 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2384 else {
2385 s->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
2386 s->val[OPT_DEPTH].w =
2387 mode_params[optindex].depth;
2388 }
2389 }
2390
2391 reload = SANE_TRUE;
2392 break;
2393 }
2394
2395 case OPT_DEPTH:
2396 sval->w = *((SANE_Word *) value);
2397 mode_params[s->val[OPT_MODE].w].depth = sval->w;
2398 reload = SANE_TRUE;
2399 break;
2400
2401 case OPT_LOAD:
2402 esci2_mech(s, "#ADFLOAD");
2403 break;
2404
2405 case OPT_EJECT:
2406 esci2_mech(s, "#ADFEJCT");
2407 break;
2408
2409 default:
2410 return SANE_STATUS_INVAL;
2411 }
2412
2413 if (reload && info != NULL)
2414 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2415
2416 return SANE_STATUS_GOOD;
2417 }
2418
2419 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *value, SANE_Int *info)2420 sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
2421 void *value, SANE_Int *info)
2422 {
2423 DBG(17, "** %s: action = %x, option = %d\n", __func__, action, option);
2424
2425 if (option < 0 || option >= NUM_OPTIONS)
2426 return SANE_STATUS_INVAL;
2427
2428 if (info != NULL)
2429 *info = 0;
2430
2431 switch (action) {
2432 case SANE_ACTION_GET_VALUE:
2433 return getvalue(handle, option, value);
2434
2435 case SANE_ACTION_SET_VALUE:
2436 return setvalue(handle, option, value, info);
2437
2438 default:
2439 return SANE_STATUS_INVAL;
2440 }
2441
2442 return SANE_STATUS_INVAL;
2443 }
2444
2445
setBit(SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue)2446 static void setBit (SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue)
2447 {
2448 SANE_Int octet = bitIndex / 8;
2449 SANE_Byte bit = 7 - (bitIndex % 8);
2450
2451 if (isTrue) {
2452 bytes[octet] |= (1 << bit);
2453 } else {
2454 bytes[octet] &= ~(1 << bit);
2455 }
2456 }
2457
getBit(SANE_Byte* bytes, SANE_Int bitIndex)2458 static SANE_Bool getBit (SANE_Byte* bytes, SANE_Int bitIndex)
2459 {
2460 SANE_Int octet = bitIndex / 8;
2461 SANE_Byte mask = 1 << (7 - (bitIndex % 8));
2462
2463 if( bytes[octet] & mask ){
2464 return SANE_TRUE;
2465 }
2466
2467 return SANE_FALSE;
2468 }
2469
swapPixel1(SANE_Int x1, SANE_Int y1, SANE_Int x2, SANE_Int y2, SANE_Byte* bytes, SANE_Byte bitsPerSample, SANE_Int samplesPerPixel, SANE_Int bytesPerRow)2470 static void swapPixel1(SANE_Int x1,
2471 SANE_Int y1,
2472 SANE_Int x2,
2473 SANE_Int y2,
2474 SANE_Byte* bytes,
2475 SANE_Byte bitsPerSample,
2476 SANE_Int samplesPerPixel,
2477 SANE_Int bytesPerRow)
2478 {
2479 SANE_Int pixelBits = bitsPerSample * samplesPerPixel;
2480 SANE_Int widthBits = bytesPerRow * 8;
2481
2482 SANE_Byte temp = getBit(bytes, widthBits * y1 + x1 * pixelBits);
2483 {
2484 SANE_Byte right = getBit(bytes, widthBits * y2 + x2 * pixelBits);
2485 setBit(bytes, widthBits * y1 + x1 * pixelBits, right);
2486 }
2487 setBit(bytes, widthBits * y2 + x2 * pixelBits, temp);
2488 }
2489
swapPixel8(SANE_Int x1, SANE_Int y1, SANE_Int x2, SANE_Int y2, SANE_Byte* bytes, SANE_Byte bitsPerSample, SANE_Int samplesPerPixel, SANE_Int bytesPerRow)2490 static void swapPixel8(SANE_Int x1,
2491 SANE_Int y1,
2492 SANE_Int x2,
2493 SANE_Int y2,
2494 SANE_Byte* bytes,
2495 SANE_Byte bitsPerSample,
2496 SANE_Int samplesPerPixel,
2497 SANE_Int bytesPerRow)
2498 {
2499 SANE_Int pixelBytes = samplesPerPixel * bitsPerSample / 8;
2500
2501 for (SANE_Byte i = 0; i < pixelBytes; i++) {
2502 SANE_Byte temp = bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)];
2503 bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)] = bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)];
2504 bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)] = temp;
2505 }
2506 }
2507
2508
2509
swapPixel(SANE_Int x1, SANE_Int y1, SANE_Int x2, SANE_Int y2, SANE_Byte* bytes, SANE_Byte bitsPerSample, SANE_Int samplesPerPixel, SANE_Int bytesPerRow)2510 static void swapPixel(SANE_Int x1,
2511 SANE_Int y1,
2512 SANE_Int x2,
2513 SANE_Int y2,
2514 SANE_Byte* bytes,
2515 SANE_Byte bitsPerSample,
2516 SANE_Int samplesPerPixel,
2517 SANE_Int bytesPerRow)
2518 {
2519 if (bitsPerSample == 1) {
2520 swapPixel1(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2521 }else if(bitsPerSample == 8 || bitsPerSample == 16){
2522 swapPixel8(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2523 }
2524 }
2525
2526
2527 void
upside_down_backside_image(epsonds_scanner *s)2528 upside_down_backside_image(epsonds_scanner *s)
2529 {
2530 // get all data from ring_buffer
2531 if (eds_ring_avail(&s->back) &&
2532 (strcmp(s->hw->sane.model, (char*)"DS-1630") == 0
2533 || strcmp(s->hw->sane.model, (char*)"DS-1610") == 0
2534 || strcmp(s->hw->sane.model, (char*)"DS-1660W") == 0))
2535 {
2536 SANE_Int bytesPerLine = s->params.bytes_per_line;
2537 SANE_Int imageSize = bytesPerLine * s->height_back;
2538
2539 SANE_Byte* workBuffer = malloc(imageSize);
2540 // if there is not enough memory, do nothing.
2541 if (workBuffer)
2542 {
2543 eds_ring_read(&s->back, workBuffer, imageSize);
2544 SANE_Int samplesPerPxel = 3;
2545 if (s->params.format == SANE_FRAME_RGB)
2546 {
2547 samplesPerPxel = 3;
2548 }
2549 else if (s->params.format == SANE_FRAME_GRAY)
2550 {
2551 samplesPerPxel = 1;
2552 }
2553
2554 SANE_Int half = (s->height_back / 2) - 1;
2555 if (half < 0) {
2556 half = 0;
2557 }
2558
2559 if((s->height_back % 2) == 1) {
2560 SANE_Int ymid = ( (s->height_back - 1 ) / 2 );
2561 for(SANE_Int x = 0;x < (s->width_back / 2); x++) {
2562 swapPixel(x, ymid, s->width_back - x - 1, ymid, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2563 }
2564 }
2565
2566 if (s->height_back != 1) {
2567 for(SANE_Int x = 0; x < s->width_back; x++) {
2568 for(SANE_Int y = 0;y <= half; y++) {
2569 swapPixel(x, y, s->width_back - x - 1, s->height_back - y -1, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2570 }
2571 }
2572 }
2573
2574 eds_ring_write(&s->back, workBuffer, imageSize);
2575 free(workBuffer);
2576 workBuffer = NULL;
2577
2578 }
2579 }
2580
2581 }
2582
2583
2584 SANE_Status
get_next_image(epsonds_scanner *s)2585 get_next_image(epsonds_scanner *s)
2586 {
2587 SANE_Status status = SANE_STATUS_GOOD;
2588
2589 if (s->acquirePage == 0 && s->current == &s->front)
2590 {
2591 DBG(20, "** %s: get_next_image\n", __func__);
2592
2593
2594 /*page info will be updatted by pen*/
2595 s->width_back = 0;
2596 s->width_front = 0;
2597 s->height_back = 0;
2598 s->height_front = 0;
2599
2600 if (s->mode_jpeg)
2601 {
2602 status = acquire_and_decode_jpeg_data(s);
2603 }else{
2604 status = acquire_raw_data(s);
2605 }
2606 if (status != SANE_STATUS_GOOD)
2607 {
2608 eds_ring_flush(&s->front);
2609 eds_ring_flush(&s->back);
2610 eds_ring_destory(&s->front);
2611 eds_ring_destory(&s->back);
2612 }
2613 DBG(20," ringFront = %d ringBack = %d\n", eds_ring_avail(&s->front), eds_ring_avail(&s->back));
2614
2615 s->acquirePage = 1;
2616 }
2617
2618 return status;
2619 }
2620
2621
2622 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)2623 sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
2624 {
2625 epsonds_scanner *s = (epsonds_scanner *)handle;
2626
2627 DBG(5, "** %s\n", __func__);
2628
2629 if (params == NULL)
2630 DBG(1, "%s: params is NULL\n", __func__);
2631
2632 /*
2633 * If sane_start was already called, then just retrieve the parameters
2634 * from the scanner data structure
2635 */
2636 if (s->scanning) {
2637 DBG(5, "scan in progress, returning saved params structure\n");
2638 } else {
2639 /* otherwise initialize the params structure */
2640 eds_init_parameters(s);
2641 }
2642
2643
2644 SANE_Status status = SANE_STATUS_GOOD;
2645
2646 status = get_next_image(s);
2647
2648 // if size auto, update page size value
2649 if(s->val[OPT_ADF_CRP].w)
2650 {
2651 // frontside
2652 if (s->current == &s->front)
2653 {
2654 DBG(20, "front side \n");
2655 if (s->width_front != 0 && s->height_front != 0)
2656 {
2657 if (s->params.format == SANE_FRAME_RGB)
2658 {
2659 s->params.bytes_per_line = s->width_front * 3;
2660 s->params.pixels_per_line = s->width_front;
2661 }
2662
2663 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2664 {
2665 s->params.bytes_per_line = s->width_front;
2666 s->params.pixels_per_line = s->width_front;
2667 }
2668
2669 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2670 {
2671 s->params.bytes_per_line = (s->width_front + 7)/8;
2672 s->params.pixels_per_line = s->width_front;
2673 }
2674 s->params.lines = s->height_front;
2675 }
2676 }
2677 // backside
2678 if (s->current == &s->back)
2679 {
2680 DBG(20, "back side \n");
2681 if (s->width_back != 0 && s->height_back != 0)
2682 {
2683 if (s->params.format == SANE_FRAME_RGB)
2684 {
2685 s->params.bytes_per_line = s->width_back * 3;
2686 s->params.pixels_per_line = s->width_back;
2687 }
2688
2689 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2690 {
2691 s->params.bytes_per_line = s->width_back;
2692 s->params.pixels_per_line = s->width_back;
2693 }
2694
2695 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2696 {
2697 s->params.bytes_per_line = (s->width_back + 7)/8;
2698 s->params.pixels_per_line = s->width_back;
2699 }
2700 s->params.lines = s->height_back;
2701 }
2702 }
2703 }
2704 if (params != NULL)
2705 *params = s->params;
2706
2707 print_params(s->params);
2708
2709 DBG(20, "s->params.line = %d s->params.bytes_per_line = %d s->params.pixels_per_line = %d \n", s->params.lines, s->params.bytes_per_line , s->params.pixels_per_line );
2710 return status;
2711 }
2712
2713
2714
2715 typedef float ColorMatrix[3][3];
2716
2717 #define CCT_TABLE_SIZE 9
get_roundup_index(double frac[], int n)2718 static int get_roundup_index(double frac[], int n)
2719 {
2720 int i, index = -1;
2721 double max_val = 0.0;
2722
2723 for (i=0; i<n; i++) {
2724 if (frac[i]<0) continue;
2725 if (max_val<frac[i]) {
2726 index = i;
2727 max_val = frac[i];
2728 }
2729 }
2730 return index;
2731 }
2732
get_rounddown_index(double frac[], int n)2733 static int get_rounddown_index(double frac[], int n)
2734 {
2735 int i, index = -1;
2736 double min_val = 1.0;
2737
2738 for (i=0; i<n; i++) {
2739 if (frac[i]>0) continue;
2740 if (min_val>frac[i]) {
2741 index = i;
2742 min_val = frac[i];
2743 }
2744 }
2745 return index;
2746 }
2747
2748
ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[])2749 void ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[])
2750 {
2751 int i, j, index;
2752 double mult_cct[CCT_TABLE_SIZE], frac[CCT_TABLE_SIZE];
2753 int sum[3];
2754 int loop;
2755
2756 for (i=0; i<CCT_TABLE_SIZE; i++) {
2757 mult_cct[i] = org_cct[i] * mult;
2758 }
2759
2760 // round value multiplied by 'mult' off to integer.
2761 for (i=0; i<CCT_TABLE_SIZE; i++) {
2762 rnd_cct[i] = (int)floor(org_cct[i] * mult + 0.5);
2763 }
2764
2765 loop=0;
2766 do {
2767 // If all element equal to 11, diagonal element is set to 10.
2768 for (i=0; i<3; i++) {
2769 if ( (rnd_cct[i*3]==11) &&
2770 (rnd_cct[i*3]==rnd_cct[i*3+1]) &&
2771 (rnd_cct[i*3]==rnd_cct[i*3+2]) ) {
2772 rnd_cct[i*3+i] --;
2773 mult_cct[i*3+i] = rnd_cct[i*3+i];
2774 }
2775 }
2776 // calc. summation of each line.
2777 for (i=0; i<3; i++) {
2778 sum[i] = 0;
2779 for (j=0; j<3; j++) {
2780 sum[i] += rnd_cct[i*3+j];
2781 }
2782 }
2783 // calc. values rounded up or down.
2784 for (i=0; i<CCT_TABLE_SIZE; i++) {
2785 frac[i] = mult_cct[i] - rnd_cct[i];
2786 }
2787
2788 // if summation does not equal to 'mult', adjust rounded up or down value.
2789 for (i=0; i<3; i++) {
2790 if (sum[i]<mult) {
2791 index = get_roundup_index(&frac[i*3], 3);
2792 if (index!=-1) {
2793 rnd_cct[i*3+index] ++;
2794 mult_cct[i*3+index] = rnd_cct[i*3+index];
2795 sum[i]++;
2796 }
2797 } else if (sum[i]>mult) {
2798 index = get_rounddown_index(&frac[i*3], 3);
2799 if (index!=-1) {
2800 rnd_cct[i*3+index] --;
2801 mult_cct[i*3+index] = rnd_cct[i*3+index];
2802 sum[i]--;
2803 }
2804 }
2805 }
2806
2807 } while ((++loop<2)&&((sum[0]!=mult)||(sum[1]!=mult)||(sum[2]!=mult)));
2808 }
2809
2810
2811
2812 /*
2813 * This function is part of the SANE API and gets called from the front end to
2814 * start the scan process.
2815 */
2816 #define CMD_BUF_SIZE 1000
2817 SANE_Status
sane_start(SANE_Handle handle)2818 sane_start(SANE_Handle handle)
2819 {
2820 epsonds_scanner *s = (epsonds_scanner *)handle;
2821 char buf[65]; /* add one more byte to correct buffer overflow issue */
2822 char cmd[CMD_BUF_SIZE]; /* take care not to overflow */
2823 SANE_Status status = 0;
2824
2825 s->pages++;
2826
2827 DBG(5, "** %s, pages = %d, scanning = %d, backside = %d, front fill: %d, back fill: %d\n",
2828 __func__, s->pages, s->scanning, s->backside,
2829 eds_ring_avail(&s->front),
2830 eds_ring_avail(&s->back));
2831
2832 s->eof = 0;
2833 s->canceling = 0;
2834 s->acquirePage = 0;
2835
2836 if ((s->pages % 2) == 1) {
2837 s->current = &s->front;
2838 } else if (eds_ring_avail(&s->back)) {
2839 DBG(5, "back side\n");
2840 s->current = &s->back;
2841 }
2842
2843 /* scan already in progress? (one pass adf) */
2844 if (s->scanning || eds_ring_avail(&s->back) > 0) {
2845 DBG(5, " scan in progress, returning early\n");
2846 return get_next_image(s);
2847 }
2848 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2849 if (s->scanEnd)
2850 {
2851 s->scanEnd = 0;
2852 return SANE_STATUS_NO_DOCS;
2853 }
2854 }else{
2855 s->scanEnd = 0;
2856 }
2857
2858 /* calc scanning parameters */
2859 status = eds_init_parameters(s);
2860 if (status != SANE_STATUS_GOOD) {
2861 DBG(1, " parameters initialization failed\n");
2862 return status;
2863 }
2864
2865 /* allocate line buffer */
2866 s->line_buffer = realloc(s->line_buffer, s->params.bytes_per_line);
2867 if (s->line_buffer == NULL)
2868 return SANE_STATUS_NO_MEM;
2869
2870 /* transfer buffer size, bsz */
2871 /* XXX read value from scanner */
2872 s->bsz = (1048576 * 4);
2873
2874 /* transfer buffer */
2875 s->buf = realloc(s->buf, s->bsz);
2876 if (s->buf == NULL)
2877 return SANE_STATUS_NO_MEM;
2878
2879 print_params(s->params);
2880
2881 /* set scanning parameters */
2882
2883 s->isDuplexScan = 0;
2884 /* document source */
2885 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2886
2887 SANE_Int status = esci2_stat(s);
2888 if (status == SANE_STATUS_NO_DOCS)
2889 {
2890 return SANE_STATUS_NO_DOCS;
2891 }
2892
2893 SANE_Int duplexMode = (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0);
2894
2895 sprintf(buf, "#ADF%s%s%s",
2896 duplexMode ? "DPLX" : "",
2897 s->val[OPT_ADF_SKEW].w ? "SKEW" : "",
2898 s->val[OPT_ADF_CRP].w ? "CRP " : ""
2899 );
2900
2901 if (duplexMode)
2902 {
2903 s->isDuplexScan = 1;
2904 }
2905 s->isflatbedScan = 0;
2906 }
2907 else if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_FLATBED) == 0) {
2908
2909 strcpy(buf, "#FB ");
2910 s->isflatbedScan = 1;
2911
2912 } else {
2913 /* XXX */
2914 }
2915
2916 strcpy(cmd, buf);
2917
2918 s->needToConvertBW = 0;
2919
2920 if (s->params.format == SANE_FRAME_GRAY) {
2921 if (s->params.depth == 1 && s->hw->has_mono == 0)
2922 {
2923 sprintf(buf, "#COLM008");
2924 s->needToConvertBW = 1;
2925 s->mode_jpeg = 1;
2926 }else
2927 {
2928 sprintf(buf, "#COLM%03d", s->params.depth);
2929 }
2930 } else if (s->params.format == SANE_FRAME_RGB) {
2931 sprintf(buf, "#COLC%03d", s->params.depth * 3);
2932 }
2933
2934 strcat(cmd, buf);
2935
2936 /* image transfer format */
2937 if (!s->mode_jpeg) {
2938 if (s->params.depth > 1 || s->hw->has_raw) {
2939 strcat(cmd, "#FMTRAW ");
2940 }
2941 } else {
2942 strcat(cmd, "#FMTJPG #JPGd090");
2943 }
2944
2945 /* set GMM */
2946 if (s->params.depth == 1)
2947 {
2948 sprintf(buf, "#GMMUG10");
2949 } else
2950 {
2951 sprintf(buf, "#GMMUG18");
2952 }
2953 strcat(cmd, buf);
2954
2955 /* resolution (RSMi not always supported) */
2956
2957 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2958 DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2959 } else if (s->val[OPT_RESOLUTION].w > 999) {
2960 sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2961 } else {
2962 sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2963 }
2964
2965 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2966 DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2967 } else if (s->val[OPT_RESOLUTION].w > 999) {
2968 sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2969 } else {
2970 sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2971 }
2972
2973 strcat(cmd, buf);
2974
2975 if (strcmp(s->hw->sane.model, (char*)"DS-70") == 0 || strcmp(s->hw->sane.model, (char*)"ES-65WR") == 0 || strcmp(s->hw->sane.model, (char*)"ES-60W") == 0
2976 || strcmp(s->hw->sane.model, (char*)"DS-80W") == 0 || strcmp(s->hw->sane.model, (char*)"ES-55R") == 0 || strcmp(s->hw->sane.model, (char*)"ES-50") == 0){
2977 sprintf(buf, "#BSZi0262144");
2978 strcat(cmd, buf);
2979 }
2980 else {
2981 sprintf(buf, "#BSZi1048576");
2982 strcat(cmd, buf);
2983 }
2984
2985
2986 /* scanning area */
2987
2988 sprintf(buf, "#ACQi%07di%07di%07di%07d",
2989 s->left, s->top, s->params.pixels_per_line, s->params.lines);
2990
2991
2992 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2993 status = esci2_stat(s);
2994 if (status != SANE_STATUS_GOOD) {
2995 goto end;
2996 }
2997 }
2998
2999 strcat(cmd, buf);
3000
3001
3002 int pos = 0;
3003
3004 {
3005 for (int i = 0; i < CMD_BUF_SIZE; i++)
3006 {
3007 // find end of string
3008 if(cmd[i] == 0)
3009 {
3010 pos = i;
3011 break;
3012 }
3013 }
3014
3015
3016 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) {
3017 DBG(10, "SANE_FRAME_GRAY\n");
3018 cmd[pos++] = '#';
3019 cmd[pos++] = 'G';
3020 cmd[pos++] = 'M';
3021 cmd[pos++] = 'T';
3022 cmd[pos++] = 'M';
3023 cmd[pos++] = 'O';
3024 cmd[pos++] = 'N';
3025 cmd[pos++] = 'O';
3026 cmd[pos++] = 'h';
3027 cmd[pos++] = '1';
3028 cmd[pos++] = '0';
3029 cmd[pos++] = '0';
3030
3031 for(int count = 0; count < 256; count++) {
3032 cmd[pos++] = LUT[s->hw->lut_id][count];
3033 }
3034 }
3035 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) {
3036 DBG(10, "SANE_FRAME_GRAY\n");
3037 cmd[pos++] = '#';
3038 cmd[pos++] = 'G';
3039 cmd[pos++] = 'M';
3040 cmd[pos++] = 'T';
3041 cmd[pos++] = 'M';
3042 cmd[pos++] = 'O';
3043 cmd[pos++] = 'N';
3044 cmd[pos++] = 'O';
3045 cmd[pos++] = 'h';
3046 cmd[pos++] = '1';
3047 cmd[pos++] = '0';
3048 cmd[pos++] = '0';
3049
3050 for(int count = 0; count < 256; count++) {
3051 cmd[pos++] = LUT[0][count];
3052 }
3053 }
3054 else if (s->params.format == SANE_FRAME_RGB) {
3055 DBG(10, "SANE_FRAME_RGB\n");
3056 cmd[pos++] = '#';
3057 cmd[pos++] = 'G';
3058 cmd[pos++] = 'M';
3059 cmd[pos++] = 'T';
3060 cmd[pos++] = 'R';
3061 cmd[pos++] = 'E';
3062 cmd[pos++] = 'D';
3063 cmd[pos++] = ' ';
3064 cmd[pos++] = 'h';
3065 cmd[pos++] = '1';
3066 cmd[pos++] = '0';
3067 cmd[pos++] = '0';
3068
3069 for(int count = 0; count < 256; count++) {
3070 cmd[pos++] = LUT_R[s->hw->lut_id][count];
3071 }
3072
3073 cmd[pos++] = '#';
3074 cmd[pos++] = 'G';
3075 cmd[pos++] = 'M';
3076 cmd[pos++] = 'T';
3077 cmd[pos++] = 'G';
3078 cmd[pos++] = 'R';
3079 cmd[pos++] = 'N';
3080 cmd[pos++] = ' ';
3081 cmd[pos++] = 'h';
3082 cmd[pos++] = '1';
3083 cmd[pos++] = '0';
3084 cmd[pos++] = '0';
3085
3086 for(int count = 0; count < 256; count++) {
3087 cmd[pos++] = LUT_G[s->hw->lut_id][count];
3088 }
3089
3090 cmd[pos++] = '#';
3091 cmd[pos++] = 'G';
3092 cmd[pos++] = 'M';
3093 cmd[pos++] = 'T';
3094 cmd[pos++] = 'B';
3095 cmd[pos++] = 'L';
3096 cmd[pos++] = 'U';
3097 cmd[pos++] = ' ';
3098 cmd[pos++] = 'h';
3099 cmd[pos++] = '1';
3100 cmd[pos++] = '0';
3101 cmd[pos++] = '0';
3102
3103 for(int count = 0; count < 256; count++) {
3104 cmd[pos++] = LUT_B[s->hw->lut_id][count];
3105 }
3106 }
3107 cmd[pos] = 0;
3108
3109 }
3110 {// Set Color Matrix
3111 if (s->params.format == SANE_FRAME_RGB && s->hw->lut_id != 0 )/*Color Matrix Target devide and color Scan*/
3112 {
3113 ColorMatrix matrix;
3114
3115 // DS-530
3116
3117 if (s->hw->lut_id == 2)
3118 {
3119 // R
3120 matrix[0][0] = 1.0229;
3121 matrix[0][1] = 0.0009;
3122 matrix[0][2] = -0.0238;
3123
3124 // G
3125 matrix[1][0] = 0.0031;
3126 matrix[1][1] = 1.0287;
3127 matrix[1][2] = -0.0318;
3128
3129 //B
3130 matrix[2][0] = 0.0044;
3131 matrix[2][1] = -0.1150;
3132 matrix[2][2] = 1.1106;
3133 }
3134
3135 // DS-1660W Flatbed
3136
3137 if (s->hw->lut_id == 4)
3138 {
3139 // R
3140 matrix[0][0] = 1.0229;
3141 matrix[0][1] = 0.0009;
3142 matrix[0][2] = -0.0238;
3143
3144 // G
3145 matrix[1][0] = 0.0031;
3146 matrix[1][1] = 1.0287;
3147 matrix[1][2] = -0.0318;
3148
3149 //B
3150 matrix[2][0] = 0.0044;
3151 matrix[2][1] = -0.1150;
3152 matrix[2][2] = 1.1106;
3153 }
3154
3155
3156 // DS-320
3157
3158 if (s->hw->lut_id == 5)
3159 {
3160 // R
3161 matrix[0][0] = 1.0250;
3162 matrix[0][1] = 0.0004;
3163 matrix[0][2] = -0.0254;
3164
3165 // G
3166 matrix[1][0] = 0.0003;
3167 matrix[1][1] = 1.0022;
3168 matrix[1][2] = -0.0025;
3169
3170 //B
3171 matrix[2][0] = 0.0049;
3172 matrix[2][1] = -0.0949;
3173 matrix[2][2] = 1.0900;
3174 }
3175
3176
3177 // ES-50
3178
3179 if (s->hw->lut_id == 6)
3180 {
3181 // R
3182 matrix[0][0] = 1.0383;
3183 matrix[0][1] = -0.0021;
3184 matrix[0][2] = -0.0362;
3185
3186 // G
3187 matrix[1][0] = 0.0046;
3188 matrix[1][1] = 1.0576;
3189 matrix[1][2] = -0.0622;
3190
3191 //B
3192 matrix[2][0] = 0.0235;
3193 matrix[2][1] = -0.2396;
3194 matrix[2][2] = 1.2161;
3195 }
3196
3197
3198 // R
3199 matrix[0][0] = 0.9864;
3200 matrix[0][1] = 0.0248;
3201 matrix[0][2] = -0.0112;
3202
3203 // G
3204 matrix[1][0] = 0.0021;
3205 matrix[1][1] = 1.0100;
3206 matrix[1][2] = -0.0112;
3207
3208 //B
3209 matrix[2][0] = 0.0139;
3210 matrix[2][1] = -0.1249;
3211 matrix[2][2] = 1.1110;
3212
3213
3214 // Set Matrix value
3215 {
3216 cmd[pos++] = '#';
3217 cmd[pos++] = 'C';
3218 cmd[pos++] = 'M';
3219 cmd[pos++] = 'X';
3220 cmd[pos++] = 'U';
3221 cmd[pos++] = 'M';
3222 cmd[pos++] = '0';
3223 cmd[pos++] = '8';
3224 cmd[pos++] = 'h';
3225 cmd[pos++] = '0';
3226 cmd[pos++] = '0';
3227 cmd[pos++] = '9';
3228 }
3229
3230
3231 // Matrix to be sent to scanner must be following d1-d9 order:
3232 //
3233 // G R B
3234 // G [d1 d4 d7]
3235 // R [d2 d5 d8]
3236 // B [d3 d6 d9]
3237 //
3238 // So, we will convert it with index table.
3239 char index[9] = {4, 1, 7, 3, 0, 6, 5, 2, 8};
3240
3241 double flatten[9] = {0};
3242 for (int row = 0; row < 3; row++) {
3243 for (int col = 0; col < 3; col++) {
3244 flatten[row * 3 + col] = matrix[row][col];
3245 }
3246 }
3247
3248 int rounded[9] = {0};
3249 ESCIRoundColorCorrectionMatrix(32, flatten, rounded);
3250
3251
3252 char ordered[9] = {0};
3253 for (int row = 0; row < 3; row++) {
3254 for (int col = 0; col < 3; col++) {
3255 int val = rounded[row * 3 + col];
3256 unsigned char oct = (unsigned char)abs(val);
3257 oct |= ((val < 0) ? (1 << 7) : 0);
3258 ordered[(signed char)index[row * 3 + col]] = oct;
3259 }
3260 }
3261 {
3262 cmd[pos++] = ordered[0];
3263 cmd[pos++] = ordered[1];
3264 cmd[pos++] = ordered[2];
3265 cmd[pos++] = ordered[3];
3266 cmd[pos++] = ordered[4];
3267 cmd[pos++] = ordered[5];
3268 cmd[pos++] = ordered[6];
3269 cmd[pos++] = ordered[7];
3270 cmd[pos++] = ordered[8];
3271 cmd[pos++] = 0; //padding
3272 cmd[pos++] = 0; //padding
3273 cmd[pos++] = 0; //padding
3274
3275
3276 DBG(1, "color matrix\n");
3277 for (int i = 0; i < 9; i++)
3278 {
3279 DBG(1, "%d\n", ordered[i]);
3280 }
3281
3282 }
3283 cmd[pos] = 0;
3284 }
3285
3286 }
3287
3288
3289 status = esci2_para(s, cmd, pos);
3290 if (status != SANE_STATUS_GOOD) {
3291 goto end;
3292 }
3293
3294 /* start scanning */
3295 DBG(1, "%s: scanning...\n", __func__);
3296
3297 /* switch to data state */
3298 status = esci2_trdt(s);
3299 if (status != SANE_STATUS_GOOD) {
3300 goto end;
3301 }
3302
3303 /* first page is page 1 */
3304 s->pages = 1;
3305 s->scanning = 1;
3306 s->dummy = 0;
3307 s->scanEnd = 0;
3308 end:
3309 if (status != SANE_STATUS_GOOD) {
3310 DBG(1, "%s: start failed: %s\n", __func__, sane_strstatus(status));
3311 }
3312
3313 return status;
3314 }
3315
acquire_jpeg_data(epsonds_scanner* s)3316 static SANE_Status acquire_jpeg_data(epsonds_scanner* s)
3317 {
3318
3319 SANE_Int read = 0;
3320
3321 SANE_Int jpegBufSize = s->params.bytes_per_line * s->params.lines;
3322 if (s->needToConvertBW)
3323 {
3324 jpegBufSize = s->params.pixels_per_line * s->params.lines;
3325 }
3326
3327
3328 s->frontJpegBuf = malloc(jpegBufSize);
3329 s->backJpegBuf = malloc(jpegBufSize);
3330 s->frontJpegBufLen = 0;
3331 s->backJpegBufLen = 0;
3332
3333 // load all images, decode and fill buffer
3334 SANE_Int status = SANE_STATUS_GOOD;
3335
3336 int eofFront = 0;
3337 int eofBack = 0;
3338
3339
3340 status = eds_ring_init(&s->front, (s->params.bytes_per_line) * s->params.lines);
3341 if (status != SANE_STATUS_GOOD) {
3342 return status;
3343 }
3344
3345 status = eds_ring_init(&s->back, (s->params.bytes_per_line) * s->params.lines);
3346 if (status != SANE_STATUS_GOOD) {
3347 return status;
3348 }
3349
3350 while (1)
3351 {
3352 status = esci2_img(s, &read);
3353 DBG(20, "acquire_jpeg_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3354 if (read)
3355 {
3356 if (s->backside)
3357 {
3358 SANE_Byte* backBuffer = s->backJpegBuf + s->backJpegBufLen;
3359 memcpy(backBuffer, s->buf, read);
3360 s->backJpegBufLen += read;
3361 }else{
3362 SANE_Byte* frontBuffer = s->frontJpegBuf + s->frontJpegBufLen ;
3363 memcpy(frontBuffer, s->buf, read);
3364 s->frontJpegBufLen += read;
3365 }
3366 }
3367 if (status == SANE_STATUS_GOOD)
3368 {
3369
3370 DBG(20, "continue acquire image\n");
3371 continue;
3372 }
3373 else if (status == SANE_STATUS_EOF)
3374 {
3375 if (s->backside)
3376 {
3377 DBG(20, "eofBack\n");
3378 eofBack = 1;
3379 }else{
3380 DBG(20, "eofFront\n");
3381 eofFront = 1;
3382 }
3383 }else if (status == SANE_STATUS_CANCELLED)
3384 {
3385 // cancel cleanup
3386 esci2_can(s);
3387
3388 free(s->frontJpegBuf);
3389 free(s->backJpegBuf);
3390 s->frontJpegBuf = NULL;
3391 s->backJpegBuf = NULL;
3392 return status;
3393 }else{
3394 // error occurs cleanup
3395 free(s->frontJpegBuf);
3396 free(s->backJpegBuf);
3397 s->frontJpegBuf = NULL;
3398 s->backJpegBuf = NULL;
3399 return status;
3400 }
3401
3402
3403 if (s->isDuplexScan)
3404 {
3405 DBG(20, "eofFront = %d eofBack = %d\n", eofFront, eofBack);
3406 // acquire finish
3407 if (eofFront && eofBack)
3408 {
3409 DBG(20, "eofFront && eofBack end\n");
3410 break;
3411 }
3412 }else{
3413 if (eofFront)
3414 {
3415 DBG(20, "eofFront end\n");
3416 break;
3417 }
3418 }
3419 }
3420
3421 return SANE_STATUS_GOOD;
3422 }
3423
3424 static SANE_Status
acquire_raw_data(epsonds_scanner* s)3425 acquire_raw_data(epsonds_scanner* s)
3426 {
3427 SANE_Int read = 0;
3428
3429 // load all images, decode and fill buffer
3430 SANE_Int status = SANE_STATUS_GOOD;
3431
3432 int eofFront = 0;
3433 int eofBack = 0;
3434 int firstWrite = 1;
3435
3436 while (1)
3437 {
3438 DBG(20, "acquire_raw_data loop start\n");
3439 status = esci2_img(s, &read);
3440 DBG(20, "acquire_raw_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3441
3442 if (read)
3443 {
3444 if (firstWrite)
3445 {
3446 status = eds_ring_init(&s->front, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3447 if (status != SANE_STATUS_GOOD) {
3448 return status;
3449 }
3450
3451 status = eds_ring_init(&s->back, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3452 if (status != SANE_STATUS_GOOD) {
3453 return status;
3454 }
3455 firstWrite = 0;
3456 }
3457
3458 DBG(20, "eds_ring_write start\n");
3459 status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read);
3460 DBG(20, "eds_ring_write end\n");
3461 }
3462 DBG(20, "acquire_raw_data3\n");
3463
3464 if (status == SANE_STATUS_GOOD)
3465 {
3466 DBG(20, "contiune acquire image\n");
3467 continue;
3468 }
3469 else if (status == SANE_STATUS_EOF)
3470 {
3471 if (s->backside)
3472 {
3473 eofBack = 1;
3474 }else{
3475 eofFront = 1;
3476 }
3477 }
3478 else if (status == SANE_STATUS_CANCELLED)
3479 {
3480 esci2_can(s);
3481 return status;
3482 }else{
3483 // error occurs cleanup
3484 return status;
3485 }
3486
3487 if (s->isDuplexScan)
3488 {
3489 // acquire finish
3490 if (eofFront && eofBack)
3491 {
3492 break;
3493 }
3494 }else{
3495 if (eofFront)
3496 {
3497 break;
3498 }
3499 }
3500 }
3501
3502
3503 int needBytes = (s->params.bytes_per_line + s->dummy) * s->params.lines;
3504 {
3505 int available = eds_ring_avail(&s->front);
3506 if (available < needBytes)
3507 {
3508 int required = needBytes - available;
3509 unsigned char* padding = (unsigned char*)malloc(required);
3510 memset(padding, 255, required);
3511 eds_ring_write(&s->front, padding, required);
3512 free(padding);
3513
3514 }
3515
3516 }
3517 {
3518 int available = eds_ring_avail(&s->back);
3519 if (available > 0 && available < needBytes)
3520 {
3521 int required = needBytes - available;
3522 unsigned char* padding = (unsigned char*)malloc(required);
3523 memset(padding, 255, required);
3524 eds_ring_write(&s->back, padding, required);
3525 free(padding);
3526 }
3527
3528 }
3529
3530 if (s->isDuplexScan)
3531 {
3532 upside_down_backside_image(s);
3533 }
3534
3535 DBG(20, "acquire_raw_data finish");
3536 return SANE_STATUS_GOOD;
3537
3538 }
3539
3540 static SANE_Status
acquire_and_decode_jpeg_data(epsonds_scanner* s)3541 acquire_and_decode_jpeg_data(epsonds_scanner* s)
3542 {
3543 SANE_Int status = acquire_jpeg_data(s);
3544 if (status == SANE_STATUS_GOOD)
3545 {
3546 DBG(20, "** %s: sane status = %d needToConvertBW = %d \n", __func__, status, s->needToConvertBW);
3547
3548 // process front page
3549 if (s->frontJpegBufLen > 0)
3550 {
3551 eds_decode_jpeg(s, s->frontJpegBuf, s->frontJpegBufLen, &s->front,0, s->needToConvertBW);
3552 free(s->frontJpegBuf);
3553 s->frontJpegBuf = NULL;
3554 }
3555 // process back page
3556 if (s->backJpegBufLen > 0)
3557 {
3558 eds_decode_jpeg(s, s->backJpegBuf, s->backJpegBufLen, &s->back, 1, s->needToConvertBW);
3559 free(s->backJpegBuf);
3560 s->backJpegBuf = NULL;
3561 }
3562
3563 if (s->isDuplexScan)
3564 {
3565 upside_down_backside_image(s);
3566 }
3567 }else{
3568 DBG(20, "** %s: sane finish status = %d\n", __func__, status);
3569 return status;
3570 }
3571 return status;
3572 }
3573
3574 int sumLength = 0;
3575 /* this moves data from our buffers to SANE */
3576 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length)3577 sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length)
3578 {
3579 epsonds_scanner *s = (epsonds_scanner *)handle;
3580 SANE_Int read = 0;
3581
3582 if (s->canceling)
3583 {
3584 esci2_can(s);
3585 *length = 0;
3586 return SANE_STATUS_CANCELLED;
3587 }
3588
3589 int available = eds_ring_avail(s->current);
3590 /* anything in the buffer? pass it to the frontend */
3591 if (available > 0) {
3592
3593 DBG(18, "reading from ring buffer, %d left\n", available);
3594
3595 eds_copy_image_from_ring(s, data, max_length, &read);
3596
3597 // data is empty fin
3598 if (read == 0) {
3599 *length = 0;
3600 eds_ring_flush(s->current);
3601 eds_ring_destory(s->current);
3602 DBG(18, "returns EOF 2\n");
3603 return SANE_STATUS_EOF;
3604 }
3605 *length = read;
3606
3607 return SANE_STATUS_GOOD;
3608 }else{
3609 *length = 0;
3610 eds_ring_flush(s->current);
3611 eds_ring_destory(s->current);
3612 DBG(18, "returns EOF 1\n");
3613 return SANE_STATUS_EOF;
3614 }
3615 }
3616
3617 /*
3618 * void sane_cancel(SANE_Handle handle)
3619 *
3620 * Set the cancel flag to true. The next time the backend requests data
3621 * from the scanner the CAN message will be sent.
3622 */
3623
3624 void
sane_cancel(SANE_Handle handle)3625 sane_cancel(SANE_Handle handle)
3626 {
3627 DBG(1, "** %s\n", __func__);
3628 ((epsonds_scanner *)handle)->canceling = SANE_TRUE;
3629 }
3630
3631 /*
3632 * SANE_Status sane_set_io_mode()
3633 *
3634 * not supported - for asynchronous I/O
3635 */
3636
3637 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle, SANE_Bool __sane_unused__ non_blocking)3638 sane_set_io_mode(SANE_Handle __sane_unused__ handle,
3639 SANE_Bool __sane_unused__ non_blocking)
3640 {
3641 return SANE_STATUS_UNSUPPORTED;
3642 }
3643
3644 /*
3645 * SANE_Status sane_get_select_fd()
3646 *
3647 * not supported - for asynchronous I/O
3648 */
3649
3650 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ *fd)3651 sane_get_select_fd(SANE_Handle __sane_unused__ handle,
3652 SANE_Int __sane_unused__ *fd)
3653 {
3654 return SANE_STATUS_UNSUPPORTED;
3655 }
3656