1141cc406Sopenharmony_ci/*
2141cc406Sopenharmony_ci * epsonds.c - Epson ESC/I-2 driver.
3141cc406Sopenharmony_ci *
4141cc406Sopenharmony_ci * Copyright (C) 2015 Tower Technologies
5141cc406Sopenharmony_ci * Author: Alessandro Zummo <a.zummo@towertech.it>
6141cc406Sopenharmony_ci *
7141cc406Sopenharmony_ci * This file is part of the SANE package.
8141cc406Sopenharmony_ci *
9141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or
10141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as
11141cc406Sopenharmony_ci * published by the Free Software Foundation, version 2.
12141cc406Sopenharmony_ci */
13141cc406Sopenharmony_ci
14141cc406Sopenharmony_ci#define EPSONDS_VERSION		1
15141cc406Sopenharmony_ci#define EPSONDS_REVISION	1
16141cc406Sopenharmony_ci#define EPSONDS_BUILD		0
17141cc406Sopenharmony_ci
18141cc406Sopenharmony_ci/* debugging levels:
19141cc406Sopenharmony_ci *
20141cc406Sopenharmony_ci *	32	eds_send
21141cc406Sopenharmony_ci *	30	eds_recv
22141cc406Sopenharmony_ci *	20	sane_read and related
23141cc406Sopenharmony_ci *	18	sane_read and related
24141cc406Sopenharmony_ci *	17	setvalue, getvalue, control_option
25141cc406Sopenharmony_ci *	16
26141cc406Sopenharmony_ci *	15	esci2_img
27141cc406Sopenharmony_ci *	13	image_cb
28141cc406Sopenharmony_ci *	12	eds_control
29141cc406Sopenharmony_ci *	11	all received params
30141cc406Sopenharmony_ci *	10	some received params
31141cc406Sopenharmony_ci *	 9
32141cc406Sopenharmony_ci *	 8	esci2_xxx
33141cc406Sopenharmony_ci *	 7	open/close/attach
34141cc406Sopenharmony_ci *	 6	print_params
35141cc406Sopenharmony_ci *	 5	basic functions
36141cc406Sopenharmony_ci *	 3	JPEG decompressor
37141cc406Sopenharmony_ci *	 1	scanner info and capabilities
38141cc406Sopenharmony_ci *	 0	errors
39141cc406Sopenharmony_ci */
40141cc406Sopenharmony_ci
41141cc406Sopenharmony_ci#include "sane/config.h"
42141cc406Sopenharmony_ci
43141cc406Sopenharmony_ci#include <ctype.h>
44141cc406Sopenharmony_ci#ifdef HAVE_SYS_SELECT_H
45141cc406Sopenharmony_ci#include <sys/select.h>
46141cc406Sopenharmony_ci#endif
47141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H
48141cc406Sopenharmony_ci# include <sys/time.h>
49141cc406Sopenharmony_ci#endif
50141cc406Sopenharmony_ci#include <sys/types.h>
51141cc406Sopenharmony_ci#include <sys/socket.h>
52141cc406Sopenharmony_ci#include <unistd.h>
53141cc406Sopenharmony_ci#include <math.h>
54141cc406Sopenharmony_ci
55141cc406Sopenharmony_ci#include "sane/saneopts.h"
56141cc406Sopenharmony_ci#include "sane/sanei_config.h"
57141cc406Sopenharmony_ci#include "sane/sanei_tcp.h"
58141cc406Sopenharmony_ci#include "sane/sanei_udp.h"
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_ci#include "epsonds.h"
61141cc406Sopenharmony_ci#include "epsonds-usb.h"
62141cc406Sopenharmony_ci#include "epsonds-io.h"
63141cc406Sopenharmony_ci#include "epsonds-cmd.h"
64141cc406Sopenharmony_ci#include "epsonds-ops.h"
65141cc406Sopenharmony_ci#include "epsonds-jpeg.h"
66141cc406Sopenharmony_ci#include "epsonds-net.h"
67141cc406Sopenharmony_ci
68141cc406Sopenharmony_cistatic SANE_Status
69141cc406Sopenharmony_cisetvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info);
70141cc406Sopenharmony_ci/*
71141cc406Sopenharmony_ci * Definition of the mode_param struct, that is used to
72141cc406Sopenharmony_ci * specify the valid parameters for the different scan modes.
73141cc406Sopenharmony_ci *
74141cc406Sopenharmony_ci * The depth variable gets updated when the bit depth is modified.
75141cc406Sopenharmony_ci */
76141cc406Sopenharmony_ci
77141cc406Sopenharmony_ci
78141cc406Sopenharmony_cistatic unsigned char LUT[][256] =
79141cc406Sopenharmony_ci{
80141cc406Sopenharmony_ci    {// 0
81141cc406Sopenharmony_ci        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
82141cc406Sopenharmony_ci        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
83141cc406Sopenharmony_ci        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
84141cc406Sopenharmony_ci        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
85141cc406Sopenharmony_ci        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
86141cc406Sopenharmony_ci        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
87141cc406Sopenharmony_ci        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
88141cc406Sopenharmony_ci        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
89141cc406Sopenharmony_ci        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
90141cc406Sopenharmony_ci        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
91141cc406Sopenharmony_ci        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
92141cc406Sopenharmony_ci        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
93141cc406Sopenharmony_ci        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
94141cc406Sopenharmony_ci        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
95141cc406Sopenharmony_ci        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
96141cc406Sopenharmony_ci        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
97141cc406Sopenharmony_ci        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
98141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
99141cc406Sopenharmony_ci        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
100141cc406Sopenharmony_ci        0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
101141cc406Sopenharmony_ci        0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
102141cc406Sopenharmony_ci        0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
103141cc406Sopenharmony_ci        0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
104141cc406Sopenharmony_ci        0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
105141cc406Sopenharmony_ci        0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
106141cc406Sopenharmony_ci        0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
107141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
108141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
109141cc406Sopenharmony_ci        0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
110141cc406Sopenharmony_ci        0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
111141cc406Sopenharmony_ci        0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
112141cc406Sopenharmony_ci        0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
113141cc406Sopenharmony_ci    },
114141cc406Sopenharmony_ci    {	//  1
115141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
119141cc406Sopenharmony_ci        0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
120141cc406Sopenharmony_ci        0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
121141cc406Sopenharmony_ci        0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
122141cc406Sopenharmony_ci        0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
123141cc406Sopenharmony_ci        0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
124141cc406Sopenharmony_ci        0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
125141cc406Sopenharmony_ci        0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
126141cc406Sopenharmony_ci        0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
127141cc406Sopenharmony_ci        0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
128141cc406Sopenharmony_ci        0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
129141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
130141cc406Sopenharmony_ci        0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
131141cc406Sopenharmony_ci        0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
132141cc406Sopenharmony_ci        0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
133141cc406Sopenharmony_ci        0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
134141cc406Sopenharmony_ci        0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
135141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
136141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
137141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
138141cc406Sopenharmony_ci        0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
139141cc406Sopenharmony_ci        0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
140141cc406Sopenharmony_ci        0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
141141cc406Sopenharmony_ci        0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
142141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
143141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
144141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
145141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
146141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
147141cc406Sopenharmony_ci    },
148141cc406Sopenharmony_ci    {	// 2
149141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
151141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
154141cc406Sopenharmony_ci		0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
155141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
156141cc406Sopenharmony_ci		0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
157141cc406Sopenharmony_ci		0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
158141cc406Sopenharmony_ci		0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
159141cc406Sopenharmony_ci		0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
160141cc406Sopenharmony_ci		0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
161141cc406Sopenharmony_ci		0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
162141cc406Sopenharmony_ci		0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
163141cc406Sopenharmony_ci		0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
164141cc406Sopenharmony_ci		0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
165141cc406Sopenharmony_ci		0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
166141cc406Sopenharmony_ci		0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
167141cc406Sopenharmony_ci		0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
168141cc406Sopenharmony_ci		0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
169141cc406Sopenharmony_ci		0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
170141cc406Sopenharmony_ci		0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
171141cc406Sopenharmony_ci		0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
172141cc406Sopenharmony_ci		0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
173141cc406Sopenharmony_ci		0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
174141cc406Sopenharmony_ci		0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
175141cc406Sopenharmony_ci		0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
176141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
177141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
178141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
179141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
180141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
181141cc406Sopenharmony_ci    },
182141cc406Sopenharmony_ci    {	// 3
183141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
184141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
185141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
186141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
187141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
189141cc406Sopenharmony_ci		0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07,
190141cc406Sopenharmony_ci		0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,
191141cc406Sopenharmony_ci		0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,
192141cc406Sopenharmony_ci		0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,
193141cc406Sopenharmony_ci		0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,
194141cc406Sopenharmony_ci		0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,
195141cc406Sopenharmony_ci		0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B,
196141cc406Sopenharmony_ci		0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67,
197141cc406Sopenharmony_ci		0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,
198141cc406Sopenharmony_ci		0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,
199141cc406Sopenharmony_ci		0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A,
200141cc406Sopenharmony_ci		0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,
201141cc406Sopenharmony_ci		0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,
202141cc406Sopenharmony_ci		0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,
203141cc406Sopenharmony_ci		0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,
204141cc406Sopenharmony_ci		0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,
205141cc406Sopenharmony_ci		0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,
206141cc406Sopenharmony_ci		0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,
207141cc406Sopenharmony_ci		0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF,
208141cc406Sopenharmony_ci		0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
209141cc406Sopenharmony_ci		0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
210141cc406Sopenharmony_ci		0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
211141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
212141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
213141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
214141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
215141cc406Sopenharmony_ci	},
216141cc406Sopenharmony_ci	{	//4
217141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
218141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
219141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
220141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
221141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
223141cc406Sopenharmony_ci		0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
224141cc406Sopenharmony_ci		0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
225141cc406Sopenharmony_ci		0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,
226141cc406Sopenharmony_ci		0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,
227141cc406Sopenharmony_ci		0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A,
228141cc406Sopenharmony_ci		0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,
229141cc406Sopenharmony_ci		0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,
230141cc406Sopenharmony_ci		0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,
231141cc406Sopenharmony_ci		0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A,
232141cc406Sopenharmony_ci		0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,
233141cc406Sopenharmony_ci		0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,
234141cc406Sopenharmony_ci		0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,
235141cc406Sopenharmony_ci		0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,
236141cc406Sopenharmony_ci		0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,
237141cc406Sopenharmony_ci		0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,
238141cc406Sopenharmony_ci		0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,
239141cc406Sopenharmony_ci		0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,
240141cc406Sopenharmony_ci		0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,
241141cc406Sopenharmony_ci		0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5,
242141cc406Sopenharmony_ci		0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
243141cc406Sopenharmony_ci		0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
244141cc406Sopenharmony_ci		0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
245141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
246141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
247141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
248141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
249141cc406Sopenharmony_ci    },
250141cc406Sopenharmony_ci    {   // 5
251141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
252141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
253141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
254141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
255141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
256141cc406Sopenharmony_ci        0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
257141cc406Sopenharmony_ci        0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
258141cc406Sopenharmony_ci        0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
259141cc406Sopenharmony_ci        0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
260141cc406Sopenharmony_ci        0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
261141cc406Sopenharmony_ci        0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
262141cc406Sopenharmony_ci        0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
263141cc406Sopenharmony_ci        0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
264141cc406Sopenharmony_ci        0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
265141cc406Sopenharmony_ci        0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
266141cc406Sopenharmony_ci        0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
267141cc406Sopenharmony_ci        0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
268141cc406Sopenharmony_ci        0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
269141cc406Sopenharmony_ci        0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
270141cc406Sopenharmony_ci        0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
271141cc406Sopenharmony_ci        0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
272141cc406Sopenharmony_ci        0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
273141cc406Sopenharmony_ci        0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
274141cc406Sopenharmony_ci        0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
275141cc406Sopenharmony_ci        0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
276141cc406Sopenharmony_ci        0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
277141cc406Sopenharmony_ci        0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
278141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
279141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
280141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
281141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
282141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
283141cc406Sopenharmony_ci    },
284141cc406Sopenharmony_ci    {	// 6
285141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
286141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
287141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
288141cc406Sopenharmony_ci        0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
289141cc406Sopenharmony_ci        0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C,
290141cc406Sopenharmony_ci        0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B,
291141cc406Sopenharmony_ci        0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38,
292141cc406Sopenharmony_ci        0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44,
293141cc406Sopenharmony_ci        0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
294141cc406Sopenharmony_ci        0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B,
295141cc406Sopenharmony_ci        0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65,
296141cc406Sopenharmony_ci        0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70,
297141cc406Sopenharmony_ci        0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A,
298141cc406Sopenharmony_ci        0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83,
299141cc406Sopenharmony_ci        0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D,
300141cc406Sopenharmony_ci        0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96,
301141cc406Sopenharmony_ci        0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
302141cc406Sopenharmony_ci        0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
303141cc406Sopenharmony_ci        0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,
304141cc406Sopenharmony_ci        0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
305141cc406Sopenharmony_ci        0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4,
306141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,
307141cc406Sopenharmony_ci        0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
308141cc406Sopenharmony_ci        0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,
309141cc406Sopenharmony_ci        0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
310141cc406Sopenharmony_ci        0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,
311141cc406Sopenharmony_ci        0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
312141cc406Sopenharmony_ci        0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
313141cc406Sopenharmony_ci        0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
314141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
315141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
316141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
317141cc406Sopenharmony_ci    },
318141cc406Sopenharmony_ci    {	// 7
319141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
320141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
321141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
322141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
323141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
324141cc406Sopenharmony_ci		0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
325141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
326141cc406Sopenharmony_ci		0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
327141cc406Sopenharmony_ci		0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
328141cc406Sopenharmony_ci		0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
329141cc406Sopenharmony_ci		0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
330141cc406Sopenharmony_ci		0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
331141cc406Sopenharmony_ci		0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
332141cc406Sopenharmony_ci		0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
333141cc406Sopenharmony_ci		0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
334141cc406Sopenharmony_ci		0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
335141cc406Sopenharmony_ci		0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
336141cc406Sopenharmony_ci		0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
337141cc406Sopenharmony_ci		0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
338141cc406Sopenharmony_ci		0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
339141cc406Sopenharmony_ci		0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
340141cc406Sopenharmony_ci		0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
341141cc406Sopenharmony_ci		0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
342141cc406Sopenharmony_ci		0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
343141cc406Sopenharmony_ci		0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
344141cc406Sopenharmony_ci		0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
345141cc406Sopenharmony_ci		0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
346141cc406Sopenharmony_ci		0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
347141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
348141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
349141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
350141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
351141cc406Sopenharmony_ci    }
352141cc406Sopenharmony_ci};
353141cc406Sopenharmony_ci
354141cc406Sopenharmony_cistatic unsigned char LUT_R[][256] =
355141cc406Sopenharmony_ci{
356141cc406Sopenharmony_ci    {	//  0
357141cc406Sopenharmony_ci        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
358141cc406Sopenharmony_ci        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
359141cc406Sopenharmony_ci        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
360141cc406Sopenharmony_ci        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
361141cc406Sopenharmony_ci        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
362141cc406Sopenharmony_ci        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
363141cc406Sopenharmony_ci        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
364141cc406Sopenharmony_ci        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
365141cc406Sopenharmony_ci        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
366141cc406Sopenharmony_ci        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
367141cc406Sopenharmony_ci        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
368141cc406Sopenharmony_ci        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
369141cc406Sopenharmony_ci        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
370141cc406Sopenharmony_ci        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
371141cc406Sopenharmony_ci        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
372141cc406Sopenharmony_ci        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
373141cc406Sopenharmony_ci        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
374141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
375141cc406Sopenharmony_ci        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
376141cc406Sopenharmony_ci        0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
377141cc406Sopenharmony_ci        0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
378141cc406Sopenharmony_ci        0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
379141cc406Sopenharmony_ci        0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
380141cc406Sopenharmony_ci        0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
381141cc406Sopenharmony_ci        0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
382141cc406Sopenharmony_ci        0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
383141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
384141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
385141cc406Sopenharmony_ci        0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
386141cc406Sopenharmony_ci        0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
387141cc406Sopenharmony_ci        0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
388141cc406Sopenharmony_ci        0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
389141cc406Sopenharmony_ci    },
390141cc406Sopenharmony_ci    {	// 1
391141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
392141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
393141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
394141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
395141cc406Sopenharmony_ci        0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
396141cc406Sopenharmony_ci        0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
397141cc406Sopenharmony_ci        0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
398141cc406Sopenharmony_ci        0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
399141cc406Sopenharmony_ci        0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
400141cc406Sopenharmony_ci        0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
401141cc406Sopenharmony_ci        0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
402141cc406Sopenharmony_ci        0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
403141cc406Sopenharmony_ci        0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
404141cc406Sopenharmony_ci        0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
405141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
406141cc406Sopenharmony_ci        0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
407141cc406Sopenharmony_ci        0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
408141cc406Sopenharmony_ci        0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
409141cc406Sopenharmony_ci        0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
410141cc406Sopenharmony_ci        0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
411141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
412141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
413141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
414141cc406Sopenharmony_ci        0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
415141cc406Sopenharmony_ci        0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
416141cc406Sopenharmony_ci        0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
417141cc406Sopenharmony_ci        0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
418141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
419141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
420141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
421141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
422141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
423141cc406Sopenharmony_ci    },
424141cc406Sopenharmony_ci    {	// 2
425141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
426141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
427141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
428141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
429141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
430141cc406Sopenharmony_ci		0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
431141cc406Sopenharmony_ci		0x10,0x12,0x14,0x16,0x19,0x1B,0x1D,0x1F,
432141cc406Sopenharmony_ci		0x21,0x23,0x25,0x27,0x28,0x2A,0x2C,0x2E,
433141cc406Sopenharmony_ci		0x30,0x32,0x33,0x35,0x37,0x39,0x3A,0x3C,
434141cc406Sopenharmony_ci		0x3E,0x40,0x41,0x43,0x45,0x46,0x48,0x4A,
435141cc406Sopenharmony_ci		0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,
436141cc406Sopenharmony_ci		0x58,0x5A,0x5B,0x5D,0x5F,0x60,0x62,0x63,
437141cc406Sopenharmony_ci		0x65,0x66,0x68,0x69,0x6B,0x6C,0x6E,0x6F,
438141cc406Sopenharmony_ci		0x71,0x72,0x74,0x75,0x77,0x78,0x7A,0x7B,
439141cc406Sopenharmony_ci		0x7D,0x7E,0x80,0x81,0x83,0x84,0x86,0x87,
440141cc406Sopenharmony_ci		0x88,0x8A,0x8B,0x8D,0x8E,0x90,0x91,0x92,
441141cc406Sopenharmony_ci		0x94,0x95,0x97,0x98,0x99,0x9B,0x9C,0x9E,
442141cc406Sopenharmony_ci		0x9F,0xA0,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,
443141cc406Sopenharmony_ci		0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,0xB4,
444141cc406Sopenharmony_ci		0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,0xBE,
445141cc406Sopenharmony_ci		0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,0xC9,
446141cc406Sopenharmony_ci		0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,0xD4,
447141cc406Sopenharmony_ci		0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,0xDE,
448141cc406Sopenharmony_ci		0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,
449141cc406Sopenharmony_ci		0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,
450141cc406Sopenharmony_ci		0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,
451141cc406Sopenharmony_ci		0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
452141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
453141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
454141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
455141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
456141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
457141cc406Sopenharmony_ci    },
458141cc406Sopenharmony_ci    {
459141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
461141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
462141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
463141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
464141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465141cc406Sopenharmony_ci		0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
466141cc406Sopenharmony_ci		0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
467141cc406Sopenharmony_ci		0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
468141cc406Sopenharmony_ci		0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
469141cc406Sopenharmony_ci		0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
470141cc406Sopenharmony_ci		0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
471141cc406Sopenharmony_ci		0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
472141cc406Sopenharmony_ci		0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
473141cc406Sopenharmony_ci		0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
474141cc406Sopenharmony_ci		0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
475141cc406Sopenharmony_ci		0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
476141cc406Sopenharmony_ci		0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
477141cc406Sopenharmony_ci		0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
478141cc406Sopenharmony_ci		0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
479141cc406Sopenharmony_ci		0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
480141cc406Sopenharmony_ci		0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
481141cc406Sopenharmony_ci		0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
482141cc406Sopenharmony_ci		0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
483141cc406Sopenharmony_ci		0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
484141cc406Sopenharmony_ci		0xE1,0xE3,0xE4,0xE5,0xE5,0xE6,0xE8,0xE9,
485141cc406Sopenharmony_ci		0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
486141cc406Sopenharmony_ci		0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
487141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
488141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
489141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
490141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
491141cc406Sopenharmony_ci	},
492141cc406Sopenharmony_ci	{
493141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
494141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
495141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
496141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
498141cc406Sopenharmony_ci		0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,
499141cc406Sopenharmony_ci		0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,
500141cc406Sopenharmony_ci		0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,
501141cc406Sopenharmony_ci		0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,
502141cc406Sopenharmony_ci		0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,
503141cc406Sopenharmony_ci		0x42,0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,
504141cc406Sopenharmony_ci		0x4F,0x50,0x52,0x53,0x55,0x56,0x58,0x59,
505141cc406Sopenharmony_ci		0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,
506141cc406Sopenharmony_ci		0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,
507141cc406Sopenharmony_ci		0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,
508141cc406Sopenharmony_ci		0x7E,0x80,0x81,0x83,0x84,0x85,0x87,0x88,
509141cc406Sopenharmony_ci		0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,
510141cc406Sopenharmony_ci		0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,
511141cc406Sopenharmony_ci		0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,
512141cc406Sopenharmony_ci		0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,
513141cc406Sopenharmony_ci		0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,
514141cc406Sopenharmony_ci		0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,
515141cc406Sopenharmony_ci		0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,
516141cc406Sopenharmony_ci		0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,
517141cc406Sopenharmony_ci		0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,
518141cc406Sopenharmony_ci		0xE8,0xE9,0xEA,0xEB,0xEB,0xED,0xEE,0xEF,
519141cc406Sopenharmony_ci		0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
520141cc406Sopenharmony_ci		0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
521141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
522141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
523141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
524141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
525141cc406Sopenharmony_ci    },
526141cc406Sopenharmony_ci    {
527141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
528141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
529141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
531141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
532141cc406Sopenharmony_ci        0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
533141cc406Sopenharmony_ci        0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,
534141cc406Sopenharmony_ci        0x20,0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,
535141cc406Sopenharmony_ci        0x2F,0x31,0x33,0x34,0x36,0x38,0x39,0x3B,
536141cc406Sopenharmony_ci        0x3D,0x3E,0x40,0x42,0x43,0x45,0x47,0x48,
537141cc406Sopenharmony_ci        0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,
538141cc406Sopenharmony_ci        0x56,0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,
539141cc406Sopenharmony_ci        0x63,0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,
540141cc406Sopenharmony_ci        0x6E,0x70,0x71,0x73,0x74,0x76,0x77,0x79,
541141cc406Sopenharmony_ci        0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
542141cc406Sopenharmony_ci        0x85,0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,
543141cc406Sopenharmony_ci        0x90,0x92,0x93,0x95,0x96,0x97,0x99,0x9A,
544141cc406Sopenharmony_ci        0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,
545141cc406Sopenharmony_ci        0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,
546141cc406Sopenharmony_ci        0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,
547141cc406Sopenharmony_ci        0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
548141cc406Sopenharmony_ci        0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,
549141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,
550141cc406Sopenharmony_ci        0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,
551141cc406Sopenharmony_ci        0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,0xED,
552141cc406Sopenharmony_ci        0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,
553141cc406Sopenharmony_ci        0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,
554141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
555141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
556141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
557141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
558141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
559141cc406Sopenharmony_ci    },
560141cc406Sopenharmony_ci    {
561141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
564141cc406Sopenharmony_ci        0x02,0x03,0x04,0x05,0x06,0x08,0x0A,0x0C,
565141cc406Sopenharmony_ci        0x0E,0x10,0x12,0x14,0x16,0x19,0x1B,0x1D,
566141cc406Sopenharmony_ci        0x1F,0x20,0x22,0x24,0x26,0x28,0x2A,0x2B,
567141cc406Sopenharmony_ci        0x2D,0x2F,0x31,0x32,0x34,0x35,0x37,0x39,
568141cc406Sopenharmony_ci        0x3A,0x3C,0x3D,0x3F,0x41,0x42,0x44,0x45,
569141cc406Sopenharmony_ci        0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x4F,0x51,
570141cc406Sopenharmony_ci        0x52,0x54,0x55,0x57,0x58,0x59,0x5B,0x5C,
571141cc406Sopenharmony_ci        0x5E,0x5F,0x60,0x62,0x63,0x64,0x66,0x67,
572141cc406Sopenharmony_ci        0x68,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x72,
573141cc406Sopenharmony_ci        0x73,0x74,0x75,0x77,0x78,0x79,0x7B,0x7C,
574141cc406Sopenharmony_ci        0x7D,0x7E,0x80,0x81,0x82,0x83,0x85,0x86,
575141cc406Sopenharmony_ci        0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,
576141cc406Sopenharmony_ci        0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,
577141cc406Sopenharmony_ci        0x9A,0x9B,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,
578141cc406Sopenharmony_ci        0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAB,0xAC,
579141cc406Sopenharmony_ci        0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,
580141cc406Sopenharmony_ci        0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,
581141cc406Sopenharmony_ci        0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,
582141cc406Sopenharmony_ci        0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
583141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,
584141cc406Sopenharmony_ci        0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,
585141cc406Sopenharmony_ci        0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xEA,
586141cc406Sopenharmony_ci        0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,
587141cc406Sopenharmony_ci        0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,
588141cc406Sopenharmony_ci        0xFB,0xFC,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
589141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
590141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
591141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
592141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
593141cc406Sopenharmony_ci    },
594141cc406Sopenharmony_ci    {
595141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
596141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
597141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
598141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
599141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
600141cc406Sopenharmony_ci		0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
601141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
602141cc406Sopenharmony_ci		0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
603141cc406Sopenharmony_ci		0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
604141cc406Sopenharmony_ci		0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
605141cc406Sopenharmony_ci		0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
606141cc406Sopenharmony_ci		0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
607141cc406Sopenharmony_ci		0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
608141cc406Sopenharmony_ci		0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
609141cc406Sopenharmony_ci		0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
610141cc406Sopenharmony_ci		0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
611141cc406Sopenharmony_ci		0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
612141cc406Sopenharmony_ci		0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
613141cc406Sopenharmony_ci		0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
614141cc406Sopenharmony_ci		0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
615141cc406Sopenharmony_ci		0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
616141cc406Sopenharmony_ci		0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
617141cc406Sopenharmony_ci		0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
618141cc406Sopenharmony_ci		0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
619141cc406Sopenharmony_ci		0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
620141cc406Sopenharmony_ci		0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
621141cc406Sopenharmony_ci		0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
622141cc406Sopenharmony_ci		0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
623141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
624141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
625141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
626141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
627141cc406Sopenharmony_ci    }
628141cc406Sopenharmony_ci};
629141cc406Sopenharmony_ci
630141cc406Sopenharmony_cistatic unsigned char LUT_G[][256] =
631141cc406Sopenharmony_ci{
632141cc406Sopenharmony_ci    {
633141cc406Sopenharmony_ci        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
634141cc406Sopenharmony_ci        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
635141cc406Sopenharmony_ci        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
636141cc406Sopenharmony_ci        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
637141cc406Sopenharmony_ci        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
638141cc406Sopenharmony_ci        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
639141cc406Sopenharmony_ci        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
640141cc406Sopenharmony_ci        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
641141cc406Sopenharmony_ci        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
642141cc406Sopenharmony_ci        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
643141cc406Sopenharmony_ci        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
644141cc406Sopenharmony_ci        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
645141cc406Sopenharmony_ci        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
646141cc406Sopenharmony_ci        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
647141cc406Sopenharmony_ci        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
648141cc406Sopenharmony_ci        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
649141cc406Sopenharmony_ci        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
650141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
651141cc406Sopenharmony_ci        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
652141cc406Sopenharmony_ci        0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
653141cc406Sopenharmony_ci        0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
654141cc406Sopenharmony_ci        0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
655141cc406Sopenharmony_ci        0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
656141cc406Sopenharmony_ci        0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
657141cc406Sopenharmony_ci        0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
658141cc406Sopenharmony_ci        0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
659141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
660141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
661141cc406Sopenharmony_ci        0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
662141cc406Sopenharmony_ci        0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
663141cc406Sopenharmony_ci        0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
664141cc406Sopenharmony_ci        0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
665141cc406Sopenharmony_ci    },
666141cc406Sopenharmony_ci    {
667141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
668141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
669141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
670141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
671141cc406Sopenharmony_ci        0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
672141cc406Sopenharmony_ci        0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
673141cc406Sopenharmony_ci        0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
674141cc406Sopenharmony_ci        0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
675141cc406Sopenharmony_ci        0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
676141cc406Sopenharmony_ci        0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
677141cc406Sopenharmony_ci        0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
678141cc406Sopenharmony_ci        0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
679141cc406Sopenharmony_ci        0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
680141cc406Sopenharmony_ci        0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
681141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
682141cc406Sopenharmony_ci        0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
683141cc406Sopenharmony_ci        0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
684141cc406Sopenharmony_ci        0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
685141cc406Sopenharmony_ci        0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
686141cc406Sopenharmony_ci        0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
687141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
688141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
689141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
690141cc406Sopenharmony_ci        0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
691141cc406Sopenharmony_ci        0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
692141cc406Sopenharmony_ci        0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
693141cc406Sopenharmony_ci        0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
694141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
695141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
696141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
697141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
698141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
699141cc406Sopenharmony_ci    },
700141cc406Sopenharmony_ci    {
701141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
702141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
703141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
704141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
705141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
706141cc406Sopenharmony_ci		0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
707141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
708141cc406Sopenharmony_ci		0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
709141cc406Sopenharmony_ci		0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
710141cc406Sopenharmony_ci		0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
711141cc406Sopenharmony_ci		0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
712141cc406Sopenharmony_ci		0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
713141cc406Sopenharmony_ci		0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
714141cc406Sopenharmony_ci		0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
715141cc406Sopenharmony_ci		0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
716141cc406Sopenharmony_ci		0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
717141cc406Sopenharmony_ci		0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
718141cc406Sopenharmony_ci		0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
719141cc406Sopenharmony_ci		0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
720141cc406Sopenharmony_ci		0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
721141cc406Sopenharmony_ci		0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
722141cc406Sopenharmony_ci		0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
723141cc406Sopenharmony_ci		0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
724141cc406Sopenharmony_ci		0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
725141cc406Sopenharmony_ci		0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
726141cc406Sopenharmony_ci		0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
727141cc406Sopenharmony_ci		0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
728141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
729141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
730141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
731141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
732141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
733141cc406Sopenharmony_ci    },
734141cc406Sopenharmony_ci    {
735141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
736141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
737141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
738141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
739141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
740141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
741141cc406Sopenharmony_ci		0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07,
742141cc406Sopenharmony_ci		0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,
743141cc406Sopenharmony_ci		0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,
744141cc406Sopenharmony_ci		0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,
745141cc406Sopenharmony_ci		0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,
746141cc406Sopenharmony_ci		0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,
747141cc406Sopenharmony_ci		0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B,
748141cc406Sopenharmony_ci		0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67,
749141cc406Sopenharmony_ci		0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,
750141cc406Sopenharmony_ci		0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,
751141cc406Sopenharmony_ci		0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A,
752141cc406Sopenharmony_ci		0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,
753141cc406Sopenharmony_ci		0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,
754141cc406Sopenharmony_ci		0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,
755141cc406Sopenharmony_ci		0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,
756141cc406Sopenharmony_ci		0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,
757141cc406Sopenharmony_ci		0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,
758141cc406Sopenharmony_ci		0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,
759141cc406Sopenharmony_ci		0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF,
760141cc406Sopenharmony_ci		0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
761141cc406Sopenharmony_ci		0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
762141cc406Sopenharmony_ci		0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
763141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
764141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
765141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
766141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
767141cc406Sopenharmony_ci	},
768141cc406Sopenharmony_ci	{
769141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
770141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
772141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
773141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
775141cc406Sopenharmony_ci		0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
776141cc406Sopenharmony_ci		0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
777141cc406Sopenharmony_ci		0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,
778141cc406Sopenharmony_ci		0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,
779141cc406Sopenharmony_ci		0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A,
780141cc406Sopenharmony_ci		0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,
781141cc406Sopenharmony_ci		0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,
782141cc406Sopenharmony_ci		0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,
783141cc406Sopenharmony_ci		0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A,
784141cc406Sopenharmony_ci		0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,
785141cc406Sopenharmony_ci		0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,
786141cc406Sopenharmony_ci		0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,
787141cc406Sopenharmony_ci		0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,
788141cc406Sopenharmony_ci		0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,
789141cc406Sopenharmony_ci		0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,
790141cc406Sopenharmony_ci		0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,
791141cc406Sopenharmony_ci		0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,
792141cc406Sopenharmony_ci		0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,
793141cc406Sopenharmony_ci		0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5,
794141cc406Sopenharmony_ci		0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
795141cc406Sopenharmony_ci		0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
796141cc406Sopenharmony_ci		0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
797141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
798141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
799141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
800141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
801141cc406Sopenharmony_ci    },
802141cc406Sopenharmony_ci    {
803141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
804141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
805141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
806141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
807141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
808141cc406Sopenharmony_ci        0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,
809141cc406Sopenharmony_ci        0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,
810141cc406Sopenharmony_ci        0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
811141cc406Sopenharmony_ci        0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
812141cc406Sopenharmony_ci        0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
813141cc406Sopenharmony_ci        0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
814141cc406Sopenharmony_ci        0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
815141cc406Sopenharmony_ci        0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
816141cc406Sopenharmony_ci        0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
817141cc406Sopenharmony_ci        0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
818141cc406Sopenharmony_ci        0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
819141cc406Sopenharmony_ci        0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
820141cc406Sopenharmony_ci        0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,
821141cc406Sopenharmony_ci        0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,
822141cc406Sopenharmony_ci        0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,
823141cc406Sopenharmony_ci        0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,
824141cc406Sopenharmony_ci        0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,
825141cc406Sopenharmony_ci        0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
826141cc406Sopenharmony_ci        0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,
827141cc406Sopenharmony_ci        0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
828141cc406Sopenharmony_ci        0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
829141cc406Sopenharmony_ci        0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
830141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
831141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
832141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
833141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
834141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
835141cc406Sopenharmony_ci    },
836141cc406Sopenharmony_ci    {
837141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
838141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
839141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
840141cc406Sopenharmony_ci        0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,
841141cc406Sopenharmony_ci        0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C,
842141cc406Sopenharmony_ci        0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B,
843141cc406Sopenharmony_ci        0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38,
844141cc406Sopenharmony_ci        0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44,
845141cc406Sopenharmony_ci        0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
846141cc406Sopenharmony_ci        0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B,
847141cc406Sopenharmony_ci        0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65,
848141cc406Sopenharmony_ci        0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70,
849141cc406Sopenharmony_ci        0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A,
850141cc406Sopenharmony_ci        0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83,
851141cc406Sopenharmony_ci        0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D,
852141cc406Sopenharmony_ci        0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96,
853141cc406Sopenharmony_ci        0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
854141cc406Sopenharmony_ci        0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
855141cc406Sopenharmony_ci        0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,
856141cc406Sopenharmony_ci        0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
857141cc406Sopenharmony_ci        0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4,
858141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,
859141cc406Sopenharmony_ci        0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
860141cc406Sopenharmony_ci        0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,
861141cc406Sopenharmony_ci        0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
862141cc406Sopenharmony_ci        0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,
863141cc406Sopenharmony_ci        0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
864141cc406Sopenharmony_ci        0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
865141cc406Sopenharmony_ci        0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
866141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
867141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
868141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
869141cc406Sopenharmony_ci    },
870141cc406Sopenharmony_ci    {	// 7
871141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
872141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
874141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
876141cc406Sopenharmony_ci		0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
877141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
878141cc406Sopenharmony_ci		0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
879141cc406Sopenharmony_ci		0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
880141cc406Sopenharmony_ci		0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
881141cc406Sopenharmony_ci		0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
882141cc406Sopenharmony_ci		0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
883141cc406Sopenharmony_ci		0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
884141cc406Sopenharmony_ci		0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
885141cc406Sopenharmony_ci		0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
886141cc406Sopenharmony_ci		0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
887141cc406Sopenharmony_ci		0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
888141cc406Sopenharmony_ci		0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
889141cc406Sopenharmony_ci		0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
890141cc406Sopenharmony_ci		0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
891141cc406Sopenharmony_ci		0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
892141cc406Sopenharmony_ci		0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
893141cc406Sopenharmony_ci		0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
894141cc406Sopenharmony_ci		0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
895141cc406Sopenharmony_ci		0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
896141cc406Sopenharmony_ci		0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
897141cc406Sopenharmony_ci		0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
898141cc406Sopenharmony_ci		0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
899141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
900141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
901141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
902141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
903141cc406Sopenharmony_ci    }
904141cc406Sopenharmony_ci};
905141cc406Sopenharmony_ci
906141cc406Sopenharmony_cistatic unsigned char LUT_B[][256] =
907141cc406Sopenharmony_ci{
908141cc406Sopenharmony_ci    {
909141cc406Sopenharmony_ci        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
910141cc406Sopenharmony_ci        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
911141cc406Sopenharmony_ci        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
912141cc406Sopenharmony_ci        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
913141cc406Sopenharmony_ci        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
914141cc406Sopenharmony_ci        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
915141cc406Sopenharmony_ci        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
916141cc406Sopenharmony_ci        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
917141cc406Sopenharmony_ci        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
918141cc406Sopenharmony_ci        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
919141cc406Sopenharmony_ci        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
920141cc406Sopenharmony_ci        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
921141cc406Sopenharmony_ci        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
922141cc406Sopenharmony_ci        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
923141cc406Sopenharmony_ci        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
924141cc406Sopenharmony_ci        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
925141cc406Sopenharmony_ci        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
926141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
927141cc406Sopenharmony_ci        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
928141cc406Sopenharmony_ci        0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
929141cc406Sopenharmony_ci        0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
930141cc406Sopenharmony_ci        0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
931141cc406Sopenharmony_ci        0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
932141cc406Sopenharmony_ci        0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
933141cc406Sopenharmony_ci        0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
934141cc406Sopenharmony_ci        0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
935141cc406Sopenharmony_ci        0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
936141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
937141cc406Sopenharmony_ci        0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
938141cc406Sopenharmony_ci        0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
939141cc406Sopenharmony_ci        0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
940141cc406Sopenharmony_ci        0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
941141cc406Sopenharmony_ci    },
942141cc406Sopenharmony_ci    {
943141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
944141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
945141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
946141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
947141cc406Sopenharmony_ci        0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D,
948141cc406Sopenharmony_ci        0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20,
949141cc406Sopenharmony_ci        0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
950141cc406Sopenharmony_ci        0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E,
951141cc406Sopenharmony_ci        0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B,
952141cc406Sopenharmony_ci        0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58,
953141cc406Sopenharmony_ci        0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
954141cc406Sopenharmony_ci        0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70,
955141cc406Sopenharmony_ci        0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
956141cc406Sopenharmony_ci        0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86,
957141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91,
958141cc406Sopenharmony_ci        0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C,
959141cc406Sopenharmony_ci        0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,
960141cc406Sopenharmony_ci        0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,
961141cc406Sopenharmony_ci        0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,
962141cc406Sopenharmony_ci        0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,
963141cc406Sopenharmony_ci        0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD,
964141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7,
965141cc406Sopenharmony_ci        0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0,
966141cc406Sopenharmony_ci        0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
967141cc406Sopenharmony_ci        0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3,
968141cc406Sopenharmony_ci        0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC,
969141cc406Sopenharmony_ci        0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
970141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
971141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
972141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
973141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
974141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
975141cc406Sopenharmony_ci    },
976141cc406Sopenharmony_ci    {
977141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
978141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
979141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
980141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
981141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
982141cc406Sopenharmony_ci		0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
983141cc406Sopenharmony_ci		0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B,
984141cc406Sopenharmony_ci		0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A,
985141cc406Sopenharmony_ci		0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39,
986141cc406Sopenharmony_ci		0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46,
987141cc406Sopenharmony_ci		0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,
988141cc406Sopenharmony_ci		0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60,
989141cc406Sopenharmony_ci		0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C,
990141cc406Sopenharmony_ci		0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78,
991141cc406Sopenharmony_ci		0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,
992141cc406Sopenharmony_ci		0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,
993141cc406Sopenharmony_ci		0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B,
994141cc406Sopenharmony_ci		0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7,
995141cc406Sopenharmony_ci		0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,
996141cc406Sopenharmony_ci		0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,
997141cc406Sopenharmony_ci		0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,
998141cc406Sopenharmony_ci		0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,
999141cc406Sopenharmony_ci		0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,
1000141cc406Sopenharmony_ci		0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,
1001141cc406Sopenharmony_ci		0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,
1002141cc406Sopenharmony_ci		0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,
1003141cc406Sopenharmony_ci		0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1004141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1005141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1006141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1007141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1008141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1009141cc406Sopenharmony_ci    },
1010141cc406Sopenharmony_ci    {
1011141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1012141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1013141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1014141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1015141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1016141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1017141cc406Sopenharmony_ci		0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x08,
1018141cc406Sopenharmony_ci		0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,
1019141cc406Sopenharmony_ci		0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,
1020141cc406Sopenharmony_ci		0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,
1021141cc406Sopenharmony_ci		0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,
1022141cc406Sopenharmony_ci		0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,
1023141cc406Sopenharmony_ci		0x52,0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,
1024141cc406Sopenharmony_ci		0x5E,0x60,0x61,0x63,0x64,0x66,0x67,0x69,
1025141cc406Sopenharmony_ci		0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,
1026141cc406Sopenharmony_ci		0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,
1027141cc406Sopenharmony_ci		0x81,0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,
1028141cc406Sopenharmony_ci		0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,
1029141cc406Sopenharmony_ci		0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,
1030141cc406Sopenharmony_ci		0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,
1031141cc406Sopenharmony_ci		0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,
1032141cc406Sopenharmony_ci		0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,
1033141cc406Sopenharmony_ci		0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,
1034141cc406Sopenharmony_ci		0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,
1035141cc406Sopenharmony_ci		0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,
1036141cc406Sopenharmony_ci		0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,
1037141cc406Sopenharmony_ci		0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,
1038141cc406Sopenharmony_ci		0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,
1039141cc406Sopenharmony_ci		0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1040141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1041141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1042141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1043141cc406Sopenharmony_ci	},
1044141cc406Sopenharmony_ci	{
1045141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1046141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1047141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1048141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1049141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1050141cc406Sopenharmony_ci		0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
1051141cc406Sopenharmony_ci		0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12,
1052141cc406Sopenharmony_ci		0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,
1053141cc406Sopenharmony_ci		0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31,
1054141cc406Sopenharmony_ci		0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E,
1055141cc406Sopenharmony_ci		0x40,0x42,0x43,0x45,0x47,0x48,0x4A,0x4B,
1056141cc406Sopenharmony_ci		0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,0x58,
1057141cc406Sopenharmony_ci		0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,
1058141cc406Sopenharmony_ci		0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70,
1059141cc406Sopenharmony_ci		0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,
1060141cc406Sopenharmony_ci		0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,0x87,
1061141cc406Sopenharmony_ci		0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92,
1062141cc406Sopenharmony_ci		0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D,
1063141cc406Sopenharmony_ci		0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,
1064141cc406Sopenharmony_ci		0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,
1065141cc406Sopenharmony_ci		0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,
1066141cc406Sopenharmony_ci		0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,
1067141cc406Sopenharmony_ci		0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,
1068141cc406Sopenharmony_ci		0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,
1069141cc406Sopenharmony_ci		0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,
1070141cc406Sopenharmony_ci		0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,
1071141cc406Sopenharmony_ci		0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,
1072141cc406Sopenharmony_ci		0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,
1073141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1074141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1075141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1076141cc406Sopenharmony_ci		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1077141cc406Sopenharmony_ci    },
1078141cc406Sopenharmony_ci    {
1079141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1080141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1081141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1082141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1083141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1084141cc406Sopenharmony_ci        0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,
1085141cc406Sopenharmony_ci        0x0E,0x10,0x12,0x14,0x16,0x16,0x18,0x1A,
1086141cc406Sopenharmony_ci        0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A,
1087141cc406Sopenharmony_ci        0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38,
1088141cc406Sopenharmony_ci        0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45,
1089141cc406Sopenharmony_ci        0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,
1090141cc406Sopenharmony_ci        0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E,
1091141cc406Sopenharmony_ci        0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A,
1092141cc406Sopenharmony_ci        0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76,
1093141cc406Sopenharmony_ci        0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81,
1094141cc406Sopenharmony_ci        0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C,
1095141cc406Sopenharmony_ci        0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97,
1096141cc406Sopenharmony_ci        0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA3,
1097141cc406Sopenharmony_ci        0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,
1098141cc406Sopenharmony_ci        0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,
1099141cc406Sopenharmony_ci        0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,
1100141cc406Sopenharmony_ci        0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,
1101141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,
1102141cc406Sopenharmony_ci        0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,
1103141cc406Sopenharmony_ci        0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,
1104141cc406Sopenharmony_ci        0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,
1105141cc406Sopenharmony_ci        0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,
1106141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1107141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1108141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1109141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1110141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1111141cc406Sopenharmony_ci    },
1112141cc406Sopenharmony_ci    {
1113141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1114141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1115141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
1116141cc406Sopenharmony_ci        0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,
1117141cc406Sopenharmony_ci        0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
1118141cc406Sopenharmony_ci        0x22,0x24,0x26,0x27,0x29,0x2B,0x2C,0x2E,
1119141cc406Sopenharmony_ci        0x30,0x31,0x33,0x35,0x36,0x38,0x39,0x3B,
1120141cc406Sopenharmony_ci        0x3C,0x3E,0x40,0x41,0x43,0x44,0x45,0x47,
1121141cc406Sopenharmony_ci        0x48,0x4B,0x4D,0x4E,0x50,0x51,0x52,0x54,
1122141cc406Sopenharmony_ci        0x55,0x56,0x58,0x59,0x5B,0x5C,0x5D,0x5F,
1123141cc406Sopenharmony_ci        0x60,0x61,0x63,0x64,0x65,0x67,0x68,0x69,
1124141cc406Sopenharmony_ci        0x6A,0x6C,0x6D,0x6E,0x70,0x71,0x72,0x73,
1125141cc406Sopenharmony_ci        0x75,0x76,0x77,0x78,0x7A,0x7B,0x7C,0x7D,
1126141cc406Sopenharmony_ci        0x7E,0x80,0x81,0x82,0x83,0x85,0x86,0x87,
1127141cc406Sopenharmony_ci        0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x90,
1128141cc406Sopenharmony_ci        0x92,0x93,0x94,0x95,0x96,0x96,0x97,0x99,
1129141cc406Sopenharmony_ci        0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA1,0xA2,
1130141cc406Sopenharmony_ci        0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,
1131141cc406Sopenharmony_ci        0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,
1132141cc406Sopenharmony_ci        0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,
1133141cc406Sopenharmony_ci        0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,
1134141cc406Sopenharmony_ci        0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,
1135141cc406Sopenharmony_ci        0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,
1136141cc406Sopenharmony_ci        0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,
1137141cc406Sopenharmony_ci        0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,
1138141cc406Sopenharmony_ci        0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,
1139141cc406Sopenharmony_ci        0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,
1140141cc406Sopenharmony_ci        0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,
1141141cc406Sopenharmony_ci        0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1142141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1143141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1144141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1145141cc406Sopenharmony_ci    },
1146141cc406Sopenharmony_ci    {
1147141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1148141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1149141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1150141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1151141cc406Sopenharmony_ci        0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
1152141cc406Sopenharmony_ci        0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C,
1153141cc406Sopenharmony_ci        0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,
1154141cc406Sopenharmony_ci        0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A,
1155141cc406Sopenharmony_ci        0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37,
1156141cc406Sopenharmony_ci        0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44,
1157141cc406Sopenharmony_ci        0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50,
1158141cc406Sopenharmony_ci        0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C,
1159141cc406Sopenharmony_ci        0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67,
1160141cc406Sopenharmony_ci        0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72,
1161141cc406Sopenharmony_ci        0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D,
1162141cc406Sopenharmony_ci        0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88,
1163141cc406Sopenharmony_ci        0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92,
1164141cc406Sopenharmony_ci        0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,
1165141cc406Sopenharmony_ci        0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
1166141cc406Sopenharmony_ci        0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0,
1167141cc406Sopenharmony_ci        0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA,
1168141cc406Sopenharmony_ci        0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,
1169141cc406Sopenharmony_ci        0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,
1170141cc406Sopenharmony_ci        0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7,
1171141cc406Sopenharmony_ci        0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1,
1172141cc406Sopenharmony_ci        0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA,
1173141cc406Sopenharmony_ci        0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,
1174141cc406Sopenharmony_ci        0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD,
1175141cc406Sopenharmony_ci        0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1176141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1177141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1178141cc406Sopenharmony_ci        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1179141cc406Sopenharmony_ci    }
1180141cc406Sopenharmony_ci};
1181141cc406Sopenharmony_ci//// profile array ////
1182141cc406Sopenharmony_ci
1183141cc406Sopenharmony_citypedef struct
1184141cc406Sopenharmony_ci{
1185141cc406Sopenharmony_ci	int  productID; // USB PID
1186141cc406Sopenharmony_ci    char		productName[50]; // ESCI/2 procduct name
1187141cc406Sopenharmony_ci	char 		deviceID[50]; // device ID (same as bonjour mdl name)
1188141cc406Sopenharmony_ci    int  lutID; // look up table no
1189141cc406Sopenharmony_ci}epsonds_profile_map;
1190141cc406Sopenharmony_ci
1191141cc406Sopenharmony_ciconst  epsonds_profile_map epsonds_models_predefined[] = {
1192141cc406Sopenharmony_ci  {0x0145, "DS-5500","DS-5500", 7},
1193141cc406Sopenharmony_ci  {0x0145, "DS-6500","DS-6500", 7},
1194141cc406Sopenharmony_ci  {0x0145, "DS-7500","DS-7500", 7},
1195141cc406Sopenharmony_ci  {0x0146, "DS-50000","DS-50000", 7},
1196141cc406Sopenharmony_ci  {0x0146, "DS-60000","DS-60000", 7},
1197141cc406Sopenharmony_ci  {0x0146, "DS-70000","DS-70000", 7},
1198141cc406Sopenharmony_ci  {0x014C, "DS-510","DS-510", 7},
1199141cc406Sopenharmony_ci  {0x0150, "DS-560","DS-560", 7},
1200141cc406Sopenharmony_ci  {0x0152, "DS-40","DS-40", 7},
1201141cc406Sopenharmony_ci  {0x014D, "DS-760","DS-760", 7},
1202141cc406Sopenharmony_ci  {0x014D, "DS-860","DS-860", 7},
1203141cc406Sopenharmony_ci  {0x0154, "DS-520","DS-520", 7},
1204141cc406Sopenharmony_ci  {0x08BC, "PID 08BC","PX-M7050 Series", 7},
1205141cc406Sopenharmony_ci  {0x08BC, "PID 08BC","WF-8510 Series", 7},
1206141cc406Sopenharmony_ci  {0x08BC, "PID 08BC","WF-8590 Series", 7},
1207141cc406Sopenharmony_ci  {0x08CC, "PID 08CC","PX-M7050FX Series", 7},
1208141cc406Sopenharmony_ci  {0x08CC, "PID 08CC","WF-R8590 Series", 7},
1209141cc406Sopenharmony_ci  {0x0165, "DS-410","DS-410", 7},
1210141cc406Sopenharmony_ci  {0x016C, "ES-50","ES-50", 6},
1211141cc406Sopenharmony_ci  {0x0160, "DS-70","DS-70", 6},
1212141cc406Sopenharmony_ci  {0x016D, "ES-55R","ES-55R", 6},
1213141cc406Sopenharmony_ci  {0x018C, "RR-60","RR-60", 6},
1214141cc406Sopenharmony_ci  {0x016E, "ES-60W","ES-60W", 6},
1215141cc406Sopenharmony_ci  {0x0166, "DS-80W","DS-80W", 6},
1216141cc406Sopenharmony_ci  {0x016F, "ES-65WR","ES-65WR", 6},
1217141cc406Sopenharmony_ci  {0x018B, "RR-70W","RR-70W", 6},
1218141cc406Sopenharmony_ci  {0x016E, "ES-60WW","ES-60WW", 6},
1219141cc406Sopenharmony_ci  {0x016E, "ES-60WB","ES-60WB", 6},
1220141cc406Sopenharmony_ci  {0x015C, "DS-1630","DS-1630", 4},
1221141cc406Sopenharmony_ci  {0x015D, "DS-1610","DS-1610", 4},
1222141cc406Sopenharmony_ci  {0x015E, "DS-1660W","DS-1660W", 4},
1223141cc406Sopenharmony_ci  {0x0159, "DS-310","DS-310", 5},
1224141cc406Sopenharmony_ci  {0x0159, "ES-200","ES-200", 5},
1225141cc406Sopenharmony_ci  {0x0162, "DS-320","DS-320", 5},
1226141cc406Sopenharmony_ci  {0x015A, "DS-360W","DS-360W", 5},
1227141cc406Sopenharmony_ci  {0x015A, "ES-300W","ES-300W", 5},
1228141cc406Sopenharmony_ci  {0x0177, "ES-300WR","ES-300WR", 5},
1229141cc406Sopenharmony_ci  {0x0181, "ES-400II","ES-400II", 2},
1230141cc406Sopenharmony_ci  {0x0183, "DS-535II","DS-535II", 2},
1231141cc406Sopenharmony_ci  {0x0184, "DS-531","DS-531", 2},
1232141cc406Sopenharmony_ci  {0x0182, "DS-530II","DS-530II", 2},
1233141cc406Sopenharmony_ci  {0x0185, "ES-500WII","ES-500WII", 2},
1234141cc406Sopenharmony_ci  {0x0188, "DS-571W","DS-571W", 2},
1235141cc406Sopenharmony_ci  {0x0187, "DS-575WII","DS-575WII", 2},
1236141cc406Sopenharmony_ci  {0x0186, "DS-570WII","DS-570WII", 2},
1237141cc406Sopenharmony_ci  {0x017F, "ES-580W","ES-580W", 2},
1238141cc406Sopenharmony_ci  {0x0180, "RR-600W","RR-600W", 2},
1239141cc406Sopenharmony_ci  {0x0167, "DS-535","DS-535", 2},
1240141cc406Sopenharmony_ci  {0x017A, "DS-535H","DS-535H", 2},
1241141cc406Sopenharmony_ci  {0x0156, "ES-400","ES-400", 2},
1242141cc406Sopenharmony_ci  {0x0155, "DS-530","DS-530", 2},
1243141cc406Sopenharmony_ci  {0x016B, "FF-680W","FF-680W", 2},
1244141cc406Sopenharmony_ci  {0x0157, "DS-570W","DS-570W", 2},
1245141cc406Sopenharmony_ci  {0x0157, "ES-500W","ES-500W", 2},
1246141cc406Sopenharmony_ci  {0x0169, "DS-575W","DS-575W", 2},
1247141cc406Sopenharmony_ci  {0x0176, "ES-500WR","ES-500WR", 2},
1248141cc406Sopenharmony_ci  {0x114E, "PID 114E","EW-052A Series", 7},
1249141cc406Sopenharmony_ci  {0x114E, "PID 114E","XP-2100 Series", 7},
1250141cc406Sopenharmony_ci  {0x1135, "PID 1135","ET-2700 Series", 7},
1251141cc406Sopenharmony_ci  {0x1135, "PID 1135","L4150 Series", 7},
1252141cc406Sopenharmony_ci  {0x114A, "PID 114A","ET-M2140 Series", 7},
1253141cc406Sopenharmony_ci  {0x114A, "PID 114A","M2140 Series", 7},
1254141cc406Sopenharmony_ci  {0x114F, "PID 114F","ET-M3140 Series", 7},
1255141cc406Sopenharmony_ci  {0x114F, "PID 114F","M3140 Series", 7},
1256141cc406Sopenharmony_ci  {0x1143, "PID 1143","L3150 Series", 7},
1257141cc406Sopenharmony_ci  {0x1143, "PID 1143","ET-2710 Series", 7},
1258141cc406Sopenharmony_ci  {0x118A, "PID 118A","ET-2810 Series", 7},
1259141cc406Sopenharmony_ci  {0x118A, "PID 118A","L3250 Series", 7},
1260141cc406Sopenharmony_ci  {0x119B, "PID 119B","XP-2150 Series", 7},
1261141cc406Sopenharmony_ci  {0x11B1, "PID 11B1","XP-2200 Series", 7},
1262141cc406Sopenharmony_ci  {0x00, "","", 0x00 }
1263141cc406Sopenharmony_ci};
1264141cc406Sopenharmony_ci
1265141cc406Sopenharmony_citypedef struct
1266141cc406Sopenharmony_ci{
1267141cc406Sopenharmony_ci  epsonds_profile_map *array;
1268141cc406Sopenharmony_ci  int used;
1269141cc406Sopenharmony_ci  int size;
1270141cc406Sopenharmony_ci}epsonds_profile_map_array;
1271141cc406Sopenharmony_ci
1272141cc406Sopenharmony_ci
1273141cc406Sopenharmony_cistatic epsonds_profile_map_array stProfileMapArray;
1274141cc406Sopenharmony_ci
1275141cc406Sopenharmony_cistatic void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element);
1276141cc406Sopenharmony_ci
1277141cc406Sopenharmony_cistatic void init_profile_maps(epsonds_profile_map_array *a, size_t initialSize) {
1278141cc406Sopenharmony_ci  a->array = malloc(initialSize * sizeof(epsonds_profile_map));
1279141cc406Sopenharmony_ci  a->used = 0;
1280141cc406Sopenharmony_ci  a->size = initialSize;
1281141cc406Sopenharmony_ci
1282141cc406Sopenharmony_ci   for (int i = 0; epsonds_models_predefined[i].productID != 0; i++) {
1283141cc406Sopenharmony_ci
1284141cc406Sopenharmony_ci		//DBG(6, "epsonds_models_predefined[i].productID         = %x\n", epsonds_models_predefined[i].productID );
1285141cc406Sopenharmony_ci
1286141cc406Sopenharmony_ci	   insert_profile_map(a, epsonds_models_predefined[i]);
1287141cc406Sopenharmony_ci   }
1288141cc406Sopenharmony_ci}
1289141cc406Sopenharmony_ci
1290141cc406Sopenharmony_cistatic void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element) {
1291141cc406Sopenharmony_ci  if (a->used == a->size) {
1292141cc406Sopenharmony_ci    a->size *= 2;
1293141cc406Sopenharmony_ci    a->array = realloc(a->array, a->size * sizeof(epsonds_profile_map));
1294141cc406Sopenharmony_ci  }
1295141cc406Sopenharmony_ci  a->array[a->used++] = element;
1296141cc406Sopenharmony_ci}
1297141cc406Sopenharmony_ci
1298141cc406Sopenharmony_cistatic void free_profile_maps(epsonds_profile_map_array *a) {
1299141cc406Sopenharmony_ci  free(a->array);
1300141cc406Sopenharmony_ci  a->array = NULL;
1301141cc406Sopenharmony_ci  a->used = a->size = 0;
1302141cc406Sopenharmony_ci}
1303141cc406Sopenharmony_ci/////////////////////////
1304141cc406Sopenharmony_ci
1305141cc406Sopenharmony_ci
1306141cc406Sopenharmony_cistruct mode_param mode_params[] = {
1307141cc406Sopenharmony_ci	{0, 0x00, 0x30, 1},
1308141cc406Sopenharmony_ci	{0, 0x00, 0x30, 8},
1309141cc406Sopenharmony_ci	{1, 0x02, 0x00, 8},
1310141cc406Sopenharmony_ci	{0, 0x00, 0x30, 1}
1311141cc406Sopenharmony_ci};
1312141cc406Sopenharmony_ci
1313141cc406Sopenharmony_cistatic SANE_String_Const mode_list[] = {
1314141cc406Sopenharmony_ci	SANE_VALUE_SCAN_MODE_LINEART,
1315141cc406Sopenharmony_ci	SANE_VALUE_SCAN_MODE_GRAY,
1316141cc406Sopenharmony_ci	SANE_VALUE_SCAN_MODE_COLOR,
1317141cc406Sopenharmony_ci	NULL
1318141cc406Sopenharmony_ci};
1319141cc406Sopenharmony_ci
1320141cc406Sopenharmony_ci
1321141cc406Sopenharmony_ci/* Define the different scan sources */
1322141cc406Sopenharmony_ci
1323141cc406Sopenharmony_ci#define STRING_FLATBED SANE_I18N("Flatbed")
1324141cc406Sopenharmony_ci#define STRING_ADFFRONT SANE_I18N("ADF Front")
1325141cc406Sopenharmony_ci#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
1326141cc406Sopenharmony_ci
1327141cc406Sopenharmony_ci/* order will be fixed: fb, adf, tpu */
1328141cc406Sopenharmony_ciSANE_String_Const source_list[] = {
1329141cc406Sopenharmony_ci	NULL,
1330141cc406Sopenharmony_ci	NULL,
1331141cc406Sopenharmony_ci	NULL,
1332141cc406Sopenharmony_ci	NULL
1333141cc406Sopenharmony_ci};
1334141cc406Sopenharmony_ci
1335141cc406Sopenharmony_ci/*
1336141cc406Sopenharmony_ci * List of pointers to devices - will be dynamically allocated depending
1337141cc406Sopenharmony_ci * on the number of devices found.
1338141cc406Sopenharmony_ci */
1339141cc406Sopenharmony_cistatic const SANE_Device **devlist;
1340141cc406Sopenharmony_ci
1341141cc406Sopenharmony_ci/* Some utility functions */
1342141cc406Sopenharmony_ci
1343141cc406Sopenharmony_cistatic size_t
1344141cc406Sopenharmony_cimax_string_size(const SANE_String_Const strings[])
1345141cc406Sopenharmony_ci{
1346141cc406Sopenharmony_ci	size_t size, max_size = 0;
1347141cc406Sopenharmony_ci	int i;
1348141cc406Sopenharmony_ci
1349141cc406Sopenharmony_ci	for (i = 0; strings[i]; i++) {
1350141cc406Sopenharmony_ci		size = strlen(strings[i]) + 1;
1351141cc406Sopenharmony_ci		if (size > max_size)
1352141cc406Sopenharmony_ci			max_size = size;
1353141cc406Sopenharmony_ci	}
1354141cc406Sopenharmony_ci	return max_size;
1355141cc406Sopenharmony_ci}
1356141cc406Sopenharmony_ci
1357141cc406Sopenharmony_cistatic SANE_Status attach_one_usb(SANE_String_Const devname);
1358141cc406Sopenharmony_cistatic SANE_Status attach_one_net(SANE_String_Const devname);
1359141cc406Sopenharmony_cistatic SANE_Status acquire_jpeg_data(epsonds_scanner* s);
1360141cc406Sopenharmony_cistatic SANE_Status acquire_and_decode_jpeg_data(epsonds_scanner* s);
1361141cc406Sopenharmony_cistatic SANE_Status acquire_raw_data(epsonds_scanner* s);
1362141cc406Sopenharmony_ci
1363141cc406Sopenharmony_cistatic void
1364141cc406Sopenharmony_ciprint_params(const SANE_Parameters params)
1365141cc406Sopenharmony_ci{
1366141cc406Sopenharmony_ci	DBG(6, "params.format          = %d\n", params.format);
1367141cc406Sopenharmony_ci	DBG(6, "params.last_frame      = %d\n", params.last_frame);
1368141cc406Sopenharmony_ci	DBG(6, "params.bytes_per_line  = %d\n", params.bytes_per_line);
1369141cc406Sopenharmony_ci	DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
1370141cc406Sopenharmony_ci	DBG(6, "params.lines           = %d\n", params.lines);
1371141cc406Sopenharmony_ci	DBG(6, "params.depth           = %d\n", params.depth);
1372141cc406Sopenharmony_ci}
1373141cc406Sopenharmony_ci
1374141cc406Sopenharmony_cistatic void
1375141cc406Sopenharmony_ciclose_scanner(epsonds_scanner *s)
1376141cc406Sopenharmony_ci{
1377141cc406Sopenharmony_ci	DBG(7, "%s: fd = %d\n", __func__, s->fd);
1378141cc406Sopenharmony_ci
1379141cc406Sopenharmony_ci	if (s->scanning)
1380141cc406Sopenharmony_ci	{
1381141cc406Sopenharmony_ci		sane_cancel(s);
1382141cc406Sopenharmony_ci	}
1383141cc406Sopenharmony_ci
1384141cc406Sopenharmony_ci	if (s->fd == -1)
1385141cc406Sopenharmony_ci		goto free;
1386141cc406Sopenharmony_ci
1387141cc406Sopenharmony_ci	if (s->locked) {
1388141cc406Sopenharmony_ci		DBG(7, " unlocking scanner\n");
1389141cc406Sopenharmony_ci		esci2_fin(s);
1390141cc406Sopenharmony_ci	}
1391141cc406Sopenharmony_ci
1392141cc406Sopenharmony_ci	if (s->hw->connection == SANE_EPSONDS_NET) {
1393141cc406Sopenharmony_ci		epsonds_net_unlock(s);
1394141cc406Sopenharmony_ci		sanei_tcp_close(s->fd);
1395141cc406Sopenharmony_ci	} else if (s->hw->connection == SANE_EPSONDS_USB) {
1396141cc406Sopenharmony_ci		sanei_usb_close(s->fd);
1397141cc406Sopenharmony_ci	}
1398141cc406Sopenharmony_ci
1399141cc406Sopenharmony_cifree:
1400141cc406Sopenharmony_ci
1401141cc406Sopenharmony_ci	free(s->front.ring);
1402141cc406Sopenharmony_ci	free(s->back.ring);
1403141cc406Sopenharmony_ci	free(s->line_buffer);
1404141cc406Sopenharmony_ci	free(s);
1405141cc406Sopenharmony_ci
1406141cc406Sopenharmony_ci	DBG(7, "%s: ZZZ\n", __func__);
1407141cc406Sopenharmony_ci}
1408141cc406Sopenharmony_ci
1409141cc406Sopenharmony_cistatic SANE_Status
1410141cc406Sopenharmony_ciopen_scanner(epsonds_scanner *s)
1411141cc406Sopenharmony_ci{
1412141cc406Sopenharmony_ci	SANE_Status status = SANE_STATUS_INVAL;
1413141cc406Sopenharmony_ci
1414141cc406Sopenharmony_ci	DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
1415141cc406Sopenharmony_ci
1416141cc406Sopenharmony_ci	if (s->fd != -1) {
1417141cc406Sopenharmony_ci		DBG(5, "scanner is already open: fd = %d\n", s->fd);
1418141cc406Sopenharmony_ci		return SANE_STATUS_GOOD;	/* no need to open the scanner */
1419141cc406Sopenharmony_ci	}
1420141cc406Sopenharmony_ci
1421141cc406Sopenharmony_ci	if (s->hw->connection == SANE_EPSONDS_NET) {
1422141cc406Sopenharmony_ci		unsigned char buf[5];
1423141cc406Sopenharmony_ci
1424141cc406Sopenharmony_ci		/* device name has the form net:ipaddr */
1425141cc406Sopenharmony_ci		status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);
1426141cc406Sopenharmony_ci		if (status == SANE_STATUS_GOOD) {
1427141cc406Sopenharmony_ci
1428141cc406Sopenharmony_ci			ssize_t read;
1429141cc406Sopenharmony_ci			struct timeval tv;
1430141cc406Sopenharmony_ci
1431141cc406Sopenharmony_ci			tv.tv_sec = 5;
1432141cc406Sopenharmony_ci			tv.tv_usec = 0;
1433141cc406Sopenharmony_ci
1434141cc406Sopenharmony_ci			setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,  sizeof(tv));
1435141cc406Sopenharmony_ci
1436141cc406Sopenharmony_ci			s->netlen = 0;
1437141cc406Sopenharmony_ci
1438141cc406Sopenharmony_ci			DBG(32, "awaiting welcome message\n");
1439141cc406Sopenharmony_ci
1440141cc406Sopenharmony_ci			/* the scanner sends a kind of welcome msg */
1441141cc406Sopenharmony_ci			// XXX check command type, answer to connect is 0x80
1442141cc406Sopenharmony_ci			read = eds_recv(s, buf, 5, &status);
1443141cc406Sopenharmony_ci			if (read != 5) {
1444141cc406Sopenharmony_ci				sanei_tcp_close(s->fd);
1445141cc406Sopenharmony_ci				s->fd = -1;
1446141cc406Sopenharmony_ci				return SANE_STATUS_IO_ERROR;
1447141cc406Sopenharmony_ci			}
1448141cc406Sopenharmony_ci
1449141cc406Sopenharmony_ci			DBG(32, "welcome message received, locking the scanner...\n");
1450141cc406Sopenharmony_ci
1451141cc406Sopenharmony_ci			/* lock the scanner for use by sane */
1452141cc406Sopenharmony_ci			status = epsonds_net_lock(s);
1453141cc406Sopenharmony_ci			if (status != SANE_STATUS_GOOD) {
1454141cc406Sopenharmony_ci				DBG(1, "%s cannot lock scanner: %s\n", s->hw->sane.name,
1455141cc406Sopenharmony_ci					sane_strstatus(status));
1456141cc406Sopenharmony_ci
1457141cc406Sopenharmony_ci				sanei_tcp_close(s->fd);
1458141cc406Sopenharmony_ci				s->fd = -1;
1459141cc406Sopenharmony_ci
1460141cc406Sopenharmony_ci				return status;
1461141cc406Sopenharmony_ci			}
1462141cc406Sopenharmony_ci
1463141cc406Sopenharmony_ci			DBG(32, "scanner locked\n");
1464141cc406Sopenharmony_ci		}
1465141cc406Sopenharmony_ci
1466141cc406Sopenharmony_ci	} else if (s->hw->connection == SANE_EPSONDS_USB) {
1467141cc406Sopenharmony_ci		status = sanei_usb_open(s->hw->sane.name, &s->fd);
1468141cc406Sopenharmony_ci
1469141cc406Sopenharmony_ci		if (status == SANE_STATUS_GOOD) {
1470141cc406Sopenharmony_ci			sanei_usb_set_timeout(USB_TIMEOUT);
1471141cc406Sopenharmony_ci		}
1472141cc406Sopenharmony_ci
1473141cc406Sopenharmony_ci	} else {
1474141cc406Sopenharmony_ci		DBG(1, "unknown connection type: %d\n", s->hw->connection);
1475141cc406Sopenharmony_ci	}
1476141cc406Sopenharmony_ci
1477141cc406Sopenharmony_ci	if (status == SANE_STATUS_ACCESS_DENIED) {
1478141cc406Sopenharmony_ci		DBG(1, "please check that you have permissions on the device.\n");
1479141cc406Sopenharmony_ci		DBG(1, "if this is a multi-function device with a printer,\n");
1480141cc406Sopenharmony_ci		DBG(1, "disable any conflicting driver (like usblp).\n");
1481141cc406Sopenharmony_ci	}
1482141cc406Sopenharmony_ci
1483141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD)
1484141cc406Sopenharmony_ci		DBG(1, "%s open failed: %s\n",
1485141cc406Sopenharmony_ci			s->hw->sane.name,
1486141cc406Sopenharmony_ci			sane_strstatus(status));
1487141cc406Sopenharmony_ci	else
1488141cc406Sopenharmony_ci		DBG(5, " opened correctly\n");
1489141cc406Sopenharmony_ci
1490141cc406Sopenharmony_ci	return status;
1491141cc406Sopenharmony_ci}
1492141cc406Sopenharmony_ci
1493141cc406Sopenharmony_cistatic int num_devices;			/* number of scanners attached to backend */
1494141cc406Sopenharmony_cistatic epsonds_device *first_dev;	/* first EPSON scanner in list */
1495141cc406Sopenharmony_ci
1496141cc406Sopenharmony_cistatic struct epsonds_scanner *
1497141cc406Sopenharmony_ciscanner_create(struct epsonds_device *dev, SANE_Status *status)
1498141cc406Sopenharmony_ci{
1499141cc406Sopenharmony_ci	struct epsonds_scanner *s;
1500141cc406Sopenharmony_ci	s = malloc(sizeof(struct epsonds_scanner));
1501141cc406Sopenharmony_ci	if (s == NULL) {
1502141cc406Sopenharmony_ci		*status = SANE_STATUS_NO_MEM;
1503141cc406Sopenharmony_ci		return NULL;
1504141cc406Sopenharmony_ci	}
1505141cc406Sopenharmony_ci
1506141cc406Sopenharmony_ci	/* clear verything */
1507141cc406Sopenharmony_ci	memset(s, 0x00, sizeof(struct epsonds_scanner));
1508141cc406Sopenharmony_ci
1509141cc406Sopenharmony_ci	s->fd = -1;
1510141cc406Sopenharmony_ci	s->hw = dev;
1511141cc406Sopenharmony_ci
1512141cc406Sopenharmony_ci	return s;
1513141cc406Sopenharmony_ci}
1514141cc406Sopenharmony_ci
1515141cc406Sopenharmony_cistatic struct epsonds_scanner *
1516141cc406Sopenharmony_cidevice_detect(const char *name, int type, SANE_Status *status)
1517141cc406Sopenharmony_ci{
1518141cc406Sopenharmony_ci	struct epsonds_scanner *s;
1519141cc406Sopenharmony_ci	struct epsonds_device *dev;
1520141cc406Sopenharmony_ci
1521141cc406Sopenharmony_ci	DBG(1, "%s, %s, type: %d\n", __func__, name, type);
1522141cc406Sopenharmony_ci
1523141cc406Sopenharmony_ci	/* try to find the device in our list */
1524141cc406Sopenharmony_ci	for (dev = first_dev; dev; dev = dev->next) {
1525141cc406Sopenharmony_ci
1526141cc406Sopenharmony_ci		if (strcmp(dev->sane.name, name) == 0) {
1527141cc406Sopenharmony_ci
1528141cc406Sopenharmony_ci			DBG(1, " found cached device\n");
1529141cc406Sopenharmony_ci
1530141cc406Sopenharmony_ci			// the device might have been just probed, sleep a bit.
1531141cc406Sopenharmony_ci			if (dev->connection == SANE_EPSONDS_NET) {
1532141cc406Sopenharmony_ci				sleep(1);
1533141cc406Sopenharmony_ci			}
1534141cc406Sopenharmony_ci
1535141cc406Sopenharmony_ci			return scanner_create(dev, status);
1536141cc406Sopenharmony_ci		}
1537141cc406Sopenharmony_ci	}
1538141cc406Sopenharmony_ci
1539141cc406Sopenharmony_ci	/* not found, create new if valid */
1540141cc406Sopenharmony_ci	if (type == SANE_EPSONDS_NODEV) {
1541141cc406Sopenharmony_ci		*status = SANE_STATUS_INVAL;
1542141cc406Sopenharmony_ci		return NULL;
1543141cc406Sopenharmony_ci	}
1544141cc406Sopenharmony_ci
1545141cc406Sopenharmony_ci	/* alloc and clear our device structure */
1546141cc406Sopenharmony_ci	dev = malloc(sizeof(*dev));
1547141cc406Sopenharmony_ci	if (!dev) {
1548141cc406Sopenharmony_ci		*status = SANE_STATUS_NO_MEM;
1549141cc406Sopenharmony_ci		return NULL;
1550141cc406Sopenharmony_ci	}
1551141cc406Sopenharmony_ci	memset(dev, 0x00, sizeof(struct epsonds_device));
1552141cc406Sopenharmony_ci
1553141cc406Sopenharmony_ci	s = scanner_create(dev, status);
1554141cc406Sopenharmony_ci	if (s == NULL)
1555141cc406Sopenharmony_ci		return NULL;
1556141cc406Sopenharmony_ci
1557141cc406Sopenharmony_ci	dev->connection = type;
1558141cc406Sopenharmony_ci	dev->model = strdup("(undetermined)");
1559141cc406Sopenharmony_ci	dev->name = strdup(name);
1560141cc406Sopenharmony_ci
1561141cc406Sopenharmony_ci	dev->sane.name = dev->name;
1562141cc406Sopenharmony_ci	dev->sane.vendor = "Epson";
1563141cc406Sopenharmony_ci	dev->sane.model = dev->model;
1564141cc406Sopenharmony_ci	dev->sane.type = "ESC/I-2";
1565141cc406Sopenharmony_ci
1566141cc406Sopenharmony_ci	*status = open_scanner(s);
1567141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD) {
1568141cc406Sopenharmony_ci		free(s);
1569141cc406Sopenharmony_ci		return NULL;
1570141cc406Sopenharmony_ci	}
1571141cc406Sopenharmony_ci
1572141cc406Sopenharmony_ci	eds_dev_init(dev);
1573141cc406Sopenharmony_ci
1574141cc406Sopenharmony_ci	/* lock scanner */
1575141cc406Sopenharmony_ci	*status = eds_lock(s);
1576141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD) {
1577141cc406Sopenharmony_ci		goto close;
1578141cc406Sopenharmony_ci	}
1579141cc406Sopenharmony_ci
1580141cc406Sopenharmony_ci	/* discover capabilities */
1581141cc406Sopenharmony_ci	*status = esci2_info(s);
1582141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD)
1583141cc406Sopenharmony_ci		goto close;
1584141cc406Sopenharmony_ci
1585141cc406Sopenharmony_ci	*status = esci2_capa(s);
1586141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD)
1587141cc406Sopenharmony_ci		goto close;
1588141cc406Sopenharmony_ci
1589141cc406Sopenharmony_ci	*status = esci2_resa(s);
1590141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD)
1591141cc406Sopenharmony_ci		goto close;
1592141cc406Sopenharmony_ci
1593141cc406Sopenharmony_ci	// assume 1 and 8 bit are always supported
1594141cc406Sopenharmony_ci	eds_add_depth(s->hw, 1);
1595141cc406Sopenharmony_ci	eds_add_depth(s->hw, 8);
1596141cc406Sopenharmony_ci
1597141cc406Sopenharmony_ci	// setup area according to available options
1598141cc406Sopenharmony_ci	if (s->hw->has_fb) {
1599141cc406Sopenharmony_ci
1600141cc406Sopenharmony_ci		dev->x_range = &dev->fbf_x_range;
1601141cc406Sopenharmony_ci		dev->y_range = &dev->fbf_y_range;
1602141cc406Sopenharmony_ci		dev->alignment = dev->fbf_alignment;
1603141cc406Sopenharmony_ci
1604141cc406Sopenharmony_ci	} else if (s->hw->has_adf) {
1605141cc406Sopenharmony_ci
1606141cc406Sopenharmony_ci		dev->x_range = &dev->adf_x_range;
1607141cc406Sopenharmony_ci		dev->y_range = &dev->adf_y_range;
1608141cc406Sopenharmony_ci		dev->alignment = dev->adf_alignment;
1609141cc406Sopenharmony_ci
1610141cc406Sopenharmony_ci	} else {
1611141cc406Sopenharmony_ci		DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n");
1612141cc406Sopenharmony_ci	}
1613141cc406Sopenharmony_ci
1614141cc406Sopenharmony_ci	*status = eds_dev_post_init(dev);
1615141cc406Sopenharmony_ci	if (*status != SANE_STATUS_GOOD)
1616141cc406Sopenharmony_ci		goto close;
1617141cc406Sopenharmony_ci
1618141cc406Sopenharmony_ci	DBG(1, "scanner model: %s\n", dev->model);
1619141cc406Sopenharmony_ci
1620141cc406Sopenharmony_ci
1621141cc406Sopenharmony_ci	s->hw->lut_id = 0;
1622141cc406Sopenharmony_ci
1623141cc406Sopenharmony_ci	for (int i = 0; i < stProfileMapArray.used; i++) {
1624141cc406Sopenharmony_ci
1625141cc406Sopenharmony_ci		epsonds_profile_map* map = &stProfileMapArray.array[i];
1626141cc406Sopenharmony_ci
1627141cc406Sopenharmony_ci
1628141cc406Sopenharmony_ci		if (strcmp(map->productName, dev->model) == 0) {
1629141cc406Sopenharmony_ci
1630141cc406Sopenharmony_ci			{//Convert to user friendly model name
1631141cc406Sopenharmony_ci				free(s->hw->model);
1632141cc406Sopenharmony_ci
1633141cc406Sopenharmony_ci				s->hw->model = strdup(map->deviceID);
1634141cc406Sopenharmony_ci				s->hw->sane.model = s->hw->model;
1635141cc406Sopenharmony_ci			}
1636141cc406Sopenharmony_ci			{// set lutid
1637141cc406Sopenharmony_ci				s->hw->lut_id = map->lutID;
1638141cc406Sopenharmony_ci			}
1639141cc406Sopenharmony_ci			break;
1640141cc406Sopenharmony_ci		}
1641141cc406Sopenharmony_ci	}
1642141cc406Sopenharmony_ci	DBG(1, "scanner lut_id: %d\n", s->hw->lut_id);
1643141cc406Sopenharmony_ci
1644141cc406Sopenharmony_ci	num_devices++;
1645141cc406Sopenharmony_ci	dev->next = first_dev;
1646141cc406Sopenharmony_ci	first_dev = dev;
1647141cc406Sopenharmony_ci
1648141cc406Sopenharmony_ci	return s;
1649141cc406Sopenharmony_ci
1650141cc406Sopenharmony_ciclose:
1651141cc406Sopenharmony_ci	DBG(1, " failed\n");
1652141cc406Sopenharmony_ci
1653141cc406Sopenharmony_ci	close_scanner(s);
1654141cc406Sopenharmony_ci	return NULL;
1655141cc406Sopenharmony_ci}
1656141cc406Sopenharmony_ci
1657141cc406Sopenharmony_ci
1658141cc406Sopenharmony_cistatic SANE_Status
1659141cc406Sopenharmony_ciattach(const char *name, int type)
1660141cc406Sopenharmony_ci{
1661141cc406Sopenharmony_ci	SANE_Status status;
1662141cc406Sopenharmony_ci	epsonds_scanner * s;
1663141cc406Sopenharmony_ci
1664141cc406Sopenharmony_ci	DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
1665141cc406Sopenharmony_ci
1666141cc406Sopenharmony_ci	s = device_detect(name, type, &status);
1667141cc406Sopenharmony_ci	if (s == NULL)
1668141cc406Sopenharmony_ci		return status;
1669141cc406Sopenharmony_ci
1670141cc406Sopenharmony_ci	close_scanner(s);
1671141cc406Sopenharmony_ci	return status;
1672141cc406Sopenharmony_ci}
1673141cc406Sopenharmony_ci
1674141cc406Sopenharmony_ciSANE_Status
1675141cc406Sopenharmony_ciattach_one_usb(const char *dev)
1676141cc406Sopenharmony_ci{
1677141cc406Sopenharmony_ci	DBG(7, "%s: dev = %s\n", __func__, dev);
1678141cc406Sopenharmony_ci	return attach(dev, SANE_EPSONDS_USB);
1679141cc406Sopenharmony_ci}
1680141cc406Sopenharmony_ci
1681141cc406Sopenharmony_cistatic SANE_Status
1682141cc406Sopenharmony_ciattach_one_net(const char *dev)
1683141cc406Sopenharmony_ci{
1684141cc406Sopenharmony_ci	char name[39 + 4];
1685141cc406Sopenharmony_ci
1686141cc406Sopenharmony_ci	DBG(7, "%s: dev = %s\n", __func__, dev);
1687141cc406Sopenharmony_ci
1688141cc406Sopenharmony_ci	strcpy(name, "net:");
1689141cc406Sopenharmony_ci	strcat(name, dev);
1690141cc406Sopenharmony_ci	return attach(name, SANE_EPSONDS_NET);
1691141cc406Sopenharmony_ci}
1692141cc406Sopenharmony_ci
1693141cc406Sopenharmony_cistatic void found_net_device(const char* device_name, const char* ip)
1694141cc406Sopenharmony_ci{
1695141cc406Sopenharmony_ci	DBG(7, "Found %s: ip = %s\n", device_name, ip);
1696141cc406Sopenharmony_ci
1697141cc406Sopenharmony_ci	int foundSupportedDevice = 0;
1698141cc406Sopenharmony_ci
1699141cc406Sopenharmony_ci	// search models
1700141cc406Sopenharmony_ci	for (int i = 0; i < stProfileMapArray.used; i++) {
1701141cc406Sopenharmony_ci		if (strcmp(stProfileMapArray.array[i].deviceID, device_name) == 0) {
1702141cc406Sopenharmony_ci			foundSupportedDevice = 1;
1703141cc406Sopenharmony_ci			break;
1704141cc406Sopenharmony_ci		}
1705141cc406Sopenharmony_ci	}
1706141cc406Sopenharmony_ci
1707141cc406Sopenharmony_ci
1708141cc406Sopenharmony_ci	if (foundSupportedDevice)
1709141cc406Sopenharmony_ci	{
1710141cc406Sopenharmony_ci		char name[39 + 4];
1711141cc406Sopenharmony_ci
1712141cc406Sopenharmony_ci		strcpy(name, "net:");
1713141cc406Sopenharmony_ci		strncat(name, ip, 39);
1714141cc406Sopenharmony_ci
1715141cc406Sopenharmony_ci		int foundCache = 0;
1716141cc406Sopenharmony_ci		// search cache and prents duplicated model
1717141cc406Sopenharmony_ci		for (epsonds_device* dev = first_dev; dev; dev = dev->next) {
1718141cc406Sopenharmony_ci			if (strcmp(dev->sane.name, name) == 0) {
1719141cc406Sopenharmony_ci				foundCache = 1;
1720141cc406Sopenharmony_ci			}
1721141cc406Sopenharmony_ci		}
1722141cc406Sopenharmony_ci		if (foundCache == 0)
1723141cc406Sopenharmony_ci		{
1724141cc406Sopenharmony_ci			attach(name, SANE_EPSONDS_NET);
1725141cc406Sopenharmony_ci		}
1726141cc406Sopenharmony_ci	}
1727141cc406Sopenharmony_ci}
1728141cc406Sopenharmony_ci
1729141cc406Sopenharmony_cistatic void
1730141cc406Sopenharmony_cisplitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID)
1731141cc406Sopenharmony_ci{
1732141cc406Sopenharmony_ci    char target[1024];
1733141cc406Sopenharmony_ci    strncpy(target, input, 1023);
1734141cc406Sopenharmony_ci
1735141cc406Sopenharmony_ci    strtok(target, ":");//profile
1736141cc406Sopenharmony_ci
1737141cc406Sopenharmony_ci    //productID
1738141cc406Sopenharmony_ci    char* pid = strtok(NULL, ",");
1739141cc406Sopenharmony_ci    sscanf(pid, "%x", (unsigned int*)outProductID);
1740141cc406Sopenharmony_ci
1741141cc406Sopenharmony_ci    //productName
1742141cc406Sopenharmony_ci    char* productName = strtok(NULL, ",");
1743141cc406Sopenharmony_ci    strncpy(outProductName, productName,  49);
1744141cc406Sopenharmony_ci
1745141cc406Sopenharmony_ci    //deviceID
1746141cc406Sopenharmony_ci    char* deviceID = strtok(NULL, ",");
1747141cc406Sopenharmony_ci    strncpy(outDeviceID, deviceID,  49);
1748141cc406Sopenharmony_ci
1749141cc406Sopenharmony_ci    //lutID
1750141cc406Sopenharmony_ci    char* lutID = strtok(NULL, ",");
1751141cc406Sopenharmony_ci    sscanf(lutID, "%d", outLutID);
1752141cc406Sopenharmony_ci}
1753141cc406Sopenharmony_ci
1754141cc406Sopenharmony_ci
1755141cc406Sopenharmony_cistatic SANE_Status
1756141cc406Sopenharmony_ciattach_one_config(SANEI_Config __sane_unused__ *config, const char *line,
1757141cc406Sopenharmony_ci		  void *data)
1758141cc406Sopenharmony_ci{
1759141cc406Sopenharmony_ci	int vendor, product;
1760141cc406Sopenharmony_ci	SANE_Bool local_only = *(SANE_Bool*) data;
1761141cc406Sopenharmony_ci	int len = strlen(line);
1762141cc406Sopenharmony_ci
1763141cc406Sopenharmony_ci	DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
1764141cc406Sopenharmony_ci	if (strncmp(line, "profile", 7) == 0 ) {
1765141cc406Sopenharmony_ci		DBG(7, " found profile device profile\n");
1766141cc406Sopenharmony_ci
1767141cc406Sopenharmony_ci		epsonds_profile_map profle_map;
1768141cc406Sopenharmony_ci
1769141cc406Sopenharmony_ci		splitProfileName(line, &profle_map.productID, profle_map.productName, profle_map.deviceID, &profle_map.lutID);
1770141cc406Sopenharmony_ci
1771141cc406Sopenharmony_ci		DBG(7, "Found profile : %x %s %s %d\n", profle_map.productID, profle_map.productName, profle_map.deviceID, profle_map.lutID);
1772141cc406Sopenharmony_ci
1773141cc406Sopenharmony_ci		insert_profile_map(&stProfileMapArray, profle_map);
1774141cc406Sopenharmony_ci	}else if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
1775141cc406Sopenharmony_ci
1776141cc406Sopenharmony_ci		DBG(7, " user configured device\n");
1777141cc406Sopenharmony_ci
1778141cc406Sopenharmony_ci		if (vendor != SANE_EPSONDS_VENDOR_ID)
1779141cc406Sopenharmony_ci			return SANE_STATUS_INVAL; /* this is not an Epson device */
1780141cc406Sopenharmony_ci
1781141cc406Sopenharmony_ci		sanei_usb_attach_matching_devices(line, attach_one_usb);
1782141cc406Sopenharmony_ci
1783141cc406Sopenharmony_ci	} else if (strncmp(line, "usb", 3) == 0 && len == 3) {
1784141cc406Sopenharmony_ci
1785141cc406Sopenharmony_ci		DBG(7, " probing usb devices\n");
1786141cc406Sopenharmony_ci
1787141cc406Sopenharmony_ci		for (int i = 0; i < stProfileMapArray.used; i++) {
1788141cc406Sopenharmony_ci			int usbPid = stProfileMapArray.array[i].productID;
1789141cc406Sopenharmony_ci			sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, usbPid, attach_one_usb);
1790141cc406Sopenharmony_ci		}
1791141cc406Sopenharmony_ci
1792141cc406Sopenharmony_ci	} else if (strncmp(line, "net", 3) == 0) {
1793141cc406Sopenharmony_ci
1794141cc406Sopenharmony_ci		if (!local_only) {
1795141cc406Sopenharmony_ci			/* remove the "net" sub string */
1796141cc406Sopenharmony_ci			const char *name =
1797141cc406Sopenharmony_ci				sanei_config_skip_whitespace(line + 3);
1798141cc406Sopenharmony_ci
1799141cc406Sopenharmony_ci			if (strncmp(name, "autodiscovery", 13) == 0)
1800141cc406Sopenharmony_ci			{
1801141cc406Sopenharmony_ci				#if WITH_AVAHI
1802141cc406Sopenharmony_ci				epsonds_searchDevices(found_net_device);
1803141cc406Sopenharmony_ci				#else
1804141cc406Sopenharmony_ci				// currently does not support
1805141cc406Sopenharmony_ci				//e2_network_discovery();
1806141cc406Sopenharmony_ci				#endif
1807141cc406Sopenharmony_ci			}
1808141cc406Sopenharmony_ci			else
1809141cc406Sopenharmony_ci				attach_one_net(name);
1810141cc406Sopenharmony_ci		}
1811141cc406Sopenharmony_ci	} else {
1812141cc406Sopenharmony_ci		DBG(0, "unable to parse config line: %s\n", line);
1813141cc406Sopenharmony_ci	}
1814141cc406Sopenharmony_ci
1815141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
1816141cc406Sopenharmony_ci}
1817141cc406Sopenharmony_ci
1818141cc406Sopenharmony_cistatic void
1819141cc406Sopenharmony_cifree_devices(void)
1820141cc406Sopenharmony_ci{
1821141cc406Sopenharmony_ci	epsonds_device *dev, *next;
1822141cc406Sopenharmony_ci
1823141cc406Sopenharmony_ci	for (dev = first_dev; dev; dev = next) {
1824141cc406Sopenharmony_ci		next = dev->next;
1825141cc406Sopenharmony_ci		free(dev->name);
1826141cc406Sopenharmony_ci		free(dev->model);
1827141cc406Sopenharmony_ci		free(dev);
1828141cc406Sopenharmony_ci	}
1829141cc406Sopenharmony_ci
1830141cc406Sopenharmony_ci	free(devlist);
1831141cc406Sopenharmony_ci	first_dev = NULL;
1832141cc406Sopenharmony_ci}
1833141cc406Sopenharmony_ci
1834141cc406Sopenharmony_cistatic void
1835141cc406Sopenharmony_ciprobe_devices(SANE_Bool local_only)
1836141cc406Sopenharmony_ci{
1837141cc406Sopenharmony_ci	DBG(5, "%s\n", __func__);
1838141cc406Sopenharmony_ci
1839141cc406Sopenharmony_ci	free_devices();
1840141cc406Sopenharmony_ci	sanei_configure_attach(EPSONDS_CONFIG_FILE, NULL,
1841141cc406Sopenharmony_ci			       attach_one_config, &local_only);
1842141cc406Sopenharmony_ci}
1843141cc406Sopenharmony_ci
1844141cc406Sopenharmony_ci/**** SANE API ****/
1845141cc406Sopenharmony_ci
1846141cc406Sopenharmony_ciSANE_Status
1847141cc406Sopenharmony_cisane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
1848141cc406Sopenharmony_ci{
1849141cc406Sopenharmony_ci	DBG_INIT();
1850141cc406Sopenharmony_ci
1851141cc406Sopenharmony_ci	init_profile_maps(&stProfileMapArray, 100);
1852141cc406Sopenharmony_ci
1853141cc406Sopenharmony_ci	DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
1854141cc406Sopenharmony_ci
1855141cc406Sopenharmony_ci	DBG(1, "epsonds backend, version %i.%i.%i\n",
1856141cc406Sopenharmony_ci		EPSONDS_VERSION, EPSONDS_REVISION, EPSONDS_BUILD);
1857141cc406Sopenharmony_ci
1858141cc406Sopenharmony_ci	if (version_code != NULL)
1859141cc406Sopenharmony_ci		*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR,
1860141cc406Sopenharmony_ci					  EPSONDS_BUILD);
1861141cc406Sopenharmony_ci
1862141cc406Sopenharmony_ci	sanei_usb_init();
1863141cc406Sopenharmony_ci
1864141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
1865141cc406Sopenharmony_ci}
1866141cc406Sopenharmony_ci
1867141cc406Sopenharmony_civoid
1868141cc406Sopenharmony_cisane_exit(void)
1869141cc406Sopenharmony_ci{
1870141cc406Sopenharmony_ci	DBG(5, "** %s\n", __func__);
1871141cc406Sopenharmony_ci	free_profile_maps(&stProfileMapArray);
1872141cc406Sopenharmony_ci	free_devices();
1873141cc406Sopenharmony_ci}
1874141cc406Sopenharmony_ci
1875141cc406Sopenharmony_ciSANE_Status
1876141cc406Sopenharmony_cisane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
1877141cc406Sopenharmony_ci{
1878141cc406Sopenharmony_ci	int i;
1879141cc406Sopenharmony_ci	epsonds_device *dev;
1880141cc406Sopenharmony_ci
1881141cc406Sopenharmony_ci	DBG(5, "** %s  local_only = %d \n", __func__, local_only);
1882141cc406Sopenharmony_ci
1883141cc406Sopenharmony_ci
1884141cc406Sopenharmony_ci	probe_devices(local_only);
1885141cc406Sopenharmony_ci
1886141cc406Sopenharmony_ci	devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
1887141cc406Sopenharmony_ci	if (!devlist) {
1888141cc406Sopenharmony_ci		DBG(1, "out of memory (line %d)\n", __LINE__);
1889141cc406Sopenharmony_ci		return SANE_STATUS_NO_MEM;
1890141cc406Sopenharmony_ci	}
1891141cc406Sopenharmony_ci
1892141cc406Sopenharmony_ci	DBG(5, "%s - results:\n", __func__);
1893141cc406Sopenharmony_ci
1894141cc406Sopenharmony_ci	for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
1895141cc406Sopenharmony_ci		DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
1896141cc406Sopenharmony_ci		devlist[i] = &dev->sane;
1897141cc406Sopenharmony_ci	}
1898141cc406Sopenharmony_ci
1899141cc406Sopenharmony_ci	devlist[i] = NULL;
1900141cc406Sopenharmony_ci
1901141cc406Sopenharmony_ci	*device_list = devlist;
1902141cc406Sopenharmony_ci
1903141cc406Sopenharmony_ci
1904141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
1905141cc406Sopenharmony_ci}
1906141cc406Sopenharmony_ci
1907141cc406Sopenharmony_cistatic SANE_Status
1908141cc406Sopenharmony_ciinit_options(epsonds_scanner *s)
1909141cc406Sopenharmony_ci{
1910141cc406Sopenharmony_ci	DBG(5, "init_options\n");
1911141cc406Sopenharmony_ci	int i;
1912141cc406Sopenharmony_ci
1913141cc406Sopenharmony_ci	for (i = 0; i < NUM_OPTIONS; i++) {
1914141cc406Sopenharmony_ci		s->opt[i].size = sizeof(SANE_Word);
1915141cc406Sopenharmony_ci		s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1916141cc406Sopenharmony_ci	}
1917141cc406Sopenharmony_ci
1918141cc406Sopenharmony_ci	s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1919141cc406Sopenharmony_ci	s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1920141cc406Sopenharmony_ci	s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1921141cc406Sopenharmony_ci	s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1922141cc406Sopenharmony_ci	s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1923141cc406Sopenharmony_ci
1924141cc406Sopenharmony_ci	/* "Scan Mode" group: */
1925141cc406Sopenharmony_ci	s->opt[OPT_STANDARD_GROUP].name = SANE_NAME_STANDARD;
1926141cc406Sopenharmony_ci	s->opt[OPT_STANDARD_GROUP].title = SANE_TITLE_STANDARD;
1927141cc406Sopenharmony_ci	s->opt[OPT_STANDARD_GROUP].desc = SANE_DESC_STANDARD;
1928141cc406Sopenharmony_ci	s->opt[OPT_STANDARD_GROUP].type = SANE_TYPE_GROUP;
1929141cc406Sopenharmony_ci	s->opt[OPT_STANDARD_GROUP].cap = 0;
1930141cc406Sopenharmony_ci
1931141cc406Sopenharmony_ci	/* scan mode */
1932141cc406Sopenharmony_ci	s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1933141cc406Sopenharmony_ci	s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1934141cc406Sopenharmony_ci	s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1935141cc406Sopenharmony_ci	s->opt[OPT_MODE].type = SANE_TYPE_STRING;
1936141cc406Sopenharmony_ci	s->opt[OPT_MODE].size = max_string_size(mode_list);
1937141cc406Sopenharmony_ci	s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1938141cc406Sopenharmony_ci	s->opt[OPT_MODE].constraint.string_list = mode_list;
1939141cc406Sopenharmony_ci	s->val[OPT_MODE].w = 0;	/* Lineart */
1940141cc406Sopenharmony_ci
1941141cc406Sopenharmony_ci	/* bit depth */
1942141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH;
1943141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
1944141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
1945141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].type = SANE_TYPE_INT;
1946141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT;
1947141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1948141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].constraint.word_list = s->hw->depth_list;
1949141cc406Sopenharmony_ci	s->val[OPT_DEPTH].w = s->hw->depth_list[1];	/* the first "real" element is the default */
1950141cc406Sopenharmony_ci
1951141cc406Sopenharmony_ci	/* default is Lineart, disable depth selection */
1952141cc406Sopenharmony_ci	s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
1953141cc406Sopenharmony_ci
1954141cc406Sopenharmony_ci	/* resolution */
1955141cc406Sopenharmony_ci	s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1956141cc406Sopenharmony_ci	s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1957141cc406Sopenharmony_ci	s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1958141cc406Sopenharmony_ci
1959141cc406Sopenharmony_ci	s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1960141cc406Sopenharmony_ci	s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1961141cc406Sopenharmony_ci
1962141cc406Sopenharmony_ci	/* range */
1963141cc406Sopenharmony_ci	if (s->hw->dpi_range.quant) {
1964141cc406Sopenharmony_ci		s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1965141cc406Sopenharmony_ci		s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
1966141cc406Sopenharmony_ci		s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
1967141cc406Sopenharmony_ci	} else { /* list */
1968141cc406Sopenharmony_ci		s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1969141cc406Sopenharmony_ci		s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->res_list;
1970141cc406Sopenharmony_ci		s->val[OPT_RESOLUTION].w = s->hw->res_list[1];
1971141cc406Sopenharmony_ci	}
1972141cc406Sopenharmony_ci
1973141cc406Sopenharmony_ci	/* "Geometry" group: */
1974141cc406Sopenharmony_ci	s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
1975141cc406Sopenharmony_ci	s->opt[OPT_GEOMETRY_GROUP].desc = "";
1976141cc406Sopenharmony_ci	s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1977141cc406Sopenharmony_ci	s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1978141cc406Sopenharmony_ci
1979141cc406Sopenharmony_ci	/* top-left x */
1980141cc406Sopenharmony_ci	s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1981141cc406Sopenharmony_ci	s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1982141cc406Sopenharmony_ci	s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1983141cc406Sopenharmony_ci	s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1984141cc406Sopenharmony_ci	s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1985141cc406Sopenharmony_ci	s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1986141cc406Sopenharmony_ci	s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
1987141cc406Sopenharmony_ci	s->val[OPT_TL_X].w = 0;
1988141cc406Sopenharmony_ci
1989141cc406Sopenharmony_ci	/* top-left y */
1990141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1991141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1992141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1993141cc406Sopenharmony_ci
1994141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1995141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1996141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1997141cc406Sopenharmony_ci	s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
1998141cc406Sopenharmony_ci	s->val[OPT_TL_Y].w = 0;
1999141cc406Sopenharmony_ci
2000141cc406Sopenharmony_ci	/* bottom-right x */
2001141cc406Sopenharmony_ci	s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2002141cc406Sopenharmony_ci	s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2003141cc406Sopenharmony_ci	s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2004141cc406Sopenharmony_ci
2005141cc406Sopenharmony_ci	s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2006141cc406Sopenharmony_ci	s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2007141cc406Sopenharmony_ci	s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2008141cc406Sopenharmony_ci	s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2009141cc406Sopenharmony_ci	s->val[OPT_BR_X].w = s->hw->x_range->max;
2010141cc406Sopenharmony_ci
2011141cc406Sopenharmony_ci	/* bottom-right y */
2012141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2013141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2014141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2015141cc406Sopenharmony_ci
2016141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2017141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2018141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2019141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2020141cc406Sopenharmony_ci	s->val[OPT_BR_Y].w = s->hw->y_range->max;
2021141cc406Sopenharmony_ci
2022141cc406Sopenharmony_ci	/* "Optional equipment" group: */
2023141cc406Sopenharmony_ci	s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment");
2024141cc406Sopenharmony_ci	s->opt[OPT_EQU_GROUP].desc = "";
2025141cc406Sopenharmony_ci	s->opt[OPT_EQU_GROUP].type = SANE_TYPE_GROUP;
2026141cc406Sopenharmony_ci	s->opt[OPT_EQU_GROUP].cap = SANE_CAP_ADVANCED;
2027141cc406Sopenharmony_ci
2028141cc406Sopenharmony_ci	/* source */
2029141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
2030141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
2031141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
2032141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
2033141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].size = max_string_size(source_list);
2034141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2035141cc406Sopenharmony_ci	s->opt[OPT_SOURCE].constraint.string_list = source_list;
2036141cc406Sopenharmony_ci	s->val[OPT_SOURCE].w = 0;
2037141cc406Sopenharmony_ci
2038141cc406Sopenharmony_ci	s->opt[OPT_EJECT].name = "eject";
2039141cc406Sopenharmony_ci	s->opt[OPT_EJECT].title = SANE_I18N("Eject");
2040141cc406Sopenharmony_ci	s->opt[OPT_EJECT].desc = SANE_I18N("Eject the sheet in the ADF");
2041141cc406Sopenharmony_ci	s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
2042141cc406Sopenharmony_ci
2043141cc406Sopenharmony_ci	if (!s->hw->adf_has_eject)
2044141cc406Sopenharmony_ci		s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
2045141cc406Sopenharmony_ci
2046141cc406Sopenharmony_ci	s->opt[OPT_LOAD].name = "load";
2047141cc406Sopenharmony_ci	s->opt[OPT_LOAD].title = SANE_I18N("Load");
2048141cc406Sopenharmony_ci	s->opt[OPT_LOAD].desc = SANE_I18N("Load a sheet in the ADF");
2049141cc406Sopenharmony_ci	s->opt[OPT_LOAD].type = SANE_TYPE_BUTTON;
2050141cc406Sopenharmony_ci
2051141cc406Sopenharmony_ci	if (!s->hw->adf_has_load)
2052141cc406Sopenharmony_ci		s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE;
2053141cc406Sopenharmony_ci
2054141cc406Sopenharmony_ci
2055141cc406Sopenharmony_ci	s->opt[OPT_ADF_SKEW].name = "adf-skew";
2056141cc406Sopenharmony_ci	s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction");
2057141cc406Sopenharmony_ci	s->opt[OPT_ADF_SKEW].desc =
2058141cc406Sopenharmony_ci		SANE_I18N("Enables ADF skew correction");
2059141cc406Sopenharmony_ci	s->opt[OPT_ADF_SKEW].type = SANE_TYPE_BOOL;
2060141cc406Sopenharmony_ci	s->val[OPT_ADF_SKEW].w = 0;
2061141cc406Sopenharmony_ci
2062141cc406Sopenharmony_ci
2063141cc406Sopenharmony_ci	s->opt[OPT_ADF_CRP].name = "adf-crp";
2064141cc406Sopenharmony_ci	s->opt[OPT_ADF_CRP].title = SANE_I18N("ADF CRP Correction");
2065141cc406Sopenharmony_ci	s->opt[OPT_ADF_CRP].desc =
2066141cc406Sopenharmony_ci		SANE_I18N("Enables ADF auto cropping"); //
2067141cc406Sopenharmony_ci	s->opt[OPT_ADF_CRP].type = SANE_TYPE_BOOL;
2068141cc406Sopenharmony_ci	s->val[OPT_ADF_CRP].w = 0;
2069141cc406Sopenharmony_ci
2070141cc406Sopenharmony_ci
2071141cc406Sopenharmony_ci	if (!s->hw->adf_has_skew)
2072141cc406Sopenharmony_ci	{
2073141cc406Sopenharmony_ci		s->val[OPT_ADF_SKEW].w = 0;
2074141cc406Sopenharmony_ci		s->opt[OPT_ADF_SKEW].cap |= SANE_CAP_INACTIVE;
2075141cc406Sopenharmony_ci	}
2076141cc406Sopenharmony_ci
2077141cc406Sopenharmony_ci	if(!s->hw->adf_has_crp)
2078141cc406Sopenharmony_ci	{
2079141cc406Sopenharmony_ci		s->val[OPT_ADF_CRP].w = 0;
2080141cc406Sopenharmony_ci		s->opt[OPT_ADF_CRP].cap |= SANE_CAP_INACTIVE;
2081141cc406Sopenharmony_ci	}
2082141cc406Sopenharmony_ci
2083141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
2084141cc406Sopenharmony_ci}
2085141cc406Sopenharmony_ci
2086141cc406Sopenharmony_ciSANE_Status
2087141cc406Sopenharmony_cisane_open(SANE_String_Const name, SANE_Handle *handle)
2088141cc406Sopenharmony_ci{
2089141cc406Sopenharmony_ci	SANE_Status status;
2090141cc406Sopenharmony_ci	epsonds_scanner *s = NULL;
2091141cc406Sopenharmony_ci
2092141cc406Sopenharmony_ci
2093141cc406Sopenharmony_ci
2094141cc406Sopenharmony_ci	DBG(7, "** %s: name = '%s'\n", __func__, name);
2095141cc406Sopenharmony_ci
2096141cc406Sopenharmony_ci	/* probe if empty device name provided */
2097141cc406Sopenharmony_ci	if (name[0] == '\0') {
2098141cc406Sopenharmony_ci
2099141cc406Sopenharmony_ci		probe_devices(SANE_FALSE);
2100141cc406Sopenharmony_ci
2101141cc406Sopenharmony_ci		if (first_dev == NULL) {
2102141cc406Sopenharmony_ci			DBG(1, "no devices detected\n");
2103141cc406Sopenharmony_ci			return SANE_STATUS_INVAL;
2104141cc406Sopenharmony_ci		}
2105141cc406Sopenharmony_ci
2106141cc406Sopenharmony_ci		s = device_detect(first_dev->sane.name, first_dev->connection,
2107141cc406Sopenharmony_ci					&status);
2108141cc406Sopenharmony_ci		if (s == NULL) {
2109141cc406Sopenharmony_ci			DBG(1, "cannot open a perfectly valid device (%s),"
2110141cc406Sopenharmony_ci				" please report to the authors\n", name);
2111141cc406Sopenharmony_ci			return SANE_STATUS_INVAL;
2112141cc406Sopenharmony_ci		}
2113141cc406Sopenharmony_ci
2114141cc406Sopenharmony_ci	} else {
2115141cc406Sopenharmony_ci
2116141cc406Sopenharmony_ci		if (strncmp(name, "net:", 4) == 0) {
2117141cc406Sopenharmony_ci			s = device_detect(name, SANE_EPSONDS_NET, &status);
2118141cc406Sopenharmony_ci			if (s == NULL)
2119141cc406Sopenharmony_ci				return status;
2120141cc406Sopenharmony_ci		} else if (strncmp(name, "libusb:", 7) == 0) {
2121141cc406Sopenharmony_ci			s = device_detect(name, SANE_EPSONDS_USB, &status);
2122141cc406Sopenharmony_ci			if (s == NULL)
2123141cc406Sopenharmony_ci				return status;
2124141cc406Sopenharmony_ci		} else {
2125141cc406Sopenharmony_ci			DBG(1, "invalid device name: %s\n", name);
2126141cc406Sopenharmony_ci			return SANE_STATUS_INVAL;
2127141cc406Sopenharmony_ci		}
2128141cc406Sopenharmony_ci	}
2129141cc406Sopenharmony_ci
2130141cc406Sopenharmony_ci	/* s is always valid here */
2131141cc406Sopenharmony_ci
2132141cc406Sopenharmony_ci	DBG(5, "%s: handle obtained\n", __func__);
2133141cc406Sopenharmony_ci
2134141cc406Sopenharmony_ci	init_options(s);
2135141cc406Sopenharmony_ci
2136141cc406Sopenharmony_ci	*handle = (SANE_Handle)s;
2137141cc406Sopenharmony_ci
2138141cc406Sopenharmony_ci	status = open_scanner(s);
2139141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
2140141cc406Sopenharmony_ci		free(s);
2141141cc406Sopenharmony_ci		return status;
2142141cc406Sopenharmony_ci	}
2143141cc406Sopenharmony_ci
2144141cc406Sopenharmony_ci	/* lock scanner if required */
2145141cc406Sopenharmony_ci	if (!s->locked) {
2146141cc406Sopenharmony_ci		status = eds_lock(s);
2147141cc406Sopenharmony_ci	}
2148141cc406Sopenharmony_ci
2149141cc406Sopenharmony_ci	setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL);
2150141cc406Sopenharmony_ci
2151141cc406Sopenharmony_ci	return status;
2152141cc406Sopenharmony_ci}
2153141cc406Sopenharmony_ci
2154141cc406Sopenharmony_civoid
2155141cc406Sopenharmony_cisane_close(SANE_Handle handle)
2156141cc406Sopenharmony_ci{
2157141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *)handle;
2158141cc406Sopenharmony_ci
2159141cc406Sopenharmony_ci	DBG(1, "** %s\n", __func__);
2160141cc406Sopenharmony_ci
2161141cc406Sopenharmony_ci	close_scanner(s);
2162141cc406Sopenharmony_ci}
2163141cc406Sopenharmony_ci
2164141cc406Sopenharmony_ciconst SANE_Option_Descriptor *
2165141cc406Sopenharmony_cisane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
2166141cc406Sopenharmony_ci{
2167141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *) handle;
2168141cc406Sopenharmony_ci
2169141cc406Sopenharmony_ci	if (option < 0 || option >= NUM_OPTIONS)
2170141cc406Sopenharmony_ci		return NULL;
2171141cc406Sopenharmony_ci
2172141cc406Sopenharmony_ci	return s->opt + option;
2173141cc406Sopenharmony_ci}
2174141cc406Sopenharmony_ci
2175141cc406Sopenharmony_cistatic const SANE_String_Const *
2176141cc406Sopenharmony_cisearch_string_list(const SANE_String_Const *list, SANE_String value)
2177141cc406Sopenharmony_ci{
2178141cc406Sopenharmony_ci	while (*list != NULL && strcmp(value, *list) != 0)
2179141cc406Sopenharmony_ci		list++;
2180141cc406Sopenharmony_ci
2181141cc406Sopenharmony_ci	return ((*list == NULL) ? NULL : list);
2182141cc406Sopenharmony_ci}
2183141cc406Sopenharmony_ci
2184141cc406Sopenharmony_ci/*
2185141cc406Sopenharmony_ci * Handles setting the source (flatbed, transparency adapter (TPU),
2186141cc406Sopenharmony_ci * or auto document feeder (ADF)).
2187141cc406Sopenharmony_ci *
2188141cc406Sopenharmony_ci * For newer scanners it also sets the focus according to the
2189141cc406Sopenharmony_ci * glass / TPU settings.
2190141cc406Sopenharmony_ci */
2191141cc406Sopenharmony_ci
2192141cc406Sopenharmony_cistatic void
2193141cc406Sopenharmony_cichange_source(epsonds_scanner *s, SANE_Int optindex, char *value)
2194141cc406Sopenharmony_ci{
2195141cc406Sopenharmony_ci	int force_max = SANE_FALSE;
2196141cc406Sopenharmony_ci
2197141cc406Sopenharmony_ci	DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
2198141cc406Sopenharmony_ci	    value);
2199141cc406Sopenharmony_ci
2200141cc406Sopenharmony_ci	s->val[OPT_SOURCE].w = optindex;
2201141cc406Sopenharmony_ci
2202141cc406Sopenharmony_ci	/* if current selected area is the maximum available,
2203141cc406Sopenharmony_ci	 * keep this setting on the new source.
2204141cc406Sopenharmony_ci	 */
2205141cc406Sopenharmony_ci	if (s->val[OPT_TL_X].w == s->hw->x_range->min
2206141cc406Sopenharmony_ci	    && s->val[OPT_TL_Y].w == s->hw->y_range->min
2207141cc406Sopenharmony_ci	    && s->val[OPT_BR_X].w == s->hw->x_range->max
2208141cc406Sopenharmony_ci	    && s->val[OPT_BR_Y].w == s->hw->y_range->max) {
2209141cc406Sopenharmony_ci		force_max = SANE_TRUE;
2210141cc406Sopenharmony_ci	}
2211141cc406Sopenharmony_ci
2212141cc406Sopenharmony_ci	if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) {
2213141cc406Sopenharmony_ci		s->hw->x_range = &s->hw->adf_x_range;
2214141cc406Sopenharmony_ci		s->hw->y_range = &s->hw->adf_y_range;
2215141cc406Sopenharmony_ci		s->hw->alignment = s->hw->adf_alignment;
2216141cc406Sopenharmony_ci
2217141cc406Sopenharmony_ci
2218141cc406Sopenharmony_ci	} else if (strcmp(TPU_STR, value) == 0) {
2219141cc406Sopenharmony_ci
2220141cc406Sopenharmony_ci		s->hw->x_range = &s->hw->tpu_x_range;
2221141cc406Sopenharmony_ci		s->hw->y_range = &s->hw->tpu_y_range;
2222141cc406Sopenharmony_ci
2223141cc406Sopenharmony_ci	} else {
2224141cc406Sopenharmony_ci
2225141cc406Sopenharmony_ci		/* neither ADF nor TPU active, assume FB */
2226141cc406Sopenharmony_ci		s->hw->x_range = &s->hw->fbf_x_range;
2227141cc406Sopenharmony_ci		s->hw->y_range = &s->hw->fbf_y_range;
2228141cc406Sopenharmony_ci		s->hw->alignment = s->hw->fbf_alignment;
2229141cc406Sopenharmony_ci	}
2230141cc406Sopenharmony_ci
2231141cc406Sopenharmony_ci	s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
2232141cc406Sopenharmony_ci	s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
2233141cc406Sopenharmony_ci
2234141cc406Sopenharmony_ci	if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
2235141cc406Sopenharmony_ci		s->val[OPT_TL_X].w = s->hw->x_range->min;
2236141cc406Sopenharmony_ci
2237141cc406Sopenharmony_ci	if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
2238141cc406Sopenharmony_ci		s->val[OPT_TL_Y].w = s->hw->y_range->min;
2239141cc406Sopenharmony_ci
2240141cc406Sopenharmony_ci	if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
2241141cc406Sopenharmony_ci		s->val[OPT_BR_X].w = s->hw->x_range->max;
2242141cc406Sopenharmony_ci
2243141cc406Sopenharmony_ci	if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
2244141cc406Sopenharmony_ci		s->val[OPT_BR_Y].w = s->hw->y_range->max;
2245141cc406Sopenharmony_ci}
2246141cc406Sopenharmony_ci
2247141cc406Sopenharmony_cistatic SANE_Status
2248141cc406Sopenharmony_cigetvalue(SANE_Handle handle, SANE_Int option, void *value)
2249141cc406Sopenharmony_ci{
2250141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *)handle;
2251141cc406Sopenharmony_ci	SANE_Option_Descriptor *sopt = &(s->opt[option]);
2252141cc406Sopenharmony_ci	Option_Value *sval = &(s->val[option]);
2253141cc406Sopenharmony_ci
2254141cc406Sopenharmony_ci	DBG(17, "%s: option = %d\n", __func__, option);
2255141cc406Sopenharmony_ci
2256141cc406Sopenharmony_ci	switch (option) {
2257141cc406Sopenharmony_ci
2258141cc406Sopenharmony_ci	case OPT_NUM_OPTS:
2259141cc406Sopenharmony_ci	case OPT_RESOLUTION:
2260141cc406Sopenharmony_ci	case OPT_TL_X:
2261141cc406Sopenharmony_ci	case OPT_TL_Y:
2262141cc406Sopenharmony_ci	case OPT_BR_X:
2263141cc406Sopenharmony_ci	case OPT_BR_Y:
2264141cc406Sopenharmony_ci	case OPT_DEPTH:
2265141cc406Sopenharmony_ci	case OPT_ADF_SKEW:
2266141cc406Sopenharmony_ci		*((SANE_Word *) value) = sval->w;
2267141cc406Sopenharmony_ci		break;
2268141cc406Sopenharmony_ci
2269141cc406Sopenharmony_ci	case OPT_MODE:
2270141cc406Sopenharmony_ci	case OPT_SOURCE:
2271141cc406Sopenharmony_ci		strcpy((char *) value, sopt->constraint.string_list[sval->w]);
2272141cc406Sopenharmony_ci		break;
2273141cc406Sopenharmony_ci
2274141cc406Sopenharmony_ci	default:
2275141cc406Sopenharmony_ci		return SANE_STATUS_INVAL;
2276141cc406Sopenharmony_ci	}
2277141cc406Sopenharmony_ci
2278141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
2279141cc406Sopenharmony_ci}
2280141cc406Sopenharmony_ci
2281141cc406Sopenharmony_cistatic SANE_Status
2282141cc406Sopenharmony_cisetvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
2283141cc406Sopenharmony_ci{
2284141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *) handle;
2285141cc406Sopenharmony_ci	SANE_Option_Descriptor *sopt = &(s->opt[option]);
2286141cc406Sopenharmony_ci	Option_Value *sval = &(s->val[option]);
2287141cc406Sopenharmony_ci
2288141cc406Sopenharmony_ci	SANE_Status status;
2289141cc406Sopenharmony_ci	const SANE_String_Const *optval = NULL;
2290141cc406Sopenharmony_ci	int optindex = 0;
2291141cc406Sopenharmony_ci	SANE_Bool reload = SANE_FALSE;
2292141cc406Sopenharmony_ci
2293141cc406Sopenharmony_ci	DBG(17, "** %s: option = %d, value = %p\n", __func__, option, value);
2294141cc406Sopenharmony_ci
2295141cc406Sopenharmony_ci	status = sanei_constrain_value(sopt, value, info);
2296141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD)
2297141cc406Sopenharmony_ci		return status;
2298141cc406Sopenharmony_ci
2299141cc406Sopenharmony_ci	if (info && value && (*info & SANE_INFO_INEXACT)
2300141cc406Sopenharmony_ci	    && sopt->type == SANE_TYPE_INT)
2301141cc406Sopenharmony_ci		DBG(17, " constrained val = %d\n", *(SANE_Word *) value);
2302141cc406Sopenharmony_ci
2303141cc406Sopenharmony_ci	if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
2304141cc406Sopenharmony_ci		optval = search_string_list(sopt->constraint.string_list,
2305141cc406Sopenharmony_ci					    (char *) value);
2306141cc406Sopenharmony_ci		if (optval == NULL)
2307141cc406Sopenharmony_ci			return SANE_STATUS_INVAL;
2308141cc406Sopenharmony_ci		optindex = optval - sopt->constraint.string_list;
2309141cc406Sopenharmony_ci	}
2310141cc406Sopenharmony_ci
2311141cc406Sopenharmony_ci	/* block faulty frontends */
2312141cc406Sopenharmony_ci	if (sopt->cap & SANE_CAP_INACTIVE) {
2313141cc406Sopenharmony_ci		DBG(1, " tried to modify a disabled parameter");
2314141cc406Sopenharmony_ci		return SANE_STATUS_INVAL;
2315141cc406Sopenharmony_ci	}
2316141cc406Sopenharmony_ci
2317141cc406Sopenharmony_ci	switch (option) {
2318141cc406Sopenharmony_ci
2319141cc406Sopenharmony_ci	case OPT_ADF_SKEW:
2320141cc406Sopenharmony_ci	case OPT_RESOLUTION:
2321141cc406Sopenharmony_ci	case OPT_ADF_CRP:
2322141cc406Sopenharmony_ci		sval->w = *((SANE_Word *) value);
2323141cc406Sopenharmony_ci		reload = SANE_TRUE;
2324141cc406Sopenharmony_ci		break;
2325141cc406Sopenharmony_ci
2326141cc406Sopenharmony_ci	case OPT_BR_X:
2327141cc406Sopenharmony_ci	case OPT_BR_Y:
2328141cc406Sopenharmony_ci		if (SANE_UNFIX(*((SANE_Word *) value)) == 0) {
2329141cc406Sopenharmony_ci			DBG(17, " invalid br-x or br-y\n");
2330141cc406Sopenharmony_ci			return SANE_STATUS_INVAL;
2331141cc406Sopenharmony_ci		}
2332141cc406Sopenharmony_ci		// fall through
2333141cc406Sopenharmony_ci	case OPT_TL_X:
2334141cc406Sopenharmony_ci	case OPT_TL_Y:
2335141cc406Sopenharmony_ci
2336141cc406Sopenharmony_ci		sval->w = *((SANE_Word *) value);
2337141cc406Sopenharmony_ci		if (NULL != info)
2338141cc406Sopenharmony_ci			*info |= SANE_INFO_RELOAD_PARAMS;
2339141cc406Sopenharmony_ci
2340141cc406Sopenharmony_ci		if (option == OPT_BR_X)
2341141cc406Sopenharmony_ci		{
2342141cc406Sopenharmony_ci			DBG(17, "OPT_BR_X = %d\n", sval->w);
2343141cc406Sopenharmony_ci		}
2344141cc406Sopenharmony_ci		if (option == OPT_BR_Y)
2345141cc406Sopenharmony_ci		{
2346141cc406Sopenharmony_ci			DBG(17, "OPT_BR_Y = %d\n", sval->w);
2347141cc406Sopenharmony_ci		}
2348141cc406Sopenharmony_ci		if (option == OPT_TL_X)
2349141cc406Sopenharmony_ci		{
2350141cc406Sopenharmony_ci			DBG(17, "OPT_TL_X = %d\n", sval->w);
2351141cc406Sopenharmony_ci		}
2352141cc406Sopenharmony_ci		if (option == OPT_TL_Y)
2353141cc406Sopenharmony_ci		{
2354141cc406Sopenharmony_ci			DBG(17, "OPT_TL_Y = %d\n", sval->w);
2355141cc406Sopenharmony_ci		}
2356141cc406Sopenharmony_ci		// adf crop set to off
2357141cc406Sopenharmony_ci		s->val[OPT_ADF_CRP].w = 0;
2358141cc406Sopenharmony_ci		break;
2359141cc406Sopenharmony_ci
2360141cc406Sopenharmony_ci	case OPT_SOURCE:
2361141cc406Sopenharmony_ci		change_source(s, optindex, (char *) value);
2362141cc406Sopenharmony_ci		reload = SANE_TRUE;
2363141cc406Sopenharmony_ci		break;
2364141cc406Sopenharmony_ci
2365141cc406Sopenharmony_ci	case OPT_MODE:
2366141cc406Sopenharmony_ci	{
2367141cc406Sopenharmony_ci		DBG(17, " OPT_MODE = index %d\n", optindex);
2368141cc406Sopenharmony_ci
2369141cc406Sopenharmony_ci		/* use JPEG mode if RAW is not available when bpp > 1 */
2370141cc406Sopenharmony_ci		if (optindex > 0 && !s->hw->has_raw) {
2371141cc406Sopenharmony_ci			s->mode_jpeg = 1;
2372141cc406Sopenharmony_ci		} else {
2373141cc406Sopenharmony_ci			s->mode_jpeg = 0;
2374141cc406Sopenharmony_ci		}
2375141cc406Sopenharmony_ci
2376141cc406Sopenharmony_ci		sval->w = optindex;
2377141cc406Sopenharmony_ci
2378141cc406Sopenharmony_ci		/* if binary, then disable the bit depth selection */
2379141cc406Sopenharmony_ci		if (optindex == 0) {
2380141cc406Sopenharmony_ci			s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2381141cc406Sopenharmony_ci		} else {
2382141cc406Sopenharmony_ci			if (s->hw->depth_list[0] == 1)
2383141cc406Sopenharmony_ci				s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
2384141cc406Sopenharmony_ci			else {
2385141cc406Sopenharmony_ci				s->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
2386141cc406Sopenharmony_ci				s->val[OPT_DEPTH].w =
2387141cc406Sopenharmony_ci					mode_params[optindex].depth;
2388141cc406Sopenharmony_ci			}
2389141cc406Sopenharmony_ci		}
2390141cc406Sopenharmony_ci
2391141cc406Sopenharmony_ci		reload = SANE_TRUE;
2392141cc406Sopenharmony_ci		break;
2393141cc406Sopenharmony_ci	}
2394141cc406Sopenharmony_ci
2395141cc406Sopenharmony_ci	case OPT_DEPTH:
2396141cc406Sopenharmony_ci		sval->w = *((SANE_Word *) value);
2397141cc406Sopenharmony_ci		mode_params[s->val[OPT_MODE].w].depth = sval->w;
2398141cc406Sopenharmony_ci		reload = SANE_TRUE;
2399141cc406Sopenharmony_ci		break;
2400141cc406Sopenharmony_ci
2401141cc406Sopenharmony_ci	case OPT_LOAD:
2402141cc406Sopenharmony_ci		esci2_mech(s, "#ADFLOAD");
2403141cc406Sopenharmony_ci		break;
2404141cc406Sopenharmony_ci
2405141cc406Sopenharmony_ci	case OPT_EJECT:
2406141cc406Sopenharmony_ci		esci2_mech(s, "#ADFEJCT");
2407141cc406Sopenharmony_ci		break;
2408141cc406Sopenharmony_ci
2409141cc406Sopenharmony_ci	default:
2410141cc406Sopenharmony_ci		return SANE_STATUS_INVAL;
2411141cc406Sopenharmony_ci	}
2412141cc406Sopenharmony_ci
2413141cc406Sopenharmony_ci	if (reload && info != NULL)
2414141cc406Sopenharmony_ci		*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2415141cc406Sopenharmony_ci
2416141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
2417141cc406Sopenharmony_ci}
2418141cc406Sopenharmony_ci
2419141cc406Sopenharmony_ciSANE_Status
2420141cc406Sopenharmony_cisane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
2421141cc406Sopenharmony_ci		    void *value, SANE_Int *info)
2422141cc406Sopenharmony_ci{
2423141cc406Sopenharmony_ci	DBG(17, "** %s: action = %x, option = %d\n", __func__, action, option);
2424141cc406Sopenharmony_ci
2425141cc406Sopenharmony_ci	if (option < 0 || option >= NUM_OPTIONS)
2426141cc406Sopenharmony_ci		return SANE_STATUS_INVAL;
2427141cc406Sopenharmony_ci
2428141cc406Sopenharmony_ci	if (info != NULL)
2429141cc406Sopenharmony_ci		*info = 0;
2430141cc406Sopenharmony_ci
2431141cc406Sopenharmony_ci	switch (action) {
2432141cc406Sopenharmony_ci	case SANE_ACTION_GET_VALUE:
2433141cc406Sopenharmony_ci		return getvalue(handle, option, value);
2434141cc406Sopenharmony_ci
2435141cc406Sopenharmony_ci	case SANE_ACTION_SET_VALUE:
2436141cc406Sopenharmony_ci		return setvalue(handle, option, value, info);
2437141cc406Sopenharmony_ci
2438141cc406Sopenharmony_ci	default:
2439141cc406Sopenharmony_ci		return SANE_STATUS_INVAL;
2440141cc406Sopenharmony_ci	}
2441141cc406Sopenharmony_ci
2442141cc406Sopenharmony_ci	return SANE_STATUS_INVAL;
2443141cc406Sopenharmony_ci}
2444141cc406Sopenharmony_ci
2445141cc406Sopenharmony_ci
2446141cc406Sopenharmony_cistatic void setBit (SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue)
2447141cc406Sopenharmony_ci{
2448141cc406Sopenharmony_ci    SANE_Int octet = bitIndex / 8;
2449141cc406Sopenharmony_ci    SANE_Byte  bit   = 7 - (bitIndex % 8);
2450141cc406Sopenharmony_ci
2451141cc406Sopenharmony_ci    if (isTrue) {
2452141cc406Sopenharmony_ci        bytes[octet] |=  (1 << bit);
2453141cc406Sopenharmony_ci    } else {
2454141cc406Sopenharmony_ci        bytes[octet] &= ~(1 << bit);
2455141cc406Sopenharmony_ci    }
2456141cc406Sopenharmony_ci}
2457141cc406Sopenharmony_ci
2458141cc406Sopenharmony_cistatic SANE_Bool getBit (SANE_Byte* bytes, SANE_Int bitIndex)
2459141cc406Sopenharmony_ci{
2460141cc406Sopenharmony_ci    SANE_Int octet = bitIndex / 8;
2461141cc406Sopenharmony_ci    SANE_Byte mask = 1 << (7 - (bitIndex % 8));
2462141cc406Sopenharmony_ci
2463141cc406Sopenharmony_ci    if( bytes[octet] & mask ){
2464141cc406Sopenharmony_ci        return SANE_TRUE;
2465141cc406Sopenharmony_ci    }
2466141cc406Sopenharmony_ci
2467141cc406Sopenharmony_ci    return SANE_FALSE;
2468141cc406Sopenharmony_ci}
2469141cc406Sopenharmony_ci
2470141cc406Sopenharmony_cistatic void swapPixel1(SANE_Int  x1,
2471141cc406Sopenharmony_ci                       SANE_Int  y1,
2472141cc406Sopenharmony_ci                       SANE_Int  x2,
2473141cc406Sopenharmony_ci                       SANE_Int  y2,
2474141cc406Sopenharmony_ci                       SANE_Byte*  bytes,
2475141cc406Sopenharmony_ci                       SANE_Byte   bitsPerSample,
2476141cc406Sopenharmony_ci                       SANE_Int  samplesPerPixel,
2477141cc406Sopenharmony_ci                       SANE_Int  bytesPerRow)
2478141cc406Sopenharmony_ci{
2479141cc406Sopenharmony_ci    SANE_Int pixelBits =  bitsPerSample * samplesPerPixel;
2480141cc406Sopenharmony_ci    SANE_Int widthBits =  bytesPerRow * 8;
2481141cc406Sopenharmony_ci
2482141cc406Sopenharmony_ci    SANE_Byte temp = getBit(bytes, widthBits * y1 + x1 * pixelBits);
2483141cc406Sopenharmony_ci    {
2484141cc406Sopenharmony_ci        SANE_Byte right =  getBit(bytes, widthBits * y2 + x2 * pixelBits);
2485141cc406Sopenharmony_ci        setBit(bytes, widthBits * y1 + x1 * pixelBits, right);
2486141cc406Sopenharmony_ci    }
2487141cc406Sopenharmony_ci    setBit(bytes, widthBits * y2 + x2 * pixelBits, temp);
2488141cc406Sopenharmony_ci}
2489141cc406Sopenharmony_ci
2490141cc406Sopenharmony_cistatic void swapPixel8(SANE_Int  x1,
2491141cc406Sopenharmony_ci                       SANE_Int  y1,
2492141cc406Sopenharmony_ci                       SANE_Int  x2,
2493141cc406Sopenharmony_ci                       SANE_Int  y2,
2494141cc406Sopenharmony_ci                       SANE_Byte*  bytes,
2495141cc406Sopenharmony_ci                       SANE_Byte   bitsPerSample,
2496141cc406Sopenharmony_ci                       SANE_Int  samplesPerPixel,
2497141cc406Sopenharmony_ci                       SANE_Int  bytesPerRow)
2498141cc406Sopenharmony_ci{
2499141cc406Sopenharmony_ci    SANE_Int pixelBytes =  samplesPerPixel * bitsPerSample / 8;
2500141cc406Sopenharmony_ci
2501141cc406Sopenharmony_ci    for (SANE_Byte i = 0; i < pixelBytes; i++) {
2502141cc406Sopenharmony_ci        SANE_Byte temp = bytes[y1 * bytesPerRow +  (pixelBytes *  x1 + i)];
2503141cc406Sopenharmony_ci        bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)] =  bytes[y2 * bytesPerRow +  (pixelBytes * x2 + i)];
2504141cc406Sopenharmony_ci        bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)] =  temp;
2505141cc406Sopenharmony_ci    }
2506141cc406Sopenharmony_ci}
2507141cc406Sopenharmony_ci
2508141cc406Sopenharmony_ci
2509141cc406Sopenharmony_ci
2510141cc406Sopenharmony_cistatic void swapPixel(SANE_Int  x1,
2511141cc406Sopenharmony_ci                      SANE_Int  y1,
2512141cc406Sopenharmony_ci                      SANE_Int  x2,
2513141cc406Sopenharmony_ci                      SANE_Int  y2,
2514141cc406Sopenharmony_ci                      SANE_Byte*  bytes,
2515141cc406Sopenharmony_ci                      SANE_Byte   bitsPerSample,
2516141cc406Sopenharmony_ci                      SANE_Int  samplesPerPixel,
2517141cc406Sopenharmony_ci                      SANE_Int  bytesPerRow)
2518141cc406Sopenharmony_ci{
2519141cc406Sopenharmony_ci    if (bitsPerSample == 1) {
2520141cc406Sopenharmony_ci        swapPixel1(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2521141cc406Sopenharmony_ci    }else if(bitsPerSample == 8 || bitsPerSample == 16){
2522141cc406Sopenharmony_ci        swapPixel8(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow);
2523141cc406Sopenharmony_ci    }
2524141cc406Sopenharmony_ci}
2525141cc406Sopenharmony_ci
2526141cc406Sopenharmony_ci
2527141cc406Sopenharmony_civoid
2528141cc406Sopenharmony_ciupside_down_backside_image(epsonds_scanner *s)
2529141cc406Sopenharmony_ci{
2530141cc406Sopenharmony_ci	// get all data from ring_buffer
2531141cc406Sopenharmony_ci	if (eds_ring_avail(&s->back)  &&
2532141cc406Sopenharmony_ci	    (strcmp(s->hw->sane.model, (char*)"DS-1630") == 0
2533141cc406Sopenharmony_ci		 || strcmp(s->hw->sane.model, (char*)"DS-1610") == 0
2534141cc406Sopenharmony_ci		 || strcmp(s->hw->sane.model, (char*)"DS-1660W") == 0))
2535141cc406Sopenharmony_ci	{
2536141cc406Sopenharmony_ci		SANE_Int bytesPerLine = s->params.bytes_per_line;
2537141cc406Sopenharmony_ci		SANE_Int imageSize = bytesPerLine * s->height_back;
2538141cc406Sopenharmony_ci
2539141cc406Sopenharmony_ci		SANE_Byte* workBuffer = malloc(imageSize);
2540141cc406Sopenharmony_ci		// if there is not enough memory, do nothing.
2541141cc406Sopenharmony_ci		if (workBuffer)
2542141cc406Sopenharmony_ci		{
2543141cc406Sopenharmony_ci			eds_ring_read(&s->back, workBuffer, imageSize);
2544141cc406Sopenharmony_ci			SANE_Int  samplesPerPxel = 3;
2545141cc406Sopenharmony_ci			if (s->params.format == SANE_FRAME_RGB)
2546141cc406Sopenharmony_ci			{
2547141cc406Sopenharmony_ci				samplesPerPxel = 3;
2548141cc406Sopenharmony_ci			}
2549141cc406Sopenharmony_ci			else if (s->params.format == SANE_FRAME_GRAY)
2550141cc406Sopenharmony_ci			{
2551141cc406Sopenharmony_ci				samplesPerPxel = 1;
2552141cc406Sopenharmony_ci			}
2553141cc406Sopenharmony_ci
2554141cc406Sopenharmony_ci			SANE_Int half = (s->height_back / 2) - 1;
2555141cc406Sopenharmony_ci			if (half < 0) {
2556141cc406Sopenharmony_ci				half = 0;
2557141cc406Sopenharmony_ci			}
2558141cc406Sopenharmony_ci
2559141cc406Sopenharmony_ci			if((s->height_back % 2) == 1) {
2560141cc406Sopenharmony_ci				SANE_Int ymid = ( (s->height_back - 1 ) / 2 );
2561141cc406Sopenharmony_ci				for(SANE_Int x = 0;x < (s->width_back / 2); x++) {
2562141cc406Sopenharmony_ci					swapPixel(x, ymid, s->width_back - x - 1, ymid, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2563141cc406Sopenharmony_ci				}
2564141cc406Sopenharmony_ci			}
2565141cc406Sopenharmony_ci
2566141cc406Sopenharmony_ci			if (s->height_back != 1) {
2567141cc406Sopenharmony_ci				for(SANE_Int x = 0; x < s->width_back; x++) {
2568141cc406Sopenharmony_ci					for(SANE_Int y = 0;y <= half; y++) {
2569141cc406Sopenharmony_ci						swapPixel(x, y, s->width_back - x - 1, s->height_back - y -1, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line);
2570141cc406Sopenharmony_ci					}
2571141cc406Sopenharmony_ci				}
2572141cc406Sopenharmony_ci			}
2573141cc406Sopenharmony_ci
2574141cc406Sopenharmony_ci			eds_ring_write(&s->back, workBuffer, imageSize);
2575141cc406Sopenharmony_ci			free(workBuffer);
2576141cc406Sopenharmony_ci			workBuffer = NULL;
2577141cc406Sopenharmony_ci
2578141cc406Sopenharmony_ci		}
2579141cc406Sopenharmony_ci	}
2580141cc406Sopenharmony_ci
2581141cc406Sopenharmony_ci}
2582141cc406Sopenharmony_ci
2583141cc406Sopenharmony_ci
2584141cc406Sopenharmony_ciSANE_Status
2585141cc406Sopenharmony_ciget_next_image(epsonds_scanner *s)
2586141cc406Sopenharmony_ci{
2587141cc406Sopenharmony_ci	SANE_Status status = SANE_STATUS_GOOD;
2588141cc406Sopenharmony_ci
2589141cc406Sopenharmony_ci	if (s->acquirePage == 0 && s->current == &s->front)
2590141cc406Sopenharmony_ci	{
2591141cc406Sopenharmony_ci		DBG(20, "** %s:  get_next_image\n", __func__);
2592141cc406Sopenharmony_ci
2593141cc406Sopenharmony_ci
2594141cc406Sopenharmony_ci		/*page info will be updatted by pen*/
2595141cc406Sopenharmony_ci		s->width_back = 0;
2596141cc406Sopenharmony_ci		s->width_front = 0;
2597141cc406Sopenharmony_ci		s->height_back = 0;
2598141cc406Sopenharmony_ci		s->height_front = 0;
2599141cc406Sopenharmony_ci
2600141cc406Sopenharmony_ci		if (s->mode_jpeg)
2601141cc406Sopenharmony_ci		{
2602141cc406Sopenharmony_ci			status = acquire_and_decode_jpeg_data(s);
2603141cc406Sopenharmony_ci		}else{
2604141cc406Sopenharmony_ci			status = acquire_raw_data(s);
2605141cc406Sopenharmony_ci		}
2606141cc406Sopenharmony_ci		if (status != SANE_STATUS_GOOD)
2607141cc406Sopenharmony_ci		{
2608141cc406Sopenharmony_ci			eds_ring_flush(&s->front);
2609141cc406Sopenharmony_ci			eds_ring_flush(&s->back);
2610141cc406Sopenharmony_ci			eds_ring_destory(&s->front);
2611141cc406Sopenharmony_ci			eds_ring_destory(&s->back);
2612141cc406Sopenharmony_ci		}
2613141cc406Sopenharmony_ci		DBG(20," ringFront = %d ringBack = %d\n", eds_ring_avail(&s->front), eds_ring_avail(&s->back));
2614141cc406Sopenharmony_ci
2615141cc406Sopenharmony_ci		s->acquirePage = 1;
2616141cc406Sopenharmony_ci	}
2617141cc406Sopenharmony_ci
2618141cc406Sopenharmony_ci	return status;
2619141cc406Sopenharmony_ci}
2620141cc406Sopenharmony_ci
2621141cc406Sopenharmony_ci
2622141cc406Sopenharmony_ciSANE_Status
2623141cc406Sopenharmony_cisane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
2624141cc406Sopenharmony_ci{
2625141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *)handle;
2626141cc406Sopenharmony_ci
2627141cc406Sopenharmony_ci	DBG(5, "** %s\n", __func__);
2628141cc406Sopenharmony_ci
2629141cc406Sopenharmony_ci	if (params == NULL)
2630141cc406Sopenharmony_ci		DBG(1, "%s: params is NULL\n", __func__);
2631141cc406Sopenharmony_ci
2632141cc406Sopenharmony_ci	/*
2633141cc406Sopenharmony_ci	 * If sane_start was already called, then just retrieve the parameters
2634141cc406Sopenharmony_ci	 * from the scanner data structure
2635141cc406Sopenharmony_ci	 */
2636141cc406Sopenharmony_ci	if (s->scanning) {
2637141cc406Sopenharmony_ci		DBG(5, "scan in progress, returning saved params structure\n");
2638141cc406Sopenharmony_ci	} else {
2639141cc406Sopenharmony_ci		/* otherwise initialize the params structure */
2640141cc406Sopenharmony_ci		eds_init_parameters(s);
2641141cc406Sopenharmony_ci	}
2642141cc406Sopenharmony_ci
2643141cc406Sopenharmony_ci
2644141cc406Sopenharmony_ci	SANE_Status status = SANE_STATUS_GOOD;
2645141cc406Sopenharmony_ci
2646141cc406Sopenharmony_ci	status = get_next_image(s);
2647141cc406Sopenharmony_ci
2648141cc406Sopenharmony_ci	// if size auto, update page size value
2649141cc406Sopenharmony_ci	if(s->val[OPT_ADF_CRP].w)
2650141cc406Sopenharmony_ci	{
2651141cc406Sopenharmony_ci		// frontside
2652141cc406Sopenharmony_ci		if (s->current == &s->front)
2653141cc406Sopenharmony_ci		{
2654141cc406Sopenharmony_ci			DBG(20, "front side \n");
2655141cc406Sopenharmony_ci			if (s->width_front != 0 && s->height_front != 0)
2656141cc406Sopenharmony_ci			{
2657141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_RGB)
2658141cc406Sopenharmony_ci				{
2659141cc406Sopenharmony_ci					s->params.bytes_per_line = s->width_front * 3;
2660141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_front;
2661141cc406Sopenharmony_ci				}
2662141cc406Sopenharmony_ci
2663141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2664141cc406Sopenharmony_ci				{
2665141cc406Sopenharmony_ci					s->params.bytes_per_line = s->width_front;
2666141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_front;
2667141cc406Sopenharmony_ci				}
2668141cc406Sopenharmony_ci
2669141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2670141cc406Sopenharmony_ci				{
2671141cc406Sopenharmony_ci					s->params.bytes_per_line = (s->width_front + 7)/8;
2672141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_front;
2673141cc406Sopenharmony_ci				}
2674141cc406Sopenharmony_ci				s->params.lines = s->height_front;
2675141cc406Sopenharmony_ci			}
2676141cc406Sopenharmony_ci		}
2677141cc406Sopenharmony_ci		// backside
2678141cc406Sopenharmony_ci		if (s->current == &s->back)
2679141cc406Sopenharmony_ci		{
2680141cc406Sopenharmony_ci			DBG(20, "back side \n");
2681141cc406Sopenharmony_ci			if (s->width_back != 0 && s->height_back != 0)
2682141cc406Sopenharmony_ci			{
2683141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_RGB)
2684141cc406Sopenharmony_ci				{
2685141cc406Sopenharmony_ci					s->params.bytes_per_line = s->width_back * 3;
2686141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_back;
2687141cc406Sopenharmony_ci				}
2688141cc406Sopenharmony_ci
2689141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8)
2690141cc406Sopenharmony_ci				{
2691141cc406Sopenharmony_ci					s->params.bytes_per_line = s->width_back;
2692141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_back;
2693141cc406Sopenharmony_ci				}
2694141cc406Sopenharmony_ci
2695141cc406Sopenharmony_ci				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1)
2696141cc406Sopenharmony_ci				{
2697141cc406Sopenharmony_ci					s->params.bytes_per_line = (s->width_back + 7)/8;
2698141cc406Sopenharmony_ci					s->params.pixels_per_line = s->width_back;
2699141cc406Sopenharmony_ci				}
2700141cc406Sopenharmony_ci				s->params.lines = s->height_back;
2701141cc406Sopenharmony_ci			}
2702141cc406Sopenharmony_ci		}
2703141cc406Sopenharmony_ci	}
2704141cc406Sopenharmony_ci	if (params != NULL)
2705141cc406Sopenharmony_ci		*params = s->params;
2706141cc406Sopenharmony_ci
2707141cc406Sopenharmony_ci	print_params(s->params);
2708141cc406Sopenharmony_ci
2709141cc406Sopenharmony_ci	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 );
2710141cc406Sopenharmony_ci	return status;
2711141cc406Sopenharmony_ci}
2712141cc406Sopenharmony_ci
2713141cc406Sopenharmony_ci
2714141cc406Sopenharmony_ci
2715141cc406Sopenharmony_citypedef float ColorMatrix[3][3];
2716141cc406Sopenharmony_ci
2717141cc406Sopenharmony_ci#define CCT_TABLE_SIZE 9
2718141cc406Sopenharmony_cistatic int get_roundup_index(double frac[], int n)
2719141cc406Sopenharmony_ci{
2720141cc406Sopenharmony_ci    int        i, index = -1;
2721141cc406Sopenharmony_ci    double    max_val = 0.0;
2722141cc406Sopenharmony_ci
2723141cc406Sopenharmony_ci    for (i=0; i<n; i++) {
2724141cc406Sopenharmony_ci        if (frac[i]<0) continue;
2725141cc406Sopenharmony_ci        if (max_val<frac[i]) {
2726141cc406Sopenharmony_ci            index = i;
2727141cc406Sopenharmony_ci            max_val = frac[i];
2728141cc406Sopenharmony_ci        }
2729141cc406Sopenharmony_ci    }
2730141cc406Sopenharmony_ci    return index;
2731141cc406Sopenharmony_ci}
2732141cc406Sopenharmony_ci
2733141cc406Sopenharmony_cistatic int get_rounddown_index(double frac[], int n)
2734141cc406Sopenharmony_ci{
2735141cc406Sopenharmony_ci    int        i, index = -1;
2736141cc406Sopenharmony_ci    double    min_val  = 1.0;
2737141cc406Sopenharmony_ci
2738141cc406Sopenharmony_ci    for (i=0; i<n; i++) {
2739141cc406Sopenharmony_ci        if (frac[i]>0) continue;
2740141cc406Sopenharmony_ci        if (min_val>frac[i]) {
2741141cc406Sopenharmony_ci            index = i;
2742141cc406Sopenharmony_ci            min_val = frac[i];
2743141cc406Sopenharmony_ci        }
2744141cc406Sopenharmony_ci    }
2745141cc406Sopenharmony_ci    return index;
2746141cc406Sopenharmony_ci}
2747141cc406Sopenharmony_ci
2748141cc406Sopenharmony_ci
2749141cc406Sopenharmony_civoid ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[])
2750141cc406Sopenharmony_ci{
2751141cc406Sopenharmony_ci    int        i, j, index;
2752141cc406Sopenharmony_ci    double    mult_cct[CCT_TABLE_SIZE], frac[CCT_TABLE_SIZE];
2753141cc406Sopenharmony_ci    int        sum[3];
2754141cc406Sopenharmony_ci    int        loop;
2755141cc406Sopenharmony_ci
2756141cc406Sopenharmony_ci    for (i=0; i<CCT_TABLE_SIZE; i++) {
2757141cc406Sopenharmony_ci        mult_cct[i] = org_cct[i] * mult;
2758141cc406Sopenharmony_ci    }
2759141cc406Sopenharmony_ci
2760141cc406Sopenharmony_ci    // round value multiplied by 'mult' off to integer.
2761141cc406Sopenharmony_ci    for (i=0; i<CCT_TABLE_SIZE; i++) {
2762141cc406Sopenharmony_ci        rnd_cct[i] = (int)floor(org_cct[i] * mult + 0.5);
2763141cc406Sopenharmony_ci    }
2764141cc406Sopenharmony_ci
2765141cc406Sopenharmony_ci    loop=0;
2766141cc406Sopenharmony_ci    do {
2767141cc406Sopenharmony_ci        // If all element equal to 11, diagonal element is set to 10.
2768141cc406Sopenharmony_ci        for (i=0; i<3; i++) {
2769141cc406Sopenharmony_ci            if (    (rnd_cct[i*3]==11) &&
2770141cc406Sopenharmony_ci                (rnd_cct[i*3]==rnd_cct[i*3+1]) &&
2771141cc406Sopenharmony_ci                (rnd_cct[i*3]==rnd_cct[i*3+2])    ) {
2772141cc406Sopenharmony_ci                rnd_cct[i*3+i] --;
2773141cc406Sopenharmony_ci                mult_cct[i*3+i] = rnd_cct[i*3+i];
2774141cc406Sopenharmony_ci            }
2775141cc406Sopenharmony_ci        }
2776141cc406Sopenharmony_ci        // calc. summation of each line.
2777141cc406Sopenharmony_ci        for (i=0; i<3; i++) {
2778141cc406Sopenharmony_ci            sum[i] = 0;
2779141cc406Sopenharmony_ci            for (j=0; j<3; j++) {
2780141cc406Sopenharmony_ci                sum[i] += rnd_cct[i*3+j];
2781141cc406Sopenharmony_ci            }
2782141cc406Sopenharmony_ci        }
2783141cc406Sopenharmony_ci        // calc. values rounded up or down.
2784141cc406Sopenharmony_ci        for (i=0; i<CCT_TABLE_SIZE; i++) {
2785141cc406Sopenharmony_ci            frac[i] = mult_cct[i] - rnd_cct[i];
2786141cc406Sopenharmony_ci        }
2787141cc406Sopenharmony_ci
2788141cc406Sopenharmony_ci        // if summation does not equal to 'mult', adjust rounded up or down value.
2789141cc406Sopenharmony_ci        for (i=0; i<3; i++) {
2790141cc406Sopenharmony_ci            if (sum[i]<mult) {
2791141cc406Sopenharmony_ci                index = get_roundup_index(&frac[i*3], 3);
2792141cc406Sopenharmony_ci                if (index!=-1) {
2793141cc406Sopenharmony_ci                    rnd_cct[i*3+index] ++;
2794141cc406Sopenharmony_ci                    mult_cct[i*3+index] = rnd_cct[i*3+index];
2795141cc406Sopenharmony_ci                    sum[i]++;
2796141cc406Sopenharmony_ci                }
2797141cc406Sopenharmony_ci            } else if (sum[i]>mult) {
2798141cc406Sopenharmony_ci                index = get_rounddown_index(&frac[i*3], 3);
2799141cc406Sopenharmony_ci                if (index!=-1) {
2800141cc406Sopenharmony_ci                    rnd_cct[i*3+index] --;
2801141cc406Sopenharmony_ci                    mult_cct[i*3+index] = rnd_cct[i*3+index];
2802141cc406Sopenharmony_ci                    sum[i]--;
2803141cc406Sopenharmony_ci                }
2804141cc406Sopenharmony_ci            }
2805141cc406Sopenharmony_ci        }
2806141cc406Sopenharmony_ci
2807141cc406Sopenharmony_ci    } while ((++loop<2)&&((sum[0]!=mult)||(sum[1]!=mult)||(sum[2]!=mult)));
2808141cc406Sopenharmony_ci}
2809141cc406Sopenharmony_ci
2810141cc406Sopenharmony_ci
2811141cc406Sopenharmony_ci
2812141cc406Sopenharmony_ci/*
2813141cc406Sopenharmony_ci * This function is part of the SANE API and gets called from the front end to
2814141cc406Sopenharmony_ci * start the scan process.
2815141cc406Sopenharmony_ci */
2816141cc406Sopenharmony_ci#define CMD_BUF_SIZE 1000
2817141cc406Sopenharmony_ciSANE_Status
2818141cc406Sopenharmony_cisane_start(SANE_Handle handle)
2819141cc406Sopenharmony_ci{
2820141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *)handle;
2821141cc406Sopenharmony_ci	char buf[65]; /* add one more byte to correct buffer overflow issue */
2822141cc406Sopenharmony_ci	char cmd[CMD_BUF_SIZE]; /* take care not to overflow */
2823141cc406Sopenharmony_ci	SANE_Status status = 0;
2824141cc406Sopenharmony_ci
2825141cc406Sopenharmony_ci	s->pages++;
2826141cc406Sopenharmony_ci
2827141cc406Sopenharmony_ci	DBG(5, "** %s, pages = %d, scanning = %d, backside = %d, front fill: %d, back fill: %d\n",
2828141cc406Sopenharmony_ci		__func__, s->pages, s->scanning, s->backside,
2829141cc406Sopenharmony_ci		eds_ring_avail(&s->front),
2830141cc406Sopenharmony_ci		eds_ring_avail(&s->back));
2831141cc406Sopenharmony_ci
2832141cc406Sopenharmony_ci	s->eof = 0;
2833141cc406Sopenharmony_ci	s->canceling = 0;
2834141cc406Sopenharmony_ci	s->acquirePage = 0;
2835141cc406Sopenharmony_ci
2836141cc406Sopenharmony_ci	if ((s->pages % 2) == 1) {
2837141cc406Sopenharmony_ci		s->current = &s->front;
2838141cc406Sopenharmony_ci	} else if (eds_ring_avail(&s->back)) {
2839141cc406Sopenharmony_ci		DBG(5, "back side\n");
2840141cc406Sopenharmony_ci		s->current = &s->back;
2841141cc406Sopenharmony_ci	}
2842141cc406Sopenharmony_ci
2843141cc406Sopenharmony_ci	/* scan already in progress? (one pass adf) */
2844141cc406Sopenharmony_ci	if (s->scanning  || eds_ring_avail(&s->back) > 0) {
2845141cc406Sopenharmony_ci		DBG(5, " scan in progress, returning early\n");
2846141cc406Sopenharmony_ci		return get_next_image(s);
2847141cc406Sopenharmony_ci	}
2848141cc406Sopenharmony_ci	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2849141cc406Sopenharmony_ci		if (s->scanEnd)
2850141cc406Sopenharmony_ci		{
2851141cc406Sopenharmony_ci	  		 s->scanEnd = 0;
2852141cc406Sopenharmony_ci	  		 return SANE_STATUS_NO_DOCS;
2853141cc406Sopenharmony_ci		}
2854141cc406Sopenharmony_ci	}else{
2855141cc406Sopenharmony_ci	   s->scanEnd = 0;
2856141cc406Sopenharmony_ci	}
2857141cc406Sopenharmony_ci
2858141cc406Sopenharmony_ci	/* calc scanning parameters */
2859141cc406Sopenharmony_ci	status = eds_init_parameters(s);
2860141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
2861141cc406Sopenharmony_ci		DBG(1, " parameters initialization failed\n");
2862141cc406Sopenharmony_ci		return status;
2863141cc406Sopenharmony_ci	}
2864141cc406Sopenharmony_ci
2865141cc406Sopenharmony_ci	/* allocate line buffer */
2866141cc406Sopenharmony_ci	s->line_buffer = realloc(s->line_buffer, s->params.bytes_per_line);
2867141cc406Sopenharmony_ci	if (s->line_buffer == NULL)
2868141cc406Sopenharmony_ci		return SANE_STATUS_NO_MEM;
2869141cc406Sopenharmony_ci
2870141cc406Sopenharmony_ci	/* transfer buffer size, bsz */
2871141cc406Sopenharmony_ci	/* XXX read value from scanner */
2872141cc406Sopenharmony_ci	s->bsz = (1048576 * 4);
2873141cc406Sopenharmony_ci
2874141cc406Sopenharmony_ci	/* transfer buffer */
2875141cc406Sopenharmony_ci	s->buf = realloc(s->buf, s->bsz);
2876141cc406Sopenharmony_ci	if (s->buf == NULL)
2877141cc406Sopenharmony_ci		return SANE_STATUS_NO_MEM;
2878141cc406Sopenharmony_ci
2879141cc406Sopenharmony_ci	print_params(s->params);
2880141cc406Sopenharmony_ci
2881141cc406Sopenharmony_ci	/* set scanning parameters */
2882141cc406Sopenharmony_ci
2883141cc406Sopenharmony_ci	s->isDuplexScan = 0;
2884141cc406Sopenharmony_ci	/* document source */
2885141cc406Sopenharmony_ci	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2886141cc406Sopenharmony_ci
2887141cc406Sopenharmony_ci		SANE_Int status = esci2_stat(s);
2888141cc406Sopenharmony_ci		if (status == SANE_STATUS_NO_DOCS)
2889141cc406Sopenharmony_ci		{
2890141cc406Sopenharmony_ci		   return SANE_STATUS_NO_DOCS;
2891141cc406Sopenharmony_ci		}
2892141cc406Sopenharmony_ci
2893141cc406Sopenharmony_ci		SANE_Int duplexMode = (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0);
2894141cc406Sopenharmony_ci
2895141cc406Sopenharmony_ci		sprintf(buf, "#ADF%s%s%s",
2896141cc406Sopenharmony_ci		duplexMode ? "DPLX" : "",
2897141cc406Sopenharmony_ci		s->val[OPT_ADF_SKEW].w ? "SKEW" : "",
2898141cc406Sopenharmony_ci		s->val[OPT_ADF_CRP].w ? "CRP " : ""
2899141cc406Sopenharmony_ci		);
2900141cc406Sopenharmony_ci
2901141cc406Sopenharmony_ci		if (duplexMode)
2902141cc406Sopenharmony_ci		{
2903141cc406Sopenharmony_ci			s->isDuplexScan = 1;
2904141cc406Sopenharmony_ci		}
2905141cc406Sopenharmony_ci		s->isflatbedScan = 0;
2906141cc406Sopenharmony_ci	}
2907141cc406Sopenharmony_ci	else if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_FLATBED) == 0) {
2908141cc406Sopenharmony_ci
2909141cc406Sopenharmony_ci		strcpy(buf, "#FB ");
2910141cc406Sopenharmony_ci		s->isflatbedScan = 1;
2911141cc406Sopenharmony_ci
2912141cc406Sopenharmony_ci	} else {
2913141cc406Sopenharmony_ci		/* XXX */
2914141cc406Sopenharmony_ci	}
2915141cc406Sopenharmony_ci
2916141cc406Sopenharmony_ci	strcpy(cmd, buf);
2917141cc406Sopenharmony_ci
2918141cc406Sopenharmony_ci	s->needToConvertBW = 0;
2919141cc406Sopenharmony_ci
2920141cc406Sopenharmony_ci	if (s->params.format == SANE_FRAME_GRAY) {
2921141cc406Sopenharmony_ci		if (s->params.depth == 1 && s->hw->has_mono == 0)
2922141cc406Sopenharmony_ci		{
2923141cc406Sopenharmony_ci			sprintf(buf, "#COLM008");
2924141cc406Sopenharmony_ci			s->needToConvertBW = 1;
2925141cc406Sopenharmony_ci			s->mode_jpeg = 1;
2926141cc406Sopenharmony_ci		}else
2927141cc406Sopenharmony_ci		{
2928141cc406Sopenharmony_ci			sprintf(buf, "#COLM%03d", s->params.depth);
2929141cc406Sopenharmony_ci		}
2930141cc406Sopenharmony_ci	} else if (s->params.format == SANE_FRAME_RGB) {
2931141cc406Sopenharmony_ci		sprintf(buf, "#COLC%03d", s->params.depth * 3);
2932141cc406Sopenharmony_ci	}
2933141cc406Sopenharmony_ci
2934141cc406Sopenharmony_ci	strcat(cmd, buf);
2935141cc406Sopenharmony_ci
2936141cc406Sopenharmony_ci	/* image transfer format */
2937141cc406Sopenharmony_ci	if (!s->mode_jpeg) {
2938141cc406Sopenharmony_ci		if (s->params.depth > 1 || s->hw->has_raw) {
2939141cc406Sopenharmony_ci			strcat(cmd, "#FMTRAW ");
2940141cc406Sopenharmony_ci		}
2941141cc406Sopenharmony_ci	} else {
2942141cc406Sopenharmony_ci		strcat(cmd, "#FMTJPG #JPGd090");
2943141cc406Sopenharmony_ci	}
2944141cc406Sopenharmony_ci
2945141cc406Sopenharmony_ci	/* set GMM */
2946141cc406Sopenharmony_ci	if (s->params.depth == 1)
2947141cc406Sopenharmony_ci	{
2948141cc406Sopenharmony_ci		sprintf(buf, "#GMMUG10");
2949141cc406Sopenharmony_ci	} else
2950141cc406Sopenharmony_ci	{
2951141cc406Sopenharmony_ci		sprintf(buf, "#GMMUG18");
2952141cc406Sopenharmony_ci	}
2953141cc406Sopenharmony_ci	strcat(cmd, buf);
2954141cc406Sopenharmony_ci
2955141cc406Sopenharmony_ci	/* resolution (RSMi not always supported) */
2956141cc406Sopenharmony_ci
2957141cc406Sopenharmony_ci	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2958141cc406Sopenharmony_ci		DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2959141cc406Sopenharmony_ci	} else if (s->val[OPT_RESOLUTION].w > 999) {
2960141cc406Sopenharmony_ci		sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2961141cc406Sopenharmony_ci	} else {
2962141cc406Sopenharmony_ci		sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2963141cc406Sopenharmony_ci	}
2964141cc406Sopenharmony_ci
2965141cc406Sopenharmony_ci		if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0 && s->val[OPT_RESOLUTION].w > 600) {
2966141cc406Sopenharmony_ci		DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n");
2967141cc406Sopenharmony_ci	} else if (s->val[OPT_RESOLUTION].w > 999) {
2968141cc406Sopenharmony_ci		sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2969141cc406Sopenharmony_ci	} else {
2970141cc406Sopenharmony_ci		sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);
2971141cc406Sopenharmony_ci	}
2972141cc406Sopenharmony_ci
2973141cc406Sopenharmony_ci	strcat(cmd, buf);
2974141cc406Sopenharmony_ci
2975141cc406Sopenharmony_ci	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
2976141cc406Sopenharmony_ci	|| 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){
2977141cc406Sopenharmony_ci		sprintf(buf, "#BSZi0262144");
2978141cc406Sopenharmony_ci		strcat(cmd, buf);
2979141cc406Sopenharmony_ci	}
2980141cc406Sopenharmony_ci	else {
2981141cc406Sopenharmony_ci		sprintf(buf, "#BSZi1048576");
2982141cc406Sopenharmony_ci		strcat(cmd, buf);
2983141cc406Sopenharmony_ci	}
2984141cc406Sopenharmony_ci
2985141cc406Sopenharmony_ci
2986141cc406Sopenharmony_ci	/* scanning area */
2987141cc406Sopenharmony_ci
2988141cc406Sopenharmony_ci	sprintf(buf, "#ACQi%07di%07di%07di%07d",
2989141cc406Sopenharmony_ci		s->left, s->top, s->params.pixels_per_line, s->params.lines);
2990141cc406Sopenharmony_ci
2991141cc406Sopenharmony_ci
2992141cc406Sopenharmony_ci	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
2993141cc406Sopenharmony_ci		status = esci2_stat(s);
2994141cc406Sopenharmony_ci		if (status != SANE_STATUS_GOOD) {
2995141cc406Sopenharmony_ci			goto end;
2996141cc406Sopenharmony_ci		}
2997141cc406Sopenharmony_ci	}
2998141cc406Sopenharmony_ci
2999141cc406Sopenharmony_ci	strcat(cmd, buf);
3000141cc406Sopenharmony_ci
3001141cc406Sopenharmony_ci
3002141cc406Sopenharmony_ci	int pos = 0;
3003141cc406Sopenharmony_ci
3004141cc406Sopenharmony_ci	{
3005141cc406Sopenharmony_ci		for (int i = 0; i < CMD_BUF_SIZE; i++)
3006141cc406Sopenharmony_ci		{
3007141cc406Sopenharmony_ci			// find end of string
3008141cc406Sopenharmony_ci			if(cmd[i] == 0)
3009141cc406Sopenharmony_ci			{
3010141cc406Sopenharmony_ci				pos = i;
3011141cc406Sopenharmony_ci				break;
3012141cc406Sopenharmony_ci			}
3013141cc406Sopenharmony_ci		}
3014141cc406Sopenharmony_ci
3015141cc406Sopenharmony_ci
3016141cc406Sopenharmony_ci		if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) {
3017141cc406Sopenharmony_ci			DBG(10, "SANE_FRAME_GRAY\n");
3018141cc406Sopenharmony_ci			cmd[pos++] = '#';
3019141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3020141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3021141cc406Sopenharmony_ci			cmd[pos++] = 'T';
3022141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3023141cc406Sopenharmony_ci			cmd[pos++] = 'O';
3024141cc406Sopenharmony_ci			cmd[pos++] = 'N';
3025141cc406Sopenharmony_ci			cmd[pos++] = 'O';
3026141cc406Sopenharmony_ci			cmd[pos++] = 'h';
3027141cc406Sopenharmony_ci			cmd[pos++] = '1';
3028141cc406Sopenharmony_ci			cmd[pos++] = '0';
3029141cc406Sopenharmony_ci			cmd[pos++] = '0';
3030141cc406Sopenharmony_ci
3031141cc406Sopenharmony_ci			for(int count = 0; count < 256; count++) {
3032141cc406Sopenharmony_ci				cmd[pos++] =  LUT[s->hw->lut_id][count];
3033141cc406Sopenharmony_ci			}
3034141cc406Sopenharmony_ci		}
3035141cc406Sopenharmony_ci		if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) {
3036141cc406Sopenharmony_ci			DBG(10, "SANE_FRAME_GRAY\n");
3037141cc406Sopenharmony_ci			cmd[pos++] = '#';
3038141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3039141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3040141cc406Sopenharmony_ci			cmd[pos++] = 'T';
3041141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3042141cc406Sopenharmony_ci			cmd[pos++] = 'O';
3043141cc406Sopenharmony_ci			cmd[pos++] = 'N';
3044141cc406Sopenharmony_ci			cmd[pos++] = 'O';
3045141cc406Sopenharmony_ci			cmd[pos++] = 'h';
3046141cc406Sopenharmony_ci			cmd[pos++] = '1';
3047141cc406Sopenharmony_ci			cmd[pos++] = '0';
3048141cc406Sopenharmony_ci			cmd[pos++] = '0';
3049141cc406Sopenharmony_ci
3050141cc406Sopenharmony_ci			for(int count = 0; count < 256; count++) {
3051141cc406Sopenharmony_ci				cmd[pos++] =  LUT[0][count];
3052141cc406Sopenharmony_ci			}
3053141cc406Sopenharmony_ci		}
3054141cc406Sopenharmony_ci		else if (s->params.format == SANE_FRAME_RGB) {
3055141cc406Sopenharmony_ci			DBG(10, "SANE_FRAME_RGB\n");
3056141cc406Sopenharmony_ci			cmd[pos++] = '#';
3057141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3058141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3059141cc406Sopenharmony_ci			cmd[pos++] = 'T';
3060141cc406Sopenharmony_ci			cmd[pos++] = 'R';
3061141cc406Sopenharmony_ci			cmd[pos++] = 'E';
3062141cc406Sopenharmony_ci			cmd[pos++] = 'D';
3063141cc406Sopenharmony_ci			cmd[pos++] = ' ';
3064141cc406Sopenharmony_ci			cmd[pos++] = 'h';
3065141cc406Sopenharmony_ci			cmd[pos++] = '1';
3066141cc406Sopenharmony_ci			cmd[pos++] = '0';
3067141cc406Sopenharmony_ci			cmd[pos++] = '0';
3068141cc406Sopenharmony_ci
3069141cc406Sopenharmony_ci			for(int count = 0; count < 256; count++) {
3070141cc406Sopenharmony_ci				cmd[pos++] =  LUT_R[s->hw->lut_id][count];
3071141cc406Sopenharmony_ci			}
3072141cc406Sopenharmony_ci
3073141cc406Sopenharmony_ci			cmd[pos++] = '#';
3074141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3075141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3076141cc406Sopenharmony_ci			cmd[pos++] = 'T';
3077141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3078141cc406Sopenharmony_ci			cmd[pos++] = 'R';
3079141cc406Sopenharmony_ci			cmd[pos++] = 'N';
3080141cc406Sopenharmony_ci			cmd[pos++] = ' ';
3081141cc406Sopenharmony_ci			cmd[pos++] = 'h';
3082141cc406Sopenharmony_ci			cmd[pos++] = '1';
3083141cc406Sopenharmony_ci			cmd[pos++] = '0';
3084141cc406Sopenharmony_ci			cmd[pos++] = '0';
3085141cc406Sopenharmony_ci
3086141cc406Sopenharmony_ci			for(int count = 0; count < 256; count++) {
3087141cc406Sopenharmony_ci				cmd[pos++] =  LUT_G[s->hw->lut_id][count];
3088141cc406Sopenharmony_ci			}
3089141cc406Sopenharmony_ci
3090141cc406Sopenharmony_ci			cmd[pos++] = '#';
3091141cc406Sopenharmony_ci			cmd[pos++] = 'G';
3092141cc406Sopenharmony_ci			cmd[pos++] = 'M';
3093141cc406Sopenharmony_ci			cmd[pos++] = 'T';
3094141cc406Sopenharmony_ci			cmd[pos++] = 'B';
3095141cc406Sopenharmony_ci			cmd[pos++] = 'L';
3096141cc406Sopenharmony_ci			cmd[pos++] = 'U';
3097141cc406Sopenharmony_ci			cmd[pos++] = ' ';
3098141cc406Sopenharmony_ci			cmd[pos++] = 'h';
3099141cc406Sopenharmony_ci			cmd[pos++] = '1';
3100141cc406Sopenharmony_ci			cmd[pos++] = '0';
3101141cc406Sopenharmony_ci			cmd[pos++] = '0';
3102141cc406Sopenharmony_ci
3103141cc406Sopenharmony_ci			for(int count = 0; count < 256; count++) {
3104141cc406Sopenharmony_ci				cmd[pos++] =  LUT_B[s->hw->lut_id][count];
3105141cc406Sopenharmony_ci			}
3106141cc406Sopenharmony_ci		}
3107141cc406Sopenharmony_ci		cmd[pos] = 0;
3108141cc406Sopenharmony_ci
3109141cc406Sopenharmony_ci	}
3110141cc406Sopenharmony_ci	{// Set Color Matrix
3111141cc406Sopenharmony_ci		if (s->params.format == SANE_FRAME_RGB && s->hw->lut_id != 0 )/*Color Matrix Target devide and color Scan*/
3112141cc406Sopenharmony_ci		{
3113141cc406Sopenharmony_ci			ColorMatrix matrix;
3114141cc406Sopenharmony_ci
3115141cc406Sopenharmony_ci			// DS-530
3116141cc406Sopenharmony_ci
3117141cc406Sopenharmony_ci			if (s->hw->lut_id == 2)
3118141cc406Sopenharmony_ci			{
3119141cc406Sopenharmony_ci				// R
3120141cc406Sopenharmony_ci				matrix[0][0] = 1.0229;
3121141cc406Sopenharmony_ci				matrix[0][1] = 0.0009;
3122141cc406Sopenharmony_ci				matrix[0][2] = -0.0238;
3123141cc406Sopenharmony_ci
3124141cc406Sopenharmony_ci				// G
3125141cc406Sopenharmony_ci				matrix[1][0] = 0.0031;
3126141cc406Sopenharmony_ci				matrix[1][1] = 1.0287;
3127141cc406Sopenharmony_ci				matrix[1][2] = -0.0318;
3128141cc406Sopenharmony_ci
3129141cc406Sopenharmony_ci				//B
3130141cc406Sopenharmony_ci				matrix[2][0] = 0.0044;
3131141cc406Sopenharmony_ci				matrix[2][1] = -0.1150;
3132141cc406Sopenharmony_ci				matrix[2][2] = 1.1106;
3133141cc406Sopenharmony_ci			}
3134141cc406Sopenharmony_ci
3135141cc406Sopenharmony_ci			// DS-1660W Flatbed
3136141cc406Sopenharmony_ci
3137141cc406Sopenharmony_ci			if (s->hw->lut_id == 4)
3138141cc406Sopenharmony_ci			{
3139141cc406Sopenharmony_ci				// R
3140141cc406Sopenharmony_ci				matrix[0][0] = 1.0229;
3141141cc406Sopenharmony_ci				matrix[0][1] = 0.0009;
3142141cc406Sopenharmony_ci				matrix[0][2] = -0.0238;
3143141cc406Sopenharmony_ci
3144141cc406Sopenharmony_ci				// G
3145141cc406Sopenharmony_ci				matrix[1][0] = 0.0031;
3146141cc406Sopenharmony_ci				matrix[1][1] = 1.0287;
3147141cc406Sopenharmony_ci				matrix[1][2] = -0.0318;
3148141cc406Sopenharmony_ci
3149141cc406Sopenharmony_ci				//B
3150141cc406Sopenharmony_ci				matrix[2][0] = 0.0044;
3151141cc406Sopenharmony_ci				matrix[2][1] = -0.1150;
3152141cc406Sopenharmony_ci				matrix[2][2] = 1.1106;
3153141cc406Sopenharmony_ci			}
3154141cc406Sopenharmony_ci
3155141cc406Sopenharmony_ci
3156141cc406Sopenharmony_ci			// DS-320
3157141cc406Sopenharmony_ci
3158141cc406Sopenharmony_ci			if (s->hw->lut_id == 5)
3159141cc406Sopenharmony_ci			{
3160141cc406Sopenharmony_ci				// R
3161141cc406Sopenharmony_ci				matrix[0][0] = 1.0250;
3162141cc406Sopenharmony_ci				matrix[0][1] = 0.0004;
3163141cc406Sopenharmony_ci				matrix[0][2] = -0.0254;
3164141cc406Sopenharmony_ci
3165141cc406Sopenharmony_ci				// G
3166141cc406Sopenharmony_ci				matrix[1][0] = 0.0003;
3167141cc406Sopenharmony_ci				matrix[1][1] = 1.0022;
3168141cc406Sopenharmony_ci				matrix[1][2] = -0.0025;
3169141cc406Sopenharmony_ci
3170141cc406Sopenharmony_ci				//B
3171141cc406Sopenharmony_ci				matrix[2][0] = 0.0049;
3172141cc406Sopenharmony_ci				matrix[2][1] = -0.0949;
3173141cc406Sopenharmony_ci				matrix[2][2] = 1.0900;
3174141cc406Sopenharmony_ci			}
3175141cc406Sopenharmony_ci
3176141cc406Sopenharmony_ci
3177141cc406Sopenharmony_ci			// ES-50
3178141cc406Sopenharmony_ci
3179141cc406Sopenharmony_ci			if (s->hw->lut_id == 6)
3180141cc406Sopenharmony_ci			{
3181141cc406Sopenharmony_ci				// R
3182141cc406Sopenharmony_ci				matrix[0][0] = 1.0383;
3183141cc406Sopenharmony_ci				matrix[0][1] = -0.0021;
3184141cc406Sopenharmony_ci				matrix[0][2] = -0.0362;
3185141cc406Sopenharmony_ci
3186141cc406Sopenharmony_ci				// G
3187141cc406Sopenharmony_ci				matrix[1][0] = 0.0046;
3188141cc406Sopenharmony_ci				matrix[1][1] = 1.0576;
3189141cc406Sopenharmony_ci				matrix[1][2] = -0.0622;
3190141cc406Sopenharmony_ci
3191141cc406Sopenharmony_ci				//B
3192141cc406Sopenharmony_ci				matrix[2][0] = 0.0235;
3193141cc406Sopenharmony_ci				matrix[2][1] = -0.2396;
3194141cc406Sopenharmony_ci				matrix[2][2] = 1.2161;
3195141cc406Sopenharmony_ci			}
3196141cc406Sopenharmony_ci
3197141cc406Sopenharmony_ci
3198141cc406Sopenharmony_ci			// R
3199141cc406Sopenharmony_ci			matrix[0][0] = 0.9864;
3200141cc406Sopenharmony_ci			matrix[0][1] = 0.0248;
3201141cc406Sopenharmony_ci			matrix[0][2] = -0.0112;
3202141cc406Sopenharmony_ci
3203141cc406Sopenharmony_ci			// G
3204141cc406Sopenharmony_ci			matrix[1][0] = 0.0021;
3205141cc406Sopenharmony_ci			matrix[1][1] = 1.0100;
3206141cc406Sopenharmony_ci			matrix[1][2] = -0.0112;
3207141cc406Sopenharmony_ci
3208141cc406Sopenharmony_ci			//B
3209141cc406Sopenharmony_ci			matrix[2][0] = 0.0139;
3210141cc406Sopenharmony_ci			matrix[2][1] = -0.1249;
3211141cc406Sopenharmony_ci			matrix[2][2] = 1.1110;
3212141cc406Sopenharmony_ci
3213141cc406Sopenharmony_ci
3214141cc406Sopenharmony_ci			// Set Matrix value
3215141cc406Sopenharmony_ci			{
3216141cc406Sopenharmony_ci				cmd[pos++] = '#';
3217141cc406Sopenharmony_ci				cmd[pos++] = 'C';
3218141cc406Sopenharmony_ci				cmd[pos++] = 'M';
3219141cc406Sopenharmony_ci				cmd[pos++] = 'X';
3220141cc406Sopenharmony_ci				cmd[pos++] = 'U';
3221141cc406Sopenharmony_ci				cmd[pos++] = 'M';
3222141cc406Sopenharmony_ci				cmd[pos++] = '0';
3223141cc406Sopenharmony_ci				cmd[pos++] = '8';
3224141cc406Sopenharmony_ci				cmd[pos++] = 'h';
3225141cc406Sopenharmony_ci				cmd[pos++] = '0';
3226141cc406Sopenharmony_ci				cmd[pos++] = '0';
3227141cc406Sopenharmony_ci				cmd[pos++] = '9';
3228141cc406Sopenharmony_ci			}
3229141cc406Sopenharmony_ci
3230141cc406Sopenharmony_ci
3231141cc406Sopenharmony_ci			// Matrix to be sent to scanner must be following d1-d9 order:
3232141cc406Sopenharmony_ci			//
3233141cc406Sopenharmony_ci			//     G  R  B
3234141cc406Sopenharmony_ci			// G [d1 d4 d7]
3235141cc406Sopenharmony_ci			// R [d2 d5 d8]
3236141cc406Sopenharmony_ci			// B [d3 d6 d9]
3237141cc406Sopenharmony_ci			//
3238141cc406Sopenharmony_ci			// So, we will convert it with index table.
3239141cc406Sopenharmony_ci			char index[9] = {4, 1, 7, 3, 0, 6, 5, 2, 8};
3240141cc406Sopenharmony_ci
3241141cc406Sopenharmony_ci			double flatten[9] = {0};
3242141cc406Sopenharmony_ci			for (int row = 0; row < 3; row++) {
3243141cc406Sopenharmony_ci				for (int col = 0; col < 3; col++) {
3244141cc406Sopenharmony_ci					flatten[row * 3 + col] = matrix[row][col];
3245141cc406Sopenharmony_ci				}
3246141cc406Sopenharmony_ci			}
3247141cc406Sopenharmony_ci
3248141cc406Sopenharmony_ci			int rounded[9] = {0};
3249141cc406Sopenharmony_ci			ESCIRoundColorCorrectionMatrix(32, flatten, rounded);
3250141cc406Sopenharmony_ci
3251141cc406Sopenharmony_ci
3252141cc406Sopenharmony_ci			char ordered[9] = {0};
3253141cc406Sopenharmony_ci			for (int row = 0; row < 3; row++) {
3254141cc406Sopenharmony_ci				for (int col = 0; col < 3; col++) {
3255141cc406Sopenharmony_ci					int val = rounded[row * 3 + col];
3256141cc406Sopenharmony_ci					unsigned char oct = (unsigned char)abs(val);
3257141cc406Sopenharmony_ci					oct |= ((val < 0) ? (1 << 7) : 0);
3258141cc406Sopenharmony_ci					ordered[(signed char)index[row * 3 + col]] = oct;
3259141cc406Sopenharmony_ci				}
3260141cc406Sopenharmony_ci			}
3261141cc406Sopenharmony_ci			{
3262141cc406Sopenharmony_ci				cmd[pos++] = ordered[0];
3263141cc406Sopenharmony_ci				cmd[pos++] = ordered[1];
3264141cc406Sopenharmony_ci				cmd[pos++] = ordered[2];
3265141cc406Sopenharmony_ci				cmd[pos++] = ordered[3];
3266141cc406Sopenharmony_ci				cmd[pos++] = ordered[4];
3267141cc406Sopenharmony_ci				cmd[pos++] = ordered[5];
3268141cc406Sopenharmony_ci				cmd[pos++] = ordered[6];
3269141cc406Sopenharmony_ci				cmd[pos++] = ordered[7];
3270141cc406Sopenharmony_ci				cmd[pos++] = ordered[8];
3271141cc406Sopenharmony_ci				cmd[pos++] = 0; //padding
3272141cc406Sopenharmony_ci 				cmd[pos++] = 0; //padding
3273141cc406Sopenharmony_ci				cmd[pos++] = 0; //padding
3274141cc406Sopenharmony_ci
3275141cc406Sopenharmony_ci
3276141cc406Sopenharmony_ci				DBG(1, "color matrix\n");
3277141cc406Sopenharmony_ci				for (int i = 0; i < 9; i++)
3278141cc406Sopenharmony_ci				{
3279141cc406Sopenharmony_ci					DBG(1, "%d\n", ordered[i]);
3280141cc406Sopenharmony_ci				}
3281141cc406Sopenharmony_ci
3282141cc406Sopenharmony_ci			}
3283141cc406Sopenharmony_ci			cmd[pos] = 0;
3284141cc406Sopenharmony_ci		}
3285141cc406Sopenharmony_ci
3286141cc406Sopenharmony_ci	}
3287141cc406Sopenharmony_ci
3288141cc406Sopenharmony_ci
3289141cc406Sopenharmony_ci	status = esci2_para(s, cmd, pos);
3290141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
3291141cc406Sopenharmony_ci		goto end;
3292141cc406Sopenharmony_ci	}
3293141cc406Sopenharmony_ci
3294141cc406Sopenharmony_ci	/* start scanning */
3295141cc406Sopenharmony_ci	DBG(1, "%s: scanning...\n", __func__);
3296141cc406Sopenharmony_ci
3297141cc406Sopenharmony_ci	/* switch to data state */
3298141cc406Sopenharmony_ci	status = esci2_trdt(s);
3299141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
3300141cc406Sopenharmony_ci		goto end;
3301141cc406Sopenharmony_ci	}
3302141cc406Sopenharmony_ci
3303141cc406Sopenharmony_ci	/* first page is page 1 */
3304141cc406Sopenharmony_ci	s->pages = 1;
3305141cc406Sopenharmony_ci	s->scanning = 1;
3306141cc406Sopenharmony_ci	s->dummy = 0;
3307141cc406Sopenharmony_ci	s->scanEnd = 0;
3308141cc406Sopenharmony_ciend:
3309141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
3310141cc406Sopenharmony_ci		DBG(1, "%s: start failed: %s\n", __func__, sane_strstatus(status));
3311141cc406Sopenharmony_ci	}
3312141cc406Sopenharmony_ci
3313141cc406Sopenharmony_ci	return status;
3314141cc406Sopenharmony_ci}
3315141cc406Sopenharmony_ci
3316141cc406Sopenharmony_cistatic SANE_Status acquire_jpeg_data(epsonds_scanner* s)
3317141cc406Sopenharmony_ci{
3318141cc406Sopenharmony_ci
3319141cc406Sopenharmony_ci	SANE_Int read = 0;
3320141cc406Sopenharmony_ci
3321141cc406Sopenharmony_ci	SANE_Int jpegBufSize = s->params.bytes_per_line * s->params.lines;
3322141cc406Sopenharmony_ci	if (s->needToConvertBW)
3323141cc406Sopenharmony_ci	{
3324141cc406Sopenharmony_ci		jpegBufSize = s->params.pixels_per_line * s->params.lines;
3325141cc406Sopenharmony_ci	}
3326141cc406Sopenharmony_ci
3327141cc406Sopenharmony_ci
3328141cc406Sopenharmony_ci	s->frontJpegBuf = malloc(jpegBufSize);
3329141cc406Sopenharmony_ci	s->backJpegBuf = malloc(jpegBufSize);
3330141cc406Sopenharmony_ci	s->frontJpegBufLen  = 0;
3331141cc406Sopenharmony_ci	s->backJpegBufLen = 0;
3332141cc406Sopenharmony_ci
3333141cc406Sopenharmony_ci		// load all images, decode and fill buffer
3334141cc406Sopenharmony_ci	SANE_Int status = SANE_STATUS_GOOD;
3335141cc406Sopenharmony_ci
3336141cc406Sopenharmony_ci	int eofFront = 0;
3337141cc406Sopenharmony_ci	int eofBack = 0;
3338141cc406Sopenharmony_ci
3339141cc406Sopenharmony_ci
3340141cc406Sopenharmony_ci	status = eds_ring_init(&s->front, (s->params.bytes_per_line) * s->params.lines);
3341141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
3342141cc406Sopenharmony_ci				return status;
3343141cc406Sopenharmony_ci	}
3344141cc406Sopenharmony_ci
3345141cc406Sopenharmony_ci	status = eds_ring_init(&s->back, (s->params.bytes_per_line) * s->params.lines);
3346141cc406Sopenharmony_ci	if (status != SANE_STATUS_GOOD) {
3347141cc406Sopenharmony_ci			return status;
3348141cc406Sopenharmony_ci	}
3349141cc406Sopenharmony_ci
3350141cc406Sopenharmony_ci	while (1)
3351141cc406Sopenharmony_ci	{
3352141cc406Sopenharmony_ci		status = esci2_img(s, &read);
3353141cc406Sopenharmony_ci		DBG(20, "acquire_jpeg_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3354141cc406Sopenharmony_ci		if (read)
3355141cc406Sopenharmony_ci		{
3356141cc406Sopenharmony_ci			if (s->backside)
3357141cc406Sopenharmony_ci			{
3358141cc406Sopenharmony_ci				SANE_Byte* backBuffer = s->backJpegBuf + s->backJpegBufLen;
3359141cc406Sopenharmony_ci				memcpy(backBuffer, s->buf, read);
3360141cc406Sopenharmony_ci				s->backJpegBufLen += read;
3361141cc406Sopenharmony_ci			}else{
3362141cc406Sopenharmony_ci				SANE_Byte* frontBuffer = s->frontJpegBuf +  s->frontJpegBufLen ;
3363141cc406Sopenharmony_ci				memcpy(frontBuffer, s->buf, read);
3364141cc406Sopenharmony_ci				s->frontJpegBufLen  += read;
3365141cc406Sopenharmony_ci			}
3366141cc406Sopenharmony_ci		}
3367141cc406Sopenharmony_ci		if (status == SANE_STATUS_GOOD)
3368141cc406Sopenharmony_ci		{
3369141cc406Sopenharmony_ci
3370141cc406Sopenharmony_ci			DBG(20, "continue acquire image\n");
3371141cc406Sopenharmony_ci			continue;
3372141cc406Sopenharmony_ci		}
3373141cc406Sopenharmony_ci		else if (status == SANE_STATUS_EOF)
3374141cc406Sopenharmony_ci		{
3375141cc406Sopenharmony_ci			if (s->backside)
3376141cc406Sopenharmony_ci			{
3377141cc406Sopenharmony_ci				DBG(20, "eofBack\n");
3378141cc406Sopenharmony_ci				eofBack = 1;
3379141cc406Sopenharmony_ci			}else{
3380141cc406Sopenharmony_ci				DBG(20, "eofFront\n");
3381141cc406Sopenharmony_ci				eofFront = 1;
3382141cc406Sopenharmony_ci			}
3383141cc406Sopenharmony_ci		}else if (status == SANE_STATUS_CANCELLED)
3384141cc406Sopenharmony_ci		{
3385141cc406Sopenharmony_ci				// cancel cleanup
3386141cc406Sopenharmony_ci				esci2_can(s);
3387141cc406Sopenharmony_ci
3388141cc406Sopenharmony_ci				free(s->frontJpegBuf);
3389141cc406Sopenharmony_ci				free(s->backJpegBuf);
3390141cc406Sopenharmony_ci				s->frontJpegBuf = NULL;
3391141cc406Sopenharmony_ci				s->backJpegBuf = NULL;
3392141cc406Sopenharmony_ci				return status;
3393141cc406Sopenharmony_ci		}else{
3394141cc406Sopenharmony_ci				// error occurs cleanup
3395141cc406Sopenharmony_ci				free(s->frontJpegBuf);
3396141cc406Sopenharmony_ci				free(s->backJpegBuf);
3397141cc406Sopenharmony_ci				s->frontJpegBuf = NULL;
3398141cc406Sopenharmony_ci				s->backJpegBuf = NULL;
3399141cc406Sopenharmony_ci				return status;
3400141cc406Sopenharmony_ci		}
3401141cc406Sopenharmony_ci
3402141cc406Sopenharmony_ci
3403141cc406Sopenharmony_ci		if (s->isDuplexScan)
3404141cc406Sopenharmony_ci		{
3405141cc406Sopenharmony_ci			DBG(20, "eofFront  = %d eofBack  = %d\n", eofFront, eofBack);
3406141cc406Sopenharmony_ci				// acquire finish
3407141cc406Sopenharmony_ci			if (eofFront && eofBack)
3408141cc406Sopenharmony_ci			{
3409141cc406Sopenharmony_ci				DBG(20, "eofFront && eofBack end\n");
3410141cc406Sopenharmony_ci				break;
3411141cc406Sopenharmony_ci			}
3412141cc406Sopenharmony_ci		}else{
3413141cc406Sopenharmony_ci			if (eofFront)
3414141cc406Sopenharmony_ci			{
3415141cc406Sopenharmony_ci				DBG(20, "eofFront end\n");
3416141cc406Sopenharmony_ci				break;
3417141cc406Sopenharmony_ci			}
3418141cc406Sopenharmony_ci		 }
3419141cc406Sopenharmony_ci	 }
3420141cc406Sopenharmony_ci
3421141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
3422141cc406Sopenharmony_ci}
3423141cc406Sopenharmony_ci
3424141cc406Sopenharmony_cistatic SANE_Status
3425141cc406Sopenharmony_ciacquire_raw_data(epsonds_scanner* s)
3426141cc406Sopenharmony_ci{
3427141cc406Sopenharmony_ci	SANE_Int read = 0;
3428141cc406Sopenharmony_ci
3429141cc406Sopenharmony_ci		// load all images, decode and fill buffer
3430141cc406Sopenharmony_ci	SANE_Int status = SANE_STATUS_GOOD;
3431141cc406Sopenharmony_ci
3432141cc406Sopenharmony_ci	int eofFront = 0;
3433141cc406Sopenharmony_ci	int eofBack = 0;
3434141cc406Sopenharmony_ci	int firstWrite = 1;
3435141cc406Sopenharmony_ci
3436141cc406Sopenharmony_ci	while (1)
3437141cc406Sopenharmony_ci	{
3438141cc406Sopenharmony_ci		DBG(20, "acquire_raw_data loop start\n");
3439141cc406Sopenharmony_ci		status = esci2_img(s, &read);
3440141cc406Sopenharmony_ci		DBG(20, "acquire_raw_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status);
3441141cc406Sopenharmony_ci
3442141cc406Sopenharmony_ci		if (read)
3443141cc406Sopenharmony_ci		{
3444141cc406Sopenharmony_ci			if (firstWrite)
3445141cc406Sopenharmony_ci			{
3446141cc406Sopenharmony_ci				status = eds_ring_init(&s->front, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3447141cc406Sopenharmony_ci				if (status != SANE_STATUS_GOOD) {
3448141cc406Sopenharmony_ci					return status;
3449141cc406Sopenharmony_ci				}
3450141cc406Sopenharmony_ci
3451141cc406Sopenharmony_ci				status = eds_ring_init(&s->back, (s->params.bytes_per_line + s->dummy) * s->params.lines);
3452141cc406Sopenharmony_ci				if (status != SANE_STATUS_GOOD) {
3453141cc406Sopenharmony_ci					return status;
3454141cc406Sopenharmony_ci				}
3455141cc406Sopenharmony_ci				firstWrite = 0;
3456141cc406Sopenharmony_ci			}
3457141cc406Sopenharmony_ci
3458141cc406Sopenharmony_ci			DBG(20, "eds_ring_write  start\n");
3459141cc406Sopenharmony_ci			status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read);
3460141cc406Sopenharmony_ci			DBG(20, "eds_ring_write  end\n");
3461141cc406Sopenharmony_ci		}
3462141cc406Sopenharmony_ci		DBG(20, "acquire_raw_data3\n");
3463141cc406Sopenharmony_ci
3464141cc406Sopenharmony_ci		if (status == SANE_STATUS_GOOD)
3465141cc406Sopenharmony_ci		{
3466141cc406Sopenharmony_ci			DBG(20, "contiune acquire image\n");
3467141cc406Sopenharmony_ci			continue;
3468141cc406Sopenharmony_ci		}
3469141cc406Sopenharmony_ci		else if (status == SANE_STATUS_EOF)
3470141cc406Sopenharmony_ci		{
3471141cc406Sopenharmony_ci			if (s->backside)
3472141cc406Sopenharmony_ci			{
3473141cc406Sopenharmony_ci				eofBack = 1;
3474141cc406Sopenharmony_ci			}else{
3475141cc406Sopenharmony_ci				eofFront = 1;
3476141cc406Sopenharmony_ci			}
3477141cc406Sopenharmony_ci		}
3478141cc406Sopenharmony_ci		else if (status == SANE_STATUS_CANCELLED)
3479141cc406Sopenharmony_ci		{
3480141cc406Sopenharmony_ci			esci2_can(s);
3481141cc406Sopenharmony_ci			return status;
3482141cc406Sopenharmony_ci		}else{
3483141cc406Sopenharmony_ci				// error occurs cleanup
3484141cc406Sopenharmony_ci				return status;
3485141cc406Sopenharmony_ci		}
3486141cc406Sopenharmony_ci
3487141cc406Sopenharmony_ci		if (s->isDuplexScan)
3488141cc406Sopenharmony_ci		{
3489141cc406Sopenharmony_ci			// acquire finish
3490141cc406Sopenharmony_ci			if (eofFront && eofBack)
3491141cc406Sopenharmony_ci			{
3492141cc406Sopenharmony_ci				break;
3493141cc406Sopenharmony_ci			}
3494141cc406Sopenharmony_ci		}else{
3495141cc406Sopenharmony_ci			if (eofFront)
3496141cc406Sopenharmony_ci			{
3497141cc406Sopenharmony_ci				break;
3498141cc406Sopenharmony_ci			}
3499141cc406Sopenharmony_ci		}
3500141cc406Sopenharmony_ci	}
3501141cc406Sopenharmony_ci
3502141cc406Sopenharmony_ci
3503141cc406Sopenharmony_ci	int needBytes =  (s->params.bytes_per_line + s->dummy) * s->params.lines;
3504141cc406Sopenharmony_ci	{
3505141cc406Sopenharmony_ci		int available = eds_ring_avail(&s->front);
3506141cc406Sopenharmony_ci		if (available < needBytes)
3507141cc406Sopenharmony_ci		{
3508141cc406Sopenharmony_ci	 	  int required = needBytes - available;
3509141cc406Sopenharmony_ci          	   unsigned char* padding = (unsigned char*)malloc(required);
3510141cc406Sopenharmony_ci		   memset(padding, 255, required);
3511141cc406Sopenharmony_ci	 	   eds_ring_write(&s->front, padding, required);
3512141cc406Sopenharmony_ci		   free(padding);
3513141cc406Sopenharmony_ci
3514141cc406Sopenharmony_ci		}
3515141cc406Sopenharmony_ci
3516141cc406Sopenharmony_ci	}
3517141cc406Sopenharmony_ci	{
3518141cc406Sopenharmony_ci		int available = eds_ring_avail(&s->back);
3519141cc406Sopenharmony_ci		if (available > 0 && available < needBytes)
3520141cc406Sopenharmony_ci		{
3521141cc406Sopenharmony_ci	 	  int required = needBytes - available;
3522141cc406Sopenharmony_ci          	   unsigned char* padding = (unsigned char*)malloc(required);
3523141cc406Sopenharmony_ci		   memset(padding, 255, required);
3524141cc406Sopenharmony_ci	 	   eds_ring_write(&s->back, padding, required);
3525141cc406Sopenharmony_ci		   free(padding);
3526141cc406Sopenharmony_ci		}
3527141cc406Sopenharmony_ci
3528141cc406Sopenharmony_ci	}
3529141cc406Sopenharmony_ci
3530141cc406Sopenharmony_ci	if (s->isDuplexScan)
3531141cc406Sopenharmony_ci	{
3532141cc406Sopenharmony_ci		upside_down_backside_image(s);
3533141cc406Sopenharmony_ci	}
3534141cc406Sopenharmony_ci
3535141cc406Sopenharmony_ci	DBG(20, "acquire_raw_data  finish");
3536141cc406Sopenharmony_ci	return SANE_STATUS_GOOD;
3537141cc406Sopenharmony_ci
3538141cc406Sopenharmony_ci}
3539141cc406Sopenharmony_ci
3540141cc406Sopenharmony_cistatic SANE_Status
3541141cc406Sopenharmony_ciacquire_and_decode_jpeg_data(epsonds_scanner* s)
3542141cc406Sopenharmony_ci{
3543141cc406Sopenharmony_ci		SANE_Int status = acquire_jpeg_data(s);
3544141cc406Sopenharmony_ci		if (status == SANE_STATUS_GOOD)
3545141cc406Sopenharmony_ci		{
3546141cc406Sopenharmony_ci			DBG(20, "** %s:  sane status = %d needToConvertBW = %d \n", __func__, status, s->needToConvertBW);
3547141cc406Sopenharmony_ci
3548141cc406Sopenharmony_ci			// process front page
3549141cc406Sopenharmony_ci			if (s->frontJpegBufLen > 0)
3550141cc406Sopenharmony_ci			{
3551141cc406Sopenharmony_ci				eds_decode_jpeg(s, s->frontJpegBuf, s->frontJpegBufLen,  &s->front,0, s->needToConvertBW);
3552141cc406Sopenharmony_ci				free(s->frontJpegBuf);
3553141cc406Sopenharmony_ci				s->frontJpegBuf = NULL;
3554141cc406Sopenharmony_ci			}
3555141cc406Sopenharmony_ci			// process back page
3556141cc406Sopenharmony_ci			if (s->backJpegBufLen > 0)
3557141cc406Sopenharmony_ci			{
3558141cc406Sopenharmony_ci				eds_decode_jpeg(s, s->backJpegBuf, s->backJpegBufLen,  &s->back, 1,  s->needToConvertBW);
3559141cc406Sopenharmony_ci				free(s->backJpegBuf);
3560141cc406Sopenharmony_ci				s->backJpegBuf = NULL;
3561141cc406Sopenharmony_ci			}
3562141cc406Sopenharmony_ci
3563141cc406Sopenharmony_ci			if (s->isDuplexScan)
3564141cc406Sopenharmony_ci			{
3565141cc406Sopenharmony_ci				upside_down_backside_image(s);
3566141cc406Sopenharmony_ci			}
3567141cc406Sopenharmony_ci		}else{
3568141cc406Sopenharmony_ci			DBG(20, "** %s:  sane finish status = %d\n", __func__, status);
3569141cc406Sopenharmony_ci			return status;
3570141cc406Sopenharmony_ci		}
3571141cc406Sopenharmony_ci		return status;
3572141cc406Sopenharmony_ci}
3573141cc406Sopenharmony_ci
3574141cc406Sopenharmony_ciint sumLength = 0;
3575141cc406Sopenharmony_ci/* this moves data from our buffers to SANE */
3576141cc406Sopenharmony_ciSANE_Status
3577141cc406Sopenharmony_cisane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length)
3578141cc406Sopenharmony_ci{
3579141cc406Sopenharmony_ci	epsonds_scanner *s = (epsonds_scanner *)handle;
3580141cc406Sopenharmony_ci	SANE_Int read = 0;
3581141cc406Sopenharmony_ci
3582141cc406Sopenharmony_ci	if (s->canceling)
3583141cc406Sopenharmony_ci	{
3584141cc406Sopenharmony_ci		esci2_can(s);
3585141cc406Sopenharmony_ci		*length = 0;
3586141cc406Sopenharmony_ci		return SANE_STATUS_CANCELLED;
3587141cc406Sopenharmony_ci	}
3588141cc406Sopenharmony_ci
3589141cc406Sopenharmony_ci	int available = eds_ring_avail(s->current);
3590141cc406Sopenharmony_ci	/* anything in the buffer? pass it to the frontend */
3591141cc406Sopenharmony_ci	if (available > 0) {
3592141cc406Sopenharmony_ci
3593141cc406Sopenharmony_ci		DBG(18, "reading from ring buffer, %d left\n", available);
3594141cc406Sopenharmony_ci
3595141cc406Sopenharmony_ci		eds_copy_image_from_ring(s, data, max_length, &read);
3596141cc406Sopenharmony_ci
3597141cc406Sopenharmony_ci				// data is empty fin
3598141cc406Sopenharmony_ci		if (read == 0) {
3599141cc406Sopenharmony_ci			*length = 0;
3600141cc406Sopenharmony_ci			eds_ring_flush(s->current);
3601141cc406Sopenharmony_ci			eds_ring_destory(s->current);
3602141cc406Sopenharmony_ci			DBG(18, "returns EOF 2\n");
3603141cc406Sopenharmony_ci			return SANE_STATUS_EOF;
3604141cc406Sopenharmony_ci		}
3605141cc406Sopenharmony_ci		*length = read;
3606141cc406Sopenharmony_ci
3607141cc406Sopenharmony_ci		return SANE_STATUS_GOOD;
3608141cc406Sopenharmony_ci	}else{
3609141cc406Sopenharmony_ci		*length = 0;
3610141cc406Sopenharmony_ci		eds_ring_flush(s->current);
3611141cc406Sopenharmony_ci		eds_ring_destory(s->current);
3612141cc406Sopenharmony_ci		DBG(18, "returns EOF 1\n");
3613141cc406Sopenharmony_ci		return SANE_STATUS_EOF;
3614141cc406Sopenharmony_ci	}
3615141cc406Sopenharmony_ci}
3616141cc406Sopenharmony_ci
3617141cc406Sopenharmony_ci/*
3618141cc406Sopenharmony_ci * void sane_cancel(SANE_Handle handle)
3619141cc406Sopenharmony_ci *
3620141cc406Sopenharmony_ci * Set the cancel flag to true. The next time the backend requests data
3621141cc406Sopenharmony_ci * from the scanner the CAN message will be sent.
3622141cc406Sopenharmony_ci */
3623141cc406Sopenharmony_ci
3624141cc406Sopenharmony_civoid
3625141cc406Sopenharmony_cisane_cancel(SANE_Handle handle)
3626141cc406Sopenharmony_ci{
3627141cc406Sopenharmony_ci	DBG(1, "** %s\n", __func__);
3628141cc406Sopenharmony_ci	((epsonds_scanner *)handle)->canceling = SANE_TRUE;
3629141cc406Sopenharmony_ci}
3630141cc406Sopenharmony_ci
3631141cc406Sopenharmony_ci/*
3632141cc406Sopenharmony_ci * SANE_Status sane_set_io_mode()
3633141cc406Sopenharmony_ci *
3634141cc406Sopenharmony_ci * not supported - for asynchronous I/O
3635141cc406Sopenharmony_ci */
3636141cc406Sopenharmony_ci
3637141cc406Sopenharmony_ciSANE_Status
3638141cc406Sopenharmony_cisane_set_io_mode(SANE_Handle __sane_unused__ handle,
3639141cc406Sopenharmony_ci	SANE_Bool __sane_unused__ non_blocking)
3640141cc406Sopenharmony_ci{
3641141cc406Sopenharmony_ci	return SANE_STATUS_UNSUPPORTED;
3642141cc406Sopenharmony_ci}
3643141cc406Sopenharmony_ci
3644141cc406Sopenharmony_ci/*
3645141cc406Sopenharmony_ci * SANE_Status sane_get_select_fd()
3646141cc406Sopenharmony_ci *
3647141cc406Sopenharmony_ci * not supported - for asynchronous I/O
3648141cc406Sopenharmony_ci */
3649141cc406Sopenharmony_ci
3650141cc406Sopenharmony_ciSANE_Status
3651141cc406Sopenharmony_cisane_get_select_fd(SANE_Handle __sane_unused__ handle,
3652141cc406Sopenharmony_ci	SANE_Int __sane_unused__ *fd)
3653141cc406Sopenharmony_ci{
3654141cc406Sopenharmony_ci	return SANE_STATUS_UNSUPPORTED;
3655141cc406Sopenharmony_ci}
3656