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 {0x0193, "ES-C220","ES-C220", 5},
1263 {0x018F, "DS-C330","DS-C330", 5},
1264 {0x0191, "DS-C490","DS-C490", 5},
1265 {0x00, "","", 0x00 }
1266 };
1267
1268 typedef struct
1269 {
1270 epsonds_profile_map *array;
1271 int used;
1272 int size;
1273 }epsonds_profile_map_array;
1274
1275
1276 static epsonds_profile_map_array stProfileMapArray;
1277
1278 static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element);
1279
init_profile_maps(epsonds_profile_map_array * a,size_t initialSize)1280 static void init_profile_maps(epsonds_profile_map_array *a, size_t initialSize) {
1281 a->array = malloc(initialSize * sizeof(epsonds_profile_map));
1282 a->used = 0;
1283 a->size = initialSize;
1284
1285 for (int i = 0; epsonds_models_predefined[i].productID != 0; i++) {
1286
1287 //DBG(6, "epsonds_models_predefined[i].productID = %x\n", epsonds_models_predefined[i].productID );
1288
1289 insert_profile_map(a, epsonds_models_predefined[i]);
1290 }
1291 }
1292
insert_profile_map(epsonds_profile_map_array * a,epsonds_profile_map element)1293 static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element) {
1294 if (a->used == a->size) {
1295 a->size *= 2;
1296 a->array = realloc(a->array, a->size * sizeof(epsonds_profile_map));
1297 }
1298 a->array[a->used++] = element;
1299 }
1300
free_profile_maps(epsonds_profile_map_array * a)1301 static void free_profile_maps(epsonds_profile_map_array *a) {
1302 free(a->array);
1303 a->array = NULL;
1304 a->used = a->size = 0;
1305 }
1306 /////////////////////////
1307
1308
1309 struct mode_param mode_params[] = {
1310 {0, 0x00, 0x30, 1},
1311 {0, 0x00, 0x30, 8},
1312 {1, 0x02, 0x00, 8},
1313 {0, 0x00, 0x30, 1}
1314 };
1315
1316 static SANE_String_Const mode_list[] = {
1317 SANE_VALUE_SCAN_MODE_LINEART,
1318 SANE_VALUE_SCAN_MODE_GRAY,
1319 SANE_VALUE_SCAN_MODE_COLOR,
1320 NULL
1321 };
1322
1323
1324 /* Define the different scan sources */
1325
1326 #define STRING_FLATBED SANE_I18N("Flatbed")
1327 #define STRING_ADFFRONT SANE_I18N("ADF Front")
1328 #define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
1329
1330 /* order will be fixed: fb, adf, tpu */
1331 SANE_String_Const source_list[] = {
1332 NULL,
1333 NULL,
1334 NULL,
1335 NULL
1336 };
1337
1338 /*
1339 * List of pointers to devices - will be dynamically allocated depending
1340 * on the number of devices found.
1341 */
1342 static const SANE_Device **devlist;
1343
1344 /* Some utility functions */
1345
1346 static size_t
max_string_size(const SANE_String_Const strings[])1347 max_string_size(const SANE_String_Const strings[])
1348 {
1349 size_t size, max_size = 0;
1350 int i;
1351
1352 for (i = 0; strings[i]; i++) {
1353 size = strlen(strings[i]) + 1;
1354 if (size > max_size)
1355 max_size = size;
1356 }
1357 return max_size;
1358 }
1359
1360 static SANE_Status attach_one_usb(SANE_String_Const devname);
1361 static SANE_Status attach_one_net(SANE_String_Const devname);
1362 static SANE_Status acquire_jpeg_data(epsonds_scanner* s);
1363 static SANE_Status acquire_and_decode_jpeg_data(epsonds_scanner* s);
1364 static SANE_Status acquire_raw_data(epsonds_scanner* s);
1365
1366 static void
print_params(const SANE_Parameters params)1367 print_params(const SANE_Parameters params)
1368 {
1369 DBG(6, "params.format = %d\n", params.format);
1370 DBG(6, "params.last_frame = %d\n", params.last_frame);
1371 DBG(6, "params.bytes_per_line = %d\n", params.bytes_per_line);
1372 DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
1373 DBG(6, "params.lines = %d\n", params.lines);
1374 DBG(6, "params.depth = %d\n", params.depth);
1375 }
1376
1377 static void
close_scanner(epsonds_scanner * s)1378 close_scanner(epsonds_scanner *s)
1379 {
1380 DBG(7, "%s: fd = %d\n", __func__, s->fd);
1381
1382 if (s->scanning)
1383 {
1384 sane_cancel(s);
1385 }
1386
1387 if (s->fd == -1)
1388 goto free;
1389
1390 if (s->locked) {
1391 DBG(7, " unlocking scanner\n");
1392 esci2_fin(s);
1393 }
1394
1395 if (s->hw->connection == SANE_EPSONDS_NET) {
1396 epsonds_net_unlock(s);
1397 sanei_tcp_close(s->fd);
1398 } else if (s->hw->connection == SANE_EPSONDS_USB) {
1399 sanei_usb_close(s->fd);
1400 }
1401
1402 free:
1403
1404 free(s->front.ring);
1405 free(s->back.ring);
1406 free(s->line_buffer);
1407 free(s);
1408
1409 DBG(7, "%s: ZZZ\n", __func__);
1410 }
1411
1412 static SANE_Status
open_scanner(epsonds_scanner * s)1413 open_scanner(epsonds_scanner *s)
1414 {
1415 SANE_Status status = SANE_STATUS_INVAL;
1416
1417 DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
1418
1419 if (s->fd != -1) {
1420 DBG(5, "scanner is already open: fd = %d\n", s->fd);
1421 return SANE_STATUS_GOOD; /* no need to open the scanner */
1422 }
1423
1424 if (s->hw->connection == SANE_EPSONDS_NET) {
1425 unsigned char buf[5];
1426
1427 /* device name has the form net:ipaddr */
1428 status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);
1429 if (status == SANE_STATUS_GOOD) {
1430
1431 ssize_t read;
1432 struct timeval tv;
1433
1434 tv.tv_sec = 5;
1435 tv.tv_usec = 0;
1436
1437 setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
1438
1439 s->netlen = 0;
1440
1441 DBG(32, "awaiting welcome message\n");
1442
1443 /* the scanner sends a kind of welcome msg */
1444 // XXX check command type, answer to connect is 0x80
1445 read = eds_recv(s, buf, 5, &status);
1446 if (read != 5) {
1447 sanei_tcp_close(s->fd);
1448 s->fd = -1;
1449 return SANE_STATUS_IO_ERROR;
1450 }
1451
1452 DBG(32, "welcome message received, locking the scanner...\n");
1453
1454 /* lock the scanner for use by sane */
1455 status = epsonds_net_lock(s);
1456 if (status != SANE_STATUS_GOOD) {
1457 DBG(1, "%s cannot lock scanner: %s\n", s->hw->sane.name,
1458 sane_strstatus(status));
1459
1460 sanei_tcp_close(s->fd);
1461 s->fd = -1;
1462
1463 return status;
1464 }
1465
1466 DBG(32, "scanner locked\n");
1467 }
1468
1469 } else if (s->hw->connection == SANE_EPSONDS_USB) {
1470 status = sanei_usb_open(s->hw->sane.name, &s->fd);
1471
1472 if (status == SANE_STATUS_GOOD) {
1473 sanei_usb_set_timeout(USB_TIMEOUT);
1474 }
1475
1476 } else {
1477 DBG(1, "unknown connection type: %d\n", s->hw->connection);
1478 }
1479
1480 if (status == SANE_STATUS_ACCESS_DENIED) {
1481 DBG(1, "please check that you have permissions on the device.\n");
1482 DBG(1, "if this is a multi-function device with a printer,\n");
1483 DBG(1, "disable any conflicting driver (like usblp).\n");
1484 }
1485
1486 if (status != SANE_STATUS_GOOD)
1487 DBG(1, "%s open failed: %s\n",
1488 s->hw->sane.name,
1489 sane_strstatus(status));
1490 else
1491 DBG(5, " opened correctly\n");
1492
1493 return status;
1494 }
1495
1496 static int num_devices; /* number of scanners attached to backend */
1497 static epsonds_device *first_dev; /* first EPSON scanner in list */
1498
1499 static struct epsonds_scanner *
scanner_create(struct epsonds_device * dev,SANE_Status * status)1500 scanner_create(struct epsonds_device *dev, SANE_Status *status)
1501 {
1502 struct epsonds_scanner *s;
1503 s = malloc(sizeof(struct epsonds_scanner));
1504 if (s == NULL) {
1505 *status = SANE_STATUS_NO_MEM;
1506 return NULL;
1507 }
1508
1509 /* clear verything */
1510 memset(s, 0x00, sizeof(struct epsonds_scanner));
1511
1512 s->fd = -1;
1513 s->hw = dev;
1514
1515 return s;
1516 }
1517
1518 static struct epsonds_scanner *
device_detect(const char * name,int type,SANE_Status * status)1519 device_detect(const char *name, int type, SANE_Status *status)
1520 {
1521 struct epsonds_scanner *s;
1522 struct epsonds_device *dev;
1523
1524 DBG(1, "%s, %s, type: %d\n", __func__, name, type);
1525
1526 /* try to find the device in our list */
1527 for (dev = first_dev; dev; dev = dev->next) {
1528
1529 if (strcmp(dev->sane.name, name) == 0) {
1530
1531 DBG(1, " found cached device\n");
1532
1533 // the device might have been just probed, sleep a bit.
1534 if (dev->connection == SANE_EPSONDS_NET) {
1535 sleep(1);
1536 }
1537
1538 return scanner_create(dev, status);
1539 }
1540 }
1541
1542 /* not found, create new if valid */
1543 if (type == SANE_EPSONDS_NODEV) {
1544 *status = SANE_STATUS_INVAL;
1545 return NULL;
1546 }
1547
1548 /* alloc and clear our device structure */
1549 dev = malloc(sizeof(*dev));
1550 if (!dev) {
1551 *status = SANE_STATUS_NO_MEM;
1552 return NULL;
1553 }
1554 memset(dev, 0x00, sizeof(struct epsonds_device));
1555
1556 s = scanner_create(dev, status);
1557 if (s == NULL)
1558 return NULL;
1559
1560 dev->connection = type;
1561 dev->model = strdup("(undetermined)");
1562 dev->name = strdup(name);
1563
1564 dev->sane.name = dev->name;
1565 dev->sane.vendor = "Epson";
1566 dev->sane.model = dev->model;
1567 dev->sane.type = "ESC/I-2";
1568
1569 *status = open_scanner(s);
1570 if (*status != SANE_STATUS_GOOD) {
1571 free(s);
1572 return NULL;
1573 }
1574
1575 eds_dev_init(dev);
1576
1577 /* lock scanner */
1578 *status = eds_lock(s);
1579 if (*status != SANE_STATUS_GOOD) {
1580 goto close;
1581 }
1582
1583 /* discover capabilities */
1584 *status = esci2_info(s);
1585 if (*status != SANE_STATUS_GOOD)
1586 goto close;
1587
1588 *status = esci2_capa(s);
1589 if (*status != SANE_STATUS_GOOD)
1590 goto close;
1591
1592 *status = esci2_resa(s);
1593 if (*status != SANE_STATUS_GOOD)
1594 goto close;
1595
1596 // assume 1 and 8 bit are always supported
1597 eds_add_depth(s->hw, 1);
1598 eds_add_depth(s->hw, 8);
1599
1600 // setup area according to available options
1601 if (s->hw->has_fb) {
1602
1603 dev->x_range = &dev->fbf_x_range;
1604 dev->y_range = &dev->fbf_y_range;
1605 dev->alignment = dev->fbf_alignment;
1606
1607 } else if (s->hw->has_adf) {
1608
1609 dev->x_range = &dev->adf_x_range;
1610 dev->y_range = &dev->adf_y_range;
1611 dev->alignment = dev->adf_alignment;
1612
1613 } else {
1614 DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n");
1615 }
1616
1617 *status = eds_dev_post_init(dev);
1618 if (*status != SANE_STATUS_GOOD)
1619 goto close;
1620
1621 DBG(1, "scanner model: %s\n", dev->model);
1622
1623
1624 s->hw->lut_id = 0;
1625
1626 for (int i = 0; i < stProfileMapArray.used; i++) {
1627
1628 epsonds_profile_map* map = &stProfileMapArray.array[i];
1629
1630
1631 if (strcmp(map->productName, dev->model) == 0) {
1632
1633 {//Convert to user friendly model name
1634 free(s->hw->model);
1635
1636 s->hw->model = strdup(map->deviceID);
1637 s->hw->sane.model = s->hw->model;
1638 }
1639 {// set lutid
1640 s->hw->lut_id = map->lutID;
1641 }
1642 break;
1643 }
1644 }
1645 DBG(1, "scanner lut_id: %d\n", s->hw->lut_id);
1646
1647 num_devices++;
1648 dev->next = first_dev;
1649 first_dev = dev;
1650
1651 return s;
1652
1653 close:
1654 DBG(1, " failed\n");
1655
1656 close_scanner(s);
1657 return NULL;
1658 }
1659
1660
1661 static SANE_Status
attach(const char * name,int type)1662 attach(const char *name, int type)
1663 {
1664 SANE_Status status;
1665 epsonds_scanner * s;
1666
1667 DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
1668
1669 s = device_detect(name, type, &status);
1670 if (s == NULL)
1671 return status;
1672
1673 close_scanner(s);
1674 return status;
1675 }
1676
1677 SANE_Status
attach_one_usb(const char * dev)1678 attach_one_usb(const char *dev)
1679 {
1680 DBG(7, "%s: dev = %s\n", __func__, dev);
1681 return attach(dev, SANE_EPSONDS_USB);
1682 }
1683
1684 static SANE_Status
attach_one_net(const char * dev)1685 attach_one_net(const char *dev)
1686 {
1687 char name[39 + 4];
1688
1689 DBG(7, "%s: dev = %s\n", __func__, dev);
1690
1691 strcpy(name, "net:");
1692 strcat(name, dev);
1693 return attach(name, SANE_EPSONDS_NET);
1694 }
1695
found_net_device(const char * device_name,const char * ip)1696 static void found_net_device(const char* device_name, const char* ip)
1697 {
1698 DBG(7, "Found %s: ip = %s\n", device_name, ip);
1699
1700 int foundSupportedDevice = 0;
1701
1702 // search models
1703 for (int i = 0; i < stProfileMapArray.used; i++) {
1704 if (strcmp(stProfileMapArray.array[i].deviceID, device_name) == 0) {
1705 foundSupportedDevice = 1;
1706 break;
1707 }
1708 }
1709
1710
1711 if (foundSupportedDevice)
1712 {
1713 char name[39 + 4];
1714
1715 strcpy(name, "net:");
1716 strncat(name, ip, 39);
1717
1718 int foundCache = 0;
1719 // search cache and prents duplicated model
1720 for (epsonds_device* dev = first_dev; dev; dev = dev->next) {
1721 if (strcmp(dev->sane.name, name) == 0) {
1722 foundCache = 1;
1723 }
1724 }
1725 if (foundCache == 0)
1726 {
1727 attach(name, SANE_EPSONDS_NET);
1728 }
1729 }
1730 }
1731
1732 static void
splitProfileName(const char * input,int * outProductID,char * outProductName,char * outDeviceID,int * outLutID)1733 splitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID)
1734 {
1735 char target[1024];
1736 strncpy(target, input, 1023);
1737
1738 strtok(target, ":");//profile
1739
1740 //productID
1741 char* pid = strtok(NULL, ",");
1742 sscanf(pid, "%x", (unsigned int*)outProductID);
1743
1744 //productName
1745 char* productName = strtok(NULL, ",");
1746 strncpy(outProductName, productName, 49);
1747
1748 //deviceID
1749 char* deviceID = strtok(NULL, ",");
1750 strncpy(outDeviceID, deviceID, 49);
1751
1752 //lutID
1753 char* lutID = strtok(NULL, ",");
1754 sscanf(lutID, "%d", outLutID);
1755 }
1756
1757
1758 static SANE_Status
attach_one_config(SANEI_Config __sane_unused__ * config,const char * line,void * data)1759 attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,
1760 void *data)
1761 {
1762 int vendor, product;
1763 SANE_Bool local_only = *(SANE_Bool*) data;
1764 int len = strlen(line);
1765
1766 DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
1767 if (strncmp(line, "profile", 7) == 0 ) {
1768 DBG(7, " found profile device profile\n");
1769
1770 epsonds_profile_map profle_map;
1771
1772 splitProfileName(line, &profle_map.productID, profle_map.productName, profle_map.deviceID, &profle_map.lutID);
1773
1774 DBG(7, "Found profile : %x %s %s %d\n", profle_map.productID, profle_map.productName, profle_map.deviceID, profle_map.lutID);
1775
1776 insert_profile_map(&stProfileMapArray, profle_map);
1777 }else if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
1778
1779 DBG(7, " user configured device\n");
1780
1781 if (vendor != SANE_EPSONDS_VENDOR_ID)
1782 return SANE_STATUS_INVAL; /* this is not an Epson device */
1783
1784 sanei_usb_attach_matching_devices(line, attach_one_usb);
1785
1786 } else if (strncmp(line, "usb", 3) == 0 && len == 3) {
1787
1788 DBG(7, " probing usb devices\n");
1789
1790 for (int i = 0; i < stProfileMapArray.used; i++) {
1791 int usbPid = stProfileMapArray.array[i].productID;
1792 sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, usbPid, attach_one_usb);
1793 }
1794
1795 } else if (strncmp(line, "net", 3) == 0) {
1796
1797 if (!local_only) {
1798 /* remove the "net" sub string */
1799 const char *name =
1800 sanei_config_skip_whitespace(line + 3);
1801
1802 if (strncmp(name, "autodiscovery", 13) == 0)
1803 {
1804 #if WITH_AVAHI
1805 epsonds_searchDevices(found_net_device);
1806 #else
1807 // currently does not support
1808 //e2_network_discovery();
1809 #endif
1810 }
1811 else
1812 attach_one_net(name);
1813 }
1814 } else {
1815 DBG(0, "unable to parse config line: %s\n", line);
1816 }
1817
1818 return SANE_STATUS_GOOD;
1819 }
1820
1821 static void
free_devices(void)1822 free_devices(void)
1823 {
1824 epsonds_device *dev, *next;
1825
1826 for (dev = first_dev; dev; dev = next) {
1827 next = dev->next;
1828 free(dev->name);
1829 free(dev->model);
1830 free(dev);
1831 }
1832
1833 free(devlist);
1834 first_dev = NULL;
1835 }
1836
1837 static void
probe_devices(SANE_Bool local_only)1838 probe_devices(SANE_Bool local_only)
1839 {
1840 DBG(5, "%s\n", __func__);
1841
1842 free_devices();
1843 sanei_configure_attach(EPSONDS_CONFIG_FILE, NULL,
1844 attach_one_config, &local_only);
1845 }
1846
1847 /**** SANE API ****/
1848
1849 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)1850 sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
1851 {
1852 DBG_INIT();
1853
1854 init_profile_maps(&stProfileMapArray, 100);
1855
1856 DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
1857
1858 DBG(1, "epsonds backend, version %i.%i.%i\n",
1859 EPSONDS_VERSION, EPSONDS_REVISION, EPSONDS_BUILD);
1860
1861 if (version_code != NULL)
1862 *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR,
1863 EPSONDS_BUILD);
1864
1865 sanei_usb_init();
1866
1867 return SANE_STATUS_GOOD;
1868 }
1869
1870 void
sane_exit(void)1871 sane_exit(void)
1872 {
1873 DBG(5, "** %s\n", __func__);
1874 free_profile_maps(&stProfileMapArray);
1875 free_devices();
1876 }
1877
1878 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1879 sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
1880 {
1881 int i;
1882 epsonds_device *dev;
1883
1884 DBG(5, "** %s local_only = %d \n", __func__, local_only);
1885
1886
1887 probe_devices(local_only);
1888
1889 devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
1890 if (!devlist) {
1891 DBG(1, "out of memory (line %d)\n", __LINE__);
1892 return SANE_STATUS_NO_MEM;
1893 }
1894
1895 DBG(5, "%s - results:\n", __func__);
1896
1897 for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
1898 DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
1899 devlist[i] = &dev->sane;
1900 }
1901
1902 devlist[i] = NULL;
1903
1904 *device_list = devlist;
1905
1906
1907 return SANE_STATUS_GOOD;
1908 }
1909
1910 static SANE_Status
init_options(epsonds_scanner * s)1911 init_options(epsonds_scanner *s)
1912 {
1913 DBG(5, "init_options\n");
1914 int i;
1915
1916 for (i = 0; i < NUM_OPTIONS; i++) {
1917 s->opt[i].size = sizeof(SANE_Word);
1918 s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1919 }
1920
1921 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1922 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1923 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1924 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1925 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1926
1927 /* "Scan Mode" group: */
1928 s->opt[OPT_STANDARD_GROUP].name = SANE_NAME_STANDARD;
1929 s->opt[OPT_STANDARD_GROUP].title = SANE_TITLE_STANDARD;
1930 s->opt[OPT_STANDARD_GROUP].desc = SANE_DESC_STANDARD;
1931 s->opt[OPT_STANDARD_GROUP].type = SANE_TYPE_GROUP;
1932 s->opt[OPT_STANDARD_GROUP].cap = 0;
1933
1934 /* scan mode */
1935 s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1936 s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1937 s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1938 s->opt[OPT_MODE].type = SANE_TYPE_STRING;
1939 s->opt[OPT_MODE].size = max_string_size(mode_list);
1940 s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1941 s->opt[OPT_MODE].constraint.string_list = mode_list;
1942 s->val[OPT_MODE].w = 0; /* Lineart */
1943
1944 /* bit depth */
1945 s->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH;
1946 s->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
1947 s->opt[OPT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
1948 s->opt[OPT_DEPTH].type = SANE_TYPE_INT;
1949 s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT;
1950 s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1951 s->opt[OPT_DEPTH].constraint.word_list = s->hw->depth_list;
1952 s->val[OPT_DEPTH].w = s->hw->depth_list[1]; /* the first "real" element is the default */
1953
1954 /* default is Lineart, disable depth selection */
1955 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
1956
1957 /* resolution */
1958 s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1959 s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1960 s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1961
1962 s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1963 s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1964
1965 /* range */
1966 if (s->hw->dpi_range.quant) {
1967 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1968 s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
1969 s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
1970 } else { /* list */
1971 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1972 s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->res_list;
1973 s->val[OPT_RESOLUTION].w = s->hw->res_list[1];
1974 }
1975
1976 /* "Geometry" group: */
1977 s->opt[OPT_GEOMETRY_GROUP].name = "";
1978 s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
1979 s->opt[OPT_GEOMETRY_GROUP].desc = "";
1980 s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1981 s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1982
1983 /* top-left x */
1984 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1985 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1986 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1987 s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1988 s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1989 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1990 s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
1991 s->val[OPT_TL_X].w = 0;
1992
1993 /* top-left y */
1994 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1995 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1996 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1997
1998 s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1999 s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
2000 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2001 s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
2002 s->val[OPT_TL_Y].w = 0;
2003
2004 /* bottom-right x */
2005 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2006 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2007 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2008
2009 s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2010 s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2011 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2012 s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2013 s->val[OPT_BR_X].w = s->hw->x_range->max;
2014
2015 /* bottom-right y */
2016 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2017 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2018 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2019
2020 s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2021 s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2022 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2023 s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2024 s->val[OPT_BR_Y].w = s->hw->y_range->max;
2025
2026 /* "Optional equipment" group: */
2027 s->opt[OPT_EQU_GROUP].name = "";
2028 s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment");
2029 s->opt[OPT_EQU_GROUP].desc = "";
2030 s->opt[OPT_EQU_GROUP].type = SANE_TYPE_GROUP;
2031 s->opt[OPT_EQU_GROUP].cap = SANE_CAP_ADVANCED;
2032
2033 /* source */
2034 s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
2035 s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
2036 s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
2037 s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
2038 s->opt[OPT_SOURCE].size = max_string_size(source_list);
2039 s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2040 s->opt[OPT_SOURCE].constraint.string_list = source_list;
2041 s->val[OPT_SOURCE].w = 0;
2042
2043 s->opt[OPT_EJECT].name = "eject";
2044 s->opt[OPT_EJECT].title = SANE_I18N("Eject");
2045 s->opt[OPT_EJECT].desc = SANE_I18N("Eject the sheet in the ADF");
2046 s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
2047
2048 if (!s->hw->adf_has_eject)
2049 s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
2050
2051 s->opt[OPT_LOAD].name = "load";
2052 s->opt[OPT_LOAD].title = SANE_I18N("Load");
2053 s->opt[OPT_LOAD].desc = SANE_I18N("Load a sheet in the ADF");
2054 s->opt[OPT_LOAD].type = SANE_TYPE_BUTTON;
2055
2056 if (!s->hw->adf_has_load)
2057 s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE;
2058
2059
2060 s->opt[OPT_ADF_SKEW].name = "adf-skew";
2061 s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction");
2062 s->opt[OPT_ADF_SKEW].desc =
2063 SANE_I18N("Enables ADF skew correction");
2064 s->opt[OPT_ADF_SKEW].type = SANE_TYPE_BOOL;
2065 s->val[OPT_ADF_SKEW].w = 0;
2066
2067
2068 s->opt[OPT_ADF_CRP].name = "adf-crp";
2069 s->opt[OPT_ADF_CRP].title = SANE_I18N("ADF CRP Correction");
2070 s->opt[OPT_ADF_CRP].desc =
2071 SANE_I18N("Enables ADF auto cropping"); //
2072 s->opt[OPT_ADF_CRP].type = SANE_TYPE_BOOL;
2073 s->val[OPT_ADF_CRP].w = 0;
2074
2075
2076 if (!s->hw->adf_has_skew)
2077 {
2078 s->val[OPT_ADF_SKEW].w = 0;
2079 s->opt[OPT_ADF_SKEW].cap |= SANE_CAP_INACTIVE;
2080 }
2081
2082 if(!s->hw->adf_has_crp)
2083 {
2084 s->val[OPT_ADF_CRP].w = 0;
2085 s->opt[OPT_ADF_CRP].cap |= SANE_CAP_INACTIVE;
2086 }
2087
2088 return SANE_STATUS_GOOD;
2089 }
2090
2091 SANE_Status
sane_open(SANE_String_Const name,SANE_Handle * handle)2092 sane_open(SANE_String_Const name, SANE_Handle *handle)
2093 {
2094 SANE_Status status;
2095 epsonds_scanner *s = NULL;
2096
2097
2098
2099 DBG(7, "** %s: name = '%s'\n", __func__, name);
2100
2101 /* probe if empty device name provided */
2102 if (name[0] == '\0') {
2103
2104 probe_devices(SANE_FALSE);
2105
2106 if (first_dev == NULL) {
2107 DBG(1, "no devices detected\n");
2108 return SANE_STATUS_INVAL;
2109 }
2110
2111 s = device_detect(first_dev->sane.name, first_dev->connection,
2112 &status);
2113 if (s == NULL) {
2114 DBG(1, "cannot open a perfectly valid device (%s),"
2115 " please report to the authors\n", name);
2116 return SANE_STATUS_INVAL;
2117 }
2118
2119 } else {
2120
2121 if (strncmp(name, "net:", 4) == 0) {
2122 s = device_detect(name, SANE_EPSONDS_NET, &status);
2123 if (s == NULL)
2124 return status;
2125 } else if (strncmp(name, "libusb:", 7) == 0) {
2126 s = device_detect(name, SANE_EPSONDS_USB, &status);
2127 if (s == NULL)
2128 return status;
2129 } else {
2130 DBG(1, "invalid device name: %s\n", name);
2131 return SANE_STATUS_INVAL;
2132 }
2133 }
2134
2135 /* s is always valid here */
2136
2137 DBG(5, "%s: handle obtained\n", __func__);
2138
2139 init_options(s);
2140
2141 *handle = (SANE_Handle)s;
2142
2143 status = open_scanner(s);
2144 if (status != SANE_STATUS_GOOD) {
2145 free(s);
2146 return status;
2147 }
2148
2149 /* lock scanner if required */
2150 if (!s->locked) {
2151 status = eds_lock(s);
2152 }
2153
2154 setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL);
2155
2156 return status;
2157 }
2158
2159 void
sane_close(SANE_Handle handle)2160 sane_close(SANE_Handle handle)
2161 {
2162 epsonds_scanner *s = (epsonds_scanner *)handle;
2163
2164 DBG(1, "** %s\n", __func__);
2165
2166 close_scanner(s);
2167 }
2168
2169 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)2170 sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
2171 {
2172 epsonds_scanner *s = (epsonds_scanner *) handle;
2173
2174 if (option < 0 || option >= NUM_OPTIONS)
2175 return NULL;
2176
2177 return s->opt + option;
2178 }
2179
2180 static const SANE_String_Const *
search_string_list(const SANE_String_Const * list,SANE_String value)2181 search_string_list(const SANE_String_Const *list, SANE_String value)
2182 {
2183 while (*list != NULL && strcmp(value, *list) != 0)
2184 list++;
2185
2186 return ((*list == NULL) ? NULL : list);
2187 }
2188
2189 /*
2190 * Handles setting the source (flatbed, transparency adapter (TPU),
2191 * or auto document feeder (ADF)).
2192 *
2193 * For newer scanners it also sets the focus according to the
2194 * glass / TPU settings.
2195 */
2196
2197 static void
change_source(epsonds_scanner * s,SANE_Int optindex,char * value)2198 change_source(epsonds_scanner *s, SANE_Int optindex, char *value)
2199 {
2200 int force_max = SANE_FALSE;
2201
2202 DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
2203 value);
2204
2205 s->val[OPT_SOURCE].w = optindex;
2206
2207 /* if current selected area is the maximum available,
2208 * keep this setting on the new source.
2209 */
2210 if (s->val[OPT_TL_X].w == s->hw->x_range->min
2211 && s->val[OPT_TL_Y].w == s->hw->y_range->min
2212 && s->val[OPT_BR_X].w == s->hw->x_range->max
2213 && s->val[OPT_BR_Y].w == s->hw->y_range->max) {
2214 force_max = SANE_TRUE;
2215 }
2216
2217 if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) {
2218 s->hw->x_range = &s->hw->adf_x_range;
2219 s->hw->y_range = &s->hw->adf_y_range;
2220 s->hw->alignment = s->hw->adf_alignment;
2221
2222
2223 } else if (strcmp(TPU_STR, value) == 0) {
2224
2225 s->hw->x_range = &s->hw->tpu_x_range;
2226 s->hw->y_range = &s->hw->tpu_y_range;
2227
2228 } else {
2229
2230 /* neither ADF nor TPU active, assume FB */
2231 s->hw->x_range = &s->hw->fbf_x_range;
2232 s->hw->y_range = &s->hw->fbf_y_range;
2233 s->hw->alignment = s->hw->fbf_alignment;
2234 }
2235
2236 s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2237 s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2238
2239 if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
2240 s->val[OPT_TL_X].w = s->hw->x_range->min;
2241
2242 if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
2243 s->val[OPT_TL_Y].w = s->hw->y_range->min;
2244
2245 if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
2246 s->val[OPT_BR_X].w = s->hw->x_range->max;
2247
2248 if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
2249 s->val[OPT_BR_Y].w = s->hw->y_range->max;
2250 }
2251
2252 static SANE_Status
getvalue(SANE_Handle handle,SANE_Int option,void * value)2253 getvalue(SANE_Handle handle, SANE_Int option, void *value)
2254 {
2255 epsonds_scanner *s = (epsonds_scanner *)handle;
2256 SANE_Option_Descriptor *sopt = &(s->opt[option]);
2257 Option_Value *sval = &(s->val[option]);
2258
2259 DBG(17, "%s: option = %d\n", __func__, option);
2260
2261 switch (option) {
2262
2263 case OPT_NUM_OPTS:
2264 case OPT_RESOLUTION:
2265 case OPT_TL_X:
2266 case OPT_TL_Y:
2267 case OPT_BR_X:
2268 case OPT_BR_Y:
2269 case OPT_DEPTH:
2270 case OPT_ADF_SKEW:
2271 case OPT_ADF_CRP:
2272 *((SANE_Word *) value) = sval->w;
2273 break;
2274
2275 case OPT_MODE:
2276 case OPT_SOURCE:
2277 strcpy((char *) value, sopt->constraint.string_list[sval->w]);
2278 break;
2279
2280 default:
2281 return SANE_STATUS_INVAL;
2282 }
2283
2284 return SANE_STATUS_GOOD;
2285 }
2286
2287 static SANE_Status
setvalue(SANE_Handle handle,SANE_Int option,void * value,SANE_Int * info)2288 setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
2289 {
2290 epsonds_scanner *s = (epsonds_scanner *) handle;
2291 SANE_Option_Descriptor *sopt = &(s->opt[option]);
2292 Option_Value *sval = &(s->val[option]);
2293
2294 SANE_Status status;
2295 const SANE_String_Const *optval = NULL;
2296 int optindex = 0;
2297 SANE_Bool reload = SANE_FALSE;
2298
2299 DBG(17, "** %s: option = %d, value = %p\n", __func__, option, value);
2300
2301 status = sanei_constrain_value(sopt, value, info);
2302 if (status != SANE_STATUS_GOOD)
2303 return status;
2304
2305 if (info && value && (*info & SANE_INFO_INEXACT)
2306 && sopt->type == SANE_TYPE_INT)
2307 DBG(17, " constrained val = %d\n", *(SANE_Word *) value);
2308
2309 if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
2310 optval = search_string_list(sopt->constraint.string_list,
2311 (char *) value);
2312 if (optval == NULL)
2313 return SANE_STATUS_INVAL;
2314 optindex = optval - sopt->constraint.string_list;
2315 }
2316
2317 /* block faulty frontends */
2318 if (sopt->cap & SANE_CAP_INACTIVE) {
2319 DBG(1, " tried to modify a disabled parameter");
2320 return SANE_STATUS_INVAL;
2321 }
2322
2323 switch (option) {
2324
2325 case OPT_ADF_SKEW:
2326 case OPT_RESOLUTION:
2327 case OPT_ADF_CRP:
2328 sval->w = *((SANE_Word *) value);
2329 reload = SANE_TRUE;
2330 break;
2331
2332 case OPT_BR_X:
2333 case OPT_BR_Y:
2334 if (SANE_UNFIX(*((SANE_Word *) value)) == 0) {
2335 DBG(17, " invalid br-x or br-y\n");
2336 return SANE_STATUS_INVAL;
2337 }
2338 // fall through
2339 case OPT_TL_X:
2340 case OPT_TL_Y:
2341
2342 sval->w = *((SANE_Word *) value);
2343 if (NULL != info)
2344 *info |= SANE_INFO_RELOAD_PARAMS;
2345
2346 if (option == OPT_BR_X)
2347 {
2348 DBG(17, "OPT_BR_X = %d\n", sval->w);
2349 }
2350 if (option == OPT_BR_Y)
2351 {
2352 DBG(17, "OPT_BR_Y = %d\n", sval->w);
2353 }
2354 if (option == OPT_TL_X)
2355 {
2356 DBG(17, "OPT_TL_X = %d\n", sval->w);
2357 }
2358 if (option == OPT_TL_Y)
2359 {
2360 DBG(17, "OPT_TL_Y = %d\n", sval->w);
2361 }
2362 // adf crop set to off
2363 s->val[OPT_ADF_CRP].w = 0;
2364 break;
2365
2366 case OPT_SOURCE:
2367 change_source(s, optindex, (char *) value);
2368 reload = SANE_TRUE;
2369 break;
2370
2371 case OPT_MODE:
2372 {
2373 DBG(17, " OPT_MODE = index %d\n", optindex);
2374
2375 /* use JPEG mode if RAW is not available when bpp > 1 */
2376 if (optindex > 0 && !s->hw->has_raw) {
2377 s->mode_jpeg = 1;
2378 } else {
2379 s->mode_jpeg = 0;
2380 }
2381
2382 sval->w = optindex;
2383
2384 /* if binary, then disable the bit depth selection */
2385 if (optindex == 0) {
2386 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2387 } else {
2388 if (s->hw->depth_list[0] == 1)
2389 s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2390 else {
2391 s->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
2392 s->val[OPT_DEPTH].w =
2393 mode_params[optindex].depth;
2394 }
2395 }
2396
2397 reload = SANE_TRUE;
2398 break;
2399 }
2400
2401 case OPT_DEPTH:
2402 sval->w = *((SANE_Word *) value);
2403 mode_params[s->val[OPT_MODE].w].depth = sval->w;
2404 reload = SANE_TRUE;
2405 break;
2406
2407 case OPT_LOAD:
2408 esci2_mech(s, "#ADFLOAD");
2409 break;
2410
2411 case OPT_EJECT:
2412 esci2_mech(s, "#ADFEJCT");
2413 break;
2414
2415 default:
2416 return SANE_STATUS_INVAL;
2417 }
2418
2419 if (reload && info != NULL)
2420 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2421
2422 return SANE_STATUS_GOOD;
2423 }
2424
2425 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)2426 sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
2427 void *value, SANE_Int *info)
2428 {
2429 DBG(17, "** %s: action = %x, option = %d\n", __func__, action, option);
2430
2431 if (option < 0 || option >= NUM_OPTIONS)
2432 return SANE_STATUS_INVAL;
2433
2434 if (info != NULL)
2435 *info = 0;
2436
2437 switch (action) {
2438 case SANE_ACTION_GET_VALUE:
2439 return getvalue(handle, option, value);
2440
2441 case SANE_ACTION_SET_VALUE:
2442 return setvalue(handle, option, value, info);
2443
2444 default:
2445 return SANE_STATUS_INVAL;
2446 }
2447
2448 return SANE_STATUS_INVAL;
2449 }
2450
2451
setBit(SANE_Byte * bytes,SANE_Int bitIndex,SANE_Bool isTrue)2452 static void setBit (SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue)
2453 {
2454 SANE_Int octet = bitIndex / 8;
2455 SANE_Byte bit = 7 - (bitIndex % 8);
2456
2457 if (isTrue) {
2458 bytes[octet] |= (1 << bit);
2459 } else {
2460 bytes[octet] &= ~(1 << bit);
2461 }
2462 }
2463
getBit(SANE_Byte * bytes,SANE_Int bitIndex)2464 static SANE_Bool getBit (SANE_Byte* bytes, SANE_Int bitIndex)
2465 {
2466 SANE_Int octet = bitIndex / 8;
2467 SANE_Byte mask = 1 << (7 - (bitIndex % 8));
2468
2469 if( bytes[octet] & mask ){
2470 return SANE_TRUE;
2471 }
2472
2473 return SANE_FALSE;
2474 }
2475
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)2476 static void swapPixel1(SANE_Int x1,
2477 SANE_Int y1,
2478 SANE_Int x2,
2479 SANE_Int y2,
2480 SANE_Byte* bytes,
2481 SANE_Byte bitsPerSample,
2482 SANE_Int samplesPerPixel,
2483 SANE_Int bytesPerRow)
2484 {
2485 SANE_Int pixelBits = bitsPerSample * samplesPerPixel;
2486 SANE_Int widthBits = bytesPerRow * 8;
2487
2488 SANE_Byte temp = getBit(bytes, widthBits * y1 + x1 * pixelBits);
2489 {
2490 SANE_Byte right = getBit(bytes, widthBits * y2 + x2 * pixelBits);
2491 setBit(bytes, widthBits * y1 + x1 * pixelBits, right);
2492 }
2493 setBit(bytes, widthBits * y2 + x2 * pixelBits, temp);
2494 }
2495
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)2496 static void swapPixel8(SANE_Int x1,
2497 SANE_Int y1,
2498 SANE_Int x2,
2499 SANE_Int y2,
2500 SANE_Byte* bytes,
2501 SANE_Byte bitsPerSample,
2502 SANE_Int samplesPerPixel,
2503 SANE_Int bytesPerRow)
2504 {
2505 SANE_Int pixelBytes = samplesPerPixel * bitsPerSample / 8;
2506
2507 for (SANE_Byte i = 0; i < pixelBytes; i++) {
2508 SANE_Byte temp = bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)];
2509 bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)] = bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)];
2510 bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)] = temp;
2511 }
2512 }
2513
2514
2515
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)2516 static void swapPixel(SANE_Int x1,
2517 SANE_Int y1,
2518 SANE_Int x2,
2519 SANE_Int y2,
2520 SANE_Byte* bytes,
2521 SANE_Byte bitsPerSample,
2522 SANE_Int samplesPerPixel,
2523 SANE_Int bytesPerRow)
2524 {
2525 if (bitsPerSample == 1) {
2526 swapPixel1(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2527 }else if(bitsPerSample == 8 || bitsPerSample == 16){
2528 swapPixel8(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2529 }
2530 }
2531
2532
2533 void
upside_down_backside_image(epsonds_scanner * s)2534 upside_down_backside_image(epsonds_scanner *s)
2535 {
2536 // get all data from ring_buffer
2537 if (eds_ring_avail(&s->back) &&
2538 (strcmp(s->hw->sane.model, (char*)"DS-1630") == 0
2539 || strcmp(s->hw->sane.model, (char*)"DS-1610") == 0
2540 || strcmp(s->hw->sane.model, (char*)"DS-1660W") == 0))
2541 {
2542 SANE_Int bytesPerLine = s->params.bytes_per_line;
2543 SANE_Int imageSize = bytesPerLine * s->height_back;
2544
2545 SANE_Byte* workBuffer = malloc(imageSize);
2546 // if there is not enough memory, do nothing.
2547 if (workBuffer)
2548 {
2549 eds_ring_read(&s->back, workBuffer, imageSize);
2550 SANE_Int samplesPerPxel = 3;
2551 if (s->params.format == SANE_FRAME_RGB)
2552 {
2553 samplesPerPxel = 3;
2554 }
2555 else if (s->params.format == SANE_FRAME_GRAY)
2556 {
2557 samplesPerPxel = 1;
2558 }
2559
2560 SANE_Int half = (s->height_back / 2) - 1;
2561 if (half < 0) {
2562 half = 0;
2563 }
2564
2565 if((s->height_back % 2) == 1) {
2566 SANE_Int ymid = ( (s->height_back - 1 ) / 2 );
2567 for(SANE_Int x = 0;x < (s->width_back / 2); x++) {
2568 swapPixel(x, ymid, s->width_back - x - 1, ymid, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2569 }
2570 }
2571
2572 if (s->height_back != 1) {
2573 for(SANE_Int x = 0; x < s->width_back; x++) {
2574 for(SANE_Int y = 0;y <= half; y++) {
2575 swapPixel(x, y, s->width_back - x - 1, s->height_back - y -1, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2576 }
2577 }
2578 }
2579
2580 eds_ring_write(&s->back, workBuffer, imageSize);
2581 free(workBuffer);
2582 workBuffer = NULL;
2583
2584 }
2585 }
2586
2587 }
2588
2589
2590 SANE_Status
get_next_image(epsonds_scanner * s)2591 get_next_image(epsonds_scanner *s)
2592 {
2593 SANE_Status status = SANE_STATUS_GOOD;
2594
2595 if (s->acquirePage == 0 && s->current == &s->front)
2596 {
2597 DBG(20, "** %s: get_next_image\n", __func__);
2598
2599
2600 /*page info will be updatted by pen*/
2601 s->width_back = 0;
2602 s->width_front = 0;
2603 s->height_back = 0;
2604 s->height_front = 0;
2605
2606 if (s->mode_jpeg)
2607 {
2608 status = acquire_and_decode_jpeg_data(s);
2609 }else{
2610 status = acquire_raw_data(s);
2611 }
2612 if (status != SANE_STATUS_GOOD)
2613 {
2614 eds_ring_flush(&s->front);
2615 eds_ring_flush(&s->back);
2616 eds_ring_destory(&s->front);
2617 eds_ring_destory(&s->back);
2618 }
2619 DBG(20," ringFront = %d ringBack = %d\n", eds_ring_avail(&s->front), eds_ring_avail(&s->back));
2620
2621 s->acquirePage = 1;
2622 }
2623
2624 return status;
2625 }
2626
2627
2628 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)2629 sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
2630 {
2631 epsonds_scanner *s = (epsonds_scanner *)handle;
2632
2633 DBG(5, "** %s\n", __func__);
2634
2635 if (params == NULL)
2636 DBG(1, "%s: params is NULL\n", __func__);
2637
2638 /*
2639 * If sane_start was already called, then just retrieve the parameters
2640 * from the scanner data structure
2641 */
2642 if (s->scanning) {
2643 DBG(5, "scan in progress, returning saved params structure\n");
2644 } else {
2645 /* otherwise initialize the params structure */
2646 eds_init_parameters(s);
2647 }
2648
2649
2650 SANE_Status status = SANE_STATUS_GOOD;
2651
2652 status = get_next_image(s);
2653
2654 // if size auto, update page size value
2655 if(s->val[OPT_ADF_CRP].w)
2656 {
2657 // frontside
2658 if (s->current == &s->front)
2659 {
2660 DBG(20, "front side \n");
2661 if (s->width_front != 0 && s->height_front != 0)
2662 {
2663 if (s->params.format == SANE_FRAME_RGB)
2664 {
2665 s->params.bytes_per_line = s->width_front * 3;
2666 s->params.pixels_per_line = s->width_front;
2667 }
2668
2669 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2670 {
2671 s->params.bytes_per_line = s->width_front;
2672 s->params.pixels_per_line = s->width_front;
2673 }
2674
2675 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2676 {
2677 s->params.bytes_per_line = (s->width_front + 7)/8;
2678 s->params.pixels_per_line = s->width_front;
2679 }
2680 s->params.lines = s->height_front;
2681 }
2682 }
2683 // backside
2684 if (s->current == &s->back)
2685 {
2686 DBG(20, "back side \n");
2687 if (s->width_back != 0 && s->height_back != 0)
2688 {
2689 if (s->params.format == SANE_FRAME_RGB)
2690 {
2691 s->params.bytes_per_line = s->width_back * 3;
2692 s->params.pixels_per_line = s->width_back;
2693 }
2694
2695 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2696 {
2697 s->params.bytes_per_line = s->width_back;
2698 s->params.pixels_per_line = s->width_back;
2699 }
2700
2701 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2702 {
2703 s->params.bytes_per_line = (s->width_back + 7)/8;
2704 s->params.pixels_per_line = s->width_back;
2705 }
2706 s->params.lines = s->height_back;
2707 }
2708 }
2709 }
2710 if (params != NULL)
2711 *params = s->params;
2712
2713 print_params(s->params);
2714
2715 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 );
2716 return status;
2717 }
2718
2719
2720
2721 typedef float ColorMatrix[3][3];
2722
2723 #define CCT_TABLE_SIZE 9
get_roundup_index(double frac[],int n)2724 static int get_roundup_index(double frac[], int n)
2725 {
2726 int i, index = -1;
2727 double max_val = 0.0;
2728
2729 for (i=0; i<n; i++) {
2730 if (frac[i]<0) continue;
2731 if (max_val<frac[i]) {
2732 index = i;
2733 max_val = frac[i];
2734 }
2735 }
2736 return index;
2737 }
2738
get_rounddown_index(double frac[],int n)2739 static int get_rounddown_index(double frac[], int n)
2740 {
2741 int i, index = -1;
2742 double min_val = 1.0;
2743
2744 for (i=0; i<n; i++) {
2745 if (frac[i]>0) continue;
2746 if (min_val>frac[i]) {
2747 index = i;
2748 min_val = frac[i];
2749 }
2750 }
2751 return index;
2752 }
2753
2754
ESCIRoundColorCorrectionMatrix(int mult,double org_cct[],int rnd_cct[])2755 void ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[])
2756 {
2757 int i, j, index;
2758 double mult_cct[CCT_TABLE_SIZE], frac[CCT_TABLE_SIZE];
2759 int sum[3];
2760 int loop;
2761
2762 for (i=0; i<CCT_TABLE_SIZE; i++) {
2763 mult_cct[i] = org_cct[i] * mult;
2764 }
2765
2766 // round value multiplied by 'mult' off to integer.
2767 for (i=0; i<CCT_TABLE_SIZE; i++) {
2768 rnd_cct[i] = (int)floor(org_cct[i] * mult + 0.5);
2769 }
2770
2771 loop=0;
2772 do {
2773 // If all element equal to 11, diagonal element is set to 10.
2774 for (i=0; i<3; i++) {
2775 if ( (rnd_cct[i*3]==11) &&
2776 (rnd_cct[i*3]==rnd_cct[i*3+1]) &&
2777 (rnd_cct[i*3]==rnd_cct[i*3+2]) ) {
2778 rnd_cct[i*3+i] --;
2779 mult_cct[i*3+i] = rnd_cct[i*3+i];
2780 }
2781 }
2782 // calc. summation of each line.
2783 for (i=0; i<3; i++) {
2784 sum[i] = 0;
2785 for (j=0; j<3; j++) {
2786 sum[i] += rnd_cct[i*3+j];
2787 }
2788 }
2789 // calc. values rounded up or down.
2790 for (i=0; i<CCT_TABLE_SIZE; i++) {
2791 frac[i] = mult_cct[i] - rnd_cct[i];
2792 }
2793
2794 // if summation does not equal to 'mult', adjust rounded up or down value.
2795 for (i=0; i<3; i++) {
2796 if (sum[i]<mult) {
2797 index = get_roundup_index(&frac[i*3], 3);
2798 if (index!=-1) {
2799 rnd_cct[i*3+index] ++;
2800 mult_cct[i*3+index] = rnd_cct[i*3+index];
2801 sum[i]++;
2802 }
2803 } else if (sum[i]>mult) {
2804 index = get_rounddown_index(&frac[i*3], 3);
2805 if (index!=-1) {
2806 rnd_cct[i*3+index] --;
2807 mult_cct[i*3+index] = rnd_cct[i*3+index];
2808 sum[i]--;
2809 }
2810 }
2811 }
2812
2813 } while ((++loop<2)&&((sum[0]!=mult)||(sum[1]!=mult)||(sum[2]!=mult)));
2814 }
2815
2816
2817
2818 /*
2819 * This function is part of the SANE API and gets called from the front end to
2820 * start the scan process.
2821 */
2822 #define CMD_BUF_SIZE 1000
2823 SANE_Status
sane_start(SANE_Handle handle)2824 sane_start(SANE_Handle handle)
2825 {
2826 epsonds_scanner *s = (epsonds_scanner *)handle;
2827 char buf[65]; /* add one more byte to correct buffer overflow issue */
2828 char cmd[CMD_BUF_SIZE]; /* take care not to overflow */
2829 SANE_Status status = 0;
2830
2831 s->pages++;
2832
2833 DBG(5, "** %s, pages = %d, scanning = %d, backside = %d, front fill: %d, back fill: %d\n",
2834 __func__, s->pages, s->scanning, s->backside,
2835 eds_ring_avail(&s->front),
2836 eds_ring_avail(&s->back));
2837
2838 s->eof = 0;
2839 s->canceling = 0;
2840 s->acquirePage = 0;
2841
2842 if ((s->pages % 2) == 1) {
2843 s->current = &s->front;
2844 } else if (eds_ring_avail(&s->back)) {
2845 DBG(5, "back side\n");
2846 s->current = &s->back;
2847 }
2848
2849 /* scan already in progress? (one pass adf) */
2850 if (s->scanning || eds_ring_avail(&s->back) > 0) {
2851 DBG(5, " scan in progress, returning early\n");
2852 return get_next_image(s);
2853 }
2854 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2855 if (s->scanEnd)
2856 {
2857 s->scanEnd = 0;
2858 return SANE_STATUS_NO_DOCS;
2859 }
2860 }else{
2861 s->scanEnd = 0;
2862 }
2863
2864 /* calc scanning parameters */
2865 status = eds_init_parameters(s);
2866 if (status != SANE_STATUS_GOOD) {
2867 DBG(1, " parameters initialization failed\n");
2868 return status;
2869 }
2870
2871 /* allocate line buffer */
2872 s->line_buffer = realloc(s->line_buffer, s->params.bytes_per_line);
2873 if (s->line_buffer == NULL)
2874 return SANE_STATUS_NO_MEM;
2875
2876 /* transfer buffer size, bsz */
2877 /* XXX read value from scanner */
2878 s->bsz = (1048576 * 4);
2879
2880 /* transfer buffer */
2881 s->buf = realloc(s->buf, s->bsz);
2882 if (s->buf == NULL)
2883 return SANE_STATUS_NO_MEM;
2884
2885 print_params(s->params);
2886
2887 /* set scanning parameters */
2888
2889 s->isDuplexScan = 0;
2890 /* document source */
2891 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2892
2893 SANE_Int status = esci2_stat(s);
2894 if (status == SANE_STATUS_NO_DOCS)
2895 {
2896 return SANE_STATUS_NO_DOCS;
2897 }
2898
2899 SANE_Int duplexMode = (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0);
2900
2901 sprintf(buf, "#ADF%s%s%s",
2902 duplexMode ? "DPLX" : "",
2903 s->val[OPT_ADF_SKEW].w ? "SKEW" : "",
2904 s->val[OPT_ADF_CRP].w ? "CRP " : ""
2905 );
2906
2907 if (duplexMode)
2908 {
2909 s->isDuplexScan = 1;
2910 }
2911 s->isflatbedScan = 0;
2912 }
2913 else if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_FLATBED) == 0) {
2914
2915 strcpy(buf, "#FB ");
2916 s->isflatbedScan = 1;
2917
2918 } else {
2919 /* XXX */
2920 }
2921
2922 strcpy(cmd, buf);
2923
2924 s->needToConvertBW = 0;
2925
2926 if (s->params.format == SANE_FRAME_GRAY) {
2927 if (s->params.depth == 1 && s->hw->has_mono == 0)
2928 {
2929 sprintf(buf, "#COLM008");
2930 s->needToConvertBW = 1;
2931 s->mode_jpeg = 1;
2932 }else
2933 {
2934 sprintf(buf, "#COLM%03d", s->params.depth);
2935 }
2936 } else if (s->params.format == SANE_FRAME_RGB) {
2937 sprintf(buf, "#COLC%03d", s->params.depth * 3);
2938 }
2939
2940 strcat(cmd, buf);
2941
2942 /* image transfer format */
2943 if (!s->mode_jpeg) {
2944 if (s->params.depth > 1 || s->hw->has_raw) {
2945 strcat(cmd, "#FMTRAW ");
2946 }
2947 } else {
2948 strcat(cmd, "#FMTJPG #JPGd090");
2949 }
2950
2951 /* set GMM */
2952 if (s->params.depth == 1)
2953 {
2954 sprintf(buf, "#GMMUG10");
2955 } else
2956 {
2957 sprintf(buf, "#GMMUG18");
2958 }
2959 strcat(cmd, buf);
2960
2961 /* resolution (RSMi not always supported) */
2962
2963 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2964 DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2965 } else if (s->val[OPT_RESOLUTION].w > 999) {
2966 sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2967 } else {
2968 sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2969 }
2970
2971 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2972 DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2973 } else if (s->val[OPT_RESOLUTION].w > 999) {
2974 sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2975 } else {
2976 sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2977 }
2978
2979 strcat(cmd, buf);
2980
2981 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
2982 || 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){
2983 sprintf(buf, "#BSZi0262144");
2984 strcat(cmd, buf);
2985 }
2986 else {
2987 sprintf(buf, "#BSZi1048576");
2988 strcat(cmd, buf);
2989 }
2990
2991
2992 /* scanning area */
2993
2994 sprintf(buf, "#ACQi%07di%07di%07di%07d",
2995 s->left, s->top, s->params.pixels_per_line, s->params.lines);
2996
2997
2998 if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2999 status = esci2_stat(s);
3000 if (status != SANE_STATUS_GOOD) {
3001 goto end;
3002 }
3003 }
3004
3005 strcat(cmd, buf);
3006
3007
3008 int pos = 0;
3009
3010 {
3011 for (int i = 0; i < CMD_BUF_SIZE; i++)
3012 {
3013 // find end of string
3014 if(cmd[i] == 0)
3015 {
3016 pos = i;
3017 break;
3018 }
3019 }
3020
3021
3022 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) {
3023 DBG(10, "SANE_FRAME_GRAY\n");
3024 cmd[pos++] = '#';
3025 cmd[pos++] = 'G';
3026 cmd[pos++] = 'M';
3027 cmd[pos++] = 'T';
3028 cmd[pos++] = 'M';
3029 cmd[pos++] = 'O';
3030 cmd[pos++] = 'N';
3031 cmd[pos++] = 'O';
3032 cmd[pos++] = 'h';
3033 cmd[pos++] = '1';
3034 cmd[pos++] = '0';
3035 cmd[pos++] = '0';
3036
3037 for(int count = 0; count < 256; count++) {
3038 cmd[pos++] = LUT[s->hw->lut_id][count];
3039 }
3040 }
3041 if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) {
3042 DBG(10, "SANE_FRAME_GRAY\n");
3043 cmd[pos++] = '#';
3044 cmd[pos++] = 'G';
3045 cmd[pos++] = 'M';
3046 cmd[pos++] = 'T';
3047 cmd[pos++] = 'M';
3048 cmd[pos++] = 'O';
3049 cmd[pos++] = 'N';
3050 cmd[pos++] = 'O';
3051 cmd[pos++] = 'h';
3052 cmd[pos++] = '1';
3053 cmd[pos++] = '0';
3054 cmd[pos++] = '0';
3055
3056 for(int count = 0; count < 256; count++) {
3057 cmd[pos++] = LUT[0][count];
3058 }
3059 }
3060 else if (s->params.format == SANE_FRAME_RGB) {
3061 DBG(10, "SANE_FRAME_RGB\n");
3062 cmd[pos++] = '#';
3063 cmd[pos++] = 'G';
3064 cmd[pos++] = 'M';
3065 cmd[pos++] = 'T';
3066 cmd[pos++] = 'R';
3067 cmd[pos++] = 'E';
3068 cmd[pos++] = 'D';
3069 cmd[pos++] = ' ';
3070 cmd[pos++] = 'h';
3071 cmd[pos++] = '1';
3072 cmd[pos++] = '0';
3073 cmd[pos++] = '0';
3074
3075 for(int count = 0; count < 256; count++) {
3076 cmd[pos++] = LUT_R[s->hw->lut_id][count];
3077 }
3078
3079 cmd[pos++] = '#';
3080 cmd[pos++] = 'G';
3081 cmd[pos++] = 'M';
3082 cmd[pos++] = 'T';
3083 cmd[pos++] = 'G';
3084 cmd[pos++] = 'R';
3085 cmd[pos++] = 'N';
3086 cmd[pos++] = ' ';
3087 cmd[pos++] = 'h';
3088 cmd[pos++] = '1';
3089 cmd[pos++] = '0';
3090 cmd[pos++] = '0';
3091
3092 for(int count = 0; count < 256; count++) {
3093 cmd[pos++] = LUT_G[s->hw->lut_id][count];
3094 }
3095
3096 cmd[pos++] = '#';
3097 cmd[pos++] = 'G';
3098 cmd[pos++] = 'M';
3099 cmd[pos++] = 'T';
3100 cmd[pos++] = 'B';
3101 cmd[pos++] = 'L';
3102 cmd[pos++] = 'U';
3103 cmd[pos++] = ' ';
3104 cmd[pos++] = 'h';
3105 cmd[pos++] = '1';
3106 cmd[pos++] = '0';
3107 cmd[pos++] = '0';
3108
3109 for(int count = 0; count < 256; count++) {
3110 cmd[pos++] = LUT_B[s->hw->lut_id][count];
3111 }
3112 }
3113 cmd[pos] = 0;
3114
3115 }
3116 {// Set Color Matrix
3117 if (s->params.format == SANE_FRAME_RGB && s->hw->lut_id != 0 )/*Color Matrix Target devide and color Scan*/
3118 {
3119 ColorMatrix matrix;
3120
3121 // DS-530
3122
3123 if (s->hw->lut_id == 2)
3124 {
3125 // R
3126 matrix[0][0] = 1.0229;
3127 matrix[0][1] = 0.0009;
3128 matrix[0][2] = -0.0238;
3129
3130 // G
3131 matrix[1][0] = 0.0031;
3132 matrix[1][1] = 1.0287;
3133 matrix[1][2] = -0.0318;
3134
3135 //B
3136 matrix[2][0] = 0.0044;
3137 matrix[2][1] = -0.1150;
3138 matrix[2][2] = 1.1106;
3139 }
3140
3141 // DS-1660W Flatbed
3142
3143 if (s->hw->lut_id == 4)
3144 {
3145 // R
3146 matrix[0][0] = 1.0229;
3147 matrix[0][1] = 0.0009;
3148 matrix[0][2] = -0.0238;
3149
3150 // G
3151 matrix[1][0] = 0.0031;
3152 matrix[1][1] = 1.0287;
3153 matrix[1][2] = -0.0318;
3154
3155 //B
3156 matrix[2][0] = 0.0044;
3157 matrix[2][1] = -0.1150;
3158 matrix[2][2] = 1.1106;
3159 }
3160
3161
3162 // DS-320
3163
3164 if (s->hw->lut_id == 5)
3165 {
3166 // R
3167 matrix[0][0] = 1.0250;
3168 matrix[0][1] = 0.0004;
3169 matrix[0][2] = -0.0254;
3170
3171 // G
3172 matrix[1][0] = 0.0003;
3173 matrix[1][1] = 1.0022;
3174 matrix[1][2] = -0.0025;
3175
3176 //B
3177 matrix[2][0] = 0.0049;
3178 matrix[2][1] = -0.0949;
3179 matrix[2][2] = 1.0900;
3180 }
3181
3182
3183 // ES-50
3184
3185 if (s->hw->lut_id == 6)
3186 {
3187 // R
3188 matrix[0][0] = 1.0383;
3189 matrix[0][1] = -0.0021;
3190 matrix[0][2] = -0.0362;
3191
3192 // G
3193 matrix[1][0] = 0.0046;
3194 matrix[1][1] = 1.0576;
3195 matrix[1][2] = -0.0622;
3196
3197 //B
3198 matrix[2][0] = 0.0235;
3199 matrix[2][1] = -0.2396;
3200 matrix[2][2] = 1.2161;
3201 }
3202
3203
3204 // R
3205 matrix[0][0] = 0.9864;
3206 matrix[0][1] = 0.0248;
3207 matrix[0][2] = -0.0112;
3208
3209 // G
3210 matrix[1][0] = 0.0021;
3211 matrix[1][1] = 1.0100;
3212 matrix[1][2] = -0.0112;
3213
3214 //B
3215 matrix[2][0] = 0.0139;
3216 matrix[2][1] = -0.1249;
3217 matrix[2][2] = 1.1110;
3218
3219
3220 // Set Matrix value
3221 {
3222 cmd[pos++] = '#';
3223 cmd[pos++] = 'C';
3224 cmd[pos++] = 'M';
3225 cmd[pos++] = 'X';
3226 cmd[pos++] = 'U';
3227 cmd[pos++] = 'M';
3228 cmd[pos++] = '0';
3229 cmd[pos++] = '8';
3230 cmd[pos++] = 'h';
3231 cmd[pos++] = '0';
3232 cmd[pos++] = '0';
3233 cmd[pos++] = '9';
3234 }
3235
3236
3237 // Matrix to be sent to scanner must be following d1-d9 order:
3238 //
3239 // G R B
3240 // G [d1 d4 d7]
3241 // R [d2 d5 d8]
3242 // B [d3 d6 d9]
3243 //
3244 // So, we will convert it with index table.
3245 char index[9] = {4, 1, 7, 3, 0, 6, 5, 2, 8};
3246
3247 double flatten[9] = {0};
3248 for (int row = 0; row < 3; row++) {
3249 for (int col = 0; col < 3; col++) {
3250 flatten[row * 3 + col] = matrix[row][col];
3251 }
3252 }
3253
3254 int rounded[9] = {0};
3255 ESCIRoundColorCorrectionMatrix(32, flatten, rounded);
3256
3257
3258 char ordered[9] = {0};
3259 for (int row = 0; row < 3; row++) {
3260 for (int col = 0; col < 3; col++) {
3261 int val = rounded[row * 3 + col];
3262 unsigned char oct = (unsigned char)abs(val);
3263 oct |= ((val < 0) ? (1 << 7) : 0);
3264 ordered[(signed char)index[row * 3 + col]] = oct;
3265 }
3266 }
3267 {
3268 cmd[pos++] = ordered[0];
3269 cmd[pos++] = ordered[1];
3270 cmd[pos++] = ordered[2];
3271 cmd[pos++] = ordered[3];
3272 cmd[pos++] = ordered[4];
3273 cmd[pos++] = ordered[5];
3274 cmd[pos++] = ordered[6];
3275 cmd[pos++] = ordered[7];
3276 cmd[pos++] = ordered[8];
3277 cmd[pos++] = 0; //padding
3278 cmd[pos++] = 0; //padding
3279 cmd[pos++] = 0; //padding
3280
3281
3282 DBG(1, "color matrix\n");
3283 for (int i = 0; i < 9; i++)
3284 {
3285 DBG(1, "%d\n", ordered[i]);
3286 }
3287
3288 }
3289 cmd[pos] = 0;
3290 }
3291
3292 }
3293
3294
3295 status = esci2_para(s, cmd, pos);
3296 if (status != SANE_STATUS_GOOD) {
3297 goto end;
3298 }
3299
3300 /* start scanning */
3301 DBG(1, "%s: scanning...\n", __func__);
3302
3303 /* switch to data state */
3304 status = esci2_trdt(s);
3305 if (status != SANE_STATUS_GOOD) {
3306 goto end;
3307 }
3308
3309 /* first page is page 1 */
3310 s->pages = 1;
3311 s->scanning = 1;
3312 s->dummy = 0;
3313 s->scanEnd = 0;
3314 end:
3315 if (status != SANE_STATUS_GOOD) {
3316 DBG(1, "%s: start failed: %s\n", __func__, sane_strstatus(status));
3317 }
3318
3319 return status;
3320 }
3321
acquire_jpeg_data(epsonds_scanner * s)3322 static SANE_Status acquire_jpeg_data(epsonds_scanner* s)
3323 {
3324
3325 SANE_Int read = 0;
3326
3327 SANE_Int jpegBufSize = s->params.bytes_per_line * s->params.lines;
3328 if (s->needToConvertBW)
3329 {
3330 jpegBufSize = s->params.pixels_per_line * s->params.lines;
3331 }
3332
3333
3334 s->frontJpegBuf = malloc(jpegBufSize);
3335 s->backJpegBuf = malloc(jpegBufSize);
3336 s->frontJpegBufLen = 0;
3337 s->backJpegBufLen = 0;
3338
3339 // load all images, decode and fill buffer
3340 SANE_Int status = SANE_STATUS_GOOD;
3341
3342 int eofFront = 0;
3343 int eofBack = 0;
3344
3345
3346 status = eds_ring_init(&s->front, (s->params.bytes_per_line) * s->params.lines);
3347 if (status != SANE_STATUS_GOOD) {
3348 return status;
3349 }
3350
3351 status = eds_ring_init(&s->back, (s->params.bytes_per_line) * s->params.lines);
3352 if (status != SANE_STATUS_GOOD) {
3353 return status;
3354 }
3355
3356 while (1)
3357 {
3358 status = esci2_img(s, &read);
3359 DBG(20, "acquire_jpeg_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3360 if (read)
3361 {
3362 if (s->backside)
3363 {
3364 SANE_Byte* backBuffer = s->backJpegBuf + s->backJpegBufLen;
3365 memcpy(backBuffer, s->buf, read);
3366 s->backJpegBufLen += read;
3367 }else{
3368 SANE_Byte* frontBuffer = s->frontJpegBuf + s->frontJpegBufLen ;
3369 memcpy(frontBuffer, s->buf, read);
3370 s->frontJpegBufLen += read;
3371 }
3372 }
3373 if (status == SANE_STATUS_GOOD)
3374 {
3375
3376 DBG(20, "continue acquire image\n");
3377 continue;
3378 }
3379 else if (status == SANE_STATUS_EOF)
3380 {
3381 if (s->backside)
3382 {
3383 DBG(20, "eofBack\n");
3384 eofBack = 1;
3385 }else{
3386 DBG(20, "eofFront\n");
3387 eofFront = 1;
3388 }
3389 }else if (status == SANE_STATUS_CANCELLED)
3390 {
3391 // cancel cleanup
3392 esci2_can(s);
3393
3394 free(s->frontJpegBuf);
3395 free(s->backJpegBuf);
3396 s->frontJpegBuf = NULL;
3397 s->backJpegBuf = NULL;
3398 return status;
3399 }else{
3400 // error occurs cleanup
3401 free(s->frontJpegBuf);
3402 free(s->backJpegBuf);
3403 s->frontJpegBuf = NULL;
3404 s->backJpegBuf = NULL;
3405 return status;
3406 }
3407
3408
3409 if (s->isDuplexScan)
3410 {
3411 DBG(20, "eofFront = %d eofBack = %d\n", eofFront, eofBack);
3412 // acquire finish
3413 if (eofFront && eofBack)
3414 {
3415 DBG(20, "eofFront && eofBack end\n");
3416 break;
3417 }
3418 }else{
3419 if (eofFront)
3420 {
3421 DBG(20, "eofFront end\n");
3422 break;
3423 }
3424 }
3425 }
3426
3427 return SANE_STATUS_GOOD;
3428 }
3429
3430 static SANE_Status
acquire_raw_data(epsonds_scanner * s)3431 acquire_raw_data(epsonds_scanner* s)
3432 {
3433 SANE_Int read = 0;
3434
3435 // load all images, decode and fill buffer
3436 SANE_Int status = SANE_STATUS_GOOD;
3437
3438 int eofFront = 0;
3439 int eofBack = 0;
3440 int firstWrite = 1;
3441
3442 while (1)
3443 {
3444 DBG(20, "acquire_raw_data loop start\n");
3445 status = esci2_img(s, &read);
3446 DBG(20, "acquire_raw_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3447
3448 if (read)
3449 {
3450 if (firstWrite)
3451 {
3452 status = eds_ring_init(&s->front, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3453 if (status != SANE_STATUS_GOOD) {
3454 return status;
3455 }
3456
3457 status = eds_ring_init(&s->back, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3458 if (status != SANE_STATUS_GOOD) {
3459 return status;
3460 }
3461 firstWrite = 0;
3462 }
3463
3464 DBG(20, "eds_ring_write start\n");
3465 status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read);
3466 DBG(20, "eds_ring_write end\n");
3467 }
3468 DBG(20, "acquire_raw_data3\n");
3469
3470 if (status == SANE_STATUS_GOOD)
3471 {
3472 DBG(20, "contiune acquire image\n");
3473 continue;
3474 }
3475 else if (status == SANE_STATUS_EOF)
3476 {
3477 if (s->backside)
3478 {
3479 eofBack = 1;
3480 }else{
3481 eofFront = 1;
3482 }
3483 }
3484 else if (status == SANE_STATUS_CANCELLED)
3485 {
3486 esci2_can(s);
3487 return status;
3488 }else{
3489 // error occurs cleanup
3490 return status;
3491 }
3492
3493 if (s->isDuplexScan)
3494 {
3495 // acquire finish
3496 if (eofFront && eofBack)
3497 {
3498 break;
3499 }
3500 }else{
3501 if (eofFront)
3502 {
3503 break;
3504 }
3505 }
3506 }
3507
3508
3509 int needBytes = (s->params.bytes_per_line + s->dummy) * s->params.lines;
3510 {
3511 int available = eds_ring_avail(&s->front);
3512 if (available < needBytes)
3513 {
3514 int required = needBytes - available;
3515 unsigned char* padding = (unsigned char*)malloc(required);
3516 memset(padding, 255, required);
3517 eds_ring_write(&s->front, padding, required);
3518 free(padding);
3519
3520 }
3521
3522 }
3523 {
3524 int available = eds_ring_avail(&s->back);
3525 if (available > 0 && available < needBytes)
3526 {
3527 int required = needBytes - available;
3528 unsigned char* padding = (unsigned char*)malloc(required);
3529 memset(padding, 255, required);
3530 eds_ring_write(&s->back, padding, required);
3531 free(padding);
3532 }
3533
3534 }
3535
3536 if (s->isDuplexScan)
3537 {
3538 upside_down_backside_image(s);
3539 }
3540
3541 DBG(20, "acquire_raw_data finish");
3542 return SANE_STATUS_GOOD;
3543
3544 }
3545
3546 static SANE_Status
acquire_and_decode_jpeg_data(epsonds_scanner * s)3547 acquire_and_decode_jpeg_data(epsonds_scanner* s)
3548 {
3549 SANE_Int status = acquire_jpeg_data(s);
3550 if (status == SANE_STATUS_GOOD)
3551 {
3552 DBG(20, "** %s: sane status = %d needToConvertBW = %d \n", __func__, status, s->needToConvertBW);
3553
3554 // process front page
3555 if (s->frontJpegBufLen > 0)
3556 {
3557 eds_decode_jpeg(s, s->frontJpegBuf, s->frontJpegBufLen, &s->front,0, s->needToConvertBW);
3558 free(s->frontJpegBuf);
3559 s->frontJpegBuf = NULL;
3560 }
3561 // process back page
3562 if (s->backJpegBufLen > 0)
3563 {
3564 eds_decode_jpeg(s, s->backJpegBuf, s->backJpegBufLen, &s->back, 1, s->needToConvertBW);
3565 free(s->backJpegBuf);
3566 s->backJpegBuf = NULL;
3567 }
3568
3569 if (s->isDuplexScan)
3570 {
3571 upside_down_backside_image(s);
3572 }
3573 }else{
3574 DBG(20, "** %s: sane finish status = %d\n", __func__, status);
3575 return status;
3576 }
3577 return status;
3578 }
3579
3580 int sumLength = 0;
3581 /* this moves data from our buffers to SANE */
3582 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)3583 sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length)
3584 {
3585 epsonds_scanner *s = (epsonds_scanner *)handle;
3586 SANE_Int read = 0;
3587
3588 if (s->canceling)
3589 {
3590 esci2_can(s);
3591 *length = 0;
3592 return SANE_STATUS_CANCELLED;
3593 }
3594
3595 int available = eds_ring_avail(s->current);
3596 /* anything in the buffer? pass it to the frontend */
3597 if (available > 0) {
3598
3599 DBG(18, "reading from ring buffer, %d left\n", available);
3600
3601 eds_copy_image_from_ring(s, data, max_length, &read);
3602
3603 // data is empty fin
3604 if (read == 0) {
3605 *length = 0;
3606 eds_ring_flush(s->current);
3607 eds_ring_destory(s->current);
3608 DBG(18, "returns EOF 2\n");
3609 return SANE_STATUS_EOF;
3610 }
3611 *length = read;
3612
3613 return SANE_STATUS_GOOD;
3614 }else{
3615 *length = 0;
3616 eds_ring_flush(s->current);
3617 eds_ring_destory(s->current);
3618 DBG(18, "returns EOF 1\n");
3619 return SANE_STATUS_EOF;
3620 }
3621 }
3622
3623 /*
3624 * void sane_cancel(SANE_Handle handle)
3625 *
3626 * Set the cancel flag to true. The next time the backend requests data
3627 * from the scanner the CAN message will be sent.
3628 */
3629
3630 void
sane_cancel(SANE_Handle handle)3631 sane_cancel(SANE_Handle handle)
3632 {
3633 DBG(1, "** %s\n", __func__);
3634 ((epsonds_scanner *)handle)->canceling = SANE_TRUE;
3635 }
3636
3637 /*
3638 * SANE_Status sane_set_io_mode()
3639 *
3640 * not supported - for asynchronous I/O
3641 */
3642
3643 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle,SANE_Bool __sane_unused__ non_blocking)3644 sane_set_io_mode(SANE_Handle __sane_unused__ handle,
3645 SANE_Bool __sane_unused__ non_blocking)
3646 {
3647 return SANE_STATUS_UNSUPPORTED;
3648 }
3649
3650 /*
3651 * SANE_Status sane_get_select_fd()
3652 *
3653 * not supported - for asynchronous I/O
3654 */
3655
3656 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle,SANE_Int __sane_unused__ * fd)3657 sane_get_select_fd(SANE_Handle __sane_unused__ handle,
3658 SANE_Int __sane_unused__ *fd)
3659 {
3660 return SANE_STATUS_UNSUPPORTED;
3661 }
3662